未来电子 发表于 2013-3-26 00:21:36

c语言++运算符的详细执行步骤,运算的和书籍的结果不一...

本帖最后由 未来电子 于 2013-3-26 19:32 编辑

        int p,q,i,j;
        i=j=3;
        q=0;
        q=++j
        printf("%d,",q);
这时候的运算的值是4,
          int p,q,i,j;
        i=j=3;
        q=0;
        q=(++j)+(++j);
        printf("%d,",q);
这时候的运算的值是10,
          int p,q,i,j;
        i=j=3;
        q=0;
        q=(++j)+(++j)+(++j);
        printf("%d,",q);
这时候的运算的值是16,
第二个结果就不明白了,会的解释一下
软件换过好几个都是这个情况。

tomhe666 发表于 2013-3-26 08:20:22

从不研究这种蛋疼用法,一般都是拆分多行和括号解决问题

dr2001 发表于 2013-3-26 08:31:55

本帖最后由 dr2001 于 2013-3-26 08:33 编辑

如果是从谭浩强的书上看到的类似完全无意义的东西,建议把书撕了;去买C Primer或The C Programming Language等严肃的而不是玩弄国内应试文字游戏的书看。

你在给变量q进行赋值,却试图打印栈上变量p的值,且p没有初值。如果你开Wall之类的选项,直接就会有未初始化警告。

如果真想研究这种具有Side Effects表达式的求值,就应该去认真阅读C标准表达式求值的规定。C标准有描述类似情形。

实际应用中除非必要,写炫技代码的人都该Fire了。

wye11083 发表于 2013-3-26 08:46:24

dr2001 发表于 2013-3-26 08:31 static/image/common/back.gif
如果是从谭浩强的书上看到的类似完全无意义的东西,建议把书撕了;去买C Primer或The C Programming Langua ...

呵呵,国内的素质低的程序员,你懂的。

whyjld 发表于 2013-3-26 09:09:13

在实际的代码中写这种表达式就是发疯。
C标准中没有没有明确的规定(++j)+(++j)在中间那个+直行的时候j到底应该是多少,每个编译器都可以有不同的处理,你google一下 "C语言 顺序点" 就明白了

laujc 发表于 2013-3-26 09:29:37

whyjld 发表于 2013-3-26 09:09 static/image/common/back.gif
在实际的代码中写这种表达式就是发疯。
C标准中没有没有明确的规定(++j)+(++j)在中间那个+直行的时候j到底 ...

是的,以前好像看到过类似的讨论,如果是(j++)+(++j)就更有迷惑性,C语言标准没有要求先执行中间的一个+号左边的还是右边的.

个人感觉,写代码一定不要想着按C语言优先级或顺序,因为具体的编译器实现可能不大相同.
我写代码时,宁可多加括号,再分多条语句来写.

dr2001 发表于 2013-3-26 09:58:52

laujc 发表于 2013-3-26 09:29 static/image/common/back.gif
是的,以前好像看到过类似的讨论,如果是(j++)+(++j)就更有迷惑性,C语言标准没有要求先执行中间的一个+号左 ...

没有Side Effects的操作可以通过加括号解决,必须一般的四则运算符。
有Side Effects的操作只能通过序列点解决,常见的方法是拆成多个语句。典型如++,--操作。

wxty 发表于 2013-3-26 10:26:17

谭浩强也说过,这玩意儿跟编译器有关,看到这里,我就不想深究了,感觉实际意义不大。。

whyjld 发表于 2013-3-26 13:21:24

laujc 发表于 2013-3-26 09:29 static/image/common/back.gif
是的,以前好像看到过类似的讨论,如果是(j++)+(++j)就更有迷惑性,C语言标准没有要求先执行中间的一个+号左 ...

你根本不明白我说的
C的的表达式求值顺序是定义好的,根据运算符优先级和结合顺序计算,各个C编译器必须而且一定要符合C的标准,否则就不能算C编译器
但是你的表达式里有两处改变了同一个变量的值,就牵扯到改变什么时候应用到变量上的问题,对于C标准,并没有规定值如何应用到变量上
把你的表达式分成三部分
左边的(++j)是第一部分
中间的+是第二部分
右边的(++j)是第三部分
这三部分执行的顺序是确定无疑的第一和第三部分肯定先执行,但是第二部分执行的时候两侧的都是j,但是值可能不一样,因为C的标准呢只要求整个表达式全部求值完成后j的值是++两次的结果,并不要求在表达式执行过程中j的值也准确。
你自己google一下就明白
如果都不想学习还问什么。

