此书槽点众多,一堆undefined behavior。所以二级类型的考试才会出些“脑残”题。
还有杜撰CS科学家---沃森。
比如某二级模拟题:
设:a=1,b=2,c=3,d=4
问:
执行printf("%d%d%d%dn",a==b==c,c=a==b,c==(a=b),b=c)的结果
执行printf("%d%d%d%dn",a,b,++a,++b)的结果。
新手可能不知道,如果看这本书入门,长期下来可能让你形成恶习。这就像吸毒,要诫很难。
至于为什么,专业点的评论详细见下:
http://bbs.chinaunix.net/thread-3565316-1-1.html
关于undefined behavior
能导致未定义行为的语句很多。。必须得有意识注意这些问题
这种用法会导致未定义行为(undefined behavior)。未定义行为基于用户对语言或数据的错误使用,具有未定义行为的程序的行为完全不可靠(就算是导致编译器崩溃也是自找的——虽然不会有厂商会让编译器表现出这种不可靠性)。被ISO C/C++定义为未定义行为的用法,可以认为不论给出什么明确的结果都是愚蠢的,于是标准不对其行为作出任何保证,用户也不应该指望有任何结果。
会出现这种问题又不说清楚undefined behavior的教材根本就是不合格。
对于这里的用法为什么属于未定义行为的严格依据
以下是C99标准关于undefined behavior:
ISO C99:
3.4.3
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.
4. Conformance
2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the
behavior is undefined. Undefined behavior is otherwise indicated in this International
Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition
of behavior. There is no difference in emphasis among these three; they all describe
‘‘behavior that is undefined’’.
5.2.1.3
2 Accessing a volatile object, modifying an object, modifying a file, or calling a function
that does any of those operations are all side effects,11) which are changes in the state of
the execution environment. Evaluation of an expression may produce side effects. At
certain specified points in the execution sequence called sequence points, all side effects
of previous evaluations shall be complete and no side effects of subsequent evaluations
shall have taken place. (A summary of the sequence points is given in annex C.)
6.5
2 Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
题外话,关于表达式求值顺序是未确定行为(unspecified behavior),可以是正确的行为,但具体行为取决于实现(这里就是编译器),不能与此混淆。而入栈出栈顺序涉及函数的调用约定(calling convention),这并不是在语言的规范中决定的,需要找其它的(例如硬件架构)编程模型规范(包括ABI)定义——事实上,C语言根本就没明确函数必需使用栈实现(尽管所有的主流硬件架构乃至虚拟机实现类C语言都使用栈来表达内建静态函数的行为)。 至于结合性,则彻底可以从表达式的语法规则(一大长串,不引用了,太罗嗦)完全、明确地推导出来,只是用来说明哪个操作数进行哪个运算,和具体求值的顺序之类更是没关系。
包含
p=(x++)+(x++)+(x++);
q=(++y)+(++y)+(++y);
这种语句明确会引起未定义行为的程序,除了实际编译器的表现以外真没什么意义了。
而且,真要看实际执行过程,不是C语言层面上能完全决定的,需要看编译器生成的代码。(反汇编就能清楚的看到了)
printf("%d %d %d %dn",p,q,x,y);本身可以是对的,不过之前有未定义行为就不可预测了。如果假定前面都正确,那么p、q、x、y、"%d %d %d %dn"这五个参数表达式会被求值。注意,参数求值没有明确的先后顺序——这是未确定行为,只是这里不确定性不会从输出结果体现出来;而像printf("%d %d %d %dn",x,y,++x,++y);这样的语句的输出结果也能体现出不确定性——甚至包括用同一个编译器编译同一个程序中给定同样的x和y值的不同位置的此条相同语句。
函数参数求值的未确定行为的积极意义在于,编译器可以在局部重新排列代码顺序进行优化,减少代码体积或提升执行效率。如果几个参数之间有依赖关系,那么用户不应写成会影响预期结果的调用形式。
具体架构的具体调用约定中会约定实现细节,包括入栈顺序、由主调函数还是被调函数清理调用栈等。以x86为例,常见有cdecl、stdcall等。printf是不定参数个数的函数,所以有特殊限制,需要主调函数清理栈(被掉函数不知道具体有几个参数),典型实现为cdecl,函数参数从右至左进栈,返回值在EAX寄存器(这里是int;浮点返回值另作处理)。这些细节并不能由C语言直接保证(除非使用非标准扩展关键字,例如MSVC的__cdecl等,进行指定),反汇编会比较清楚一点。
打算成为程序员的可以不用看它了,此书适合二级党
《C语言程序设计》热门书评
-
二年级小学生写给一年级小学学的作文
46有用 0无用 薛非 2010-02-15
水平程度相当,所以很受没有判断力的一年级小学生的追捧利用公权力推销造成事实上的垄断是这本书销量大最重要的原因之一...
-
算法:程序的灵魂
43有用 10无用 春琴 2010-02-11
“作为可能性之阴影的现实性” [楔子]从前、或现在,也可能是将来,有一男一女,他们是恋人,一年前不明不白地分手了。在一个冬夜,这个可怜的男人发现自己竟一直对此念念不忘,于是他决定找到她,并再见她一面,以确定他们是不是真该就此彻底成为路人。就在这时——极富戏剧性地,这...
-
呃,竟然是它把我带入了另一个世界
43有用 5无用 Baye Wayly 2009-12-23
貌似我看的第一本编程的书(如果曾经很老的计算机信息技术中的VB9X和一本2001[或者是1999年吧,记不清了..]年出版的CFan 不算的话...)依然还记得刚学编程时那种思维转变的纠结,解出来的课后习题是当时最大的乐趣了。虽然当时还不知道什么设计模式, 什么最佳实践、 重构 。等到今天依次经历过...
-
这本书不是人看的
25有用 3无用 大叔 2007-03-05
错误相当多,而且有些章节我们是根本不学的,老师说会误人子弟。。。应该说,作为一本教科书,很差劲,但是作为一本垫桌角的书,它是很合适的,厚度刚好!...
-
不推荐入门者使用此书
20有用 3无用 饭卡 2010-03-16
别的不说,int a,b,c;这种垃圾代码风格,让多少初学者代码风格不规范。1.只讲规则,不讲原因,这也是国内技术书籍常见的问题。2.代码风格不好。3.结构松散,未将相关的知识进行联系。比如,数组与指针的关系,可能我忘记了,我不记得这本书里面讲过这个。入门者应当在入门的时候建立一个对C语言正确的印象...