为什么使用多个 "if"s 不起作用,但在 while 循环中使用 "if"s 和 "else if"s 却有效?

Why does it not work to use multiple "if"s but it does work to use "if"s and "else if"s inside a while loop?

这是我的代码,没有使用 else if

#include <stdio.h>

main()
{
    long s = 0, t = 0, n = 0;
    int c;
    while ((c = getchar()) != EOF)
        if (c == ' ')
            ++s;
        if (c == '\t')
            ++t;
        if (c == '\n')
            ++n;
    printf("spaces: %d tabulations: %d newlines: %d", s, t, n);
}

这是使用 else if 的代码:

#include <stdio.h>

main()
{
    long s = 0, t = 0, n = 0;
    int c;
    while ((c = getchar()) != EOF)
        if (c == ' ')
            ++s;
        else if (c == '\t')
            ++t;
        else if (c == '\n')
            ++n;
    printf("spaces: %d tabulations: %d newlines: %d", s, t, n);
}

出于某种原因,不使用 else if 是行不通的。是什么原因?我知道使用 if 一个接一个地执行,而使用 else if 在第一个为真的语句处停止。这在性能上有所不同。无论如何,在这个特定的(如果不是其他的)while 循环中不使用 else if 似乎不起作用。

谢谢。

缩进正确,您的第一个程序如下所示:

#include <stdio.h>

main()
{
    long s = 0, t = 0, n = 0;
    int c;
    while ((c = getchar()) != EOF)
        if (c == ' ')
            ++s;
    if (c == '\t')
        ++t;
    if (c == '\n')
        ++n;
    printf("spaces: %d tabulations: %d newlines: %d", s, t, n);
}

while 循环的主体是单个语句。

if ... else if ... else if ... else 全部组成一个大语句。通过将您的条件分成多个语句(ififif),您已将除第一个语句之外的所有语句移出 while 循环。

为避免此问题,请始终使用复合语句(即块:{ ... })作为 whileif 的主体声明。

顺便说一下,main() 自 1999 年以来就不是有效的 C。它应该是 int main(void)

来自standard(只选择了语法规则的相关部分)

   iteration-statement: while ( expression ) statement

   statement: selection-statement

   selection-statement:
             if ( expression ) statement
             if ( expression ) statement else statement

您正在编写一个迭代语句 - 它由 while(expression) 和一个语句组成。在你的案例中,该声明是一个选择声明 - 现在检查它。除非您使用 else ifelse,否则它不是单个语句 - 而是多个语句,除了 while 语句中的一个,其余的都在它之外。

你的代码基本上就是这个意思

  while ((c = getchar()) != EOF){ <--- the selection statement
    if (c == ' ')
        ++s;
  }<-- 
  if (c == '\t')
        ++t;
  if (c == '\n')
        ++n;

在块中加上括号和缩进可以避免这种错误。

因为你忘记了 while 两边的大括号,所以它只循环第一个 if 语句,然后退出循环并计算其他两个 if 语句。

此外,您为什么不使用 switch 语句?

while ((c = getchar()) != EOF) {
    switch(c) {
       case ' ':
          ++s;
          break; 
       case  '\t':
          ++t;
          break;
       case '\n':
          ++n;
          break;
    }
}
printf("spaces: %d tabulations: %d newlines: %d", s, t, n);