2.2 main 函数一定是程序执行的第一个函数吗?
这是一个开放性问题,不能简单的回答是或者不是,有些编译器(比如 gcc)是支持 main 函数之前执行函数的,有些编译器不支持。
下面我们说一下 gcc 中的一个属性关键字,直接看代码
// 33-4.c
#include<stdio.h>
#ifndef __GNUC__ // 如果是gcc编译器,就定义宏__attribute__(x)
#define __attribute__(x)
#endif
__attribute__((constructor)) // constructor告诉编译器,下面的函数将在main函数之前运行
void before_main()
printf("%s\n", __FUNCTION__);// 宏__FUNCTION__将打印当前函数名
__attribute__((destructor)) // destructor告诉编译器,下面的函数将在main函数之后运行
void after_main()
printf("%s\n", __FUNCTION__);
int main()
printf("%s\n", __FUNCTION__);
return 0;
第 3-5 行表示,如果是 gcc 编译器,将定义宏 __attribute__,如果不是 gcc 编译器,将删除 3-5 行的代码;第 7 行宏参数 constructor 表示下面的函数将在 main 函数之前执行,第 12 行的宏参数 destructor 表示下面的函数将在 main 函数之后执行。
下面编译运行一下试试,结果如下:
$ gcc 33-4.c -o 33-4
$ ./33-4
before_main
after_main
确实有函数可以在 main 函数之后执行。同样的程序在 window 下面用 vs 编译器编译。

可以看到只打印了 main。因为不是使用 gcc 编译器,源程序中第 3-5 行,第 7 行,第 12 行将被删除,程序变为下面的样子
// 33-4.c
#include<stdio.h>
void before_main()
printf("%s\n", __FUNCTION__);// 宏__FUNCTION__将打印当前函数名
void after_main()
printf("%s\n", __FUNCTION__);
int main()
printf("%s\n", __FUNCTION__);
return 0;
所以当然不会执行函数 before_main() 和函数 after_main() 了,只会执行 main 函数。
除了标准 C 语言之外,编译器还会支持自己的属性,有了 gcc 属性关键字,gcc 编译器就支持在 main 函数之前,之后执行别的函数,我们在项目中尽量不要编写编译器相关的代码,这样代码的可移植性才会高,不然换一个编译器就不能用了,这样的产品显然不太好。
1、一个 C 程序是从 main 函数开始执行的
2、main 函数是操作系统调用的函数
3、main 函数有参数和返回值(操作系统根据 main 返回值判断程序执行状态,一般返回 0 为正常)
4、现代编译器支持在 main 函数前调用其他函数