kri*_*iss 138
两者都做(几乎)相同的事情的唯一情况是在main()函数中,因为从main执行返回exit().
示例return:
#include <stdio.h>
void f(){
printf("Executing f\n");
return;
}
int main(){
f();
printf("Back from f\n");
}
Run Code Online (Sandbox Code Playgroud)
如果您执行此程序,它会打印:
Run Code Online (Sandbox Code Playgroud)Executing f Back from f
另一个例子exit():
#include <stdio.h>
#include <stdlib.h>
void f(){
printf("Executing f\n");
exit(0);
}
int main(){
f();
printf("Back from f\n");
}
Run Code Online (Sandbox Code Playgroud)
如果您执行此程序,它会打印:
Run Code Online (Sandbox Code Playgroud)Executing f
你永远不会得到"从f回来".还要注意#include <stdlib.h>调用库函数的必要性exit().
还要注意参数of exit()是一个整数(它是启动程序进程可以获得的进程的返回状态;传统的用法是0表示成功或任何其他错误值).
return语句的参数是函数的返回类型.如果函数返回void,则可以省略函数末尾的返回值.
最后一点,exit()有两种口味_exit()和exit().表单之间的区别在于exit()(并从main返回)调用使用atexit()或on_exit()在真正终止进程之前注册的函数,而_exit()(来自#include <unistd.h>或来自它的同义_Exit #include <stdlib.h>)会立即终止进程.
现在还存在特定于C++的问题.
当C++退出函数(return-ing)时,它比C执行更多的工作.具体来说,它调用本地对象的析构函数超出范围.在大多数情况下,程序员在进程停止后不会太关心程序的状态,因此它没有太大区别:分配的内存将被释放,文件资源关闭等等.但是,如果析构函数执行IO,则可能很重要.例如,OStream本地创建的自动C++ 在调用退出时不会刷新,您可能会丢失一些未刷新的数据(另一方面静态OStream将被刷新).
如果您使用好的旧C FILE*流,则不会发生这种情况.这些将被刷新exit().实际上,规则与注册的退出函数相同,FILE*将在所有正常终止上刷新,包括exit()但不调用_exit()或中止().
您还应该记住,C++提供了第三种退出函数的方法:抛出异常.这种退出函数的方式将调用析构函数.如果未在调用者链中的任何位置捕获,则异常可以转到main()函数并终止进程.
如果return从程序中main()或从exit()程序中的任何位置调用,将调用静态C++对象(全局变量)的析构函数.如果使用_exit()或终止程序,则不会调用它们abort().abort()在调试模式下最常用,目的是立即停止程序并获得堆栈跟踪(用于事后分析).它通常隐藏在assert()仅在调试模式下活动的宏后面.
什么时候退出()有用吗?
exit()表示您想立即停止当前进程.当我们遇到某种不可恢复的问题时,它可以用于错误管理,这些问题不允许您的代码再做任何有用的事情.当控制流程复杂并且错误代码必须一直向上传播时,它通常很方便.但请注意,这是糟糕的编码习惯.在大多数情况下,静默地结束该过程会导致更糟糕的行为,并且应该首选实际的错误管理(或者在C++中使用异常).
exit()如果在库中完成,直接调用尤其糟糕,因为它会使库用户失败,应该是库用户选择是否实现某种错误恢复.如果你想要一个为什么exit()从库中调用是坏的一个例子,它会引导人们提出这个问题.
exit()作为支持它的操作系统上的fork()启动子进程的方法,有一种无可争议的合法用法.回到fork()之前的代码通常是个坏主意.这是解释为什么exec()系列的函数永远不会返回给调用者的基本原理.
小智 17
我写了两个程序:
int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)
和
#include <stdlib.h>
int main(){exit(0)}
Run Code Online (Sandbox Code Playgroud)
执行后gcc -S -O1.这是我在装配时看到的(仅限重要部分):
main:
movl $0, %eax /* setting return value */
ret /* return from main */
Run Code Online (Sandbox Code Playgroud)
和
main:
subq $8, %rsp /* reserving some space */
movl $0, %edi /* setting return value */
call exit /* calling exit function */
/* magic and machine specific wizardry after this call */
Run Code Online (Sandbox Code Playgroud)
所以我的结论是:尽可能使用return,exit()何时需要.
在C语言中,在程序的启动功能(可使用时有没有太大的区别main(),wmain(),_tmain()或你的编译器使用的默认名称).
如果您return进入main(),控制权将返回到_start()最初启动您的程序的C库中的函数,然后exit()无论如何都会调用该函数.所以你使用哪一个并不重要.
| 归档时间: |
|
| 查看次数: |
82769 次 |
| 最近记录: |