19-1 함수 포인터와 void 포인터
컴파일러가 문장을 OK 해주는 기준은 type 정보를 보고 OK를 해준다. (물론 다른 기준도 있다)
int * ptr = ~; // 이건 포인터 형(tpye)이 있기 때문에 이걸 보고 컴파일 해준다.
*0x20 = ~; // 실제 주소값을 입력해도 컴파일러 입장에선 type형이 없기때문에 주소값인지 숫자인지 구분할수 없어 컴파일이 안된다.
type정보는 내가 어떠한 정보인지 알려주는 역할을 한다.
포인터 = 주소값 + type정보
함수의 type정보에는 매개변수 정보랑 반환형 정보가 필요하다.
int fct(int num) 함수의 type정보는 '반환형은 int 이고 매개변수로 int형 변수 하나가 선언되어 있다.' 라고 말한다.
함수의 이름은 포인터(상수형태, 함수포인터) 이다.함수를 컴파일해서 실행시키면 메인메모리에 저장이 된다. 함수의 이름은 그 주소 값을 의미하는 상수가 된다.
변수만 메모리 공간에 저장되는 것은 아니다. 프로그램 실행의 흐름을 구성하는 함수들도 바이너리 형태로 메모리 공간에 저장되어서 호출 시 실행된다. 그리고 이렇게 메모리상에 저장된 함수의 주소 값을 저장하는 포인터 변수가 바로
'함수 포인터 변수' 이다.
함수 포인터의 이해
프로그래머가 정의하는 모든 함수는 프로그램 실행 시 '메인 메모리'에 저장되어서 실행이 된다.
배열과 마찬가지로 함수의 이름은 함수가 저장된 메모리 공간의 주소 값을 의미한다.
배열과 마찬가지로 그 형태가 상수이다. 그런데 이런 함수의 주소 값 저장을 위한 포인터 변수를 별도로 선언할 수 있으며, 선언된 포인터 변수를 가르켜 '함수 포인터 변수'라 한다.
포인터형
모든 포인터가 그렇듯 선언하기에 앞서 포인터 형을 결정해야 한다.
함수이름의 포인터 형은 반환형과 매개변수의 선언을 통해서 결정짓도록 약속되어있다.
int SimpleFunc(int num) {. . . . . . .};
-> 반환형이 int이고 매개변수로 int형 변수 하나가 선언된 포인터 형이다.
적절한 함수 포인터 변수의 선언
반환형과 매개변수가 모두 포함되어 있어야한다. ex int (*fptr) (int, int) -> 반환형 int, 매개변수가 int 형 변수 2개다.
함수포인터는 배열 포인터와 마찬가지로 상수, 변수인지의 차이만 있고 똑같이 사용이 가능하다. (함수포인터로 함수호출 가능)
형(Type)이 존재하지 않는 void 포인터
void* ptr;
반환형 void와 다르게 포인터의 void는 '타입형이 존재하지 않고, 주소값 정보만 담긴다' 라는 뜻이다.
void형 포인터 변수는 어떠한 변수의 주소 값이든 담을 수 있다. 하다못해 함수의 주소 값도 담을 수 있다.
하지만 void형 포인터변수를 가지고는 아무런 포인터 연산도 하지 못한다. 값의 변경이나 참조도 불가능하다.
void형 포인터 변수에는 가르키는 대상의 어떠한 형(type)정보도 담겨있지 않으므로 이는 당연한 것이다.
일단 주소 값에만 의미를 두고, 포인터 형은 나중에 결정할때 유용하게 사용한다.
(메모리 동적 할당 과 매우 깊은 관계가 있다.)
19-2 main 함수로의 인자전달
main함수는 우리가 직접 호출하는 함수가 아니라 자동으로 호출이 되는 함수다. 그래서 인자를 전달하는데 직접 전달을 하는게 아니고 간접적 형태를 띄며 전달한다. (인자를 형성할수 있는 정보만 제공) 우리가 정보를 제공하면 운영체제가 그 정보를 참조하여 main함수를 호출할때 전달할 인자를 직접 구성해서 전달을 한다.
int main(int argc, char* argv[])
이런식으로 매개변수에 선언이 가능하고 실행시 명령 프로프톰을 이용해서 실행이 가능하다.
char* argv[] 의 포인터 형:
char** 포인터 이다.
매개변수 선언시 *arr을 arr[]로 대신할수 있다. // char** argv == char* argv[]
char* argv[] 해석방법
1. char형 더블 포인터 변수이다.
2. char* 포인터변수로 이뤄진 1차원 배열의이름이 인자로 전달이 된다.
인자의 형성과정
int main(int argc, char *argv[])
{
int i = 0;
printf("전달된 문자열의 수: %d \n", argc);
while(argv[i] != NULL)
{
printf("%d번째 문자열: %s \n", i+1, argv[i]);
i++;
}
return 0;
}
이 함수는 main함수이기 때문에 직접 실행시킬순 없고 OS가 실행을 시킨다.
명령프로프톰에서 문장을 입력하면 공백을 기준으로 입력한 데이터들을 문자열화 시켜서 메모리공간에 문자열로 저장을 시킨다. 그 후 문자열에 맞는 배열이 만들어져 main함수를 호출하면서 그 배열을 인자값으로 전달이되고 첫번째 인자는 문자열의 갯수가 전달이 된다.
문자열을 출력할땐 널문자를 활용할수 있고 argc를 활용해서 출력할수 있다.
큰 따옴표로 묶으면 공백을 포함하는 문자열을 생성해서 main 함수의 인자로 전달하는 것이 가능하다.
'책 정리 > 윤성우의 열혈 C' 카테고리의 다른 글
(Part04. C언어의 깊은 이해) Chapter 21. 문자와 문자열 관련 함수 (0) | 2019.10.03 |
---|---|
Chapter20. 도전! 프로그래밍3 (0) | 2019.10.02 |
Chapter 18. 다차원 배열과 포인터의 관계 (0) | 2019.09.28 |
Chapter 17. 포인터의 포인터 (0) | 2019.09.27 |
(Part 03 포인터와 배열의 완성) Chapter16 다차원배열. (0) | 2019.09.27 |