C 语言三大预处理功能
- 宏定义
- 文件包含
- 条件编译
编译预处理指令
- #开头的是编译预处理指令
- 他们不是C语言的成分,但是C语言离不开他们
- #define用来定义一个宏
宏定义
再高级的宏定义也只是替换,不做计算或表达式求解。
define
- #define<名字><值>
- 注意没有结尾的分号,因为这不是C的语句
- 名字必须是一个单词,值可以是各种东西
- 在C语言的编译器开始编译之前,编译预处理程序(cpp)会把程序中的名字换成值
-完全的文本替换
预定义的宏
- LINE 源代码所在行的行号
- FILE 源代码文件的文件名
- DATE 编译时候的日期和时间
- TIME
- STDC
不带参数的宏定义
- 为了和普通的变量进行区分,宏的名字通常我们约定是全部由大写字母组成。
- 宏定义知识简单地进行替换,并且由于预处理是在编译之前进行,而编译工作的任务之一就是语法检查,所以编译器不会对宏定义进行语法检查。
- 宏定义不是说明或语句,在末尾不必加分号。
- 宏定义的作用域是从定义的位置开始到整个程序结束。
- 可以用#undef来终止宏定义的作用域。
- 宏定义允许嵌套。(宏定义中使用另一个宏)
宏定义分为带参数和不带参数两种情况,不带参数的情况就是我们熟悉的直接替换操作。
#define PI 3.14
这个宏定义的作用是把程序中出现的 PI 在预处理阶段全部替换成 3.14。
#include <stdio.h>
#define PI 3.14
int main(void)
{
int r;
float s;
printf("请输入圆的半径:");
scanf("%d",&r);
s = PI * r *r;
printf("圆的面积是:%.2f\n",s);
return 0;
}
结果如下:
#include <stdio.h>
#define PI 3.14
int main(void)
{
int r;
float s;
printf("请输入圆的半径:");
scanf("%d",&r);
#undef PI
s = PI * r *r;
printf("圆的面积是:%.2f\n",s);
return 0;
}
例子:
#include <stdio.h>
#define R 6371
#define PI 3.14
#define V PI * R * R * R * 4 / 3
int main(void)
{
printf("地球的体积大概是:%.2f\n",V);
return 0;
}
结果如下:
带参数的宏定义
像函数的宏
- #define cube(x)((x)(x)(x))
- 宏可以带参数
C 语言允许宏定义带有参数
- 在宏定义中的参数称为形式参数
- 在宏调用中的参数称为实际参数,这点和函数有些类似。
错误的宏定义
#define RADTODEG1(x)(x*57.29578)
#define RADTODEG2(x)(x)*57.29578
带参数的宏的原则
- 一切都要括号
- 整个值要括号
- 参数出现的每个地方都要括号
#define RADTODEG(x)((x)*57.29578)
带参数的宏
- 可以带多个参数
-#define MIN(a,b)((a)>(b)?(b):(a)) - 也可以组合(嵌套)使用其他宏
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#include <stdio.h>
#define MAX(x,y) (((x)>(y))?(x):(y))
int main(void)
{
int x,y;
printf("请输入两个整数:");
scanf("%d%d",&x,&y);
printf("%d是较大的那个数!\n",MAX(x,y));
return 0;
}
结果如下: