C语言三大预处理功能:
宏定义;文件包含;条件编译
不带参数的宏定义
#define PI 3.14
所有PI都替换为3.14
- 宏定义名字约定俗成为大写
- 宏定义在编译之前进行替换,而编译工作的任务之一就是语法检查,所以编译器不会对宏定义进行语法检查
- 宏定义不是说明或者语句,在末尾不必加分号
- 宏定义的作用域是从定义的位置开始到整个程序结束
- 可以用#undef来终止宏定义的作用域
- 宏定义允许嵌套
例子
#include<stdio.h>
#define PI 3.14
#define R 6371
#define V PI*R*R*R*4/3 //宏定义的嵌套
int main()
{
int r;
float s;
printf("input r:");
scanf("%d",&r);
#undef PI //这里之后就没有PI的定义了
s=PI*r*r;
printf("the area is:%.2f\n",s);
return 0;
}
带参数的宏定义
类似于函数,但实际上是机械地替换
比如
#define MAX(x,y) (((x)>(y))?(x):(y)) //求出x,y中较大的那个
注意!!下面的写法错误
#define MAX (x,y) (((x)>(y))?(x):(y)) //名称和参数没有紧密连在一起
易犯错误2
一旦写成x+1
宏定义并不会在替换时自动添加括号
反而会变成这种形式引起报错x+1*x+1
所以在宏定义的书写时候要尽量多加括号
SQURE(x) (x)*(x)
改写成这种形式后比较不容易犯错
注意尽量还是用函数,少用宏定义
宏定义的坑
#define STR(s) # s
int main(void)
{
int num = 520;
printf("%s\n", STR(num));
return 0;
}
这里并不会打印520 因为宏替换是预处理命令,在代码编译之前进行机械替换,早在num被赋值为520之前,printf("%s/n",STR(num))就被替换为printf("%s\n",“num”)了