Странный вывод этой программы на C - PullRequest
1 голос
/ 04 августа 2011
#include<stdio.h>
main()
{
int i;
char c;
for (i=0;i<5;i++){
        scanf("%d",&c);
        printf("%d",i);
}
printf("\n");
}

Я думал, что это напечатает 0 1 2 3 4, но это не так.В чем причина странного вывода?

Ответы [ 5 ]

5 голосов
/ 04 августа 2011

Неопределенное поведение .

Вы пытаетесь прочитать int ("%d" в вызове scanf) в объект типа char (c). Не делай этого!

4 голосов
/ 04 августа 2011

Эта программа демонстрирует неопределенное поведение : тип &c (char *) не соответствует типу аргумента scanf (%d хочет подписать int *).

Вероятно, происходит то, что scanf записывает 4 байта в ячейку памяти, начиная с адреса c. Длина которого составляет всего 1 байт, поэтому остальные 3 байта перезаписывают первые 3 байта значения i. В системе с прямым порядком байтов это фактически установит i в любое целочисленное значение, которое вы вводите, смещенное вправо на 8 бит.

Но, конечно, поведение не определено. В следующий раз, когда вы скомпилируете этот код, он может сделать что-то совершенно другое. Другой компилятор или тот же компилятор с другими параметрами может хранить i в регистре (где scanf не может его перезаписать) (но вместо этого он может разбить адрес возврата в стеке, вызывая сбой при завершении программы), или он может поместить значения в стек в обратном порядке (то же самое), или он может оставить 4 байта в стеке для c (не вызывая неожиданного поведения), или он может обнаружить ситуацию и прервать работу с ошибкой, или это может даже заставить демонов вылететь из вашего носа .

0 голосов
/ 04 августа 2011

Вы читаете в c, но печатаете i, поэтому вы увидите 01234. Возможно, вы хотите печатать c.Но этого недостаточно.c должно быть объявлено как int, потому что вы читаете в формате "%d", который ожидает int.Либо используйте формат hhd, либо измените c на тип int

0 голосов
/ 04 августа 2011

В чем причина странного вывода?

Это потому, что вы неправильно использовали scanf.Когда вы используете "% d", вы должны дать scanf указатель на int, но вы дали ему указатель на символ.

Измените char c на int c

(Вам также следует проверить функции на наличие ошибок. Например, scanf вернет EOF в конце ввода. Он также вернет количество присвоенных значений. Поскольку вы дали ему 1 значение, &c, вам следует проверить, что scanf возвращает 1. Еслинет, могло случиться что-то плохое)

0 голосов
/ 04 августа 2011
scanf("%d",&c);

должно быть

scanf("%c",&c);

кстати.Он попросит вас ввести значение для c в каждой итерации, а затем выведет одно значение i.Что ты получаешь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...