Answers:
在大多数情况下,没有什么区别,但这是一个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的返回等同于调用exit。但是,如果在清理过程中可能需要main本地数据,则不能期望从main返回数据。
对于C ++
当使用exit(0)退出程序时,不会调用本地范围内的非静态对象的析构函数。但是,如果使用return 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 –使用return 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不兼容,则未指定返回到主机环境的终止状态。