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 ~로 읽으면 된다.