如何在main函数之前和之后执行代码

前几天同事说面试的时候遇到了这个问题,我记得原来看过,现在整理一下。

那么,main函数是一个程序的入口,如何在main函数之前或者之后执行一些代码呢?

  • 在main函数之前执行代码
    想要知道如何在main函数之前执行代码,首先就要搞明白,在面函数之前,程序到底做了啥?
    简单来说,main函数之前,主要做了这些:

    • 配置堆栈
    • 初始化静态和全局变量
    • 为未初始化部分的全局变量赋值
    • 运行全局构造器
    • 将main函数的参数(argv,argc等)传递给main函数

    这些基本都是变量、环境的配置。因此,如果想执行一段代码,最简单的办法就只有一个了:利用构造函数
    大方向敲定,那么剩下的小细节无非就是类放在哪的问题了。

    1. 全局变量

    2. 静态变量

    3. include文件中的全局或静态变量

    4. 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注册的函数执行之后执行。
原创文章 34 获赞 41 访问量 5963

猜你喜欢

转载自blog.csdn.net/qq_44844115/article/details/98945612