The C Programming Language (2nd)--笔记--1.5.4

1.5.4 单词计数

        第4个程序用于统计行数、单词数与字符数。这里对单词定义较宽松,它是任何不包含空格、制表符或换行符的字符序列。以下程序是Unix系统中wc程序的骨干:

#include <stdio.h>

#define IN	1                 /* Inside a word*/
#define OUT 0                 /* Outside a word*/

/* Count lines, words, and characters in input*/
main()
{
    int c, nl, nw, nc, state;

    state = OUT;
    nl = nw = nc = 0;
    while ((c = getchar()) != EOF) {
        ++nc; 
        if (c == '\n')
            ++nl;
        if (c = ' '|| c == '\n'|| c == '\t')
            state = OUT;
        else if (state == OUT) {
            state = IN;
            ++nw; 
        }
    }
    printf ("%d %d %d\n",nl, nw, nc);
}

        程序执行时, 每当遇到单词的第1个字符, 它就作为1个新单词加以统计。state 变量记录程序当前是否正位于一个单词之中,它的初值是“不在单词中”,即初值被赋为OUT。在此使用符号常量IN与OUT,而未使用其对应的数值 1 与 0 ,程序更易读。在较小程序中,此做法也许看不出优势,但在较大程序中,若从一开始就如此,因此而增加的一点工作量与提高程序可读性带来的好处相比是值得的。也发现,若程序中的幻数都以符号常量形式出现,对程序进行大量修改就会相对容易得多。

        语句:

nl = nw = nc = 0;

将把三个变量都设置为0。此用法常见,但要注意:在兼有值与赋值两种功能的表达式中,赋值结合次序是由右向左。所以上条语句等同于:

nl = (nw = (nc = 0));

        运算符 || 代表OR(逻辑或), 所以下列语句

if (c == ' ' || c == '\n' || c == '\t');

的意义是“如果c是空格,或是换行符,或是制表符”(前讲过,转移字符序列\t 是制表符的可见表现形式)。相应地,运算符&&代表AND(逻辑与),它仅比 || 高一个优先级。由 && 或 | | 连接的表达式由左至右求值,并保证在求值过程中只要给出能够判断最终的结果为真或假,求值就立即终止。若c是空格,则没有必要再测试它是否为换行符或制表符,这样就不必执行后面两个测试。在此,这一点并不特别重要,但在某些更复杂情况下这样做就有必要了,不久将会看到例子。

        该程序还包括else部分,指定当语句中的条件部分为假时要执行的动作。其一般形式:

if (表达式)
    语句1
else
    语句2

        其中,if-else中两条语句有且仅有一条语句被执行。若表达式的值为真,执行语句1;否则执行语句2。这两条语句都既可以是单条语句,也可以是锁在花括号内的语句序列。在单词计数程序中,else之后的语句仍然是一个if语句,它控制了包含在花挂号内的两条语句。

练习1-11          如何测试单词计数程序?若程序存在错误,什么样的输入最可能发现这类错误?

练习1-12         编程,以每行一个单词的形式打印其输入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值