2016-12-04 4 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» в качестве индекса «mol» в том, что вы хотели быть телом цикла 'for'. –

+1

Возможный дубликат [Сообщение об ошибке: поиск имени «jj» изменен для ISO 'для' scoping, (если вы используете '-fpermissive', G ++ примет ваш код)] (http://stackoverflow.com/questions/6556449/ error-message-name-lookup-of-jj-changed-for-iso-for-scoping-if-you-use) –

+1

В c не разрешено объявлять переменную в 'for'. Переместите 'int i;' перед 'for'. Вы также должны удалить ';' из строки с '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: поставить { в конце строки с заявлением if, for, while, do или switch. Это делает гораздо менее вероятным ввести ложный ; между оператором управления и его блоком.

Также рекомендуется всегда использовать фигурные скобки для составных операторов и всегда использовать заглавные буквы для макросов.

Вот ваша программа с этим отступа и стимуляцией стиле:

#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);, но вам нужно будет поддерживать согласованность между 999 и определением MAXN, что неочевидно.

  • 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

Смежные вопросы