HI,
有人可以帮助我理解为什么SQUARE(x)的值是49?
我正在使用Visual C ++ 6.0。
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
答案 0 :(得分:16)
Neil Butterworth,Mark和Pavel是对的。
SQUARE(++ y)扩展为++ y * ++ y,它的增量是y的两倍。
您可能遇到的另一个问题:SQUARE(a + b)扩展为a + b * a + b,它不是(a + b)*(a + b)而是a +(b * a)+ b。在定义宏时,您应该在需要时在元素周围添加括号:#define SQUARE(X)((X)*(X))风险稍低。 (Ian Kemp在他的评论中首先写了它)
您可以改为使用内联模板函数(在运行时效率不低),如下所示:
template <class T>
inline T square(T value)
{
return value*value;
}
您可以检查它是否有效:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(无需写
square<int>(++i)
因为int类型是隐含的i)
答案 1 :(得分:15)
因为宏扩展为:
++y * ++y
在C ++中给出了未定义的行为 - 结果可以 做任何事。任何涵盖宏使用的体面教科书都应该涵盖这个众所周知的问题。你在用哪一个?
答案 2 :(得分:5)
因为宏会进行文本替换,所以您编写的代码会扩展为
printf("%d\n",++y * ++y );
然后操作的顺序是未定义的行为,因此编译器看到2个增量,然后是乘法
因此,最好小心使用宏,因为编译器可以内联扩展不再需要运行。
其次不要假设如果增加和使用变量会发生什么
答案 3 :(得分:5)
宏不是函数:它们只是改变程序的文本。此操作称为预处理,它在代码编译之前自动执行。人们编写宏来节省时间并为源代码引入一些可变性。
当您编写SQUARE(x)
时,不会发生实际的函数调用,只会修改文本。操作非常愚蠢,所以你必须在像你这样的情况下采取额外的预防措施。请参阅其他答案以解释您的案例。