以下两个C代码之间有什么区别

siv*_*iva -2 c

我刚刚发现,如果我在文件中指定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;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我使用"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;
}
Run Code Online (Sandbox Code Playgroud)

为什么我得到这种输出

pax*_*blo 5

这是因为你正在做的事情是未定义的,因此编译器可以自由地做它想做的事情.如果没有插入序列点,则不允许多次更改变量的值,其列表可在C99或C11的附录C中找到.

您的表达式CUBE(++x)评估为:

((++x)*(++x)*(++x))
Run Code Online (Sandbox Code Playgroud)

您获得不同结果的最可能原因是,对于x = 5版本,编译器可以在编译时评估结果,并且可能只是给您机器代码打印出它计算的常量值.

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

一种解决方法是不使用宏代码,这是我没有了做的时间-我只有现在使用他们的条件编译代码,因为宏是可以做到的内联函数和宏常量可以用枚举来完成.

换句话说,使用:

inline int cube (int r) { return r * r * r; }
Run Code Online (Sandbox Code Playgroud)

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