简短回答
C语言程序的默认开始执行点是 main 函数。

int main(void) {
// 程序从这里开始执行
return 0;
}
详细解释
虽然 main 函数是程序的入口点,但事情比这稍微复杂一些,我们需要从几个层面来理解:
标准规定:main 函数
根据C语言标准(如 C89/C90, C99, C11等),程序的执行始于 main 函数的调用,当操作系统加载你的可执行文件并准备运行它时,它会找到这个特殊的 main 函数,并将程序的执行权交给它。
在 main 函数执行完毕后(通常通过 return 语句),程序将终止,并将 main 函数的返回值传递回操作系统,这个返回值通常被称为“退出状态码”(exit status),在大多数操作系统中,返回 0 表示程序成功执行,非零值则表示发生了某种错误或异常。
main 函数的不同形式
main 函数有几种标准的形式,但它们的作用基本相同:

-
int main(void)- 这是最常见的形式。
int表示它返回一个整数给操作系统。 (void)表示它不接受任何命令行参数。
- 这是最常见的形式。
-
*`int main(int argc, char argv[])`**
- 这是处理命令行参数的形式。
argc(argument count) 是一个整数,表示传给程序的参数个数(包括程序名本身)。argv(argument vector) 是一个字符指针数组,每个元素指向一个命令行参数的字符串。- 在命令行运行
my_program arg1 arg2,argc会是 3,argv会是["my_program", "arg1", "arg2"]。
-
int main(int argc, char *argv[], char *envp[])- 这是第三种形式,它除了命令行参数外,还接收一个环境变量数组
envp,这种形式在标准C中不那么常见,但在某些系统(如Unix-like系统)中是支持的。
- 这是第三种形式,它除了命令行参数外,还接收一个环境变量数组
注意:在C99标准之前,
int main()(不带括号内参数)也是合法的,但现在更推荐使用int main(void)来明确表示不接受参数。
程序启动的幕后过程:main 之前发生了什么?
这是一个非常关键的点,也是很多面试题的考点。main 函数真的是第一个被调用的吗?不是的。
在 main 函数被调用之前,通常会有一个“启动代码”(startup code)或“引导代码”(bootstrap code)被先执行,这段代码通常是由编译器提供的,而不是你写的,它的主要任务是:
- 设置环境:为程序的运行准备一个合适的环境,设置栈、堆、初始化一些数据段(如
.data和.bss)。 - 调用
main:完成所有准备工作后,这段启动代码会调用你编写的main函数。 - 处理
main的返回值:当main函数返回后,启动代码会获取其返回值,并调用exit函数(或类似的系统调用)将这个返回值传递给操作系统,从而正式结束程序。
这个过程在不同的操作系统和编译器实现中细节不同,但大致流程是一致的,你可以把它想象成一个“幕后英雄”,在你出场之前,它已经把舞台搭好了。
全局变量初始化:main 之前又发生了什么?
还有一个发生在 main 之前的重要事情:全局变量和静态变量的初始化。
- 对于全局变量和静态变量,如果它们被赋予了初始值(
int global_var = 10;),那么这个初始化工作是在main函数执行之前完成的。 - 这个初始化过程也是在启动代码的“设置环境”阶段完成的。
- 注意:这个初始化只针对有显式初始值的变量,对于未初始化的全局/静态变量(在
.bss段),它们会被自动初始化为零。
#include <stdio.h>
int global_var = 100; // 这个变量在 main 之前就已经被初始化为 100
int main(void) {
printf("global_var = %d\n", global_var); // 输出会是 100
return 0;
}
可以不叫 main 吗?
理论上,你可以通过编译器选项(GCC 的 -Wl,-emain,my_entry)来指定一个不同的函数作为程序的入口点,但这是一种非常规操作,通常用于特殊场景(如嵌入式开发、特定库的测试等),在常规应用开发中,永远应该使用 main 函数作为入口点。
| 问题 | 答案 |
|---|---|
| 程序的开始执行点是什么? | main 函数。 |
main 函数必须存在吗? |
是的,对于独立的可执行程序,main 函数是必需的。 |
main 函数在 main 之前执行? |
不是。main 函数是用户代码的入口点,但程序启动后,会先执行一段由编译器提供的启动代码,它会准备好环境并调用 main。 |
在 main 之前还做了什么? |
执行全局变量和静态变量的初始化。 设置程序的运行环境(如栈、堆等)。 然后调用 main 函数。 |
main 函数返回后会发生什么? |
程序会将 main 的返回值传递给操作系统,然后终止。 |
虽然你写的代码是从 main 函数开始的,但从程序生命周期的角度看,main 函数只是整个执行流程中的一个重要环节,而不是绝对的起点。
