Программа компилируется, но завершается при выполнении.Зачем? - PullRequest
0 голосов
/ 12 июля 2011
int main() {  
    char first,second,third,fourth,fifth;  
    scanf("%c %c %c %c %c",first,second,third,fourth,fifth);  
    printf("%c%c%c%c%c",first,second,third,fourth,fifth);  
    getch();  
    return 0;  
}

Вышеуказанная программа компилируется без каких-либо ошибок (GNU GCC), но при выполнении минимизирует «текущее окно» и завершает работу снова без каких-либо ошибок. Почему?

Обновление

int main() {
    char first,second,third,fourth,fifth;
    scanf("%c %c %c %c %c",&first,&second,&third,&fourth,&fifth);
    printf("%c%c%c%c%c",first,second,third,fourth,fifth);
    getch();
    return 0;
}

Приведенный выше код изменен после получения ответов, но все еще ведет себя так же, только на этот раз компилятор выдает любую ошибку или даже предупреждения.

Ответы [ 3 ]

2 голосов
/ 12 июля 2011

При использовании scanf вы должны предварять каждую переменную символом амперсанда, потому что вы должны передать указатель на переменную без указателя, а не только на саму переменную, например:

scanf("%c %c %c %c %c",&first,&second,&third,&fourth,&fifth);
2 голосов
/ 12 июля 2011

Быстрое решение.

Поскольку вы передаете переменные char в scanf вместо указателей.

scanf("%c %c %c %c %c", &first, &second, &third, &fourth, &fifth);

Правило большого пальца.

Icemanind упомянул, что "При использовании scanf вы должны предварять каждую переменную амперсандом ", но это слишком широко.Если вы строго следуете этому правилу, вы можете передавать указатели на указатели -...Вместо этого, как правило, вы должны

  • передать адрес переменной, в которую вы хотите записать .

и

  • Тип цели должен точно соответствовать спецификации токенов формата ,

О последнем: Например, вы облажались, если вы проходите двойнойуказатель для токена формата %d.

Prevention.

Если вы использовали предупреждения компилятора, в вашем конкретном случае -Wformat, но в общем случае просто используйте -Wall (ижелательно -Wextra (тоже), компилятор предупредил бы вас:

gcc -Wall -Wextra foo.c

warning.cc: In function `int main()':
warning.cc:4: warning: format argument is not a pointer (arg 2)
warning.cc:4: warning: format argument is not a pointer (arg 3)
warning.cc:4: warning: format argument is not a pointer (arg 4)
warning.cc:4: warning: format argument is not a pointer (arg 5)
warning.cc:4: warning: format argument is not a pointer (arg 6)

Для любопытных: Это предупреждение основано на расширении компилятора, которое предназначено для строк формата (см. список атрибутов gcc *)1037 *:

Атрибут формата указывает, что функция принимает аргументы стиля printf, scanf, strftime или strfmon, которые должны проверяться типом по строке формата. Например, объявление:

      extern int
      my_printf (void *my_object, const char *my_format, ...)
            __attribute__ ((format (printf, 2, 3)));
2 голосов
/ 12 июля 2011

Поскольку вы передаете неинициализированные значения в scanf как указатели. Попробуйте

scanf("%c %c %c %c %c", &first, &second, &third, &fourth, &fifth);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...