前几天同事说面试的时候遇到了这个问题,我记得原来看过,现在整理一下。
那么,main函数是一个程序的入口,如何在main函数之前或者之后执行一些代码呢?
-
在main函数之前执行代码
想要知道如何在main函数之前执行代码,首先就要搞明白,在面函数之前,程序到底做了啥?
简单来说,main函数之前,主要做了这些:- 配置堆栈
- 初始化静态和全局变量
- 为未初始化部分的全局变量赋值
- 运行全局构造器
- 将main函数的参数(argv,argc等)传递给main函数
这些基本都是变量、环境的配置。因此,如果想执行一段代码,最简单的办法就只有一个了:利用构造函数。
大方向敲定,那么剩下的小细节无非就是类放在哪的问题了。-
全局变量
-
静态变量
-
include文件中的全局或静态变量
-
namespace中
等等…
比如:
class A{ public: A(){ cout << "before main()" << endl; } ~A(){ cout << "after main()" << endl; } } A a; //全局变量 int main(){ cout << "this is in main()" << endl; return 0; }
-
在main函数之后执行代码
和之前同样的思路,想在main函数之后执行,一个办法就是利用析构函数。在此就不在赘述。除此之外,C\C++还提供了另一个方法:onexit( func )(对于C)或atexit( func )(对于C++)。
不过这两个函数有一点小小的差别:
onexit( func ) 要求注册的函数func返回值为int型;
而atexit( func ) 要求函数没有返回值,即返回值类型为void;
不过这两个函数都要求函数没有传入参数。
具体代码如下:int func1(void){ cout << "function 1" << endl; } void func2(void){ cout << "function 2" << endl; } int main(){ onexit(func1); atexit(func2); return 0; }
这里值得注意的两点:
- onexit和atexit可以混用,但是注册函数时,是一个入栈的过程,执行是出栈,因此如上代码最后的输出应该是先输出“function
2”,然后是“function 1”。 - 析构函数在onexit和atexit注册的函数执行之后执行。
- onexit和atexit可以混用,但是注册函数时,是一个入栈的过程,执行是出栈,因此如上代码最后的输出应该是先输出“function