前面已经学过了第四章中的后半部分,今天继续学习第五章,《选择结构程序设计》。由于谭师傅这一章讲得比较拖沓,也没有太多细节上的错误。所以这一章我们基本上就高屋建瓴吧。
谭师傅开篇就给了一个无比经典的语句,特抄录如下:
我每次看到这样的写法头就要大一圈,偏偏中国同事们还特别喜欢用。以前我总是百思不得其解。现在好了,找到根子了。
在 92页上,谭师傅本来讲关系表达式讲得挺好的,突然中间插了一句:“C++…以True表示‘真’,以False表示‘假’“。要不是谭师傅也写了 C++的书,我还以为谭师傅从来没写过C++的程序呢。当然,这也可以理解为排版工人的问题,或者是Word自动改大小写,把true写成了True,等 等。
在讲到 if 语句时,谭师傅又别也心裁地把 if 语句分成了三种类型:只有 if、if 加 else、多重 if-else (即 if else if else if … else)。其实,第三种和第二种没什么区别。只要讲清楚了 if-else 整个是一个语句(其实后面谭师傅也讲了这点),那么各种的嵌套就是不言而喻的,并不值得单独分成一类。因为如果这样分了之后,那么如果我有 if if else 算不算第四类?if if if else 算不算第五类?我看这个可能是因为谭师傅对于程序语言的定义没有一个清晰的概念。这也可以解释为什么谭师傅总是侧重于各种语法、句法上的边边角角(虽然很 多时候整得不太对)。
有一个值得一提的是,谭师傅讲到 if 后面的表达式“不限于逻辑表达式,可以是任意数值类型”,“包括整型、…、指针型数据“。这句话不太对。最重要的,就是指针型数据并不是“数值类型”。
具 体到 if 语句,指针和其它类型的区别在于,当变量 p 不为指针时,if (p) 实际上相当于 if (p != 0),而当 p 为指针时,if (p) 则相当于 if (p != NULL)。也许你要说了,NULL不就是0吗?事实上,如果编译器把NULL定义为0,那是纯属偶然。NULL只需要被定义成某个不可能出现的地址就可 以了。在有些系统中NULL的确不为0。但是为了方便,如果编译器发现你把某个指针和0作比较,它会自动把0换成NULL。所以,如果说 if (p) 是测试 p 的值是否为0,这个论断只对 p 不是指针时才准确。当然,这点对于初学者来说问题不大。只要记住指针是C语言一个特殊类型,和一般算术类型不同就行了。
谭师傅花了很大的 力气讲 if 语句的嵌套,并且在好几处地方提醒同学们,要注意哪个 if 和哪个 else 匹配。其实,if 和 else 匹配的问题之所以成为问题,完全是因为谭师傅在开头的那个经典语句。如果谭师傅从一开始就教导大家把这个语句写成下面这样,还能成问题吗?
y = 1;
} else {
y = -1;
}
谭 师傅还用了整整一个小节去讲“条件运算符”(即 ?: 操作符)。固然又知道了几种茴字的写法,却让人头又大了一圈。不仅如此,有一个很重要的问题谭师傅还没有讲到,就是如果后面两个操作数的类型不同,那么这 整个表达式的类型是什么?如果只是一般的算术类型也许还好说,但加上const呢?指针呢?如果一个是结构体另一个是联合体呢?我敢说谭师傅可能想都没想 到过这个问题。其实对于初学者,最好的忠告就是,非到不得已,不要用这个操作符。
这一章里最雷人的,莫过于谭师傅对于switch的讲 解。有些已有Yush以及其他人讲过了,不过在这里还是再提一下。首先,谭师傅再次祭出“谭氏标准”,说“switch后面括号内的‘表达式’,ANSI 标准允许它为为任何类型”。实际上,没有任何C的标准(包括ANSI之前的K&R C)可以允许这个表达式是“任何类型”。它只能是整数类型(即可以表达为整数的类型,包括诸如字符、枚举等)。其次,在105页上,谭师傅自己也说,一个 case执行完之后会执行下一个case而不会自动跳出switch,但同时又说,“各个case和default出现的次序不影响执行结果”。这怎么可 能呢?必需还要加上一个条件:每个case和default后面都有break,这才有可能成立。可这时谭师傅还没讲过break是什么东东呢。
在这一章最后一小节里,谭师傅又给了好几个程序的例子。粗看了一下,应该没有什么大错,不过称不上是范例。一些写法很有问题。不过这里就不多讲了。下次再说。
2009年4月13日 at 12:29 am
继续学习
2009年4月22日 at 7:52 pm
我手头有谭师傅的书第2版和第3版,手头也有扫描仪可以扫描下来。博主如果有兴趣把这个系列继续写下去的话(我希望能继续下去),我可以向您提供扫描文件。请发一封邮件给我(我的邮箱在上面),我就把扫描件发给您。
2009年5月10日 at 11:43 pm
if( x>0 ) y=1; else y=-1;
可以被视为非常不规范的写法.
不过 if , if else, if else 嵌套是可以划分的.比如我们对if else 嵌套通常要建议不要超过三层.
2009年6月2日 at 6:23 pm
像if( x>0 ) y=1; else y=-1; 这种写法的规范性,我觉得讨论简直就是SB。
因为它太简单了。
一切均应以可读性为基本原则。if( x>0 ) y=1; else y=-1;的写法我读起来一点都不费劲,任何一个写过2年c语言的人读也不费劲,而且绝对不可能误解。
考虑到有人习惯
if(a){
b = 1;
}
有人习惯
if(a)
{
b=1;
}
这种习惯性的讨论毫无意义,因为他们都足够清晰,而且不会误读,所以随便用哪种好了。
谭老师恐怕本来习惯性的是写 y = (x>0)? 1:-1;结果为了讲if else,不得不写了一行,而他又在一个超小分辨率的机器上干活,一行能解决何必写5行?