본문 바로가기

데브코스

객체 지향 프로그래밍

컴파일 언어 이해하기(3)

함수 포인터

int (*func)(int a); // 자료형 (*함수 포인터 이름)(인자 목록)
#inclde <stdio.h>

int plus(int a, int b) {
	return a+b;
}

int main() {
	int a=20;
    int b=10;
    int (*fptr)(int pa, int pb);
    
    fptr = plus;
    int result = fptr(a,b); // 간접 참조 
    
    printf("결과값: %d\n", result);
    
    return 0;
}

: 함수명 앞에 *만 붙여주면 함수 포인터가 선언된다.

: 함수 포인터도 포인터이므로 주소값을 저장한다. 

 

함수 포인터의 사용 이유 ( 왜 직접 호출 x ?)

: 메모리의 크기 및 위치가 결정되는 시점은 컴파일 타임(정적 바인딩) 또는 런타임 시점(동적 바인딩)

: 비주얼 스튜디오 코드에서 사용되는 extension 들은 플러그인 방식으로 동작 

     ➡️ 새로운 기능을 추가해도 매번 다시 컴파일 해야 하는 불편함이 없음

: 함수 포인터의 사용은 프로그램의 유연한 확장성을 제공

 

구조체

하나 이상의 서로 다른 종류의 변수들을 묶어서 새로운 데이터 타입을 정의하는 것

구조체 그룹: 정수형, 문자형, 실수형, 포인터, 배열

 

구조체를 사용하는 이유

연관된 변수들을 하나로 묶어서 관리함으로써 데이터 관리에 유용하다.

데이터 양(변수의 개수)이 많아지면 구조체가 유리하다. 

 

구조체의 기본 형태

struct student {
	char name[10]; // 구조체 멤버
	int age;
	int height;
}

➡️ 구조체 student 는 사용자인 내가 정의한 새로운 데이터 타입이다. 

 

구조체 멤버에 접근하기 

[구조체 변수명].[구조체 멤버]

ex) st1.name, st1.age

➡️ 멤버에 접근 시 점(.)을 사용하는데, 이를 직접 접근이라고 한다. 

 

공용체

: 사용자 정의 자료형

: 구조체와 차이점은 메모리 공간을 공유한다는 점이다.

union unTemp {
	char a;
	int b;
	double c;
}

 

열거형

데이터들을 열거한 집합

enum Week {
    sun=0,
    mon,
    tue,
    wed,
    thu,
    fri,
    sat
};

: 열거형의 멤버들은 각 요일을 나타낸다.

: 첫 번째 멤버 sun 을 0으로 설정하면 다음 멤버 mon 은 1씩 증가한다. 

 

동적 메모리 할당

메모리 영역

 

코드 영역

: 실행할 명령어들이 순서대로 쌓인다. CPU 가 이 영역에서 명령어들을 하나씩 가져다 처리한다.

 

스택 영역

: 후입 선출 구조, 나중에 들어온 녀석이 먼저 빠져 나간다. 

: 지역 변수 및 매개변수 등은 모두 스택 메모리를 사용

 

힙 영역

: 힙은 컴파일 시가 아닌 실행 시 사용자로부터 할당 메모리를 입력 받음

 

데이터 영역

: 전역 변수와 static 변수가 저장되는 메모리 영역. 이 메모리는 프로그램 종료 시 소멸 

 

동적 메모리 할당

void * malloc(size_t size);

void* 의 의미 : 타입이 지정되지 않은 포인터 ( 난 당신이 원하는 메모리 크기만큼 할당해줄테니, 메모리는 당신이 원하는 형태로 정해서 사용하세요. ) 

#include <stdio.h>
{
    int num;
    int *student;
    
    printf("학생 수를 입력하세요 :");
    scanf("%d", &num);
    
    student= (int*)malloc(sizeof(int)*num);
    
    if(student == NULL){
    	printf("메모리가 할당되지 않았습니다.\n");
        return 0;
    }
    
    printf("할당된 메모리의 크기는 %d 입니다.\n", sizeof(int)*num);
    free(student);
}

객체 지향 프로그래밍

객체 : 영문으로 Object, '사물' 을 나타내는 추상적인 개념

지향:  영문으로 Oriented, '~를 향한다' 는 의미

 

구조적 프로그래밍 vs 객체 지향 프로그래밍

구조적 프로그래밍

: 순차적, 하향식, 폭포수 방식

: 기능적인 기본 단위는 함수이다.

 

객체 지향 프로그래밍

: 기능 단위는 객체이다 => 유연하다

: 대표적인 예가 이벤트 기반의 모든 윈도우 프로그램

 

추상화

추상: 대상에서 특징만을 뽑아낸 것

 

캡슐화

: 은닉하다, 숨긴다의 의미

: 캡슐화 한다는 것은 외부에서 그 내부를 볼 수 없게 한다는 의미

: 외부로부터 데이터를 조작할 인터페이스가 필요

: 클래스 = 데이터 + 메소드 

 

클래스

: 사전적인 의미로는 '학급'

: 클래스는 사용자 정의 데이터 타입이다 => 추상적인 데이터 타입

: 클래스의 본질은 데이터 타입이라는 점

: 구조체와 비슷, 멤버 변수멤버 함수로 구성됨

 

