C语言中表达式(++5)+(++5)+(++5)的运算过程是

lvjunjie0901 2009-05-16 10:05:39
C语言中表达式(++5)+(++5)+(++5)的运算过程是?结果是?
在Java语言中表达式(++5)+(++5)+(++5)的运算过程是?结果是?
谢谢!
...全文
773 63 打赏 收藏 转发到动态 举报
写回复
用AI写文章
63 条回复
切换为时间正序
请发表友善的回复…
发表回复
lvjunjie0901 2009-05-18
  • 打赏
  • 举报
回复
谢谢,大哥,大姐们!小弟明白了!再次谢谢!
hurricane880 2009-05-17
  • 打赏
  • 举报
回复
杂还在讨论阿,这个东西C标准里面根本没有确切结果,可以算是标准未定义的。
你想想阿,如果C标准把啥都给定义了,那他还叫C么?
用C写代码就要把自己当上帝。因为编译器把你当上帝,你说啥都是对的。
光宇广贞 2009-05-17
  • 打赏
  • 举报
回复
[Quote=引用 59 楼 barbara0000 的回复:]
vc++ 结果是22
但我不知道为什么~
[/Quote]

你一定是 vc2005之前的版本。
kiffa 2009-05-17
  • 打赏
  • 举报
回复
月经题。。。

操作符(运算符)的优先级和结合性并不决定表达式的求值顺序,只是用于进行语法分析,决定语法树的生成。

3 + 4 * 5,可以解析成(3 + 4) * 5 或者 3 + (4 * 5),因为乘法优先级高于加法,所以会选择第二种解析方法。
3 + 4 + 5,可以解析成(3 + 4) + 5 或者 3 + (4 + 5),因为加法是自左向右结合,所以会选择第一种解析方法。

解析成3 + (4 * 5)后,对这个表达式求值,“+”操作符有两个操作数,左操作数为 3,右操作数为 4 * 5,那么是先对左操作数 3 求值呢,还是先对右操作数 4 * 5 求值呢?答案是未指定的,由编译器决定。

标准并没有指定“+”操作符的求值顺序,标准只指定了“,”、“&&”、“||”、“?:”这四种操作符的求值顺序是自左向右,其余的操作符的求值顺序都是未指定的。

因此 3 + (4 * 5),并非先算4 * 5,然后算 3 ,而是由编译器自己决定,求值顺序是未指定的。同理:
int i = f() + g(); // 并非一定先执行f(),后执行g(),而是由编译器决定


所以 ++i + ++i + ++i; 会被解析成 ((++i) + (++i)) + (++i);

这个表达式是一个典型的未定义行为,因为 ++i 有两个作用,第一:对i加1;第二:返回一个值(或者应该说返回一个引用)。这里的对i加1属于副作用(side effect),而副作用什么时候生效呢?标准只规定了在跨越一个序列点的时候,序列点之前的副作用必须全部完成,此外就没有硬性要求了。

序列点是一个时间点(在整个表达式全部计算完毕之后或在||、&&、? : 或逗号运算符处, 或在函数调用之前), 此刻尘埃落定, 所有的副作用都已确保结束。

而((++i) + (++i)) + (++i); 这个表达式的序列点就是语句的结束之处,也就是";"所在之处,在此之前副作用何时生效(也就是何时给i加1)完全由编译器决定,编译器可以任意选择,比如:

a, 先计算左边的子表达式((++i) + (++i)):
先对左边的i加1(此时i == 6),再对右边的i加1(i == 7),然后再对左边的表达式求值,得到7,对右边的表达式求值,得到7,对子表达式求值,得到 7 + 7 = 14;
b,再计算右边的子表达式 (++i)
因为此时i == 7,所以++i == 8,子表达式值为8.
c, 计算整个表达式的值:14 + 8 = 22;

编译器还可以选择先对所有的3个i都加1(完成副作用),然后再分别求值,得到8 + 8 + 8 = 24.

当然也可以挨个加1、求值,得到6 + 7 + 8 = 21.

