C언어 main 함수 표준 정의
샌드박스 공부하다가 새로운 걸 알게 되어서 한번 정리해보려 한다
ANSI (American National Standards Institute)에서 1989년에 C에 대한 공식 표준을 발표했다
이는 C를 사용하는 대부분의 사람들에게 빠르게 받아들여졌다
공식적으로는 ANS X3.15-1989
라는 이름이었으나 ANSI C
표준이라는 이름으로 불리게 된다
1990년 ISO (International Standards Organization)와 IEC (International Electrotechnical Commission) 공동 위원회가 ANSI C
를 약간의 수정과 함께 채택하게 되면서 ISO/IEC 9899:1990
이라는 공식적인 이름으로 국제 표준으로 정해지게 되었다
하지만 여전히 ANSI C 표준이라는 이름으로 사람들에게 불리게 된다
이후 C99
이라는 비공식 이름으로 흔히 불리는 ISO/IEC 9899:1999
으로 1999년에 개정되었다
여기서 C++
처럼 슬래시 두 개로 주석 표시를 할 수 있게 되었다
멀티 스레드 지원 등의 기능을 포함해 2011년에 새로 개정되기도 했다
main 함수
정의
실행 인자가 없는 경우와 있는 경우 두 가지로 구분된다
(실행 인자와 반환 값이 없을 수도 있다)
실행 인자가 없는 경우
int main(void) {
return 0;
}
본인이 가장 친숙한 구조로 되어 있다
인자는 void
로 전달되지 않으며 int
자료형으로 값이 반환된다
위 함수에서는 0이 반환되게 된다
실행 인자가 있는 경우
int main(int argc, char *세argv[]) {
return 0;
}
대학교 1학년 수업 들으면서도 써본 적이 없다
그 동안 보기만 했지 스스로 공부하면서도 쓴 적이 잘 없다
어떻게 쓰이는 지는 대강 알고 있었으나 직접 써본 적은 없었다
argc
는 Argument Count의 약자로 인자의 개수를 의미한다
바이너리 실행 시 입력된 명령줄 인자를 처리하기 위한 매개변수이다
기본적으로 바이너리 실행 자체도 하나의 인자로 간주되어 최소값은 1이다
./ex_file 1
가령 이런 식으로 인자와 함께 바이너리를 실행할 경우 argc
에 int
자료형으로 2를 저장하는 것이다
argv
는 Argument Vector로 명령줄의 인자들의 배열이다
문자열 포인터 배열로, 명령줄에서 입력한 값들을 저장한다
가장 첫 번째 인덱스 (argv[0]
)에는 무조건 실행된 바이너리의 이름이 들어가게 되며 가장 마지막 인덱스(argv[argc]
)에는 NULL(\0)
으로 널 바이트가 저장된다
./ex_file dead beef
argc
는 3이 되고, argv[0]
= dead, argv[2]
= beef, argv[3]
= NULL
가 되는 것이다
실행 인자와 반환 값이 없는 경우
void main() {
}
오랜만에 C 하거나 가끔 실수로 썼을 때 빼고 의도적으로 이렇게 써보지는 않았다
이렇게 해도 오류는 나지 않았던 것 같다
표준 형식이 아니라서 gcc
등의 컴파일러는 컴파일 오류를 뱉기도 한다
하지만 이렇게 해도 작동되는 컴파일러들은 내부적으로 int main
과 return 0
로 처리한다
원래는 컴파일러가 바이너리의 진입점을 찾지 못하기 때문에 오류가 발생하는 것이 맞지만 예외적으로 void main()
도 진입점으로 인식해주는 것이다
그럼 반환 값은 왜 필요한가 싶은데 쉘 등에서 마지막으로 실행된 바이너리의 반환 값을 확인할 수 있기 때문이다
만약 반환 값을 활용하게 될 경우에는 바이너리의 반환 값이 필요해지는 것이다
운영 체제에서 활용되는 것이다
표준 정의
int main(int argc, char *argv[], char *envp[]) {
return 0;
}
세 번째 인자 env
는 환경 변수를 저장하는 포인터 배열이다
시스템의 환경 변수에 대한 포인터의 배열로, null
포인터에 의해 종료된다