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

main函数执行之前

  • 设置栈指针
  • 初始化静态变量和全局变量
  • 未初始化全局变量赋初值
  • 全局对象初始化(调用构造函数)
  • 将argc,argv函数传递给main函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // main函数的参数传递
    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char const *argv[])
    {
    printf("the number of command line parameters is %d!\n",argc );
    for (int i = 0; i < argc; ++i)
    {
    printf("argv[%d] is %s\n",i,argv[i]);
    }
    return 0;
    }

    // 运行结果
    // C:\Users\wushiyu\Desktop>test.exe wu shi yu go!
    // the number of command line parameters is 5!
    // argv[0] is test.exe
    // argv[1] is wu
    // argv[2] is shi
    // argv[3] is yu
    // argv[4] is go!

因此,如果在main函数之前想执行一段代码,最简单的办法是:利用构造函数。

类可以放在:

  • 全局变量
  • 静态变量
  • include文件中的全局或静态变量
  • namespace中
  • ……

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
using namespace std;
class A{
public:
A(){
cout << "A before main" << endl;
}
~A(){
cout << "A after main" << endl;
}
};
class B{
public:
B(){
cout << "B before main" << endl;
}
~B(){
cout << "B after main" << endl;
}
};
A a; //全局对象A
B b; //全局对象B
int main(){
cout << "main in" << endl;
cout << "main out" << endl;
return 0;
}

// 运行结果
// A before main
// B before main
// main in
// main out
// B after main
// A after main()

注意:

  • 执行顺序为:构造函数、main函数、析构函数
  • 当有多个对象时,先定义先构造后析构

main函数执行之后

  • 全局对象的析构在main函数之后(同上)
  • atexit(C++) 、**_onexit**(C)注册的函数,会在main函数之后执行

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>
#include <cstdlib>
using namespace std;
int func_onexit(void){
cout << "func_onexit" << endl;
}
void func_atexit(void){
cout << "func_atexit" << endl;
}
class A{
public:
A(){
cout << "A before main" << endl;
}
~A(){
cout << "A after main" << endl;
}
};
A a; //全局对象
int main(){
_onexit(func_onexit);
atexit(func_atexit);
cout << "main in" << endl;
cout << "main out" << endl;
return 0;
}

// 运行结果
// A before main
// main in
// main out
// func_atexit
// func_onexit
// A after main

注意:

  • 使用_onexit、atexit需要包含头文件cstdlib
  • _onexit要求注册函数返回值为int型、atexit要求注册函数返回值类型为void型
  • 注册函数的参数列表为空
  • _onexit和atexit可以混用
  • 注册函数是一个入栈的过程,执行注册函数是一个出栈过程,因此以上代码先输出“func_atexit”,后输出“func_onexit”
  • 全局对象、main、注册函数的执行顺序为:全局对象的构造函数、main函数、注册函数、全局对象的析构函数

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!
个人邮箱: wushiyu0314@163.com