본문으로 바로가기

 

 

배열을 포인터 형으로 바꾸기

 

int data[3];

data[2] =  2;

*(data + 3) = 2;

 

int data[2][3];

data[1][2] = 3;

data[1]을 A로 치환한다.

A[2] = 3;

*(A + 2) = 3;

*(data[1] + 2) = 3;

*(*(data + 1) + 2) = 3;

 

 

함수 포인터

 

함수의 포인터는 기계어 명령문을 가리킬 수 있는 포인터이다. 함수의 ip를 기억했다가 사용한다.

일반적인 포인터는 데이터 포인터를 말한다. 즉, 행위는 그대로이지만 매개변수의 조건을 바꾸어줄 수 있다.

특정 함수를 구성하는 시작 명령의 위치를 가리키는 포인터이다. 함수의 포인터를 이용하여 주로 함수를 호출하여 실행한다.

 

int Sum(int a, int b)

{

    int res = 0;                    //  이 명령문이 저장된 위치의 주소가 Sum 함수의 시작 주소와 같다.

    res = a + b;

    return res;

}

 

int res = Sum(2, 3);

∑                              //  Sum 함수의 첫 번째 명령문의 주소를 의미한다. & 연산자가 생략 가능해 함수의 이름(Sum)만 적어도

     해당 함수 첫 번째 명령문의 주소를 의미한다. 

 

함수의 주소 값으로 함수 실행하기

 

함수 포인터는 함수 원형을 사용해서 포인터를 선언한다.

 

함수 포인터 선언 및 함수의 주소 대입

 

int (*p) (int, int)                //  Sum 함수를 가리킬 수 있는 포인터를 한다. 매개변수의 개수, 매개변수의 자료형을 알아야 한다.

            이 포인터가 가리키는 함수를 호출 하는데 2, 3을 매개변수로 가진다.

p = &Sum                          //   Sum 함수의 주소를 p에 저장한다.

 

함수 포인터로 함수 호출하기

 

int res = (*p)(2, 3)            //  int res = Sum(2, 3); 과 동일하다.

 

이렇게 복잡하게 함수의 포인터를 사용하는 이유는 구체적인 대상이 없어도 사용가능하기 때문이다.

일반적인 포인터와 마찬가지로 함수 포인터도 행위만 있지 대상은 정해지지 않았다. 나중에 호출할 때 대상만 정해주면 된다.

 

함수의 원형이 같은 함수들을 묶기

 

함수의 포인터로 같은 수의 매개변수와 자료형 그리고 같은 형태의 반환 값을 가지는 함수들을 그룹으로 묶을 수 있다.

 

위 사칙연산들은 함수의 원형이 같다. int [연산이름](int a, int b); 즉, int (*p) (int, int) 형으로 묶을 수 있다.

int (*p) (int, int)로 사칙연산의 함수를 모두 호출할 수 있다.

 

int (*p[4]) (int, int) = (&Sum, &Sub, &Mul, &Div);        //  &연산자 생략 가능하다. 함수의 포인터도 배열을 사용할 수 있다.

 

 

 

 

라이브러리를 만드는 라이브러리 프로그래머

 

라이브러리 프로그래머(판매자)는 자신의 기술로 함수를 만들어 함수를 라이브러리 형식의 파일로 사용자(구매자)에게 판매한다. 사용자는 라이브러리를 받아서 헤더 파일에 선언하면 함수를 사용할 수 있다.

 

라이브러리 프로그래머의 고민

 

고객의 요구가 늘어나면서 프로그래머가 계속해서 고객에 요구에 따라 소스코드를 수정하고 재배포하는 것은 매우 힘들다. 즉, 고객의 모든 요구를 반영할 수 없다. 이런 재배포가 힘든 상황에서 라이브러리에 포함된 함수는 본래의 기능을 유지하고 사용자가 원하는 경우에 사용자가 직접 함수의 기능을 수정해서 상용할 수 있도록 제공하는것이  함수 포인터의 기능이다.

 

void (*p) (int *);                                             //  반환값이 없고 매개변수로 int * 형을 받을 수 있는 함수의 포인터이다.

 

매개 변수로 받은 두개의 수의 합을 구하는 함수를 만든다고 가정해보자. 아래와 같이 사용해 주면 된다.

 

int k = Sum(2, 3, NULL);                                //  원래 함수의 덧셈 기능만 사용할려면 NULL을 추가로 적어준다.

 

int Sum(int a, int b, void (*fp) (int *))            //  void (*fp) (int *)는 함수의 포인터이다.

{

return a+b;

}

 

만일 사용자의 요구가 a에 음수가 오더라도 양수로 바꿔서 더하라는 요청이 온다면 아래와 같이 작성하면 된다.

 

