linuxism
2012. 3. 7. 22:54
C소스의 main() 이라는 메인 함수는, 평범한 함수가 아니라, "프로그램 그 자체"입니다. 그리고 C에서는 모든 것이 함수들로 이루어져 있습니다. 그래서 어느 함수부터 코드를 실행할지 지정해야 할 것입니다. 그 시작점이 바로 main() 함수입니다. main() 함수가 없으면 exe 같은 실행 파일을 만들 수 없습니다.
main() 함수도 일반 함수와 마찬가지로 인수(파라미터)를 입력받거나 어떤 값을 반환할 수 있습니다.
일반함수는 자신을 호출한 함수와 값을 주고받지만, main() 함수는 자신을 호출한 함수가 없습니다. 호출한 함수가 있다면 그것은 바로 운영체제입니다. 따라서 운영체제(OS)와 값을 주고받습니다.
이것은
main(int argc, char* argv[])
프로그램을 실행할 때 준 옵션을 받는 코드입니다. 그리고 메인함수의 return문은 운영체제에 어떤 값을 반환하는 것입니다.
각 함수에는 인수(파라미터)를 지정할 수 있습니다. 프로그램 본체인 main() 함수에도 당연히 인수를 지정할 수 있습니다. 메인 함수의 인수는, 운영체제에서 그 프로그램을 실행할 때 지정해 준 "옵션"입니다.
예를 들어 도스창(명령 프롬프트;CMD.EXE)에서
dir /?
이렇게 하면 dir 명령에 대한 도움말이 출력됩니다. 이때 "/?" 라는 문자열이 옵션이 되는 것입니다.
main(int argc, char* argv[])
에서
argc 는, 프로그램을 실행할 때 지정해 준 "명령행 옵션"의 "개수"가 저장되는 곳입니다.
argv 는, 프로그램을 실행할 때 지정해 준 "명령행 옵션의 문자열들"이 실제로 저장되는 배열입니다.
다음 예제를 보면 쉽습니다.
int argc, char* argv[] 사용법 예제; main() Option Example
소스 파일명: 0.cpp
#include <stdio.h>
#include <stdlib.h> // exit()
int main(int argc, char* argv[]) {
// 옵션 지정하지 않았을 때 에러 출력하고 종료
if (argc == 1) {
fputs("에러! 옵션을 입력하지 않으셨군요...\n", stderr);
exit(1);
}
// 옵션 개수 출력
printf("%d 개의 옵션을 입력하셨군요\n\n", argc - 1);
// 옵션 배열의 요소들을 하나씩 출력
for (int i = 1; i < argc; i++)
printf("argv[%d] = %s\n", i, argv[i]);
return 0;
}
컴파일 및 실행 결과 화면:
D:\Z>cl /nologo 0.cpp
0.cpp
D:\Z>0.exe
에러! 옵션을 입력하지 않으셨군요...
D:\Z>0.exe 111 222
2 개의 옵션을 입력하셨군요
argv[1] = 111
argv[2] = 222
D:\Z>0.exe AAA BBB CCC
3 개의 옵션을 입력하셨군요
argv[1] = AAA
argv[2] = BBB
argv[3] = CCC
D:\Z>0.exe 자장면 탕수육 짬뽕 불도장 팔보채
5 개의 옵션을 입력하셨군요
argv[1] = 자장면
argv[2] = 탕수육
argv[3] = 짬뽕
argv[4] = 불도장
argv[5] = 팔보채
D:\Z>
옵션을 하나도 입력하지 않으면 argc 는 1이 됩니다. 즉 argc 는 항상 1 이상입니다. 0이 되지 않습니다.
위의 경우, argv[0]은 0.exe 가 됩니다. 즉 argv 의 첫번째 요소는 항상 "프로그램 자신의 파일명"입니다.
따라서 옵션의 정확한 개수를 구하려면 argc 에서 1을 마이너스해 주어야 합니다.
public static void main(String args[]) {...
메인(main) 메소드(함수)의, 기본으로 항상 있는 args[] 라는 "문자열 배열"은
자바 프로그램 실행시에 주어진 "옵션"들이 자동으로 담겨지는 곳입니다.Arguments 즉, "인수" = "매개 변수" = "파라미터" 라는 뜻입니다.
실행시 옵션이란?
도스창(명령 프롬프트;cmd.exe)에서
dir *.txt
라고 하면 모든 txt 확장자를 가진 파일들의 목록이 출력됩니다. "dir"은 명령어이고 "*.txt"는 옵션입니다. 자바 프로그램에서는 "*.txt" 이런 옵션이String args[] 라는 문자열 배열에 자동으로 들어갑니다.
"java Foo" 이런 명령으로, Foo.class 라는 자바프로그램을 실행할 때
java Foo ABC IBM GOOGLE Yahoo! Hmmmm... 1234
이렇게 뒤쪽에 문자열을 붙여서 실행했다면
ABC
IBM
GOOGLE
Yahoo!
Hmmmm...
1234
이런 6개의 옵션들이 args[] 라는 배열에 자동으로 들어가고, 프로그래머는 이 배열에서 값을 꺼내서 사용하면 됩니다.
가령 --help 또는 -help 라는 옵션이 발견된다면, 사용자가 도움말을 필요로 한다는 뜻이므로 도움말을 출력하면 되겠지요.
String args[]
이렇게 해도 되고
String[] args
이렇게 대괄호를 앞쪽에 붙여도 똑같습니다.
다음 예제는 args[] 배열의 요소 개수와 내용을 출력하는 간단한 예제입니다.
자바 메인 함수 String args[] 사용 예제
소스 파일명: Foo.java
class Foo {
public static void main(String args[]) {
// 옵션 개수 검사. 옵션 없으면 에러 메시지 출력하고 종료
if (args.length == 0) {
System.err.println("옵션을 입력하세요");
System.exit(1);
}
// 옵션 개수 출력
System.out.println("모두 " + args.length + "개의 옵션을 입력하셨군요.");
System.out.println(); // 줄바꿈
// 모든 옵션 하나씩 화면에 출력
for (int i = 0; i < args.length; i++)
System.out.format("args[%d] : %s%n", i, args[i]);
}
}
위의 예제 컴파일 및 실행 결과:
D:\Z>javac Foo.java
D:\Z>java Foo
옵션을 입력하세요
D:\Z>java Foo 111 222 333 444
모두 4개의 옵션을 입력하셨군요.
args[0] : 111
args[1] : 222
args[2] : 333
args[3] : 444
D:\Z>java Foo 자장면 탕수육 짬뽕 우동 물만두
모두 5개의 옵션을 입력하셨군요.
args[0] : 자장면
args[1] : 탕수육
args[2] : 짬뽕
args[3] : 우동
args[4] : 물만두
D:\Z>
좀더 실용적인 예제는 여기 있습니다: ▶▶ 자바,Java] 유니코드(UTF-8)변환, KS완성형 파일을 유니코드로 바꾸기
이것은 옵션으로 지정해준 한글완성형 파일을 유니코드로 변환하여 새 파일로 저장합니다.
return (리턴) 이라는 것은 함수가 아니라, C언어의 키워드(예약어)입니다. 현재의 함수를 종료시키고 그 함수를 호출했던 곳으로 되돌아가라는 뜻입니다. 단, 돌아가며 어떤 값을 가지고 갈 수 있습니다. 즉, 값을 반환하는 것입니다.
예를 들어 다음과 같은 소스가 있다고 할 때
파일명: 0.cpp
#include <stdio.h>
int foo(void);
int main(void) {
printf("%d\n", foo());
return 0;
}
int foo(void) {
return 1234;
}
컴파일을 하고 실행하면
D:\Z>cl /nologo 0.cpp && 0.exe
0.cpp
1234
D:\Z>
이렇게 1234 라는 값이 출력됩니다.
foo()라는 함수가, 자신을 호출한 printf() 함수에 1234 라는 값을 리턴했기 때문입니다. int foo... 라고 되어 있기에, 정수(int)만을 반환할 수 있습니다.
그리고 프로그램 본체인 main() 함수 역시 return 0; 를 사용하여 어딘가로 0 이라는 값을 돌려주고 있습니다. main() 함수의 return문은 "운영체제"로 값을 반환합니다. MS윈도우XP에서 위의 예제 프로그램을 실행했다면, 윈도우XP의 명령 프롬프트(cmd.exe)로 0이라는 값을 반환하는 것입니다.
왜 return 0; 이렇게 0 이라는 값을 반환했느냐 하면, "에러가 없이 정상적으로 프로그램이 종료되었다"는 뜻입니다.
만약 main() 에서 무슨 에러가 있었다면 0이 아닌 값, 예를 들어 1이나 2 또는 -1 등을 윈도우로 반환해야 합니다.
보통 함수에서는 그 함수가 하는 일에 따라서 리턴 값이 달라지지만, main() 함수에서는 되도록 위의 규칙에 맞게 반환값을 정해야 합니다.
그렇지 않으면, 그 프로그램을 배치 파일 (BATCH; .BAT) 등에서 사용할 때 문제가 생길 수 있습니다.
배치 파일 안에서는, 방금 실행한 프로그램이 성공적으로 종료되었는지 아닌지 판단하기 위해, 그 프로그램의 반환값을 사용합니다. 반환값이 0이면 그 프로그램이 성공적으로 종료되었다고 판단하고 그 다음 작업을 계속합니다. 0 이 아니면 에러가 있다는 뜻이니까, 에러에 대한 적절한 처리를 해야 합니다. (▶▶ [배치 파일] 프로그램 실행의 성공 여부를 Error Level 로 확인/판단하기: ERRORLEVEL 참고)
[C언어 기초] return 이란? 함수인가요? return 0; 의 의미는?
return 은 함수가 아니라, C언어의 키워드(keyword) 즉 "예약어"입니다. C언어에서는 뒤에 소괄호"()"가 없으면 함수가 아닙니다. (▶▶ "[C언어] C언어와 C++의 예약어 리스트; Keywords" 참조)
(참고로, 펄(Perl)의 함수에서는 소괄호를 생략할 수 있음)
return 은, 현재 있는 함수에서 빠져나가며, 그 함수를 호출했던 곳으로 되돌아 가라는 뜻입니다. 되돌아 가면서 그 함수를 호출했던 곳 즉 calling routine 에 어떤 값을 반환하는 것입니다.
return 0; 는 0 이라는 값을 반환하라는 의미이고
return 1; 은 1 이라는 값을 반환하라는 뜻입니다.
return 은 함수의 어떤 곳에서도 위치할 수 있는데, return 이 실행되는 즉시 그 함수는 무조건 실행이 종료됩니다.
즉, 현재의 함수에서 빠져 나가라는 의미입니다.
* 그 함수가 무엇을 계산하는 함수라면, 그 계산 결과의 값을 return 으로 반환합니다.
* 계산이 아닌, 어떤 일을 하는 함수라면, 그 일이 성공했을 때에는 0 을, 실패했을 때에는 1 을 반환하며 끝내는 것이 보통입니다. 그러면 그 함수를 호출한 곳에서, 그 함수가 제대로 실행되었는지 판단할 수가 있습니다.
#include <stdio.h>
int main() {
puts("하하하하");
return 0;
}
위의 예제는, 지구상에서 가장 단순한 C프로그램입니다. 그냥 하하하하 라는 문자열을 명령 프롬프트 화면에 출력하는 것이 전부입니다.
puts() 함수에서 에러가 나는 경우는 사실상 없고, 그래서 성공적으로 프로그램이 실행되었기에, return 0; 이라고 끝났습니다. main() 함수에서 빠져나가면서 정수 0 을 반환하라는 의미입니다. main() 함수는 프로그램 그 자체이므로, main() 함수에서 빠져나간다는 것은, 그 프로그램을 종료시킨다는 의미입니다. main() 함수를 호출한 루틴은, 컴퓨터 OS 그 자체이므로, 결국 OS에 0 이라는 값을 반환하는 것입니다. 이것을 도스/윈도우에서는 "Error Level" 이라고 합니다. 윈도의 명령 프롬프트에서,
echo %ERRORLEVEL%
이라고 치면, return이 방금 반환한 그 값을 볼 수 있습니다. 이 경우에는 0 이라는 값이 화면에 출력됩니다. 그런데 %ERRORLEVEL% 은, 어떤 명령어나 프로그램의 실행이 종료될 때마다 값이 자동으로 변경됩니다. (▶▶ "[배치 파일] 프로그램 실행의 성공 여부를 Error Level 로 확인/판단하기: ERRORLEVEL" 참조)
※ 단, 윈도98에서는 echo %ERRORLEVEL% 이 작동하지 않습니다. 윈도2000 이상의 OS에서만 됩니다.
main() 앞에 int 라고 함수형이 정의되어 있는데, 이것은 main()이 return 을 사용해 반환하는 값이 '정수'라는 의미입니다.
만약 void main()... 이라고 되어 있다면, "void"는 "아무것도 없다"는 뜻이기에, 결과값이 없다는 뜻이고, 그래서 return 문으로 결과값을 반환할 수 없는 것이 원칙입니다. 억지로 return 문을 사용한다면 "warning C4098: 'main' : 'void' function returning a value (반환값이 없는 함수인 main이 어떤 값을 반환했음)" 이런 경고가 나옵니다. 그래도 컴파일은 되지만 이런 경고를 고치지 않으면 나중에 버그투성이의 프로그램이 될 가능성이 높아집니다.
업데이트:
void 형 함수에서도 return; 을 쓸 수 있습니다. 아무것도 반환하지 않는 return; 즉, 단지 함수를 종료시키기 위한 return; 이라면 됩니다. 이 부분에 대한 설명이 누락되었는데 이상곤님께서 지적해 주셔서 방금 업데이트했습니다 ^^;
예제:
#include <stdio.h>
void main() {
return;
}
출처 -
http://mwultong.blogspot.com/2007/06/c-main-main-function.html