C언어 선언은 굉장히 복잡하다.
그러나 해석하는 법만 제대로 학습하면, C언어의 어떤 선언이든 쉽게 읽어낼 수 있다.void (*siganl(int sig, void (*func)(int)))(int);여기서
signal의 데이터 형을 온전하게 유도해낼 수 있는가?
위의 선언을 해석해 낼 수 없다면, 이 글을 한 번 읽어보는 것을 추천한다.
읽다가 이해가 안되더라도 일단 넘어가며 읽어보길 추천한다.
적용 단계에서 하나 둘씩 이해가 될 것이다.
하지만, 빨간색으로 강조한 punctuator 읽는 법은 꼭 암기해야 한다.
*()()사이에 parameter의 type name(데이터형명)을 적어준다.void foo(int size);는 function(int) returning void가 된다.[][n]으로 선언됐다면, array of n ~이라고 적어준다.int arr[4];는 array of 4 int가 된다.()=[]>*[], ())가 포인터를 의미하는 punctuator(*)보다 명칭과 먼저 묶인다.int *pi;
pi의 데이터 타입은 pointer to int다.int foo(void);
void bar(int);
foo의 타입은 function returning int다.bar의 타입은 function(int) returning void다.int arr[5];
arr의 타입은 array of 5 int다.int *foo(void);
()우선순위가 *보다 높으므로 명칭 foo와 먼저 묶인다.foo의 타입은 function returning ~ 형태로 시작한다.foo와 *가 묶인다.foo의 타입은 function returning pointer to int가 된다.int *arr[5];
[]가 먼저 명칭 arr와 묶인다.*와 묶인다.arr의 타입은 array of 5 pointer to int가 된다.int *handler[5](void); /* wrong */
handler 양 옆에 있는 * vs [] 중 [] 우선순위가 더 높다.* vs ()를 비교해야 하는데, 규칙에 따라 ()우선순위가 높다.*와 결합해서 array of 5 function returning pointer to int된다.int (*handler[5])(void); /* correct */
()로 결합되는 우선순위를 바꿀 수 있다.*handler[5]를 둘러 싼 ()는 함수를 의미하는 punctuator가 아닌 괄호 연산자임을 주의해야 한다.[]가 먼저 명칭 handler와 묶이므로, array of 5 ~로 시작한다.*와 먼저 묶이므로, array of 5 pointer to ~가 된다.()와 묶여 handler의 타입은 array of 5 pointer to function returning int가 된다.const, volatile, restrict같은 키워드를 Type Qualifier라고 한다.int와 const int 그리고 const volatile int모두 구분되는 데이터 타입이다.const int * const cpci = (void *)0;
cpci의 데이터 타입은 const pointer to const int가 된다.void (*siganl(int sig, void (*func)(int)))(int);
signal명칭이 과연 어떤 데이터 타입인지 해석해보자.siganl이 우선순위 규칙에 따라 ()와 먼저 결합된다.sig의 타입은 int다.void (*func)(int))로 조금 복잡한데, 이 것도 지금까지 배운 방식대로 해석해내면 된다.func의 타입은 pointer to function(int) returning void가 된다.signal은 function(int, pointer to function(int) returning void) returning ~형태가 된다.signal은 괄호 연산자()에 의해 *와 결합된다.()와 결합된다.signal의 타입은 function(int, pointer to function(int) returning void) returning pointer to function(int) returning void다."그래서 결국 그 명칭의 데이터 타입이 뭔데?"
signal은 굉장히 복잡한 선언을 갖지만, 결국 어찌됐든 함수(function)다.signal의 최종유도형을 함수라고 한다.여담이지만, C++에서
&punctuator는 reference to ~로 읽으면 된다.
그럼, 함수를 리턴하는 고차함수인가요?