C++中的自增小问题

发布时间:2024-05-22 15:55 发布:上海旅游网

问题描述:

int x=-1;
int y = (++x) + (++x) + (++x)
省略了其他,问下y=多少?,要附有说明分析过程,谢谢!
答案是4,但是不太明白唉。。。。

问题解答:

别再纠结这个问题了!
我告诉你正确的答案是:不确定。请避免在程序中使用这样的写法。
凡是给出确定值的都是错误的。
因为这种写法在C99和C++2003里面是“未说明”(unspecified)的,未说明就是没有进行规定,因此不同的编译器会产生不同的结果。
这里面涉及到“序列点”的问题。凡是在一个序列点之前多次修改一个变量都会造成结果的不确定。
我就不细说了,有兴趣可以自己看一下!

补充:标准就是标准,不是某些人觉得是什么样就是什么样的,这些在C99和C++2003标准里面写的都是很清楚的。
建议楼主非要弄明白序列点的话可以看这篇文章:
http://www.blogjava.net/zellux/archive/2008/05/16/200811.html
只记住结论的话也是没问题的!

另外,引用一本书里写的:
以下内容引自《C 语言常见问题集》 原著:Steve Summit 翻译:朱群英, 孙 云
4.3 对于代码 int i = 3; i = i++; 不同编译器给出不同的结果, 有的为 3, 有的为 4, 哪个是正确的?

没有正确答案;这个表达式无定义。参见问题 3.1, 3.7 和 11.32。 同时注意, i++ 和 ++i 都不同于 i+1。如果你要使 i 自增 1, 使用 i=i+1, i+=1, i++ 或 ++i, 而不是任何组合, 参见问题 3.10。

12.35 有人说 i = i++ 的行为是未定义的, 但是我刚在一个兼容 ANSI 的编译器上测试, 得到了我希望的结果。

面对未定义行为的时候, 包括范围内的实现定义行为和未确定行为, 编译器可以做任何实现, 其中也包括你所有期望的结果。但是依靠这个实现却不明智。参加问题 7.4, 11.31, 11.32 和 11.34。

4.2 使用我的编译器,下面的代码 int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么顺序计算, 难道不该打印出56吗?

尽管后缀自加和后缀自减操作符 ++ 和 -- 在输出其旧值之后才会执行运算, 但这里的``之后"常常被误解。没有任何保证确保自增或自减会在输出变量原值之后和对表达式的其它部分进行计算之前立即进行。也不能保证变量的更新会在表达式 ``完成" (按照 ANSI C 的术语, 在下一个 ``序列点" 之前, 参见问题 3.7) 之前的某个时刻进行。本例中, 编译器选择使用变量的旧值相乘以后再对二者进行自增运算。

包含多个不确定的副作用的代码的行为总是被认为未定义。(简单而言, ``多个不确定副作用" 是指在同一个表达式中使用导致同一对象修改两次或修改以后又被引用的自增, 自减和赋值操作符的任何组合。这是一个粗略的定义; 严格的定义参见问题 3.7, ``未定义" 的含义参见问题 11.32。) 甚至都不要试图探究这些东西在你的编译器中是如何实现的 (这与许多 C 教科书上的弱智练习正好相反); 正如 K&R 明智地指出, ``如果你不知道它们在不同的机器上如何实现, 这样的无知可能恰恰会有助于保护你。

4.7 我怎样才能理解复杂表达式?``序列点" 是什么?

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

在上一个和下一个序列点之间, 一个对象所保存的值至多只能被表达式的计算修改一次。而且前一个值只能用于决定将要保存的值。
第二句话比较费解。它说在一个表达式中如果某个对象需要写入, 则在同一表达式中对该对象的访问应该只局限于直接用于计算将要写入的值。这条规则有效地限制了只有能确保在修改之前才访问变量的表达式为合法。例如 i = i+1 合法, 而 a[i] = i++ 则非法 (参见问题 3.1)。

核桃,我当然承认这个表达式在标准中是未定义的。
ISO/IEC 14882:2003(E) 中有这样一段话:
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined. [Example:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
—end example]
。。。
the expression ++x is equivalent to x+=1
。。。
In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.
这些已足以说明这个表达式的行为是未定义的,但是未定义的东西也是要实现的,未定义就不能讨论了?更何况很多未定义都是为了语法语义分析实现上的方便,大家针对不同的实现讨论讨论怎么了?
标准本身就是少数人制定的,本身就是某些人觉得是什么样就是什么样,标准也在不断完善发展 ,核桃,你的补充什么意思啊?难道就不许对标准有什么看法么?
标准都没有定义的东西,你倒是给正确答案了?

应该是6吧

看编译器的版本了

应该是x的最终结果相加

0
在这个表达式(除逗号表达式)执行完前 x的值 都不会增加,都是-1..但表达式执行完后 就会连增三次.

VC2005输出的结果是6,我也不解,关注。用反汇编这个说法就有意思了。

y=4,但是我也想不通为什么

热点新闻