您的位置:首页 > 其它

《再读》第二章 语法“陷阱”

2010-09-01 22:02 369 查看
看了第一章后发现第一节还是那么深奥啊~呵呵,今天看了第二章,虽然后点麻烦,不过

如果掌握了作者所说的关键的话,其实也不是特别难了,但还是有些声明的方法觉得很怪异,也

许是因为没有这样用过,也没听说过吧。今天难得的在书中找到了一些错误啊~呵呵,这算是一

个不大不小的收获吧。

1.对函数声明的理解。

在C语言中,声明分为两个部分:类型部分和一组类似表达式的声明符部分。声明符从表

面上来看与表达式有些类似,对它求值的话应该会返回一个声明中给定的类型的结果。一旦知道

了如何声明一个给定类型的变量,那么该类型的类型转换符就很容易得到了:只要不声明中的变

量和句末的分号去掉,然后用括号将之“封装”起来就行了。对于复杂的声明,我们只需要一层

一层的剖析,慢慢地就会知道其中的意思了。

2.运算符的优先级。

在C语言中,运算符是相当复杂的东西,不仅仅需要考虑优先级,还得考虑结合性,在这

一节中,作者为我们解决了优先级问题,同时,我也是在这一章发现的书中的错误。首先说说正

确的运算符的优先级顺序。

最高是:()(函数调用运算符)、[](下标运算符)、(->.)(结构成员选择运算符)这四个运算符。

其次是:单目运算符再次算术运算符,其中 % * / +
-
的优先级高。

再次是:移位运算符再次关系运算符,其中
< > <= >=
== != 的优先级高。

再次是:按位运算符,按位与的优先级高于按位或的优先级,按位异或的优先级在两者之间。

再次是:逻辑运算符

再次是:条件运算符(唯一的三目运算符)。

再次是:赋值运算符(包括复合赋值运算符)。

最后是:逗号运算符

我们要记住两点1.任何一个逻辑运算符的优先级低于任何一个关系运算符的优先级。2.移位

运算符的优先级比运算符低,但是比关系运算符高。

发现的错误:

在原书(中文版)中,优先级分成最高级的四个运算符,单目运算符和双目运算符三部分,

其中双目运算符又分为了算符运算符、位移运算符、关系运算符、逻辑运算符、赋值运算符、条

件运算符这几个依次降低的等级。而错误也就出现在这里,赋值运算符的真正的优先级应该比条

件运算符的低,这一点在后文中也有提到,而此处所说的是赋值运算符的优先级比条件运算符的

优先级高,这是我发现的书中的第一个错误(暂时),第二个错误是将条件运算符作为了二目元

算符,当然这一点译者也有指出,这个失误应该是原书作者的失误,至于第一个就不得而知了。

书中还提到“所有按位运算符的优先级要比顺序由运算符的优先级高,每个‘与’运算符的优先

级要比相应的‘或’运算符的优先级高,而按位异或运算符的优先级介于按位与运算符与按位或

运算符之间”。这个顺序运算符我不知道是单独指逗号运算符还是指&&、||、?:和,这四个运算符,

我暂时也没有查到,但看到网上有人将逗号运算符称作顺序求值运算符,但是根据我的理解和思

考,我个人认为指的是四种运算符,日后查到在做更改,如有知情者,可以留言或通过发邮件等

方式告诉我,谢谢合作。

3.注意作为语句结束标志的分号。

尤其要注意if、while、return、结构体的声明等语句。

4.Switch语句。

建议:每一个case语句后面都要记得加break;如果是特殊情况,需要将几句话共用的话要

写注释。default语句可有可无,可放置于任意位置,建议放置于最后,并且在末尾加一个break

语句,以防万一。

5.函数调用。

与某些语言不同,不论函数是否有参数,调用时都必须带有括号。例如:f();与f;f();是

函数的调用,而f;却什么也不做,说的更精确点是计算函数f的地址,并不调用该函数。

6.“悬垂”。

根据C语言的处理方式,else会与向上的第一个if配对,因此在进行if语句嵌套时往往

会引发“悬垂”的问题,即使是经验丰富的程序员也会犯这样的错误。例如下列代码:

if ( x == 0 )

if
( y == 0 )

err();

else {

z
= x + y;

f(&z);

}

这段代码的真正目的是先判断x是否等于0,如果是,则判断y是否等于0,如果是,则调用err

函数,不是,则什么也不干;如果x不等于0,则执行else的语句。但是由于“悬垂”问题导

致程序与编程者的意图大相径庭。整理代码:

if ( x == 0 )

if
( y == 0 )

err();

else
{

z
= x + y;

f(&z);

}

也就是说,这段代码真正实现的是先判断x是否等于0,是,则判断y是否等于0,是则执行err

函数,不是则执行else的语句,如果x不等于0则什么也不做。

建议,将if的语句用括号括起来,如下列代码:

if ( x == 0 ) {
if
( y == 0 )
err();
} else {
z
= x + y;
f(&z);
}

又或者进行一些宏定义,做一下处理:

#define IF { if {

#defien THEN } {

#define ELSE } else {

#defien FI } }

IF x == 0 THEN

IF
y == 0 THEN

err();

FI

ELSE

z
= x + y;

f(&z);

FI

这是第二章的内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: