· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
CLangauge Complex Declaration

함수 포인터나 복잡한 선언이 나올 경우 당황하지 않기 위해 쉽게 읽는 법에 대해 다루겠습니다.

일단 가장 먼저 다음 세 개 목록을 외우시기 바랍니다:

연산자읽는 법주의사항
*a pointer to
(...)a function(...) returning여기서 "..."는 인자 목록(parameter list)임
NarrayN of여기서 N은 배열 크기를 나타냄

복잡한 선언을 읽는 방법은 다음과 같습니다:

  • 이름(identifier)이 있는 곳부터 차례대로 읽는다.
  • 읽는 순서는 연산자 결합 순위가 높은 것부터 읽는?

위 표에 나온 연산자는 "읽는 법"에 따라 읽되, 위 표의 괄호는 함수 선언을 위한 것입니다. 연산자 우선 순위를 변경하기 위한 괄호는 읽지 않습니다.

예를 들어 아래 선언을 읽어 봅시다:

int *a;

먼저 이름을 찾아야 합니다. 위 선언에서 "a"가 이름이니까, "a"부터 읽어나가면 됩니다. a에서 가장 먼저 결합하는 기호는 "*"입니다. 따라서 위의 표를 참고로 하여 읽으면 다음과 같습니다:

a = a pointer to ...

그럼 이제 나머지는 "int"이므로 그냥 읽습니다:

a = a pointer to int

즉 "a"는 int를 가리키는 포인터 타입입니다.

좀 더 어려운 예를 들어봅시다.

int *(*foo)(int, int);

위 예에서 이름은 "foo"이므로, foo에서부터 읽어 나가면 됩니다. 가장 먼저 결합하는 것은 "foo"와 함께 괄호 안에 있는 "*"입니다. 차례대로 읽는 것을 표로 나타내면 다음과 같습니다 (현재 읽고 있는 부분은 @...@ 사이의 부분입니다):

 int  * (@*foo@)(int, int) ;foo - a pointer to ...
 int  *@( *foo )(int, int)@;foo - a pointer to a function(int, int) returning ...
 int @* ( *foo )(int, int)@;foo - a pointer to a function(int, int) returning a pointer to ...
@int  * ( *foo )(int, int)@;foo - a pointer to a function(int, int) returning a pointer to int.

즉 우리말로 읽자면, "foo"는 "int를 가리키는 포인터를 리턴하는 함수 (인자는 두 개의 int)를 가리키는 포인터"라 할 수 있습니다.

흔히 typedef를 써서 위와 같은 함수 포인터를 다른 이름으로 정의합니다:

typedef int (*proc_t)(const void *);

이 경우, "typedef"를 빼고 읽으면 됩니다. 즉,

proc_ta pointer to function(const void *) returning int.

물론 "typedef"를 썼으므로 이는 변수 선언이 아니라, 새로운 타입을 정의한 것이죠.

마지막으로 주의할 것은, 함수 인자에 이름이 있을 경우, 어떤 것이 기준이 되는 이름인지 잘 알고 읽어야 합니다. 예를 들어:

int (*proc_t)(int type, const void *data);

여기서 기준이 되는 이름은 "type", "data"가 아닌 "proc_t"입니다. 따라서 proc_t를 해석할 때에는 "type"이나 "data"에 신경쓸 필요는 없습니다.

proc_ta pointer to function(int type, const void *data) returning int.

끝 - [http]신성국


TODO. 배열 N에 대한 예제를 만들 것.

TODO. 예제. "int (*ap)[30];", "(*(void(*)())0)();", "void (*(*signal)(int, void (*)(int)))(int);"에 대한 설명을 넣을 것.


int (*ap)[30]
  int   (@*ap@)[30] ;ap - a pointer to ...
  int  @( *ap )[30]@;ap - a pointer to array[30] of
 @int   ( *ap )[30]@;ap - a pointer to array[30] of int

int *ap[30] (pointer arrays)
  int   *@ap[30]@ ;ap - an array[30] of ...
  int   @*ap[30]@ ;ap - an array[30] of a pointer to ...
  @int   *ap[30]@ ;ap - an array[30] of a pointer to int

void (*(*signal)(int,void(*)(int)))(int);
  void ( * (@*signal@)(int,void(*)(int)) )(int) ;signal - a pointer to ...
  void ( *@( *signal )(int,void(*)(int))@)(int) ;signal - a pointer to a function(int,void(*)(int)) returning ...
  void (@* ( *signal )(int,void(*)(int))@)(int) ;signal - a pointer to a function(int,void(*)(int)) returning a pointer to ...
  void@( * ( *signal )(int,void(*)(int)) )(int)@;signal - a pointer to a function(int,void(*)(int)) returning a pointer to a function(int) returning ...
 @void ( * ( *signal )(int,void(*)(int)) )(int)@;signal - a pointer to a function(int,void(*)(int)) returning a pointer to a function(int) returning void.

cf. Chapter 5.12 Complicated Declaration from K&R 2nd Ed.
  • int *f() /* f: function returning pointer to int */
  • int (*pf)() /* pf: pointer to function returning int */
  • char **argv /* argv: pointer to pointer to char */
  • int (*daytab)[13] /* daytab: pointer to array[13] of int */
  • int *daytab[13] /* daytab: array[13] of pointer to int */
  • void *comp() /* comp: function returning pointer to void */
  • void (*comp)() /* comp: pointer to function returning void */
  • char (*(*x())[])() /* x: function returning pointer to array[] of pointer to function returning char */
  • char (*(*x3)())5 /* x: array[3] of pointer to function returning pointer to array[5] of char */
  • 내용 추가 [박용범]
  • 내용 추가 cheeky

ID
Password
Join
You can do very well in speculation where land or anything to do with earth is concerned.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-12-08 20:03:01
Processing time 0.0064 sec