2013-06-30 31 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語句不再處於循環中。使用{}來包含循環語句。