免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8683 | 回复: 13

i++ * i++ [复制链接]

论坛徽章:
0
发表于 2008-10-12 23:18 |显示全部楼层
int i =3, j;
j = i++ * i++;  // j = 9 为什么不是12
j = ++i * ++i;  // j = 49为什么不是42

查看了一下c faq, 有如下entry:

4.2 使用我的編譯器,下面的代碼  int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什麼順序計算, 難道不該打印出56嗎?
儘管後綴自加和後綴自減操作符 ++ 和 -- 在輸出其舊值之後才會執行運算, 但這裡的``之後"常常被誤解。沒有任何保證確保自增或自減會在輸出變量原值之後和對表達式的其它部分進行計算之前立即進行。也不能保證變量的更新會在表達式 ``完成" (按照 ANSI C 的術語, 在下一個 ``序列點" 之前, 參見問題 3.7) 之前的某個時刻進行。本例中, 編譯器選擇使用變量的舊值相乘以後再對二者進行自增運算。
包含多個不確定的副作用的代碼的行為總是被認為未定義。(簡單而言, ``多個不確定副作用" 是指在同一個表達式中使用導致同一對像修改兩次或修改以後又被引用的自增, 自減和賦值操作符的任何組合。這是一個粗略的定義; 嚴格的定義參見問題 3.7, ``未定義" 的含義參見問題 11.32。) 甚至都不要試圖探究這些東西在你的編譯器中是如何實現的 (這與許多 C 教科書上的弱智練習正好相反); 正如  K&R 明智地指出, ``如果你不知道它們在不同的機器上如何實現, 這樣的無知可能恰恰會有助於保護你。begintex2html_deferred

參考資料: [K&R1, Sec. 2.12 p. 50]; [K&R2, Sec. 2.12 p. 54]; [ISO, Sec. 6.3]; [H&S, Sec. 7.12 pp. 227-9]; [CT&P, Sec. 3.7 p. 47]; [PCS, Sec. 9.5 pp. 120-1]。

md,为什么现在的笔试都喜欢考这种题

论坛徽章:
0
发表于 2008-10-12 23:39 |显示全部楼层
现在笔试都不出这个了吧...

这种题...强烈BS.

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2008-10-13 00:01 |显示全部楼层
我开始不理解当初C语言为什么要造这么一个完全没有必要存在的运算

论坛徽章:
0
发表于 2008-10-13 00:14 |显示全部楼层
-> 甚至都不要試圖探究這些東西在你的編譯器中是如何實現的 (這與許多 C 教科書上的弱智練習正好相反); 正如  K&R 明智地指出, ``如果你不知道它們在不同的機器上如何實現, 這樣的無知可能恰恰會有助於保護你。

我被打击了


另外,文中提到 ”嚴格的定義參見問題 3.7,“,LZ把这个严格的定义放出来吧,我很好奇。

论坛徽章:
0
发表于 2008-10-13 00:19 |显示全部楼层
原帖由 kiffa 于 2008-10-13 00:14 发表
-> 甚至都不要試圖探究這些東西在你的編譯器中是如何實現的 (這與許多 C 教科書上的弱智練習正好相反); 正如  K&R 明智地指出, ``如果你不知道它們在不同的機器上如何實現, 這樣的無知可能恰恰會有助於保護你。 ...

3.7    我怎样才能理解复杂表达式?“序列点” 是什么?
序列点是一个时间点(在整个表达式全部计算完毕之后或在||、&&、? : 或
逗号运算符处, 或在函数调用之前), 此刻尘埃落定, 所有的副作用都已确保结束。
ANSI/ISO C 标准这样描述:
在上一个和下一个序列点之间, 一个对象所保存的值至多只能被表
达式的计算修改一次。而且前一个值只能用于决定将要保存的值。
第二句话比较费解。它说在一个表达式中如果某个对象需要写入, 则在同一
表达式中对该对象的访问应该只局限于直接用于计算将要写入的值。这条规则有
效地限制了只有能确保在修改之前才访问变量的表达式为合法。例如i = i+1 合
法, 而a = i++ 则非法(参见问题3.1)。
参见下边的问题3.8。
参考资料:  [ISO, Sec.  5.1.2.3, Sec.  6.3, Sec.  6.6, Annex C]; [Rationale, Sec.
2.1.2.3]; [H&S, Sec. 7.12.1 pp. 228-9]。

3.1    为什么这样的代码:   a = i++; 不能工作?
子表达式i++ 有一个副作用—– 它会改变i 的值—– 由于i 在同一表达式的
其它地方被引用, 这会导致无定义的结果, 无从判断该引用(左边的a 中)是旧值
还是新值。(注意, 尽管在K&R 中建议这类表达式的行为不确定, 但C 标准却强
烈声明它是无定义的, 参见问题11.32。
参考资料: [K&R1, Sec. 2.12]; [K&R2, Sec. 2.12]; [ISO, Sec. 6.3]; [H&S, Sec.
7.12 pp. 227-9]。

[ 本帖最后由 blizzard213 于 2008-10-13 00:26 编辑 ]

论坛徽章:
0
发表于 2008-10-13 00:20 |显示全部楼层
原帖由 cjaizss 于 2008-10-13 00:01 发表
我开始不理解当初C语言为什么要造这么一个完全没有必要存在的运算


可惜没有《The Design and Evolution of C》。

论坛徽章:
0
发表于 2008-10-13 00:40 |显示全部楼层
对于 i = i++,你们的编译器能通过吗?

论坛徽章:
0
发表于 2008-10-13 00:43 |显示全部楼层
原帖由 kiffa 于 2008-10-13 00:40 发表
对于 i = i++,你们的编译器能通过吗?

我用vc8.0是可以编译通过的

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
发表于 2008-10-13 08:50 |显示全部楼层
原帖由 cjaizss 于 2008-10-13 00:01 发表
我开始不理解当初C语言为什么要造这么一个完全没有必要存在的运算


++应该有道理存在吧。

论坛徽章:
0
发表于 2008-10-13 08:52 |显示全部楼层
这个问题真头疼,反正编译器怎么出结果都可以。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP