함수포인터에 대해서 헷갈리지 않게 부연설명 합니다.

김경태의 이미지

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이라는 유틸리티를 이용하면 영어를 c의 선언형태로 c의 선언을 영어로 상호변환을 할 수 있습니다..;D

익명 사용자의 이미지

죄송 --;
여기서 부터 이해가 안돼요...
<----
int (*) (int)가 됩니다.
그러므로 이때는 이것이 return value가 됩니다.
---->
예를 좀 들어 주시면 감사하겠습니다.

vacancy의 이미지

딴지 걸려고 하는 얘기는 아니고요,
좋은 정보라고 생각합니다.

혹시 응용해서 쓰려고 하시는 분들이 계실까봐
걱정이 되어 적습니다.
이론적으로는 이렇지만, 가장 중요한 것은,
가급적이면 이러한 형태의 선언은
피해주는 것이 좋다는 것입니다.

OS등을 작성하지 않는 이상 쓰지 않겠지만요.
혹시 쓰게된다면 적당히 쪼개서 써주는 것이 좋겠죠.
( typedef 등을 사용해서요. )

김경태의 이미지

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으로 컴파일러의 판단을 추적해 보았습니다.

잘 생각해 보시면 매우 단순한 규칙, 즉 결합도 우선의 법칙에 의해서 반복해서 해석하고 있음을 알수 있을 것입니다.

도움이 되셨기를 바랍니다. ^^;

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.