C 什么是论证评价?

C 什么是论证评价?,c,C,赫伯特·席尔德说: 在某些情况下,应该使用实函数来代替宏之类的函数,例如:代码大小要最小化,或者参数的计算不能超过一次 他所说的“一个参数不能被计算多次”是什么意思?让我们用一个宏来计算两个值的最大值: #define MAX(a, b) ((a) < (b) ? (a) : (b)) 然后将宏扩展为 int max = ((x++) < (y++) ? (x++) : (y++)); 现在,如果调用宏作为 int sum = MUL(x + 3, y - 2); 然后扩展就变

赫伯特·席尔德说:

在某些情况下,应该使用实函数来代替宏之类的函数,例如:代码大小要最小化,或者参数的计算不能超过一次


他所说的“一个参数不能被计算多次”是什么意思?

让我们用一个宏来计算两个值的最大值:

#define MAX(a, b) ((a) < (b) ? (a) : (b))
然后将宏扩展为

int max = ((x++) < (y++) ? (x++) : (y++));
现在,如果调用宏作为

int sum = MUL(x + 3, y - 2);
然后扩展就变成了

int sum = x + 3 * y - 2;
这等于

int sum = x + (3 * y) - 2;
如果一个人期望
(x+3)*(y-2)
,通常与预期不完全一样


这个问题也可以通过使用函数来“解决”。

有时参数有副作用

例如,
i++
的值是
i
,但是
i
增加了1。因此,next
i++
的值将为
i+1

在宏中,每次调用参数时都会对其求值,从而产生结果值;在函数中,计算(实际)参数并将其复制到函数中的(形式)参数,从而消除副作用


在实现一个函数时,您不关心副作用。但是,隐式类型提升和转换可能更容易出错。

Schildt是。我不知道那本书,但是如果引用的陈述是这种风格的典型,我完全同意怀疑论者的观点。@DevSolar,你的意思是,对吗?还是因为这个问题有标记而没有,所以你用a来拼写P@tac不管你住在池塘的哪一边,它都被用作那个句子中的副词,所以它应该是怀疑的。正如约阿希姆在他的回答中所说,MAX(x++,y++)被扩展为
((x++)<(y++)?(x++):(y++)并因此计算两次。对应的函数
max(x++,y++)
,仅对每个参数求值once@haccks
x++
y++
表达式都作为条件的一部分进行计算。然后根据三元表达式中的条件再次计算
x++
y++
中的一个。@haccks但是宏只是扩展到宏的主体,没有对“参数”的计算,因为这些参数只是粘贴到扩展的宏中。当使用我的答案中定义的宏(如
MAX
)时,则处理宏扩展的是预处理器,编译器本身看不到宏调用,只看到扩展的三元表达式。第二个问题通过
#define MUL(a,b)((a)*(b))得到缓解
我认为你的第二个例子对这个问题没有帮助。正如Erburat所说,你可以通过添加一些括号来解决这个问题——因此这是一个使用格式不好的宏的例子,而不是一个应该使用函数的宏的例子。
int sum = x + 3 * y - 2;
int sum = x + (3 * y) - 2;