2016-12-04 52 views
-1

name lookup of 'i' change for ISO 'for' scoping[-fpermissive]我的程序有什麼問題? -fpermissive

這是什麼意思?
我的代碼有什麼問題?

的代碼應該計算摩爾質量:

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

#define maxn 1000 

int main() { 
    double c = 12.01, h = 1.008, n = 14.01, o = 16.00, sum = 0, al, num; 
    char mol[maxn]; 

    scanf("%s", mol); 
    for (int i = 0; i < strlen(mol); i++); 
    { 
     if (isalpha(mol[i])) { 
      if (mol[i] == 'C') 
       al = c; 
      if (mol[i] == 'H') 
       al = h; 
      if (mol[i] == 'O') 
       al = o; 
      if (mol[i] == 'N') 
       al = n; 
      if (isalpha(mol[i + 1])) 
       sum += al; 
      else { 
       num = mol[i + 1] - '0'; 
       sum += al * num; 
      } 
     } 
    } 
    printf("%lf\n", sum); 
    return 0; 
} 
+1

參見';'在'爲(...)'行的末尾?因爲這個原因,你有效地使用了未聲明的'i'作爲'for'循環體的'mol'索引。 –

+1

可能的重複[錯誤消息:'jj'的名稱查找已針對'範圍確定'更改爲ISO(如果使用'-fpermissive',則G ++將接受您的代碼)](http://stackoverflow.com/questions/6556449/錯誤消息名稱查找的jj更改爲iso作爲範圍,如果你使用) –

+1

在c中不允許在'for'語句中聲明變量。在'for'語句之前移動'int i;'。如果你想在你的循環中做任何事情,你還應該從'for'的行中刪除';'。 – woockashek

回答

1

由於@ChronoKitsune指出你有for循環後進行額外的;

在錯誤發生之前關閉之前;使用clang-format或其他自動格式化工具!這會使這些錯誤變得明顯。

關注,當我clang-format您的代碼示例會發生什麼:

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#define maxn 1000 
int main() 
{ 
    double c = 12.01, h = 1.008, n = 14.01, o = 16.00, sum = 0, al, num; 
    char mol[maxn]; 
    scanf("%s", mol); 
    for (int i = 0; i < strlen(mol); i++) 
     ; 
    { 
     if (isalpha(mol[i])) { 
      if (mol[i] == 'C') 
       al = c; 
      if (mol[i] == 'H') 
       al = h; 
      if (mol[i] == 'O') 
       al = o; 
      if (mol[i] == 'N') 
       al = n; 
      if (isalpha(mol[i + 1])) 
       sum += al; 
      else { 
       num = mol[i + 1] - '0'; 
       sum += al * num; 
      } 
     } 
    } 
    printf("%lf\n", sum); 
    return 0; 
} 

而且錯字脫穎而出英里:

for (int i = 0; i < strlen(mol); i++) 
     ; 
    { 

刪除錯誤;和重新申請clang-format(其中,由方式,是你使用的任何代碼編輯器的單一鍵盤命令):

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#define maxn 1000 
int main() 
{ 
    double c = 12.01, h = 1.008, n = 14.01, o = 16.00, sum = 0, al, num; 
    char mol[maxn]; 
    scanf("%s", mol); 
    for (int i = 0; i < strlen(mol); i++) { 
     if (isalpha(mol[i])) { 
      if (mol[i] == 'C') 
       al = c; 
      if (mol[i] == 'H') 
       al = h; 
      if (mol[i] == 'O') 
       al = o; 
      if (mol[i] == 'N') 
       al = n; 
      if (isalpha(mol[i + 1])) 
       sum += al; 
      else { 
       num = mol[i + 1] - '0'; 
       sum += al * num; 
      } 
     } 
    } 
    printf("%lf\n", sum); 
    return 0; 
} 

這是內置的webkit風格。您可以指定自己的樣式,例如,如果您希望if (mol[i] == 'C') al = c;在足夠短的時間內位於同一行上。

1

有在for (int i = 0; i < strlen(mol); i++);

環路是空結束的額外;,下面的代碼執行與i等於strlen(mol),但由於i是隻對for聲明的範圍定義,它是不確定的在塊中。因此錯誤信息。

您可以通過使用Kernighan和Ritchie縮進風格避免這種愚蠢的錯誤的:把{在與ifforwhiledoswitch語句行的末尾。這使得在控制語句和它的塊之間輸入虛假的;的可能性要小得多。

對於複合語句總是使用大括號並始終對宏使用大寫字母也是可取的。

下面是這個縮進和起搏風格程序:

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

#define MAXN 1000 

int main() { 
    double c = 12.01, h = 1.008, n = 14.01, o = 16.00, sum = 0, al, num; 
    char mol[MAXN]; 

    scanf("%s", mol); 
    for (int i = 0; i < strlen(mol); i++) { 
     if (isalpha(mol[i])) { 
      if (mol[i] == 'C') { 
       al = c; 
      } 
      if (mol[i] == 'H') { 
       al = h; 
      } 
      if (mol[i] == 'O') { 
       al = o; 
      } 
      if (mol[i] == 'N') { 
       al = n; 
      } 
      if (isalpha(mol[i + 1])) { 
       sum += al; 
      } else { 
       num = mol[i + 1] - '0'; 
       sum += al * num; 
      } 
     } 
    } 
    printf("%lf\n", sum); 
    return 0; 
} 

還要注意的是:

  • scanf("%s", mol);不能阻止緩衝區overfow如果輸入的是廁所長。您可以使用scanf("%999s", mol);,但您需要保持999MAXN的定義之間的一致性,這是不明顯的。

  • isalpha(mol[i])如果char默認爲有符號且mol[i]爲負值,則可能調用未定義的行爲。您可以通過編寫isalpha((unsigned char)mol[i])來防止此問題。

  • 您認爲mol只包含字母和數字字符。如果用戶輸入其他內容,則num = mol[i + 1] - '0'將不是數字的值,並且計算結果不正確。

  • 實際上,如果用戶輸入未知元素,如果分子中給定元素的數量超過9,例如癸烷C10H22或者如果最後一個元素後面沒有數字如H2O

下面是一個改進版本:

#include <stdio.h> 
#include <ctype.h> 

int main() { 
    double c = 12.01, h = 1.008, n = 14.01, o = 16.00, sum = 0, al, num; 
    char mol[1000]; 

    scanf("%999s", mol); 
    for (int i = 0; mol[i] != '\0'; i++) { 
     if (isalpha((unsigned char)mol[i])) { 
      if (mol[i] == 'C') { 
       al = c; 
      } else 
      if (mol[i] == 'H') { 
       al = h; 
      } else 
      if (mol[i] == 'O') { 
       al = o; 
      } else 
      if (mol[i] == 'N') { 
       al = n; 
      } else { 
       printf("unknown element: '%c'\n", mol[i]); 
       al = 0; 
      } 
      num = 1; 
      if (isdigit((unsigned char)mol[i + 1])) { 
       num = 0; 
       for (int j = 1; isdigit((unsigned char)mol[j]); j++) { 
        num = num * 10 + mol[j] - '0'; 
       } 
      } 
      sum += al * num; 
     } 
    } 
    printf("%f\n", sum); 
    return 0; 
} 
+0

難道你錯過了一些大括號?至少,我不明白爲什麼一些「if」陳述沒有大括號。我不會自己添加大括號,但是您提倡一致性而不是完全一致,或者解釋明顯的不一致。 –

+0

@JonathanLeffler:我應該更加明確。 K&R主張在聲明不重要時使用大括號。當它是一條單一語句中的單個語句時,它們只會省略大括號。我同意一致性是一個黃金法則,並且總是需要花括號的簡單慣例是可取的。 – chqrlie