两者之间有什么区别(如果有的话)
#define BUF (8)
和
#define BUF 8
我对c编程不太有经验,从未见过#define只有1个数字,而且没有将其放在方括号中。
PS:代码使用带有-m32标志的gcc在64位linux系统上编译。因此最终的二进制文件是32位ELF可执行文件。
答案 0 :(得分:7)
作用域内宏标识符的外观仅由替换文本替换。因此,这段代码...
#define BUF 8
#define BUF2 (8)
x = BUF * BUF2;
...扩展为
x = 8 * (8);
尤其是,括号是替换文本的一部分,而不是宏定义的一部分。 (但是,请勿将其与类似函数的宏定义混淆,后者在标识符和左括号之间没有空格。)
在这种情况下,两个宏定义几乎可以全部使用,但不能完全互换使用。但是,在其他情况下,括号的影响更大。考虑一下:
#define MY_SIZE 16 + 7
#define MY_SIZE2 (16 + 7)
void *x = malloc(8 * MYSIZE);
void *y = malloc(8 * MYSIZE2);
它扩展为
void *x = malloc(8 * 16 + 7);
void *y = malloc(8 * (16 + 7));
,它为x
和y
保留了不同的内存量。
答案 1 :(得分:6)
我无法想象在这种特殊情况下明智地使用它会产生什么区别,但是请考虑一下:
#define add(x,y) x+y
int i=add(3,5)*2
现在,您会期望i的值为16,对吗?但是它会扩展为i = 3 + 5 * 2,使i的值为13。
HolyBlackCat在评论中写道float x = sin BUF;
在后一种情况下不会编译,这是完全正确的。但是,使用这样的宏是一个非常糟糕的主意。
在括号内插入内容永远不会造成伤害,而且通常会有所帮助。宏基本上只是一种高级复制粘贴。因此,如果您可以想象一段代码,其中字符序列(8)
会产生与8
不同的结果,那么这两个宏将以相同的方式发生变化。
出于类似的原因,如果一个宏包含多个语句,则最好将它们包含在do-while循环中。考虑一下:
#define callMy2Funcs(x,y) \
myFunc1(x); \
myFunc2(y);
现在,这个:
if(x>5)
callMy2Funcs(x,x);
将扩展为
if(x<5)
myFunc1(x);
myFunc2(x);
代替
if(x<5) {
myFunc1(x);
myFunc2(x);
}
解决方案是这样的:
#define callMy2Funcs(x,y) \
do {\
myFunc1(x); \
myFunc2(y); \
} while(0)
答案 2 :(得分:2)
在这样简单的宏定义(仅是一个常量)的情况下,实际上不需要将8
括在()
中。这对()
可以防止某些滥用,但是这些示例是人为的并且不现实。
但是一旦涉及到运算符,即被替换的文本旨在成为表达式,那么添加这些()
就变得更加重要。例如,如果您还具有一系列包含负值的相关清单常量定义,那么将这些()
添加到使用一元-
的替换中是一个很好的主意< / p>
#define CONSTANT_A 2
#define CONSTANT_B 1
#define CONSTANT_C 0
#define CONSTANT_D (-1)
在这种情况下,仅出于一致性考虑,将它们全部封装在()
中是有意义的。这是个人喜好。