“++j + ++j + ++j"不同编译器不同结果

软件和网站开发以及相关技术探讨
头像
tlhl28
帖子: 474
注册时间: 2006-09-02 18:58
来自: 深圳

“++j + ++j + ++j"不同编译器不同结果

#1

帖子 tlhl28 » 2007-11-09 11:35

代码: 全选

#include <stdio.h>
main()
{
    int a,j=100;
       a = ++j + ++j + ++j;
       printf("%d",a);
}
TC的结果是 309。GCC , g++ 和 VC++的结果是307。为什么?!
TC的结果可以理解,但307就不能理解了 。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

#2

帖子 eexpress » 2007-11-09 11:37

看自己写的标题。
● 鸣学
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
联系:

#3

帖子 BigSnake.NET » 2007-11-09 11:46

这些代码不好..
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
madoldman
帖子: 599
注册时间: 2006-02-27 20:19
来自: works system
联系:

#4

帖子 madoldman » 2007-11-09 11:51

代码是写给人看的,不是写给机器看的!
这种代码除了在学校某些脑子缺几个二极管的老师会考之外还有别的用处吗?
东西路,南北走
十字路口人咬狗
拿起狗来打砖头
砖头咬了狗一口
图片
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
联系:

#5

帖子 BigSnake.NET » 2007-11-09 11:53

代码: 全选

        movl    $100, -8(%ebp)
        addl    $1, -8(%ebp)
        addl    $1, -8(%ebp)
        movl    -8(%ebp), %eax
        addl    -8(%ebp), %eax
        addl    $1, -8(%ebp)
        addl    -8(%ebp), %eax
看上去是这样的 ..
先做前两个 ++ , 然后相加, 然后再做最后一个++, 再相加
++j -> j=101
++j -> j=102
j+j -> tmp = 204
++j -> j=103
tmp +j -> 307
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

#6

帖子 eexpress » 2007-11-09 12:04

球猫,变态的才去理会这样的代码的。
● 鸣学
头像
karron
帖子: 6226
注册时间: 2005-06-11 14:03
来自: 不明真相的群众
联系:

#7

帖子 karron » 2007-11-09 12:10

不要去做这样的题目或者测试, 没有任何意义. 真正写代码的时候要写最容易理解的代码, 即便性能不是最高.
我的blog,关于技术,软件,linux,vim <---- 所有博客均被河蟹.
头像
FFFrog
帖子: 621
注册时间: 2006-05-12 23:28
来自: 江西乐平
联系:

#8

帖子 FFFrog » 2007-11-09 12:13

这种代码如何处理,在C语言标准里没有规定。编译器爱怎么处理就怎么处理。因而代码也不具备良好的可移植性,没有很大的实际意义。
alabor
帖子: 113
注册时间: 2007-03-17 13:16

#9

帖子 alabor » 2007-11-09 12:24

吃饱撑着了!!!
dbzhang800
帖子: 3182
注册时间: 2006-03-10 15:10
来自: xi'an China
联系:

#10

帖子 dbzhang800 » 2007-11-09 13:06

没用的代码,这种东西是未定义的,不论你的编译器让它等于1, 100,1000,还是 10000 你都得接受,如果你用这样的代码的话
Wang Lei
帖子: 214
注册时间: 2007-07-16 21:42

#11

帖子 Wang Lei » 2007-11-09 16:04

BigSnake.NET 写了:

代码: 全选

        movl    $100, -8(%ebp)
        addl    $1, -8(%ebp)
        addl    $1, -8(%ebp)
        movl    -8(%ebp), %eax
        addl    -8(%ebp), %eax
        addl    $1, -8(%ebp)
        addl    -8(%ebp), %eax
看上去是这样的 ..
先做前两个 ++ , 然后相加, 然后再做最后一个++, 再相加
++j -> j=101
++j -> j=102
j+j -> tmp = 204
++j -> j=103
tmp +j -> 307
正确!鉴定完毕!
HP Compaq 6515b(GL087PA)
Sawfish+Emacs+Firefox+Xpdf+MPlayer...
头像
speme
帖子: 723
注册时间: 2005-10-02 8:22
联系:

#12

帖子 speme » 2007-11-09 20:32

写这种代码不是给人看的。是给自己看的。自己要记得是用什么的编译器编的。然后,让其它人猜去。
子曰,三人行,必有我师,吾曰,世间万物,皆为我师.
头像
tlhl28
帖子: 474
注册时间: 2006-09-02 18:58
来自: 深圳

#13

帖子 tlhl28 » 2007-11-11 17:12

明白......
首先,非常感谢 BigSnake.NET ,我学会了一个方法去看代码了.
这代码似乎很没用......对于你们来说.但是我就想知道个为什么.我认为,理这段代码的不会是变态,也不是吃饱撑着......谢谢回贴的前辈们......
我不会再来发这种没用的代码了,即使我不明白.
czk
帖子: 232
注册时间: 2006-10-08 22:20

#14

帖子 czk » 2007-11-15 7:33

参看The C Programming Language第2章最后一节

Function calls, nested assignment statements, and increment and decrement operators cause "side effects" - some variable is changed as a by-product of the evaluation of an expression. In any expression involving side effects, there can be subtle dependencies on the order in which variables taking part in the expression are updated. One unhappy situation is typified by the statement

a = i++;

The question is whether the subscript is the old value of i or the new. Compilers can interpret this in different ways, and generate different answers depending on their interpretation. The standard intentionally leaves most such matters unspecified. When side effects (assignment to variables) take place within an expression is left to the discretion of the compiler, since the best order depends strongly on machine architecture. (The standard does specify that all side effects on arguments take effect before a function is called, but that would not help in the call to printf above.)

The moral is that writing code that depends on order of evaluation is a bad programming practice in any language. Naturally, it is necessary to know what things to avoid, but if you don't know how they are done on various machines, you won't be tempted to take advantage of a particular implementation.

函数调用、嵌套赋值语句、自增与自减运算符都有可能产生“副作用”——在对表达式求值的同时,修改了某些变量的值。在有副作用影响的表达式中,其执行结果同表达式中的变量被修改的顺序之间存在着微妙的依赖关系。下列语句就是一个典型的令人不愉快的情况:

a = i++;

问题是:数组下标i是引用旧值还是引用新值?对这种情况编译器的解释可能不同,并因此产生不同的结果。C语言标准对大多数这类问题有意未作具体规定。表达式何时会产生这种副作用(对变量赋值),将由编译器决定,因为最佳的求值顺序同机器结构有很大关系。(ANSI C标准明确规定了所有对参数的副作用都必须在函数调用之前生效,但这对前面介绍的printf函数调用没有什么帮助。)

在任何一种编程语言中,如果代码的执行结果与求值顺序相关,则都是不好的程序设计风格。很自然,有必要了解哪些问题需要避免,但是,如果不知道这些问题在各种机器上是如何解决的,就最好不要尝试运用某种特殊的实现方式。
x3y1
帖子: 8
注册时间: 2007-11-15 9:08

Re: “++j + ++j + ++j"不同编译器不同结果

#15

帖子 x3y1 » 2007-11-15 9:10

tlhl28 写了:

代码: 全选

#include <stdio.h>
main()
{
    int a,j=100;
       a = ++j + ++j + ++j;
       printf("%d",a);
}
TC的结果是 309。GCC , g++ 和 VC++的结果是307。为什么?!
TC的结果可以理解,但307就不能理解了 。
这就是上吊时需要把绳子多往脖子上缠几圈,不然勒不死!写出这样的代码有什么意思?自己给自己找麻烦!
回复