嵌入式学习-01C语言day11
1 预处理器
1.1 基本介绍
1.1.1 预处理器
C语言编译器在编译程序之前,会先使用预处理器(preprocessor)处理代码,代码经过预处理之后再送入编译器进行编译。
预处理器的主要任务包括宏替换、文件包含、条件编译等。
1.1.2 预处理指令
预处理过程中会执行预处理指令,预处理指令以 # 号开头,用于指导预处理器执行不同的任务。
预处理指令具有如下特点:
(1)预处理指令应该放在代码的开头部分。
(2)预处理指令都以 # 开头,指令前面可以有空白字符(比如空格或制表符),# 和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。
// 推荐写法
#include <stdio.h>
// 不推荐写法
#include <stdio.h>
# include <stdio.h>
(3)预处理指令都是一行的,除非在行尾使用反斜杠,将其折行。
#include <std\
io.h>
(4)预处理指令不需要分号作为结束符,指令结束是通过换行符来识别的。
#include <stdio.h>; // 这里有分号会报错
#define PI 3.14; // 分号会成为 PI 的值的一部分
(5)预处理指令通常不能写在函数内部,有些编译器的扩展允许将预处理指令写在函数里,但强烈不建议这么干。
int main ()
{
// 一般不允许写在这里
#include <stdio.h>
return 0;
}
1.2 宏定义
1.2.1 基本介绍
宏定义,就是用一个标识符(宏名称)来表示一个替换文本,如果在后面的代码中出现了宏名称,预处理器会将它替换为对应的文本,称为宏替换或宏展开。
宏定义的基本语法形式如下:
#define 宏名称 替换文本
宏名称:宏的名称,是一个标识符,通常使用大写字母表示,以便与变量名区分开来。
替换文本:宏名称在代码中的每次出现都会被替换为这段文本。
前面的案例中,我们曾经使用宏定义来定义常量和布尔类型。
1.2.2 使用宏定义常量
#include <stdio.h>
// 定义常量
#define PI 3.14
int main()
{
// 定义变量保存半径,值通过用户输入获取
double radius;
printf("请输入半径:");
scanf("%lf", &radius);
// 计算面积并输出
printf("圆的面积:%.2f", radius * PI * PI);
return 0;
}
上面代码中,使用宏定义声明了N,后面代码中出现了 N,会替换成 100。
1.2.3 使用宏定义数据类型
#include <stdio.h>
// 宏定义
#define BOOL int
#define TRUE 1
#define FALSE 0
int main()
{
// 使用整型表示真假两种状态
// int isPass = 0;
// int isOk = 1;
// 借助于宏定义
BOOL isPass = FALSE;
BOOL isOk = TRUE;
if (isPass)
{
printf("Pass");
}
if (isOk)
{
printf("Ok");
}
return 0;
}
上面代码中使用宏定义声明了BOOL、TURE、FALSE,后面代码中出现BOOL会替换成int,出现TRUE会替换成1,出现FALSE替换成0。
1.2.4 宏定义的替换文本
替换文本可以含任何字符,它可以是字面量、表达式、if 语句、函数等,预处理程序对它不作任何检查,直接进行文本替换,如有错误,只能在编译已被宏展开后的源程序时发现。
代码示例:
#include <stdio.h>
#define M (n * n + 3 * n)
#define PRINT_SUM printf("sum=%d", sum)
int main()
{
int n = 3;
int sum = 3 * M + 4 * M + 5 * M; // 宏展开 3*(n*n+3*n)+4*(n*n+3*n)+5*(n*n+3*n);
PRINT_SUM; // 宏展开 printf("sum=%d", sum)
return 0;
}
输出结果:
sum=216
1.2.5 宏定义嵌套
宏定义允许嵌套,在宏定义的替换文本中可以使用已经定义的宏名,在宏展开时由预处理程序层层替换。
代码示例:
#include <stdio.h>
#define PI 3.1415926
#define S PI *y *y
int main()
{
int y = 2;
printf("%f", S); // 宏替换变为 printf("%f", 3.1415926*y*y);
return 0;
}
输出结果:
12.566370
1.2.6 取消宏定义
如要取消宏定义使用#undef命令。
#include <stdio.h>
#define PI 3.14159
int main()
{
printf("PI=%f", PI);
return 0;
}
#undef PI // 取消宏定义
void func()
{
// printf("PI=%f", PI); //错误,这里不能使用到PI了
}
输出结果:
PI=3.141590
1.3 带参数的宏定义
1.3.1 基本介绍
C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实际参数”,这点和函数有些类似。
对带参数的宏,在展开过程中不仅要进行文本替换,还要用实参去替换形参。
带参宏定义的一般形式为:
#define 宏名称(形参列表) 可以包含形参的替换文本
带参宏调用的一般形式为:
宏名称(实参列表);
代码示例:
#include <stdio.h>
// 定义带参数的宏定义取两个数字中较大的一共
#define MAX(a, b) a > b ? a : b
int main()
{
printf("两个数字中较大的:%d \n", MAX(101, 451))