返回:安全开发篇(一)目录 · 上一篇:003、项目搭建第一个 C 语言程序 · 下一篇:005、注释方式

对应视频:1.3 基础-C语言程序架构.mp4

1、学习目标

这一节关注 C 程序由哪些部分组成。写代码时不能只会照着抄,还要知道每一块在程序结构里扮演什么角色。

需要掌握:

  1. 预处理指令;
  2. 函数;
  3. 语句;
  4. 代码块;
  5. 注释;
  6. 程序入口。

2、最小程序架构

1
2
3
4
5
6
7
#include <stdio.h>

int main(void)
{
printf("Hello\n");
return 0;
}

可以把它拆成下面几层:

结构 示例 作用
预处理指令 #include <stdio.h> 编译前引入头文件
函数定义 int main(void) 定义程序入口函数
代码块 { ... } 包裹一组语句
函数调用 printf("Hello\n"); 调用标准库函数
返回语句 return 0; 结束函数并返回结果

3、语句和分号

C 语言里大多数语句以分号结尾:

1
2
3
int age = 20;
printf("%d\n", age);
return 0;

但不是所有行都需要分号,例如:

1
2
3
4
5
6
#include <stdio.h>

int main(void)
{
return 0;
}

#include 是预处理指令,函数头和 {} 也不是普通表达式语句。

4、代码块

代码块由 {} 包围,用来组织一组语句。

1
2
3
4
5
if (1)
{
int value = 10;
printf("%d\n", value);
}

代码块会影响变量作用域。后面学习局部变量、栈空间和函数调用时,代码块是理解变量生命周期的基础。

5、程序入口

C 程序从 main 函数开始执行。

常见写法:

1
2
3
4
int main(void)
{
return 0;
}

带命令行参数的写法:

1
2
3
4
int main(int argc, char *argv[])
{
return 0;
}

初学阶段先用 int main(void),后续写命令行工具时再重点使用 argc 和 argv。

6、安全开发观察

理解程序架构,是为了后面能读懂更复杂的工程:

当前基础 后续连接
#include 头文件、API 声明、宏定义
main 程序入口、调试起点
函数调用 调用栈、参数传递、返回地址
代码块 局部变量作用域和生命周期
语句顺序 执行流和控制流分析

逆向分析里看到的入口点、函数边界和调用关系,本质上都可以先从这里建立直觉。

7、代码实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

void print_line(void)
{
printf("----------------\n");
}

int main(void)
{
print_line();
printf("C program structure\n");
print_line();

return 0;
}

观察重点:

  1. 程序从 main 进入;
  2. main 调用 print_line;
  3. print_line 执行后返回调用位置;
  4. 输出顺序和代码执行顺序一致。

8、复盘题

8.1 C 程序必须有 main 函数吗?

普通控制台 C 程序需要 main 作为入口函数。没有入口函数,链接阶段通常无法生成可运行程序。

8.2 为什么 #include 后面没有分号?

因为 #include 是预处理指令,不是普通 C 语句。它在编译前由预处理器处理。

8.3 {} 的作用是什么?

{} 用来形成代码块,组织一组语句,并影响局部变量的作用范围。函数体、条件分支和循环体都常用代码块。

这一节的核心是建立“程序由结构组成”的感觉。以后再看复杂代码时,先找入口、函数、语句块和调用关系。