int k = Sum(2, 3, Modify);                              //  변형해서 사용할 때 Modify가 먼저 호출된다.

 

int Sum(int a, int b, void (*fp) (int *))            //  void (*fp) (int *)는 함수의 포인터이다.

{

if( fp != NULL) (*fp)(&a);                         //  이 함수는 a에 대해서 미래를 예측할 수 있다. 즉, 미래를 대처할 수 있는 함수이다.

return a+b;

}

 

void Modify(int *a)                                       //  사용자의 요구가 직접 반영되는 부분이다.

{                                                                   //  사용자가 직접 작성한다.

if(*a<0)

*a = *a * -1;

}

 

위 함수를 보면 Sum 함수는 바뀌지 않고 사용자가 Modify를 추가한 것이다. Modify 함수로 인해 Sum 함수가 바뀌는 구조이다.

또한 Sum 함수를 만들 때 함수 포인터를 사용하면 사용자가 만든 Modify 함수가 없어도 에러 없이 컴파일이 된다.

 

콜백 함수

 

명시적으로 호출한것이 아니라 함수 포인터에 의해서 호출된다. 자싱이 함수를 구현했지만 언제 어떻게 호출되는지 알 수 없다.

 

c++

 

c, c++언어는 철학의 차이이다.

c, c++은 누가 더 좋다의 문제가 아니라 누가 더 어떠한 상황에 적합한것 인지의 차이이다.

c, c++은 성향 차이일 뿐 c, c++은 호환이 가능하다.

c언어는 절차 지향 프로그램이고 c++언어는 객체 지향 프로그램이다. 하지만 객체 지향 프로그램은 모두 c++을 가리키는것이 아니며 많은 객체 지향 프로그램 중 하나가 c+언어일 뿐이다. 또한 간혹 "c++이 객체 지향 프로그램이 아니다"라고 말하는 사람이 있는데 그 의미는 c++언어가 객체 지향만 할 수 있는 언어가 아니라 다양한 기능을 할 수 있다는 뜻이다.

 

c는 묘사하는 문법이다. 필요한 함수가 생기면 그때 그때 만들어서 사용한다.

c++은 절략을 짜는 문법이다. 전략을 우선 짜고 프로그래밍을 하는 언어이다. 전략을 잘 짜는 것은 경험에서 나온다. 또한 이론적으로 좋아지고 있는 문법들이 보강되고 있다.

 

c언어의 장점 : 효율이 좋다.

c언어의 단점 : 내부적 변화에 좋지 않다. 변화에 대처하기 힘들다. 함수와 데이터가 직접 대면하는 관계이기 때문에 데이터에 변화가 오면 함수에 영향을 미친다.

 

c++언어의 장점 : 변화에 영향을 받지 않는다. 융통성이 좋아진다.

c++언어의 단점 : 속도가 느리다.

 

c++은 객체 단위로 묶어서 자신이 해야할 일(역할)이 줄어든다.

c++은 사용자를 위한 문법(언어)이 아니라 프로그래머를 위한 문법(언어)이다.

 

프로그램은 데이터와 함수로 이루어져 있다. 데이터는 함수가 사용하는 것이다. 모든 함수는 데이터를 바라 보고 있는 구조이다.

즉, 변화는 데이터에 있다. 이 데이터가 모든 변화의 키이다. 이 데이터를 어떠한 관점에서 바라보는가가 데이터 유지보수의 키이다.

데이터의 변화를 줄이고 막아야 할 때 데이터가 바뀌는 길목을 최대한 하나로 줄이면 된다. 이렇게 되면 예외, 현상은 길목에서 잘 대처하면 된다.

c++ 문법이 데이터가 바뀌는 길목을 하나로 줄여준다. 따라서 데이터 변화 대처가 용이하다.

 

규칙을 찾고 표준을 찾아서 객체를 만드는 것이 c++ 언어의 특징이다.

 

객체(Object)란 무엇일까?

 

일상적인 행위나 작업을 표준화 시켜 하나의 제품으로 만들어 놓은것이다. 비슷한 행위가 반복되는것 중 표준적인 행위를 꾸며 제품으로 만드는 것이다.

 

함수 vs 객체

 

함수는 명령을 그룹짓는다.

객체는 함수를 어떻게 사용해야 하는지 그룹 짓는 행위이다. 

 

객체와 c의 차이

 

프로그램을 하나 만들었다면 그 다음 만들 프로그램은 비슷한 프로그램을 만들 확률이 매우 높다.

새로운 프로그램을 잘 만드는것 보다 기존의 프로그램을 잘 활용하는것이 더 중요하다.

c++ 언어는 처음 만들 때는 힘들지만 한 번 만들면 생산성이 매우 좋다. 생산성이 매우 좋도록 입각해서 만들어진 언어이다.