함수포인터에 대해서 헷갈리지 않게 부연설명 합니다.
1. 함수 포인터
int (*song) (int);
함수 포인터입니다. 왜냐하면 song을 보면 제일 먼저 만나는 것이 *표시 즉 song이란 놈은 포인터다라고 미리 밝히고 있기 때문이죠.
그리고 나서 보니 왼쪽에 int, 오른쪽에 (int)가 있는데 이럴때는 당연히 오른쪽으로 먼저 결합! song은 포인터인데 int를 인자로 가지는 함수를 가르키고 그 함수는 int를 리턴한다...이렇게 해석합니다.
즉 int를 리턴하고 int를 인자로 가지는 song이라는 이름의 함수 포인터입니다.
2. 함수
int (*song(int))(int);
이것은 해석할때 song이 괄호안의 (int)라는 것과 결합을 먼저합니다.
그래서 song이라는 함수는 int를 인자로 가진다 라고 일단 해석해야 합니다.
song이 함수이고 인자를 가졌으므로 이것을 제외한 나머지는 int (*) (int)가 됩니다.
그러므로 이때는 이것이 return value가 됩니다.
따라서 이 경우는 <song이라는 함수는 int를 인자로 가지며 리턴 값은 int를 리턴하고 int를 인자로 가지는 함수포인터>가 되겠죠.
3. 2번 함수를 가르키는 함수 포인터
int (*(*song)(int))(int);
먼저 보면 (*song)이 것을 보면 이건 "song이란 놈은 포인터다"라고 했습니다. 그런데 밖을 보니 왼쪽에 *, 오른쪽에 (int)가 있지요? 그럼 당연 오른쪽에 (int)를 먼저 봅니다. "song이란 놈은 포인터인데 int를 인자로 가지는 함수를 가르킨다" 가 됩니다.
이미 song이란 놈이 함수포인터임을 명시하고 있기에 나머지 바깥쪽의 int (*)(int)를 해석할 때는 이 함수포인터의 리턴 값으로 해석이 가능하죠?
그래서....
전체적으로 묶어 보면....
<song이란 놈은 포인터인데 int를 인자로 가지는 함수를 가르키는데, 그 함수의 리턴값으로 (int를 인자로 갖고 리턴값이 int인 함수포인터)를 가진다>
라고 봐야 합니다.
도움이 되셨기를 바랍니다.
cdecl을 이용하시면 편합니다..
cdecl이라는 유틸리티를 이용하면 영어를 c의 선언형태로 c의 선언을 영어로 상호변환을 할 수 있습니다..;D
죄송 --;여기서 부터 이해가 안돼요...<----int
죄송 --;
여기서 부터 이해가 안돼요...
<----
int (*) (int)가 됩니다.
그러므로 이때는 이것이 return value가 됩니다.
---->
예를 좀 들어 주시면 감사하겠습니다.
딴지 걸려고 하는 얘기는 아니고요,좋은 정보라고 생각합니다.혹
딴지 걸려고 하는 얘기는 아니고요,
좋은 정보라고 생각합니다.
혹시 응용해서 쓰려고 하시는 분들이 계실까봐
걱정이 되어 적습니다.
이론적으로는 이렇지만, 가장 중요한 것은,
가급적이면 이러한 형태의 선언은
피해주는 것이 좋다는 것입니다.
OS등을 작성하지 않는 이상 쓰지 않겠지만요.
혹시 쓰게된다면 적당히 쪼개서 써주는 것이 좋겠죠.
( typedef 등을 사용해서요. )
int ( *) (int)가 리턴값이 되는 이유
2. 함수
int (*song(int))(int);
이것은 해석할때 song이 괄호안의 (int)라는 것과 결합을 먼저합니다.
<--
컴파일러가 이 문장을 볼때 괄호를 열어보고 song이란 단어를 중심으로 해석을 시도합니다.
맨먼저 하는 일이 *song()이란 문장에서 왼쪽을 먼저 해석하면 song이란 어떤 형태든 포인터가 될 것이고 ()을 먼저 해석하면 song은 어떤 형태이던지 함수가 될 것입니다.
그런데 컴파일러는 *보다, ()나 []를 결합도가 더 높이 평가하므로 song은 함수가 됩니다.
-->
그래서 song이라는 함수는 int를 인자로 가진다 라고 일단 해석해야 합니다.
song이 함수이고 인자를 가졌으므로 이것을 제외한 나머지는 int (*) (int)가 됩니다.
그러므로 이때는 이것이 return value가 됩니다.
<--
song이란 것이 함수임을 알았으니 다음은 ()안을 해석할텐데 그때에 int라는 글자를 인식하고 song이란 함수는 integer를 인자로 한다고 판단합니다.
그다음에는 song(int)가 다 해석되었으므로 왼쪽의 *를 판단해야 하는데 song(int)를 빼고 보면 (*)라는게 걸리게 됩니다. (물론 song이 함수이며 인자까지를 판단한 컴파일러는 (*)가 뭔지는 모르지만 리턴값이라고 판단합니다)
따라서 컴파일러는 (*)이것이 무언가를 가르키는 포인터이며 리턴값인데 도대체 그것이 뭘까 하고 (*)양쪽을 보게 되는데 이때에는 양쪽에 int와 (int)가 있고 따라서 당연 결합도가 더 높은 (int)를 먼저 해석하고 비로서 포인터가 int를 인자로 가지는 함수임을 알게 되며 나머지 int를 해석하여 이 함수의 리턴값은 int임을 확인합니다.
이러한 과정을 거쳐 컴파일러는 song의 리턴값이 포인터이며 int를 인자로 하고 int를 리턴하는 함수를 가르킨다고 최종 판단하게 됩니다.
-->
따라서 이 경우는 <song이라는 함수는 int를 인자로 가지며 리턴 값은 int를 리턴하고 int를 인자로 가지는 함수포인터>가 되겠죠.
---------------------------------------------------------------------------------
좀 이해하기 쉽게 step by step으로 컴파일러의 판단을 추적해 보았습니다.
잘 생각해 보시면 매우 단순한 규칙, 즉 결합도 우선의 법칙에 의해서 반복해서 해석하고 있음을 알수 있을 것입니다.
도움이 되셨기를 바랍니다. ^^;
댓글 달기