클래스의 구성

: 사물의 특성을 정리하여 필드와 메소드로 표현하는 과정이 추상화

: 추상화된 결과를 하나의 클래스에 포함시키고 스스로 보호하는 것을 캡슐화 

 

클래스 선언 형식

: 클래스 선언 시 class 키워드를 쓰고, 그 뒤에 클래스 이름을 붙인다.

: 클래스의 요소로는 생성자, 멤버 변수, 메소드 등으로 구성된다. 

class Dog {
	private int eyes, nose, mouse,ears;
	public void bark(){}
}

 

접근 지정자

  • public : 누구나 접근 가능하다.
  • protected: 상속 관계에 있을 때 상속 받은 자식 클래스에서 접근이 가능하다. 그 외에는 접근 불가
  • internal: 같은 어셈블리(프로젝트) 내의 모든 클래스가 접근 가능하다.
  • protected internal: protected 와 internal 의 의미를 모두 포함한다.
  • private : 내 클래스 내부에서만 접근 가능하고, 외부에서는 절대 접근할 수 없다. 

객체의 선언

: 데이터 타입을 통해 변수를 선언할 수 있다.

: 클래스를 통해 선언한 변수를 객체라고 한다.

Dog a = new Dog();

 

생성자(constructor)

: 객체도 본질적으로 변수이므로 선언되면 초기화 해야한다.

: 객체 생성시 초기화 전용 메소드를 제공하는데 바로 생성자이다.

: 객체 생성시 자동으로 호출되는 메소드

⚠️ 클래스 이름과 이름이 동일해야 한다, 리턴 타입이 필요없다. 

 

상속성

: 이미 완성된 클래스를 다른 클래스에 상속할 수 있다.

: 부모 클래스로부터 상속을 받을 때 클래스 이름 끝에 콜론(:) , 자바의 경우 extends 를 붙인 후 부모 클래스의 이름을 적는다. 

 

다형성

: 함수의 이름이 같더라도 전달 인자의 타입이나 개수에 따라 구분된다.

: 객체 지향에서는 대표적으로 오버로딩(overloading)과 오버라이딩(overriding) 기법이 있다. 

 

오버로딩

: 사전적 의미 => '과적하다' , '적재하다' 

: 겉모습은 똑같지만 내용이 다른 경우

: 이름이 같은 함수일지라도 전달인자 타입이나 개수가 다른 경우 

int Plus ( int a, int b) {
	return a+b;
}

char Plus ( char a, char b) {
	return a+b;
}

 

오버라이딩

: 사전적 의미 => '위로 올라탄다' , '엎어친다' 는 의미를 갖는다.

: 무언가에 올라타서 기존의 것을 덮어 버린다는 개념

: 상속의 개념이 기반이 되어야한다. 

 

인터페이스

: 메소드의 목록만을 가지고 있는 명세, 사용자 정의 타입

: 메소드의 목록만 선언하고 구현은 하지 않는다.

 

인터페이스를 사용하는 이유

  • 인터페이스는 본체가 정의되지 않는 추상 메소드만 갖는다.
  • 인터페이스의 목적은 기존의 기능을 추가하거나 수정의 개념보다는 동일한 개념의 기능을 새롭게 구현하는 기능이다.
  • 공동 작업 시 표준을 정하는 역할
public interface IUnit{
	void Attack();
	void Move();
}

public class Zergling: IUnit {
    public void Attack(){ ... }
    public void Move(){ ... }
}

 

메모리 관리

  • 플랫폼 기반의 객체 지향 언어는 가비지 컬렉터가 메모리를 자동 관리한다.
  • 백그라운드에서 더 이상 사용되지 않는 메모리를 찾아 회수한다.

람다 

익명 메소드

  • 메소드를 미리 정의하지 않고 사용할 때 정의한다.
  • 코드가 간결해진다.
  • 별도의 메소드를 만들지 않으므로 코딩 오버헤드를 줄일 수 있다.
  • 내용 자체가 복잡하면 안된다.
  • 람다식에서 사용된다. 

람다식

  • 기존 익명 메소드를 더욱 간결하게 만든다. 
  • 코드를 짧고 간결하게 표현하는 것이 목적이다. 

람다식 표현

  • (인수) => 표현식 또는 명령문
  • (x,y) => x+y 람다식은 "x와 y가 x+y 가 된다 " 로 읽는다. 

🌟 배운 점

오늘 드디어 객체 지향 프로그래밍에 대해 배웠다. 이전에 자바를 배워서 오늘 배운 내용을 이해하는 데 큰 어려움은 없었다. 하지만 자바스크립트를 사용하면서 잊고 있던 부분들을 다시 상기하고 복습할 기회가 되었다. 이제 타입스크립트를 배우게 되는데, 자바스크립트와 어떤 점이 다르고, 또 어떤 면에서 더 편리할지 기대가 된다.

'데브코스' 카테고리의 다른 글

타입스크립트(2)  (0) 2024.10.29
타입스크립트(Typescript)  (2) 2024.10.28
컴파일 언어 이해하기(2)  (1) 2024.10.26
컴파일 언어 이해하기  (0) 2024.10.24
자바스크립트(2)  (3) 2024.10.23