main 함수
main 함수 (main function)
프로그램을 실행하면 운영체제가 가장 먼저 호출하는 함수가 바로 main이에요. 모든 C 프로그램에는 이 main 함수의 정의가 있어야 하고, 그 반환값과 인자로 프로그램 시작과 종료가 어떻게 다뤄지는지가 정해져 있어요.
출처: cppreference
본문
호스트(hosted) 실행 환경에서 돌도록 작성된 모든 C 프로그램에는 main이라는 이름의 함수의 정의(프로토타입이 아니라)가 포함돼 있어요. 이 함수가 프로그램의 지정된 시작점이에요.
int main (void) { body } |
(1) | |
int main (int argc, char *argv[]) { body } |
(2) | |
/* another implementation-defined signature */ |
(3) | (C99부터) |
매개변수
| argc | 프로그램이 실행되는 환경에서 프로그램에 전달된 인자의 개수를 나타내는 음이 아닌 값. |
| argv | argc + 1개의 포인터로 이루어진 배열의 첫 요소를 가리키는 포인터. 마지막 포인터는 널이고, 그 앞쪽 포인터들은(있으면) 호스트 환경에서 전달된 인자를 나타내는 문자열을 가리켜요. argv[0]이 널 포인터가 아니면(또는 동등하게 argc > 0이면) 프로그램 이름을 나타내는 문자열을 가리키는데, 호스트 환경에서 프로그램 이름을 얻을 수 없으면 그 문자열은 비어 있어요. |
argc와 argv라는 이름은 "argument count"와 "argument vector"를 뜻하며 전통적으로 쓰이지만, 다른 이름을 써도 되고 타입의 동등한 다른 선언을 써도 돼요. int main(int ac, char** av)도 동등하게 유효해요.
main의 흔한 구현 정의 형태는 int main(int argc, char *argv[], char *envp[])예요. 여기서 char** 타입의 세 번째 인자는 실행 환경 변수들 에 대한 포인터 배열을 가리켜요.
반환값
return 문이 사용되면 그 반환값은 암시적인 exit() 호출의 인자로 쓰여요(아래 설명 참고). 값 0과 EXIT_SUCCESS는 성공적인 종료를, EXIT_FAILURE는 실패한 종료를 나타내요.
설명
main 함수는 모든 정적 저장 기간 객체가 초기화된 후, 프로그램 시작 시 호출돼요. 이것은 호스트 환경(즉 운영체제가 있는 환경)에서 실행되는 프로그램의 지정된 진입점이에요. 프리스탠딩(freestanding) 프로그램(부트 로더, OS 커널 등)의 진입점 이름과 타입은 구현 정의예요.
두 매개변수 형태의 main 함수 매개변수는 실행 환경에서 임의의 멀티바이트 문자열을 전달받을 수 있게 해줘요(이것을 보통 명령줄 인자 라고 해요). argv[1] .. argv[argc-1] 포인터는 각 문자열의 첫 문자를 가리켜요. argv[0](널이 아니면)은 프로그램 자신을 실행하는 데 사용된 이름을 나타내는 널 종료 멀티바이트 문자열의 첫 문자를 가리키는 포인터예요(호스트 환경이 이를 지원하지 않으면 argv[0][0]은 0이 됨이 보장돼요).
호스트 환경이 소문자와 대문자 둘 다 제공할 수 없으면 명령줄 인자는 소문자로 변환돼요.
그 문자열들은 수정 가능하고, 수정 사항은 프로그램 종료까지 유지돼요. 다만 이 수정은 호스트 환경으로 다시 전파되지는 않아요. 예를 들어 strtok와 함께 사용할 수 있죠.
argv가 가리키는 배열의 크기는 적어도 argc + 1이고, 마지막 요소인 argv[argc]는 널 포인터임이 보장돼요.
main 함수는 몇 가지 특별한 속성을 가져요:
-
프로그램이 이 함수의 프로토타입을 제공할 수 없어요.
-
main 함수의 반환 타입이
int와 호환되면, main에 대한 최초 호출의 반환(재귀 호출의 반환은 아님)은 main이 반환하는 값을 인자로 전달한exit함수를 실행한 것과 동등해요. 그렇게 되면atexit으로 등록된 함수들을 호출하고, 모든 스트림을 플러시·닫고,tmpfile로 만든 파일을 삭제하고, 실행 환경으로 제어를 되돌려줘요. -
다음 표처럼 C99를 기준으로 반환 타입에 따른 종료 상태 규칙이 달라져요.
main 함수가 값을 지정하지 않는 return을 실행하거나, return 없이 종료하는 }에 도달하면 호스트 환경으로 돌려주는 종료 상태는 정의되지 않아요. |
(C99 이전) |
main 함수의 반환 타입이 int와 호환되지 않으면(예: void main(void)), 호스트 환경으로 돌려주는 값은 불특정이에요. 반환 타입이 int와 호환되고 제어가 종료하는 }에 도달하면 환경으로 돌려주는 값은 return 0;을 실행한 것과 같아요. |
(C99부터) |
예제
프로그램에 입력을 어디서 찾고 결과를 어디에 쓸지 알려주는 방법을 보여주는 예제예요. 명령줄 인자 argc/argv가 어떻게 채워지는지 확인해 볼게요. 실행: ./a.out indatafile outdatafile
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("argc = %d\n", argc);
for (int ndx = 0; ndx != argc; ++ndx)
printf("argv[%d] --> %s\n", ndx, argv[ndx]);
printf("argv[argc] = %p\n", (void*)argv[argc]);
}
가능한 출력:
argc = 3
argv[0] --> ./a.out
argv[1] --> indatafile
argv[2] --> outdatafile
argv[argc] = (nil)
더 알아보기
main이 반환하는 것으로 끝나는 프로그램 종료 처리는exit문서를 참고해요.- 반환값으로 성공·실패를 정하는 매크로는
EXIT_SUCCESS/EXIT_FAILURE를 확인할 수 있어요.