| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1055 人关注过本帖
标题:请教C语言
只看楼主 加入收藏
elmnd123
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2008-10-8
收藏
得分:0 
z=fun(fun(x++,y++), fun(--x, --y));//右面先过左面咯
2008-10-08 23:48
kd0376
Rank: 1
等 级:新手上路
帖 子:92
专家分:0
注 册:2007-12-7
收藏
得分:0 
回复10##额~~多谢~~貌似老谭的书里只是简单的说过好多求值顺序是有编译系统自己安排的~学习了~继续研究老谭的书去

[[it] 本帖最后由 kd0376 于 2008-10-8 23:55 编辑 [/it]]
2008-10-08 23:54
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
这事情还没完呢……首先先看看标准。在ISO/IEC 9899:1999 C Standard 6.5.2.3里面有这么一句话:
10 The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

那么,11L和大家仪仗的“函数参数由右向左计算”就不成立了(虽然我们知道,大多数情况下,函数参数的确是这么计算的)。
对于:z=fun(fun(x++,y++), fun(--x, --y));
为了区别,我们按照出现的顺序,称之为fun1,fun2,fun3。我们知道,fun1肯定在fun1和fun2调用之后才调用,这一点标准是严格规定了。而对于fun2来说,首先计算x++和y++,并返回x和y的原始值,接下来存在一个顺序点。而在fun3之中,也有相同的情况。问题在于,fun2和fun3的调用顺序,也就是上述两个顺序点的运算次序是“
unspecified”的。我们归纳如下:
假设先计算fun2的参数:
1 x为6,y为7,调用fun2,返回13,这时有一个顺序点,x变为7,y变为8
2 然后根据x=7,y=8调用fun3,这时有一个顺序点,x,y立即变为6,7然后调用fun3,这时返回13
3 fun1被调用,参数为13,13,结果应为26
假设先计算fun3参数:
1 x为6,y为7,立即自减以后调用fun3,参数为5,6,返回11。此顺序点后,x=5,y=6。
2 这时调用fun2,参数为5,6,返回11,顺序点后x,y自增为6,7。
3 调用fun1,参数为11,11,结果返回22。

所以,其实上面的说法不适合。确切的说,这道题的结果是“unspecified”而不是“Undefined”。其结果是有定义的,只不过并没有明确地由标准来确定,而是由实现来定义的。所以这段代码是不可移植的。

下面转一段《C专家编程》的内容:
ANSI C标准可以说是非常独特的,我们可以从好几个有趣的方面来说明这一点。它定义了下面一些术语,用于描述某种编译器的特点。如果你对这些术语有一个比较好的了解,就有助于你理解什么东西能被语言接受,什么东西不能被语言接受。前两个术语涉及不可移植的代码(Unportable code),接下来两个术语跟坏代码(bad code)有关。而最后两个术语则跟可移植的代码(portable code)有关。
[bo]不可移植的代码(unportable code)[/bo]
由编译器定义的(implementation-defined)——由编译器设计者决定采取何种行动(就是说,在不同的编译器中所采取的行为可能并不相同,但它们都是正确的),并作好文档记录,例如,当整型数向右移位的时候,要不要扩展符号位。
未确定的(unspecified)——在某些正确情况下的做法,标准未明确规定应该怎样做,例如:计算参数的顺序。
[bo]坏代码(bad code)[/bo]
未定义的(undefined)——在某些不正确情况下的做法,但标准并未规定应该怎样做,你可以采取任何行动,可以什么也不做,也可以发出一条警告信息,或者可以中止程序以及让CPU陷入瘫痪,甚至可以反射核导弹(只要你安装了能发射核导弹的硬件系统)。
例如:当一个有符号数溢出时应该采取什么行动。
约束条件(a constraint)——这是一个必须遵守的限制或要求。如果你不遵守,那么你的程序的行为就会变成像上面所说的那样是未定义的。这就出现了一种很有意思的情况:分辨某种东西是否是一个约束条件是很容易的,因为标准的每个主题都附有一个“约束(constraint)”小节,列出了所有的约束条件,现在又出现了一个更为有趣的情况:标准规定编译器只有在违反语法规则和约束条件的情况下才能产生错误信息!这意味着所有不属于约束条件的语义规则你都可以不遵循,而且由于这种行为属于未定义行为,编译器可以采取任何行动,甚至不必通知你!

突然发现自己好像在抄书……就当是练习打字吧……这是本好书,建议买了收藏……

[[it] 本帖最后由 StarWing83 于 2008-10-9 00:57 编辑 [/it]]

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-10-09 00:31
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1687
专家分:4253
注 册:2007-12-27
收藏
得分:0 
回复 13# StarWing83 的帖子
补充一点:
假如先调用fun2,(见LS)
由于++出现在变量后面,所以fun2接收到的值是变量原值,之后变量的值才会变化,这个是确定的没错。

问题是似乎这个“之后”发生在
(1)fun2调用之后,fun3调用之前
(2)整个z=...;之后
这个问题也是unspecified
所以即使先调用fun2,后调用fun3,结果也未必是26,也可能是24呢
2008-10-09 00:44
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
LS 不对,标准明确规定了,在函数调用前有一个顺序点,所以上面一行语句是有四个顺序点的。自增和自减操作,无论死前还是后,都必须在顺序点到来前完成,所以“之后”肯定发生在其作为参数的那个函数调用之前。

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-10-09 00:50
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
刚刚找到了:C99 6.5.2.4下有这样的描述:
2 The result of the postfix ++ operator is the value of the operand. After the result is
  obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate
  type is added to it.) See the discussions of additive operators and compound assignment
  for information on constraints, types, and conversions and the effects of operations on
  pointers. The side effect of updating the stored value of the operand shall occur between
  the previous and the next sequence point.

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-10-09 00:54
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1687
专家分:4253
注 册:2007-12-27
收藏
得分:0 
哦,原来是这样,我理解失误
我就不改了,放在那儿给后来的吸取教训吧
2008-10-09 01:00
liu675772760
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-10-9
收藏
得分:0 
wu

终于可以用了
2008-10-09 08:23
kd0376
Rank: 1
等 级:新手上路
帖 子:92
专家分:0
注 册:2007-12-7
收藏
得分:0 
又是英文书?崩溃~~还好~从问题学到很多东西了

[[it] 本帖最后由 kd0376 于 2008-10-9 11:43 编辑 [/it]]
2008-10-09 11:41
快速回复:请教C语言
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015331 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved