为什么在这里只使用一次呢?

时间:2018-07-26 14:08:39

标签: c

我不理解这段代码的一部分:

#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("char: %c %x | state: %d | word: %d\n", c, c, state, nw);
      }
      printf("%d %d %d\n", nl, nw, nc);
}

为什么他们一次只使用“ else if”,而第二次不使用?

2 个答案:

答案 0 :(得分:1)

无论第一个if测试的结果如何,都必须执行第二个if测试。因此,第二项测试没有其他要求。也许更好的书写方式是:

if ( (c == ' ') || (c == '\n') || (c == '\t') ) {
   state = OUT;
   if ( c == '\n' ) {
      ++n1;
   }
} else {
   state = IN;
   ++nw;
}

使用isspace()函数可以使其更加清晰(假设这是真正需要的):

if ( isspace(c) ) {
   state = OUT;
   if ( c == '\n' ) {
      ++n1;
   }
} else {
   ...
}

答案 1 :(得分:0)

这里要进行两种不同的测试。

第一个测试是查看下一个字符是否特别是换行符;如果是,那么我们增加nl(跟踪行数)。

第二个测试是查看我们是在单词的“内部”还是“外部”(在此程序中,单词定义为非空白字符序列)。如果下一个字符是任何空白字符(包括换行符),则我们在单词的“外面”并将state设置为OUT。否则,如果我们处于OUT状态,则需要更改为IN状态并更新单词数。

可以这样写:

while ((c = getchar()) != EOF) {
    ++nc;
    /**
     * Are we starting on a new line?
     */
    if (c == '\n')
       ++nl;

    /**
     * Are we inside or outside of a word?
     */
    if (c == ' ' || c == '\n' || c == '\t')
       state = OUT;
    else if (state == OUT) {
         state = IN;
         ++nw;
    }

这就是为什么只使用一个else if的原因。