Alimy 发表于 2013-3-26 13:45:27

本帖最后由 Alimy 于 2013-3-26 14:01 编辑

请不要研究   q=(++j)+(++j);或者q=(++j)+(++j)+(++j);这种问题。。
毫无意义,浪费生命。。。。
简而言之依赖于实现,不同的编译器就会有不同的结果。。
对于自加运算符。
只要搞清楚 :q= i++; 和 q = ++i;的区别就行了。。
--------------------------------------------------------------------------
如果一定要研究。对底层实现有兴趣的话,请自学汇编语言,看汇编代码...

laujc 发表于 2013-3-26 13:50:46

whyjld 发表于 2013-3-26 13:21 static/image/common/back.gif
你根本不明白我说的
C的的表达式求值顺序是定义好的,根据运算符优先级和结合顺序计算,各个C编译器必须 ...

我知道你的意思,但是我还是喜欢分成多条语句写.
保证自己写的代码在不同的编译器上都是正确的.

懒得看标准了.也理解你的意思.

x11223y 发表于 2013-3-26 13:55:42

当年老师教C++的时候这个我就死活不懂的

dr2001 发表于 2013-3-26 14:26:20

本帖最后由 dr2001 于 2013-3-26 14:30 编辑

whyjld 发表于 2013-3-26 13:21 static/image/common/back.gif
你根本不明白我说的
C的的表达式求值顺序是定义好的,根据运算符优先级和结合顺序计算,各个C编译器必须 ...

(WG14 N1256) C99标准,6.5-2,是我知道的关于类似问题的唯一规定:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. 72) Furthermore, the prior value shall be read only to determine the value to be stored. 73)

如果基于这个条款理解,q = (++j) + (++j) + (++j)由于不满足前半句的要求,因而执行完毕后的结果是Undefined,即啥结果都可能,包含表达式q的值和j的值都是不定的。C标准在这里没有保障任何东西。

当然,详细讨论这货没啥意思。。。

rookies 发表于 2013-3-26 14:35:34

你连程序都没抄对,看起来太乱好好的理一下,你定义一个数,就是在内存中弄一个单元,然后存起来。你要对这个内存单元操作,那么++ 几次 最后处理加起来不就完了,你认为编译器会那么笨弄一个中转!printf 少用,DEBUG 看看 内存中,数据是什么样的,不行就看看反汇编是如何实现的。

未来电子 发表于 2013-3-26 21:18:03

whyjld 发表于 2013-3-26 09:09 static/image/common/back.gif
在实际的代码中写这种表达式就是发疯。
C标准中没有没有明确的规定(++j)+(++j)在中间那个+直行的时候j到底 ...

谢谢好像明白一点

未来电子 发表于 2013-3-26 21:18:55

rookies 发表于 2013-3-26 14:35 static/image/common/back.gif
你连程序都没抄对,看起来太乱好好的理一下,你定义一个数,就是在内存中弄一个单元,然后存起来。你要对这 ...

恩、
你的方法我没有试过

未来电子 发表于 2013-3-26 21:21:18

Alimy 发表于 2013-3-26 13:45 static/image/common/back.gif
请不要研究   q=(++j)+(++j);或者q=(++j)+(++j)+(++j);这种问题。。
毫无意义,浪费生命。。。。
简而言 ...

谢谢


方法很好

hhxb 发表于 2013-3-26 21:50:09

本帖最后由 hhxb 于 2013-3-26 21:54 编辑

中国人长期受应试教育的荼毒,形成了错误思维定势
我看过一本书讲过这类问题,
详细区分了三种情况。 未规定,由编译器自己去确定,编译器个不一样;
                  不确定,某家编译器自己制定的标准,所有版本均一直。
                  未知,编译器的前后版本也不一致;

                  
页: [1]
查看完整版本: c语言++运算符的详细执行步骤,运算的和书籍的结果不一...