2016-12-04 45 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