#include
#define TWO 2
#define OW "Consistency is the last refuge of the unimagina tive. -Oscar Wilde"
#define FOUR TWO*TWO
#define PX printf("X is %d.\n",x)
#define FMT "X is %d.\n"
int main()
{
int X = TWO;
printf(FMT, X);
printf("%s\n",OW);
printf("TWO:OW\n");
return 0;
}
程序运行结果:
X is 2.
Consistency is the last refuge of the unimagina tive. -Oscar Wilde
TWO:OW
假设把LIMIT定义为20,稍后在该文件中又把它定义为25。这个过程为重定义常量
在#define中使用参数可以创建外形和作用与函数参数类似的类函数宏。带有参数的宏看上去很像函数,因为这样的宏也使用圆括号。类函数宏定义的圆括号中可以有一个或多个参数,随后这些参数出现在替换体中
#include
#define SQUARE(X) X*X
#define PR(X) printf("The result is %d.\n",X)
int main()
{
int x = 5;
int z;
printf("x=%d\n", x);
z = SQUARE(x);
printf("Evaluating SQUARE(x):");//5*5
PR(z);
printf("Evaluating SQUARE(x+2):");//5+2*5+2
PR(SQUARE(x + 2));
}
程序运行结果:
x=5
Evaluating SQUARE(x):The result is 25.
Evaluating SQUARE(x+2):The result is 17.
C允许在字符串中包含宏参数,那么#x就是转换为字符串“‘x’的形参名,这个过程称为字符串化
#include
#define PSQR(x) printf("The square of "#x" is %d.\n",((x)*(x)));
int main()
{
int y = 5;
PSQR(y);
PSQR(2 + 4);
return 0;
}
程序运行结果:
The square of y is 25.
The square of 2 + 4 is 36.
##运算符可用于类函数宏的替换部分,##还可用于对象宏的替换部分,##运算符把两个记号组合成一个记号
#include
#define XNAME(n) x ## n
#define PRINT_XN(n) printf("x" #n "=%d\n",x##n);
int main()
{
int XNAME(1) = 14;//变成int x1=14;
int XNAME(2) = 20;//变成int x2=20;
int x3 = 30;
PRINT_XN(1);//变成printf("x1=%d\n",x1);
PRINT_XN(2);//变成printf("x2=%d\n",x2);
PRINT_XN(3);//变成printf("x3=%d\n",x3);
return 0;
}
程序运行结果:
x1=14
x2=20
x3=30
注意:PRINT_XN()宏用#运算符组合字符串,##运算符把记号组合成一个新的标识符
注意事项
- 宏名中不能有空格,但是替换字符串中可以有空格,ANSI C允许在参数列表中使用空格
- 用圆括号把宏的参数和整个替换体括起来。这样能确保被括起来的部分在下面这样的表达式中正确地展开
- 用大写字母表示宏参数的名称、大写字母可以提醒程序员注意,宏可能产生的副作用
- 如果打算使用宏来加快程序的运行速度,那么首先要确定使用宏和使用函数是否会导致较大的差异。
为什么要包含文件?
因为编译器需要这些文件中的信息
#include指令有两种形式:
文件名在尖括号中:尖括号告诉预处理器在标准系统目录中查找该文件
#include
文件名在双引号中:双引号告诉预处理编译器首先在当前目录中(或文件名中指定的其他目录)查找该文件,如果未找到再查找标准系统目录
#include"test.h"
#undef指令用于“取消”已定义的#define指令
#define LIMIT 400
#undef LIMIT //将上面定义移除,如果想想使用一个名称,有不确定之前是否使用过,为安全起见,可以用#undef指令取消该名字的定义
使用这些指令告诉编译器根据编译时的条件执行或忽略信息(或代码)块
#ifdef指令说明,如果预处理已定义了后面的标识符,则执行#else或#endif指令之前的所有指令并编译所有C代码(先出现哪个智指令就执行到哪里。
#ifndef指令和#ifdef指令的用法类似,也可以和#else,#endif一起使用,但是它们的逻辑相反。#ifndef指令判断后面的标识符是否是未定义的,常用于定义之前未定义的常量
#if指令很像C语言中的if。#if后面跟整型常量表达式。如果表达式为非零,则表达式为真,可以在指令中使用C的关系运算符和逻辑运算符
#if SYS==1
#include
#elif SYS==2
#include
elif SYS==3
#include
else
#include
#endif