“ #define BUF 8”和“ #define BUF(8)

时间:2019-04-16 18:53:58

标签: c

两者之间有什么区别(如果有的话)

#define BUF (8)

#define BUF 8

我对c编程不太有经验,从未见过#define只有1个数字,而且没有将其放在方括号中。

PS:代码使用带有-m32标志的gcc在64位linux系统上编译。因此最终的二进制文件是32位ELF可执行文件。

3 个答案:

答案 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));

,它为xy保留了不同的内存量。

答案 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)

在这种情况下,仅出于一致性考虑,将它们全部封装在()中是有意义的。这是个人喜好。