4.2 有值的宏

除了定义宏,也可以给一个宏赋一个具体的值。这个值会替换源代码中所有这个宏出现的地方。下面的程序使用了一个NUM宏,来替代一个将会被打印的值:

include

int

main (void)

{

printf("Value of NUM is %d\n", NUM);

return 0;

}

注意宏不会出现在字符串中--只有字符串以外的宏会被预处理器识别。

可以使用'-D'命令行选项定义一个有值的宏'-DNAME=VALUE'。例如下面的命令行在编译程序时定义了NUM宏的值为100:

$ gcc -Wall -DNUM=100 dtestval.c

$ ./a.out

Value of NUM is 100

这个例子中使用了数字但是宏可以代表任何其他的值。无论宏的值是什么,都会被直接插入到源代码中出现宏的地方。例如,下面的定义使NUM宏的值为"2+2":

$ gcc -Wall -DNUM="2+2" dtestval.c

$ ./a.out

Value of NUM is 4

预处理器用"2+2"替换NUM之后,等同于编译下面程序:

include

int

main (void)

{

printf("Value of NUM is %d\n", 2+2);

return 0;

}

注意无论何时当他们是表达式的一部分时使用括号把宏括起来是一个非常好的习惯。例如,下面的程序使用括号来确保 10*NUM 表达式的正确含义:

include

int

main (void)

{

printf ("Ten times NUM is %d\n", 10 * (NUM));

return 0;

}

使用括号后,使用相同命令编译程序时产生的结果和预期的一样:

$ gcc -Wall -DNUM="2+2" dtestmul10.c

$ ./a.out

Ten times NUM is 40

当没有括号时程序的结果会是22,表达式是这样的102+2 = 22而不是期望的值10(2+2) = 40。

当只用'-D'选项定义宏时GCC使用默认值1。例如使用'-DNUM'选项编译前面的程序会产生如下结果:

$ gcc -Wall -DNUM dtestval.c

$ ./a.out

Value of NUM is 1

也可以使用命令行 -DNAME="" 定义一个包含空值的宏。这样的宏仍然有效,但是扩展后为空。

如果一个宏中包含引号可以使用斜杠字符转义。例如命令行选项 -DMESSAGE="\"Hello,World!\"" 定义了MESSAGE宏,它被扩展为字符串"Hello,World!"。参见"GNU Bash Reference Manual"了解更多内容。