답변:
대부분의 경우,이 차이 없지만 여기 사용 여부에 따라 다르게 작동 할 가능성이 높습니다 C 프로그램의 return 0;
또는 exit(0);
:
#include <stdio.h>
#include <stdlib.h>
static char *message;
void cleanup(void) {
printf("message = \"%s\"\n", message);
}
int main(void) {
char local_message[] = "hello, world";
message = local_message;
atexit(cleanup);
#ifdef USE_EXIT
puts("exit(0);");
exit(0);
#else
puts("return 0;");
return 0;
#endif
}
때문에의 atexit()
통화 중 exit(0);
또는 return 0;
원인이되는 cleanup
함수가 호출된다. 차이점은 프로그램이을 호출 exit(0);
하면 "호출" main()
이 여전히 활성화되어있는 동안 정리가 수행 되므로 local_message
개체가 여전히 존재한다는 것입니다. 실행 return 0;
하지만, 즉시의 호출을 종료 main()
하고 다음 호출 cleanup()
기능을. 이후 cleanup()
(글로벌을 통해 의미하지 않습니다 message
에 로컬로 할당 된 것 개체에 대한 포인터) main
, 해당 개체가 더 이상 존재하지, 동작은 정의되지 않는다.
시스템에서 볼 수있는 동작은 다음과 같습니다.
$ gcc -DUSE_EXIT c.c -o c && ./c
exit(0);
message = "hello, world"
$ gcc c.c -o c && ./c
return 0;
message = ""
$
-DUSE_EXIT
충돌이나 인쇄를 포함 하여 프로그램을 실행하지 않고 실행하면 "hello, world"
메모리 사용량 local_message
이 줄어들지 않는 경우가 있습니다.
그러나 실제로는 내부 main()
에 정의 된 객체 가 main()
포인터를 저장하여 외부 에 표시 되는 경우에만이 차이가 나타납니다 . 이것은 아마도 그럴 수도있다 argv
. (시스템에서 실험 한 결과와에서 가리키는 객체는에서 돌아온 후에도 계속 존재 하지만 argv
그에 의존해서는 안됩니다.)*argv
main()
C
의 경우 표준에 따르면 초기 통화에서 메인 통화로 복귀하는 것은 통화 종료와 같습니다. 그러나 정리하는 동안 main에서 로컬로 데이터가 필요할 경우 main에서 리턴 할 수 없습니다.
C ++ 용
exit (0)을 사용하여 프로그램을 종료하면 로컬 범위의 비 정적 객체에 대한 소멸자가 호출되지 않습니다. 그러나 리턴 0이 사용되면 소멸자가 호출됩니다.
프로그램 1 –-exit (0)을 사용하여 종료
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
class Test {
public:
Test() {
printf("Inside Test's Constructor\n");
}
~Test(){
printf("Inside Test's Destructor");
getchar();
}
};
int main() {
Test t1;
// using exit(0) to exit from main
exit(0);
}
출력 : 내부 테스트 생성자
프로그램 2 – 리턴 0을 사용하여 종료
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
class Test {
public:
Test() {
printf("Inside Test's Constructor\n");
}
~Test(){
printf("Inside Test's Destructor");
}
};
int main() {
Test t1;
// using return 0 to exit from main
return 0;
}
출력 : 내부 테스트 생성자
내부 테스트 소멸자
예를 들어 소멸자에게 파일 닫기와 같은 리소스를 해제하는 코드가있는 경우 소멸자를 호출하는 것이 때때로 중요합니다.
exit ()를 호출하더라도 정적 객체는 정리됩니다. 예를 들어, 다음 프로그램을 참조하십시오.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
class Test {
public:
Test() {
printf("Inside Test's Constructor\n");
}
~Test(){
printf("Inside Test's Destructor");
getchar();
}
};
int main() {
static Test t1; // Note that t1 is static
exit(0);
}
출력 : 내부 테스트 생성자
내부 테스트 소멸자
finally
C 표준 (C99)은 독립형 환경 과 호스팅 환경 이라는 두 가지 유형의 실행 환경을 정의한다는 점은 주목할 가치가 있습니다 . 독립형 환경은 C 라이브러리를 지원하지 않으며 임베디드 응용 프로그램 등을위한 C 환경입니다. C 라이브러리를 지원하는 AC 환경을 호스팅 환경이라고합니다.
C99에 따르면, 독립형 환경에서 프로그램 종료는 구현이 정의되어 있습니다. 따라서 구현 main
에서 return n
, 및를 정의 하면 exit
해당 동작은 해당 구현에서 정의 된 것과 같습니다.
C99는 호스팅 환경 동작을 다음과 같이 정의합니다.
기본 함수의 리턴 유형이 호환 가능한 유형 인 경우, 초기 함수에서 기본 함수로의 리턴은 기본 함수가 리턴 한 값을 인수로 사용하여 종료 함수를 호출하는 것과 같습니다. 주 함수를 종료하는}에 도달하면 값 0이 리턴됩니다. 리턴 유형이 int와 호환되지 않으면 호스트 환경으로 리턴되는 종료 상태는 지정되지 않습니다.
C 표준의 관점에서, 실제로는 아니지만 return
진술과 exit()
함수 가 아닙니다 . 등록 된 모든 함수 atexit()
가 호출되고 프로그램이 종료됩니다.
주의해야 할 몇 가지 상황이 있습니다.
main()
. 실제로는 거의 보이지 않지만 C에서는 합법적입니다 (C ++에서는 명시 적으로 금지합니다).main()
. 때로는 기존 main()
이름이 다른 이름으로 바뀌어 new로 호출되기도합니다 main()
.exit()
코드를 작성한 후, 특히 비정상적으로 종료되지 않는 경우이 중 하나를 사용 하면 버그가 발생합니다. 이를 피하려면 main()
기능 으로 처리 return
하고 종료하려는 경우 사용 하는 습관을들이는 것이 좋습니다 .