小结
概念与术语
■ C语言中关系运算运算符共有4种:>、>=、<、<=,运算结果只可能为0或1。
■ C语言中判等运算运算符共有两种:==、!=,运算结果只可能为0或1。
■ 由于浮点类型通常只能近似地表示数值,所以对浮点数据进行判等运算是一般是没有意义的。
■ C语言中逻辑运算运算符共有3种:!、&&、||,运算结果只可能为0或1。
■ 在某个点之前,前面的全部运算及副效应必须完成,这就是所谓的序点。
■ &&和||及条件运算符中的“?”是程序中的序点。
■ if语句共有两种形式:带else子句与不带else子句。
■ 执行if语句时,首先求“()”中表达式的值,如果这个值不为0则执行“()”后面的语句;否则if语句结束(不带else子句的if语句)或执行else后面的语句。
■ else子句总是属于前面最近的没有与其他else结合的同层次的if语句。
■ switch语句中“()”内的表达式必须是整数类型。
■ switch语句中case后必须是整数类型常量表达式。
■ switch语句中任何两个case后的整数类型常量表达式不可以相等。
■ switch语句中最多只能有一个default语句标号。
■ switch语句的执行过程是,首先求“()”内表达式的值,然后转到与这个值相等的case语句标号处继续执行;如果这个值与任何一个case后的整数类型常量表达式都不同,则执行default语句标号后的语句,如果没有default语句标号,则switch语句结束。
■ switch语句中的break语句的作用是结束该switch语句。
■ 在switch语句中,语句标号并不影响语句的顺序执行。影响语句顺序执行的是break语句或goto语句。
■ break语句只结束所在的最内层的switch语句。
■ goto语句只在所在的函数内有效。
■ 条件运算符是C语言中唯一的三元运算符,在运算时可能发生算术转换。
■ 程序开发通常要经过“定义程序功能”、“设计数据结构和算法”、“代码编辑”、“编译与链接”、“测试与运行”、“调试”、“维护”这些阶段,其中可能经过多次反复。
风格与习惯
■ 养成把if语句首先写成如下格式,然后再向()或{}中添写代码的习惯,会减少许多无谓的低级错误:
■ 类似地,switch语句也是如此。
常见错误
■ 在if语句中忘记把if子句或else子句中的几条语句用{}括起来。可以通过建立良好的编程习惯克服这点。
■ 把“==”误写为“=”。克服方法:养成把“=”读做“赋值为”的习惯。
■ 把i==j&&j==k误写为i==j==k或把a>b&&b>c误写为a>b>c。克服方法:注意区分数学中关系的表示与C代码中逻辑运算之间的差别。
■ 忘记switch语句中的break语句。克服方法:一旦确定使用带break形式的switch语句首先写出各个case标号后的break语句,然后再写其他内容。
■ 在&&或||右侧出现改变变量值的表达式,如:
这样的写法有时b=2不会被执行,况且这种写法的逻辑含义本身就是说不清道不明的。
牛角尖
■ unsigned int a=1, b=2; a-b>1的值是多少?
解答:unsigned类型的减法总是有意义的,当一个小的unsigned类型数据减去大的unsigned类型数据的时候(例如例子中的a-b),其真正含义是a + UINT_MAX - b + 1,这个值为FFFFFFFFU,显然a - b>1的值为1。
下面的switch语句合法吗?
解答:
尽管比较古怪,但这个switch语句完全合法。
首先,switch语句的语法形式是switch()后跟一语句(本例中跟的是一if-else语句),由于语句标号可以出现在任何语句的前面,所以这个switch语句是合乎语法要求的。
其次switch()后语句中可以出现若干case标号,这些case标号可以并列在一起,这一点例句也不违反语法规定。
然而这个语句本身是违反结构化程序设计原则的,其语意特别晦涩难解,实际应用中应尽力避免。这个语句的原来目的据说是这个是为了提高效率。
■ 下面的代码片段的输出结果是什么?
解答:在这个嵌套的switch语句中只有唯一一个break语句,这个break语句只结束所在的最内层的switch语句。因此输出的结果为: