1.5.4 单词计数
我们将介绍的第4个实用程序用于统计行数、单词数与字符数。这里对单词的定义比较宽松,它是任何其中不包含空格、制表符或换行符的字符序列。下面这段程序是UNIX系统中wc程序的骨干部分:
程序执行时,每当遇到单词的第一个字符,它就作为一个新单词加以统计。state变量记录程序当前是否正位于一个单词之中,它的初值是“不在单词中”,即初值被赋为OUT。我们在这里使用了符号常量IN与OUT,而没有使用其对应的数值1与0,这样程序更易读。在较小的程序中,这种做法也许看不出有什么优势,但在较大的程序中,如果从一开始就这样做,因此而增加的一点工作量与提高程序可读性带来的好处相比是值得的。读者也会发现,如果程序中的幻数都以符号常量的形式出现,对程序进行大量修改就会相对容易得多。
下列语句
将把其中的3个变量nl、nw与nc都设置为0。这种用法很常见,但要注意这样一个事实:在兼有值与赋值两种功能的表达式中,赋值结合次序是由右至左。所以上面这条语句等同于
运算符代表OR(逻辑或),所以下列语句
的意义是“如果c是空格,或c是换行符,或c是制表符”(前面讲过,转义字符序列\t是制表符的可见表示形式)。相应地,运算符&&代表AND(逻辑与),它仅比高一个优先级。由&&或连接的表达式由左至右求值,并保证在求值过程中只要能够判断最终的结果为真或假,求值就立即终止。如果c是空格,则没有必要再测试它是否为换行符或制表符,这样就不必执行后面两个测试。在这里,这一点并不特别重要,但在某些更复杂的情况下这样做就有必要了,不久我们将会看到这种例子。
这段程序中还包括一个else部分,它指定当if语句中的条件部分为假时所要执行的动作。其一般形式为:
if(表达式)
语句1
else
语句2
其中,if-else中的两条语句有且仅有一条语句被执行。如果表达式的值为真,则执行语句1,否则执行语句2。这两条语句都既可以是单条语句,也可以是括在花括号内的语句序列。在单词计数程序中,else之后的语句仍是一个if语句,该if语句控制了包含在花括号内的两条语句。
练习1-11 你准备如何测试单词计数程序?如果程序中存在某种错误,那么什么样的输入最可能发现这类错误呢?
练习1-12 编写一个程序,以每行一个单词的形式打印其输入。