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

时间:2013-08-31 12:16:09

标签: 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;
}

但是,当我使用“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;
}

为什么我会得到这种输出

2 个答案:

答案 0 :(得分:5)

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

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

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

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

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

一个解决方案是不使用宏代码,这是我没有为 long 时间做的事情 - 我现在只使用它们进行条件编译,因为代码宏可以作为内联函数和常量来完成宏可以用枚举来完成。

换句话说,使用:

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

由于inline仅仅是一个建议(并且,当然,该函数不会受到未定义的行为影响),因此它不像完全那样代码宏,但我经常找不到现在有用的内联建议,因为编译器比以前的优化要聪明得多。

答案 1 :(得分:1)

两者都会给你一个undefined behaviour。使用适当的功能。像你的多维数据集的内联函数,像这样: -

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