【问题标题】:Behaviour of preincrement operator in C programC 程序中预增量运算符的行为
【发布时间】:2012-05-06 23:20:59
【问题描述】:

我正在运行以下 C 代码:

#define cube(x) (x*x*x)
void main()
{   
    int x=2,y;   
    y=cube(++x);            
    printf("%d %d",++x,y);    
}

我期待结果

6,60

但它给出了不同的结果。我想我对预处理器有误解。我认为代码将类似于

void main()
{   
    int x=2,y;   
    y=++x*++x*++x;            
    printf("%d %d",++x,y);    
}

如果我错了,请纠正我。

我将结果解释为 3*4*5=60
但它即将到来 125

【问题讨论】:

  • 你能解释一下为什么你期望这个结果吗?听起来您对 C 语言有误解,因为没有理由期待任何特定的结果。 (也许您将乘法发生的已定义顺序与要相乘的事物本身计算的未指定顺序混淆了?)
  • 我是否遗漏了什么,当我在 Mac OSX Lion 中运行上述代码(第一个使用预处理器的代码)时,gcc 版本为 4.2.1,我得到的值是 6,60
  • @DavidSchwartz:据我所知,前缀增量是从右到左关联的,所以 ++x*++x*++x 即 3*4*5 将给出 60。
  • @SachinMhetre:我得到了 6,125 作为输出

标签: c pre-increment


【解决方案1】:

您定义了一个宏,它用作简单的字符串替换,因此呈现的翻译是正确的。

但是,子表达式的执行顺序是未定义的,例如,它们可以是交错的,这会导致未定义的行为

【讨论】:

  • 变量x 在序列点之间被多次修改,这就是导致未定义行为的原因。虽然子表达式的求值顺序是未定义的,但它本身并不一定会导致未定义的行为(x*x*x 是完美定义的,例如)。
【解决方案2】:

预处理器采用我们给出的表达式,因此,对于您的 c 代码,最初 x=2,因此在执行宏时,

先用两个值相乘,再用第三个值乘以结果,所以顺序应该是,

++x * ++x => 3(第一个增量),4(再次为下一个增量),所以现在x值为4,根据表达式

4 * 4 => 16,

再次为下一个增量 x => 5,所以根据你的表达式结果应该是,

16 * 5 => 80

所以现在乘法的总结果是80,x值是5。

【讨论】:

  • 这种情况下的输出是 5*5*5=125 和 x 的值为 6
  • 不不,我只是解释了值如何递增以及乘法如何发生,不要取最后一个 x 值。显然我提到了结果是 4*4*5 => 80,x 值是 5。如果你在这个操作之后增加 x,x 值应该是 6。
  • 我编译了该程序,输出为 125。(mohan raj 不是 80)。 @Mohanraj 您使用的是哪个编译器...您在您的编译器上验证了您的输出吗?
  • 我正在使用 ubuntu 11.10 和 GCC 编译器,我的整个程序是 #include #define cube(v) (vvv) void main() { int x=2,y; printf("%d \n",x); printf("%d \n", 立方体(++x)); printf("%d \n",x); 2 80 5 我的输出是
  • @Jaguar 你在聊天室吗。
【解决方案3】:

此程序的输出因编译器、操作系统甚至同一编译器的不同版本而异,因为输出取决于子表达式的执行顺序。
我用 Visual Studio 编译它:o/p 是 125。
当我用 gcc 编译时:o/p 是 80。
所以你无法预测输出。
而且我不知道为什么人们在面试中问这些类型的问题(那些没有明确的结果)?

【讨论】:

    【解决方案4】:

    表达式++x*++x*++x 将使x 的值增加三次,即x 的值将是分配给表达式的5。所以5*5*5 = 125 是输出。同样,该值因编译器的体系结构而异。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2017-06-30
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多