只要满足在((++i) + (++i)) + (++i);结束之后,i == 8(副作用完成)就行了,具体过程标准并没有指定,由编译器自己决定。

至于说这种行为属于未定义,是因为c标准中有这么一条:

在上一个和下一个序列点之间, 一个对象所保存的值至多只能被表达式的计算修改一次。而且前一个值只能用于决定将要保存的值。

而这里的i显然在一条语句中被修改了多次。
barbara0000 2009-05-17
  • 打赏
  • 举报
回复
vc++ 结果是22
但我不知道为什么~
  • 打赏
  • 举报
回复
C code:
#include <stdio.h>
void main()
{
int i=5,a,b;
a=(i++)+(i++)+(i++);
b=(++i)+(++i)+(++i);
printf("i=%d,a=%d,b=%d",i,a,b);
}
运行结果是i=11,a=15,c=31
看看书
ahui5252 2009-05-16
  • 打赏
  • 举报
回复
跟编译器有关,TC上是24
EnextC 2009-05-16
  • 打赏
  • 举报
回复
好像不可以吧
threewall 2009-05-16
  • 打赏
  • 举报
回复
最好不要这么用,这样的代码不利于其他人阅读,是个不好的习惯。
飛雪一刀 2009-05-16
  • 打赏
  • 举报
回复
跟编译器有关吧
livs_ly_2010 2009-05-16
  • 打赏
  • 举报
回复
24
nadoo 2009-05-16
  • 打赏
  • 举报
回复

int _tmain(int argc, _TCHAR* argv[])
{
int i = 5;
int j = (++i) + (++i) + (++i);
printf("i=%d, j-%d\n", i, j);

int m = 5;
int n = (m++) + (m++) + (m++);
printf("m=%d, n-%d\n", m, n);

return 0;
}


i=8, j-24
m=8, n-15
pathuang68 2009-05-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lvjunjie0901 的回复:]
对不起,我没有把问题说清楚:int i=5;
i=(++i)+(++i)+(++i);
printf( "i=%d ",i);或者System.out.println(i);
[/Quote]

请看:
某网友关于++运算符的问题
hurricane880 2009-05-16
  • 打赏
  • 举报
回复
这道题目没有答案,因为这种表达式是最后编译处理是和编译器有关系的,写代码不要写这样的代码
得出确切的答案的同学换个编译器试试,然后看看汇编代码,不同编译的处理方式是不一样的
结贴吧~~
zsjsgyy 2009-05-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 hikaliv 的回复:]
楼上说的全都不对。

答案是 24.

是三八二十四。

给你看这个:

C/C++ code
int i = 5;
int j = (++i)+(++i)+(++i);




执行过程是先对i进行三次自增操作,然后对三个值求和。

同志们不要想当然……
[/Quote]
正解
liuxiuming 2009-05-16
  • 打赏
  • 举报
回复
c 的话应该是24
java 应该是 21
breezes2008 2009-05-16
  • 打赏
  • 举报
回复
你多在机子上测试一下不就清楚了吗?
像C中,++,--这样的操作符运算结果是视编译器而定的。
光宇广贞 2009-05-16
  • 打赏
  • 举报
回复
自增操作优于加法,二元加法的优先级低得可怜,自增没有做完,怎么可能进行加法运算。
光宇广贞 2009-05-16
  • 打赏
  • 举报
回复
楼上说的全都不对。

答案是 24.

是三八二十四。

给你看这个:

int i = 5;
int j = (++i)+(++i)+(++i);


执行过程是先对i进行三次自增操作,然后对三个值求和。

同志们不要想当然……
shenjigong19801109 2009-05-16
  • 打赏
  • 举报
回复
这个就是简单的加法运算,(++i)+(++i) = 14;(++i)+(++i) +(++i)= 22;(++i)+(++i) +(++i)+(++i)= 31;....
对应7+7=14;7+7+8=22;7+7+8+9=31如果还有依次推算
加载更多回复(42)

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