C语言#define的用法
引导语:预处理器是在真正的编译开始之前由编译器调用的独立程序。以下是百分网小编分享给大家的C语言#define的用法,欢迎阅读!
#define的用法
#define 是一个预处理指令,这个预处理执行可以定义宏。与所有预处理指令一样,预处理指令#define用#符号作为行的开头。预处理指令从#开始,到其后第一个换行符为止。也就是说,指令的长度限于一行代码。如果想把指令扩展到几个物理行,可使用反斜线后紧跟换行符的方法实现,该出的换行符代表按下回车键在源代码文件中新起一行所产生的字符,而不是符号 \n 代表的字符。在预处理开始钱,系统会删除反斜线和换行符的组合,从而达到把指令扩展到几个物理行的效果。可以使用标准C注释方法在#define行中进行注释。
//使用反斜线+回车
#define OW "hello\
world!" /*注意第二行要左对齐*/
每一个#define行由三部分组成:
第一部分,指令#deine自身。
第二部分,所选择的缩略语,这些缩略语称为宏(分为对象宏和函数宏)。宏的名字中不允许有空格,而且必须遵循C变量命名规则:只能使用字母、数字和下划线(_),第一个字符不能为数字。习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。
第三部分,(#define行的其余部分)称为替换列表或主体。
注意,结尾没有分号
下面来看一个例子:
#include
#define OW 2 * 2
#define OW 2 * 2
//#undef OW 需要先取消宏定义
#define OW 2*2
int main (void)
{
printf ("%d\n", OW);
return 0;
}
输出结果:
define.c:5:0: 警告: “OW”重定义 [默认启用]
define.c:4:0: 附注: 这是先前定义的位置
相同定义意味着主体具有相同顺序的语言符号。因此,下面两个定义相同:
#define OW 2 * 2
#define OW 2 * 2
两者都有三个相同的语言符号,而且额外的`空格不是主体的一部分。下面的定义则被认为是不同的:
#define OW 2*2
上式只有一个(而非三个)语言符号,因此与前面两个定义不同。可以使用#undef指令重新定义宏。
宏所代表的数字可以在编译命令中指定(使用-D选项)
/*
宏演示
*/
#include
int main()
{
int num=0;
int arr[SIZE]={}; //使用gcc -D可以宏定义这个数字
for(num = 0;num <= SIZE - 1;num++)
{
arr[num]=num;
printf("%d ",arr[num]);
}
printf("\n");
return 0;
}
gcc -DSIZE=4 define.c
输出结果:
0 1 2 3
函数宏:
通过使用参数,可以创建外形和作用都与函数相似的类函数宏。宏的参数也用圆括号括起来。类函数宏的定义中,用圆括号括起来一个或多个参数,随后这些参数出现在替换部分。
#include
#define SQUARE(X) X*X
#define PR(X) printf ("The result is %d\n", X)
int main (void)
{
int x = 4;
int z;
printf ("x = %d\n", x);
z = SQUARE(x);
printf ("Evaluating SQUARE(x): ");
PR(z);
z = SQUARE(2);
printf ("Evaluating SQUARE(2): ");
PR(z);
printf ("Evaluating 100/SQUARE(2): ");
PR(100/SQUARE(2));
z = SQUARE(x+2);
printf ("Evaluating SQUARE(x+2): ");
PR(z);
printf ("x is %d\n", x);
z = SQUARE(++x);
printf ("Eavluating SQUARE(++x): ");
PR(SQUARE (++x));
printf ("After incrementing, x is %x\n", x);
return 0;
}
输出结果:
x = 4
Evaluating SQUARE(x): The result is 16
Evaluating SQUARE(2): The result is 4
Evaluating 100/SQUARE(2): The result is 100
Evaluating SQUARE(x+2): The result is 14
x is 4
Eavluating SQUARE(++x): The result is 36
After incrementing, x is 6
SQUARE(x+2) 输出结果是14,而不是想要的6*6 = 36。这是因为预处理器不进行计算,而只进行字符串替换。在出现x的地方,预处理都用字符串 x+2进行替换。x*x 变为 x+2*x+2 根据运算符优先级,则结果为 14
100/SQUARE(2)输出结果是 100,而不是想要的 25。因为,根据优先级规则,表达式是从左到右求值的。
100/2*2 = 100
要处理前面两个示例中的情况,需要如下定义:
#define SQUARE(x) ((x) * (x))
从中得到的经验是使用必须的足够多的圆括号来保证以正确的顺序进行运行和结合。
SQUARE(++x) 根据编译器的不同会出现两种不同的结果。解决这个问题的最简单的方法是避免在宏的参数中使用++x。一般来说,在宏中不要使用增量或减量运算符。
参看:C 语言再学习 -- 运算符与表达式
利用宏参数创建字符串:#运算符
在类函数宏的替换部分中,#符号用作一个预处理运算符,它可以把语言符号转化为字符串。