第四章-预处理

一、C 语言编译过程

预处理、编译、汇编链接

gcc -E hello.c -o hello.i 1、预处理

gcc -S hello.i –o hello.s 2、编译

gcc -c hello.s -o hello.o 3、汇编

gcc hello.o -o hello_elf 4、链接

1、预编译

​ 将.c 的头文件、宏展开

​ 生成.i 文件

2、编译

​ 将预处理的.i 文件生成 .s 汇编文件

3、汇编

​ 将.s 汇编文件生成.o 目标文件

4、链接

​ .o 文件链接成目标文件

二、include

#include<> 用尖括号包括头文件,在系统指定的路径找到头文件

#include”” 用双引号包括头文件,先在当前目录下找到头文件,找不到再系统指定的路径下找

三、define

定义 宏用 define

1、不带参数的宏

1
2
3
#define PI 3.14
//终止宏的定义 定义
#undef PI

2、带参宏

#define S(a,b) a*b

注意带参宏的形参 ab 没有类名

S(2,4)在预处理代替成字符串的形参 2 * 4

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

#define S(a,b) ((a)*(b))

int main(){
printf("%d\n",S(2,4));
//((2+8))*(4))=40
printf("%d\n",S(2 + 8,4));
}

3、带参宏和代餐函数的区

​ 带参宏被调用多少次就会展开多少次,执行代码的时候没有函数调用的过程,不需要压栈弹栈。带参宏,浪费空间

​ 带参函数,代码只有一份,存放在代码段,调用的时候去代码段指令,调用的时候要压栈弹栈。带参函数浪费了时间,节省了空间

四、选择性编译

1、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifdef AAA
代码段一
#else
代码段二
#endif

//如果在当前.c ifdef上边定义AAA,就编译代码段一,否则编译代码段二
#include AAA

int main(){
#ifdef AAA
printf("hello kitty\n");
#else
printf("hello ddd");
#endif
return 0;
}

2、

1
2
3
4
5
6
#ifndef AAA
代码段一
#else
代码段二
#endif
//和第一种互补,用在防止头文件重复包含,用于多文件编程中.h的第一行就是#indef #endif结尾

3、

1
2
3
4
5
6
7
#if 表达式
代码块一
#else
代码块二
#endif
//如果表达式为真,编译第一段,否则第二段
//多用于注释多行代码