📄 一句话概括
main 是主函数,是操作系统启动你程序时唯一认得的入口。它的长相由四部分组成:int(返回值类型,交回一个整数)+ main(函数名固定,不能改)+ ()(参数表,现在空着)+ { }(函数体,真正干活的地方)。务必记住:程序不是"从上到下把所有代码跑一遍",而是"跳到 main 的第一行,开始往下走"。
一、逐块拆解
int main() {
cout << "Hello" << endl;
return 0;
}
| 部件 | 写法 | 含义 | 写错的后果 |
|---|---|---|---|
| 返回值类型 | int |
函数执行完,交回一个整数给操作系统 | 写成 void 多数编译器能过,但不合标准 |
| 函数名 | main |
系统约定的入口名,必须原样 | Main/mian → 链接错误"找不到入口" |
| 参数表 | () |
括号里放"外面传进来的数据",现在没有 | 忘了括号 → 语法错误 |
| 函数体 | { ... } |
花括号里是从上往下执行的语句 | 少一个 } → 报"文件意外结束" |
二、为什么必须叫 main
这是一个约定大于配置的典型例子:
你双击 hello.exe
↓
Windows 加载这个程序,找到程序的"起点"
↓
链接器在编译时就写好了:起点=main 函数的第一条指令
↓
所以你改了 main 的名字,链接器就找不到起点 → 报错
报错原话大致是:undefined reference to 'main' 或 LNK2019: unresolved external symbol main——看到 "main" 字样,先去查函数名有没有拼错。
两个合法形式(都会在书里出现):
int main() // 常用形式,本章都用它
int main(int argc, char* argv[]) // 带命令行参数的形式(第 12 章之后)
argc = argument count(参数个数),argv = argument vector(参数字符串数组)。现在不用管,知道"括号里可以放东西"就够。
三、执行顺序:一个必须破除的错觉
#include <iostream>
using namespace std;
void sayHi() { // ① 定义在 main 前面
cout << "我先写,但不先跑" << endl;
}
int main() { // ② 程序真正从这里开始
cout << "从 main 开始" << endl;
return 0;
}
运行结果只有一行:从 main 开始。sayHi 里那行代码根本没执行——因为没有任何地方"调用"它。
三条铁律:
- 程序从
main的第一条语句开始执行,跟它写在文件的第几行无关 - 函数定义不等于函数执行——定义只是"准备好",得有人"叫它"才会跑(第 5 章讲函数调用)
main只能有一个:两个main会报"重定义"(redefinition)
四、动手 Demo:两个实验,亲眼看"入口"的重要性
实验一:改名字
把 int main() 改成 int Main(),Ctrl+S → F11。
- 预期:报错里出现
undefined reference to 'main'之类的链接错误(不是语法错误!) - 关键体会:语法全对,编译器认得每一行,但链接器找不到入口——这就是"入口"两个字的重量
实验二:两个 main
新建一个文件,写两个 main:
int main() { return 0; }
int main() { return 1; }
- 预期:报
redefinition of 'int main()'——入口有且只有一个
看到什么算成功:两个实验都能说出"这是语法错还是链接错",并知道成因。
30 秒实验:在 main 后面定义 sayHi(),然后在 main 里面写 sayHi();,编译运行——这次它执行了。这一对比,就把"定义"和"调用"分清楚了(提前预习第 5 章)。
五、常见误区
- "函数名可以自己起,
main只是习惯"——不行。main是标准强制规定的入口名 - "
void main()更简单,就用它"——老编译器/老教材里有,现代标准要求返回int。用void main()在严格模式下会报错或警告,从一开始就写int main() - "代码从文件第一行开始执行"——从
main第一条语句开始。文件顶部的#include、函数定义都只是"准备" - "
main里可以什么都不写"——可以(空的花括号也能编过),但那样程序什么也不做,还会被老师/同事当成敷衍
自测四问(点开对答案)
1. `int main()` 的四个部件分别是什么?——`int` 返回值类型、`main` 函数名(固定)、`()` 参数表、`{ }` 函数体。 2. 为什么 `main` 不能改名字?——链接器把 **main 的第一条指令**登记为程序入口;改名后找不到入口,报链接错误。 3. 程序按什么顺序执行?——从 `main` 第一条语句开始往下走,遇到 `return` 结束;其他函数只有被**调用**才执行。 4. `main` 能有几个?——**有且只有一个**;写两个会报重定义。- ☑ 函数体