能力值:
( LV3,RANK:20 )
|
-
-
2 楼
首先明确优先级:++ > +
c =(++a)+(++a)+(++a); ==> ++a; ++a; ++a; c = a + a + a; // c = 24, a = 8
d =(b++)+(b++)+(b++); ==> d = b + b + b; b++; b++; b++; // d = 15, b = 8
这么写只是为了方便理解,LZ可自行调试一下
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
你说了 ++ 优先级大于 +
那d =(b++)+(b++)+(b++); 也应该是先做自增预算啊.先做三个 b++,然后做加法.
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
与编译器有关,不同的编译器结果不一样.
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
这在C语言中属于“未定义行为”,出现任何运行结果都是允许的(包括崩溃!)
c =(++a)+(++a)+(++a);//同一级的括号运算优先级是相等的, 这3个括号的运算优先级是平等的.所以这3个括号内的表达式计算顺序完全是不确定的(编译器甚至可能搞并行优化).
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
为什么要 深究这个 ++i与i++
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
完全同意,这跟C语言中定义的序列化点有关。
C语言在两个序列化点之间,只允许写同一变量一次,并且如果既读又写,那么一定是只能用读出来的值来计算要写进去的值。(很含糊吧)
所谓序列化点包括
a;b;(分号)保证 a在b前执行
if(a){b} while(a){b} 保证 a在b前执行
(a,b) (逗号运算符,与函数调用的分隔符不一样) 保证a在b前执行
a=a+b; 可以,符合读出来的值用来计算写入的值
a && b 保证a在b前执行
a || b 也是一样
等等
特别注意的是自增、赋值、加减乘除、位与或等等都不是序列点,
这个不仅仅是优先级的问题,加括号也不能改变(其实括号就只是用来强制优先级,但是优先级规定的结合性,而不是哪个先计算,这与我们平时的自然语言习惯有不同)
这里的“在……之前”只是从效果上来说,编译器优化是允许的(意即除了代码变快不能有别的可观察的区别)
至于未定义行为,标准要求编译器自行选择合理(但没有规定什么叫合理 )的行为。
违反了规定,编译器可以给警告(要打开关,比如gcc的-Wall -W就会警告这种错误),也可以不给(因为很难检测)
我记得Java就规定了一大堆的东西,比如a+b中a要在b前计算。(我不熟悉Java)
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
debug版和release版的区别是 ,他们断句的粒度不一样,我们知道 i++,是等这一行执行完了才加一,所以debug版和release版的结果也不一样.
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
http://bbs.pediy.com/showthread.php?t=61272&highlight=%E8%87%AA%E5%A2%9E
|
能力值:
( LV15,RANK:670 )
|
-
-
10 楼
c =(++a)+(++a)+(++a);
a 先自增了三次,然后再相加的。
所以
c = 8+8+8 // 在赋值给c之前,a的值是8
同样的
d =(b++)+(b++)+(b++);
先把三个 b 相加,然后b再自增三次。
d=5+5+5 // 在赋值给d之后,b的值是8
以上的行为是在VC编译中的情况。
在GCC中,比较有意思:
a = 5;
c =(++a)+(++a)+(++a);
对应的反汇编代码如下:
004013A6 movl $0x5,(%esp) a=5
004013AD incl (%esp) ++a -> a=6
004013B0 incl (%esp) ++a -> a=7
004013B3 mov (%esp),%eax eax=7
004013B6 add %eax,%eax eax=14=7+7
004013B8 incl (%esp) ++a -> a=8
004013BB add (%esp),%eax eax=22=14+8 -> c=22
也就是说在GCC中是分两步进行保存的,a 自增两次之后,中间结果保存给c,然后c再和第三次自增的结果相加。结果是22
另外:
printf("%d,%d,%d,%d,%d,%d",a,b,c,d);
%d 的个数和后面的参数列表不符,多了两个,实际会多输出栈上的数据。
|
能力值:
( LV12,RANK:320 )
|
-
-
11 楼
这种题,好像只有蛋疼的大学考试还会有..
|
能力值:
( LV3,RANK:30 )
|
-
-
12 楼
功底相当扎实!
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
进来学习了,这些天找工作,笔试题大多都有这种题,真是有点懵了- -!
|
能力值:
( LV3,RANK:20 )
|
-
-
14 楼
关于前++和后++,我不好描述, 你自己理解下。
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
真是让人蛋疼的结果啊。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
汗,似乎每个人初学C语言时都会问这个问题,我当初也是……
如果没记错的话C99标准说这种情况是未定义的(undefined),所以到底会发生什么样的结果是不确定的,甚至在不同的编译器下编译运行的结果也是不相同的,没必要去理会这个问题了。
|
能力值:
( LV4,RANK:50 )
|
-
-
17 楼
看了此篇,深刻理解C自增自减了
|
能力值:
( LV4,RANK:50 )
|
-
-
18 楼
这个写得很好~~~
|
能力值:
(RANK:10 )
|
-
-
19 楼
很麻烦啊,一般不这样用
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
我一般是这么记着的,++i是先自增再进行运算,i++是运算后再自增。
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
这个确实。。。没什么用但是对笔试什么的很有用 mark 了
|
能力值:
( LV3,RANK:30 )
|
-
-
22 楼
不知道考試為什麼靠這種蛋疼的題
|
能力值:
( LV6,RANK:80 )
|
-
-
23 楼
没事钻研这个干啥
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
不同的编译器处理的结果也不一样
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
7楼兄台所言极是。
|
|
|