함수 포인터 변수 - 메모리상에 저장된 함수의 주소 값을 저장하는 포인터 변수


배열의 이름이 배열의 시작주소값을 의미하듯, 함수의 이름도 함수가 저장된 메모리 공간의 주소 값을 의미하는 것이다.

함수의 이름도 상수이다. 그런데 이러한 함수의 주소 값 저장을 위한 포인터 변수를 별도로 선언할 수 있으며, 이를 함수 포인터 변수라고 한다.


int SimpleFunc(int num) { . . . . }


이 함수의 반환형은 int, 매개변수 선언은 int num 그리고 함수의 이름 SimpleFunc는 SimpleFunc함수의 주소 값을 의미하는 상수형태의 함수 포인터가 된다.

이때 SimpleFunc함수의 함수 포인터 형을 결정하는 것은 반환형과 매개변수의 선언형태를 기준으로 구분하기로 한다.

반환형이 int이고 매개변수로 int형 변수가 하나 선언된 포인터 형이다.


반환형과 매개변수의 선언이 일치하면 형이 일치한다.


포인터 변수의 선언방법은 이렇다.


int (*fptr)(int) 


ex)

int SoSimple(int num1, int num2) {. . . .}

>> int (*fptr)(int, int)


그리고 이 함수 포인터 변수에 함수 SoSimple의 주소 값을 저장하려면 대입연산을 하면 된다.


fptr = SoSimple;


대입연산이 끝나면 fptr과 SoSimple에는 동일한 값이 저장되고, 유일한 차이점은 상수냐 변수냐 이 둘의 유일한 차이점이다.


fptr(3, 4);    // SoSimple(3, 4) 둘은 같다.


ex)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
 
void SimpleAdder(int n1,n2)
{
    printf("%d + %d = %d \n", n1, n2, n1+n2);
}
 
void ShowString(char * str)
{
    printf("%s \n",str);
}
 
int main()
{
    char *str = "Function Pointer";
    int num1 = 10, num2 = 20;
    
    void (*fptr1)(intint= SimpleAdder;
    void (*fptr2)(char *= ShowString;
 
    fptr1(num1,num2);
    fptr2(str);
    
    return 0;
}
 
 

cs

출력결과

10 + 20 = 30 

Function Pointer 


형(Type)이 존재하지 않는 void 포인터


void *ptr;    // void형 포인터 변수


void형 포인터 변수에는 어떠한 변수의 주소값을 담을 수 있고, 함수의 주소 값도 담을 수 있다.

무엇이든 담으면 좋아보이지만, 이를 가지고 아무런 포인터 연산이 불가능하다. 값의 변경이나 참조도 불가능하다.

void형 포인터변수에는 가리키는 대상에 대한 어떠한 형(type) 정보도 담겨있지 않으므로!

따라서 *ptr=20;, ptr++; 이 연산은 에러가 발생한다. 


main함수로의 인자전달


int main(void) { . . . . } 


가 아닌


int main(int argc, char *argv[]) { . . . . }


이렇게도 정의가 가능하다.


ex)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
 
int main(int argc,char *argv[])
{
    int i;
    printf("전달된 문자열의 수: %d \n",argc);
    
    for(i=0;i<argc;i++)
    {
        printf("%d번째 문자열: %s \n",i+1, argv[i]);
    }
    
    return 0;
}
 

cs


출력결과



위의 소스분석에 앞서 다음 매개변수 선언에 대해 간단히 설명하고자 한다.


char *argv[]


위의 매개변수 선언은


void SimpleFunc(char **arr)

void SimpleFunc(char *arr[])


즉 이는 TYPE(char)형 1차원 배열의 이름(주소 값)을 인자로 전달받을 수 있는 매개변수 선언이다.


main함수의 매개변수 argv는 char형 더블 포인터 변수이고, 이는 char형 포인터 변수로 이뤄진 1차원 배열의 이름을 전달받을 수 있는 매개변수이다.


ex)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>
 
void ShowAllString(int argc, char *argv[])
{
    int i;
    for(i=0;i<argc;i++)
    {
        printf("%s \n",argv[i]);
    }
}
 
int main()
{
    char * str[3= {"C Programming""C++ Programming""Java Programming"};
    ShowAllString(3, str);
    
    return 0;
}
 

cs

출력결과

C Programming 

C++ Programming 

Java Programming 


3행 : argv는 char형 더블 포인터 변수이므로 argv에는 char**형 데이터가 전달될 수 있다.

14행 : 1차원 배열이름의 포인터 형은 배열이름이 가리키는 대상을 통해서 결정이 되는데, 배열이름 str이 가리키는 첫 번째 요소가 char* 형 데이터이므로, 배열이름 str의 형은 char**이다. 그래서 3행에 정의된 함수의 두 번째 인자로 전달이 가능하다.


인자의 형성과정


이제 위의 프롬프트를 보면


c:\>ArgcArgv I like you


여기서 argcArgv는 argcArgv.exe의 실행을 명령하는 것이다. 이게 실행이 되면 main함수로 4개의 문자열 정보가 전달된다.


1. "ArgcArgv"

2. "I"

3. "like"

4. "you"


공백은 문자열을 나누는 기준이 되어 4개의 문자열이 하나의 배열에 묶여서 main함수의 두 번째 인자로 전달이 되며, 첫 번째 인자로는 문자열의 수가 전달된다.





'programming > C' 카테고리의 다른 글

C // 구조체와 사용자 정의 자료형 1  (0) 2017.12.29
C // 문자와 문자열관련함수  (0) 2017.12.28
C // 2차원 배열이름의 포인터 형  (0) 2017.12.24
C // 포인터의 포인터  (0) 2017.12.23
C // 다차원배열  (0) 2017.12.22

+ Recent posts