"나선형"규칙 종류는 다음 우선 순위 규칙에서 제외됩니다.
T *a[] -- a is an array of pointer to T
T (*a)[] -- a is a pointer to an array of T
T *f() -- f is a function returning a pointer to T
T (*f)() -- f is a pointer to a function returning T
첨자 []
와 함수 호출 ()
연산자는 단항보다 더 높은 우선 순위를 가지고 있습니다 *
그래서, *f()
같은 구문 분석 *(f())
과 *a[]
같은 구문 분석됩니다 *(a[])
.
당신이 배열 또는 함수에 대한 포인터에 대한 포인터를 원한다면, 당신은 명시 적으로 그룹에 필요한 *
에서와 같이 식별자, (*a)[]
또는 (*f)()
.
그럼 당신은 그 실현 a
및 f
단지 식별자보다 더 복잡하게 표현 될 수있다; 으로는 T (*a)[N]
, a
단순한 식별되거나, 그와 같은 함수를 호출 할 수있는 (*f())[N]
( a
-> f()
), 또는이 같은 배열 될 수있다 (*p[M])[N]
( a
-> p[M]
), 또는이 같은 함수 포인터 배열 될 수있다 (*(*p[M])())[N]
( a
-> (*p[M])()
) 기타
간접 연산자 *
가 단항 대신 접두어 인 경우 좋을 것이므로 선언을 왼쪽에서 오른쪽으로 읽는 것이 다소 쉬워집니다 ( void f[]*()*();
확실히보다 낫습니다 void (*(*f[])())()
).
이와 같은 털이 선언을 발견하면 가장 왼쪽의 식별자 를 찾아 위의 우선 순위 규칙을 적용하여 함수 매개 변수에 재귀 적으로 적용하십시오.
f -- f
f[] -- is an array
*f[] -- of pointers ([] has higher precedence than *)
(*f[])() -- to functions
*(*f[])() -- returning pointers
(*(*f[])())() -- to functions
void (*(*f[])())(); -- returning void
signal
표준 라이브러리 의 기능은 아마도 이런 종류의 광기에 대한 유형 표본 일 것입니다.
signal -- signal
signal( ) -- is a function with parameters
signal( sig, ) -- sig
signal(int sig, ) -- which is an int and
signal(int sig, func ) -- func
signal(int sig, *func ) -- which is a pointer
signal(int sig, (*func)(int)) -- to a function taking an int
signal(int sig, void (*func)(int)) -- returning void
*signal(int sig, void (*func)(int)) -- returning a pointer
(*signal(int sig, void (*func)(int)))(int) -- to a function taking an int
void (*signal(int sig, void (*func)(int)))(int); -- and returning void
이 시점에서 대부분의 사람들은 "use typedefs"라고 말합니다.
typedef void outerfunc(void);
typedef outerfunc *innerfunc(void);
innerfunc *f[N];
그러나...
식에 어떻게 사용 f
하시겠습니까? 포인터 배열이라는 것을 알고 있지만 올바른 함수를 실행하는 데 어떻게 사용합니까? typedef를 살펴보고 올바른 구문을 퍼즐로 만들어야합니다. 대조적으로, "네이 키드 (naked)"버전은 눈에 띄지 않지만, 표현식에서 사용 하는 방법을 정확하게 알려줍니다 f
(즉, (*(*f[i])())();
어느 함수도 인수를 사용하지 않는다고 가정).