Suj*_*osh 5 c++ macros visual-c++-6
嗨,
有人可以帮助我理解为什么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;
}
Run Code Online (Sandbox Code Playgroud)
moa*_*ala 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;
}
Run Code Online (Sandbox Code Playgroud)
你可以检查它的工作原理:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
Run Code Online (Sandbox Code Playgroud)
(不需要写
square<int>(++i)
Run Code Online (Sandbox Code Playgroud)
因为int类型是隐含的i)
小智 15
因为宏扩展到:
++y * ++y
Run Code Online (Sandbox Code Playgroud)
它在C++中给出了未定义的行为 - 结果可能是任何东西.任何涵盖宏使用的体面教科书都应该涵盖这个众所周知的问题.你在用哪一个?
因为宏会进行文本替换,所以您编写的代码会扩展为
printf("%d\n",++y * ++y );
Run Code Online (Sandbox Code Playgroud)
然后操作的顺序是未定义的行为,因此编译器看到2个增量,然后是乘法
所以要小心使用宏来使用函数,因为编译器可以内联扩展不再需要运行.
其次,不要假设如果增量和使用变量会发生什么
宏不是函数:它们只是改变程序的文本.此操作称为预处理,它在代码编译之前自动执行.人们编写宏来节省时间并为源代码引入一些可变性.
当你写SQUARE(x),没有实际的函数调用发生,只是文本被修改.操作非常愚蠢,所以你必须在像你这样的情况下采取额外的预防措施.有关您的案例的解释,请参阅其他答案.
| 归档时间: |
|
| 查看次数: |
4315 次 |
| 最近记录: |