-2

我刚刚发现,如果我在文件中将 x 的值指定为 5 并按照以下代码运行它,我得到的输出为 392

#include<stdio.h>
#define CUBE(r) ((r)*(r)*(r))
int main()
{
    int x;
    x=5;
    printf("%d\n", CUBE(++x));
    return 1;
}

但是当我使用“scanf()”来获取 x 的值并为以下代码提供输入为 5 时,我得到的输出为 336

#include<stdio.h>
#define CUBE(r) ((r)*(r)*(r))
int main()
{
    int x;
    scanf(" %d",&x);
    printf("y is %d\n", CUBE(++x));
    return 1;
}

为什么我会得到这种输出

4

2 回答 2

5

这是因为你正在做的事情是未定义的,所以编译器可以自由地做它想做的事情。在没有插入序列点的情况下,您不得多次更改变量的值,其列表可在 C99 或 C11 的附录 C 中找到。

您的表达式CUBE(++x)计算为:

((++x)*(++x)*(++x))

您得到不同结果的最可能原因是,使用该x = 5版本,编译器可以在编译时评估结果,并且很可能只给您机器代码来打印出它计算的常量值。

对于数据输入版本,计算很可能留给运行时间,这可能会使用不同的计算方法。

一个解决方案是不要将宏用于代码,这是我很长时间没有做过的事情——我现在只将它们用于条件编译,因为代码宏可以作为内联函数来完成,而常量宏可以通过枚举来完成。

换句话说,使用:

inline int cube (int r) { return r * r * r; }

这与代码宏不完全inline一样,因为它只是一个建议(当然,该函数不会受到未定义行为的影响)但我经常找不到现在有用的内联建议,因为编译器比他们聪明得多曾经是关于优化的。

于 2013-08-31T12:19:22.710 回答
1

两者都会给你一个未定义的行为。使用适当的功能。就像多维数据集的内联函数一样,如下所示:-

inline int cube(int z) 
{ 
 return z*z*z; 
}
于 2013-08-31T12:19:08.270 回答