2013-06-30 30 views
1

只是一个简单的问题;我一直在努力通过K & R和数字/空白/其他计数器的代码工作正常。然而,当试图让我的头围绕else的功能时,我遇到了一些不能按预期工作的东西。'if'陈述不像预期的那样没有'else'

从书中的代码如下:

#include <stdio.h> 

/* count digits, white space, others */ 
main() 
{ 
    int c, i, nwhite, nother; 
    int ndigit[10]; 

    nwhite = nother = 0; 
    for (i = 0; i < 10; ++i) 
     ndigit[i] = 0; 

    while ((c = getchar()) != EOF) 
     if (c >= '0' && c <= '9') 
      ++ndigit[c-'0']; 
     else if (c == ' ' || c == '\n' || c == '\t') 
      ++nwhite; 
     else 
      ++nother; 

    printf("digits ="); 
    for (i = 0; i < 10; ++i) 
     printf(" %d", ndigit[i]); 
    printf(", white space = %d, other = %d\n", nwhite, nother); 
} 

如果我再修改while循环,所以它读取:

while ((c = getchar()) != EOF) 
      if (c >= '0' && c <= '9') 
       ++ndigit[c-'0']; 
      if (c == ' ' || c == '\n' || c == '\t') 
       ++nwhite; 

它仍然应该具有相同的功能,除了原来的代码因为它不会计算其他字符。然而,我实际上得到的只是'数字'部分的工作,'nwhite'无论输入什么都返回零。我认为这种差距可能是由于对陈述如何运作的根本误解所致。

+7

你需要花括号中的代码。 – Elazar

+1

请注意,很多人总是写'while(expression){statement; ...}使用大括号来避免这个错误。 –

回答

2
while ((c = getchar()) != EOF) 
     if (c >= '0' && c <= '9') 
      ++ndigit[c-'0']; 
     if (c == ' ' || c == '\n' || c == '\t') 
      ++nwhite; 

是相当于

while ((c = getchar()) != EOF) { 
     if (c >= '0' && c <= '9') 
      ++ndigit[c-'0']; 
} 
if (c == ' ' || c == '\n' || c == '\t') 
     ++nwhite; 

只有遵循循环或分支结构“属于”该构造中的第一条语句。这就是为什么最初的if-else if-else链没有大括号的原因。每条语句链接到前一个,并且第一个if/else语句属于while循环,第二个if/else属于第一个if/else。用这种方式表达逻辑以避免不必要的缩进是习惯用法。

它可以帮助用户呈现括号

while ((c = getchar()) != EOF) { 
    if (c >= '0' && c <= '9') { 
     ++ndigit[c-'0']; 
    } 
    else { 
     if (c == ' ' || c == '\n' || c == '\t') { 
      ++nwhite; 
     } 
     else { 
      ++nother; 
     } 
    } 
} 
10
while ((c = getchar()) != EOF) 
     if (c >= '0' && c <= '9') 
      ++ndigit[c-'0']; 
     if (c == ' ' || c == '\n' || c == '\t') 
      ++nwhite; 

第二个if语句不再处于循环中。使用{}来包含循环语句。