더북(TheBook)

3. 포인터 매개변수를 배열로 표기한다. null이 될 수 없는 포인터는 항상 이렇게 표기한다. 예를 들면 다음과 같다.

/* 인수가 null이 될 수 없음을 강조한다. */
size_t strlen(char const string[static 1]);
int main(int argc, char* argv[argc+1]);
/* 위 함수를 다음과 같이 선언할 수도 있다. */
size_t strlen(const char *string);
int main(int argc, char **argv);

첫 번째 문장은 strlen이 유효한 (null이 아닌) 포인터를 받고 string 원소를 최소한 한 개 받는다는 것을 강조한 것이다. 두 번째 문장은 mainchar에 대한 포인터로 구성된 배열을 받는다는 것을 표현한 것이다. 이 배열은 프로그램 이름과 프로그램 인수(argc-1)와 배열의 끝을 나타내는 null 포인터로 구성된다.

앞에 나온 그대로 네 문장을 모두 작성해도 문제없다. 세 번째와 네 번째 선언문은 이미 컴파일러가 아는 사실과 동일한 선언을 추가했을 뿐이다.

4. 함수 포인터 매개변수는 함수처럼 표기한다. 배열과 마찬가지로 함수 포인터도 null이 될 수 없을 때마다 이렇게 표현한다.

/* handler란 인수가 null이 될 수 없음을 강조한 표현 */
int atexit(void handler(void));
/* 같은 내용을 다르게 선언한 문장 */
int atexit(void (*handler)(void));

첫 번째 atexit 선언은 handler란 이름의 함수를 인수로 받으며 null 함수 포인터는 허용하지 않는다고 강조한 것이다. 참고로 배열 매개변수가 오브젝트 포인터로 변환되듯이, 함수 매개변수인 handler는 함수 포인터로 변환된다.

이 코드 역시 두 문장 모두 작성해도 문제없다. 두 번째 문장은 첫 번째 선언과 표현 방식이 다를 뿐이다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.