Целые числа C выключены, возможно переполнение

Я пытаюсь создать программу на C, которая будет подсчитывать и печатать количество вкладок, пробелов и строк, введенных пользователем. Проблема в том, что когда он печатает эти числа, они сильно отличаются. Вот мой программный код:

int c, b, t, nl;
b, t, nl = 0, 0, 0;
while ((c = getchar()) != EOF) 
{
    if (c == '\b') 
        b++;
    if (c == '\t') 
        t++;
    if (c == '\n') 
        nl++;
}
printf("b=%d t=%d nl=%d\n", b, t, nl);

Когда я ввожу некоторые данные из терминала (3 строки, один пробел, одна табуляция), результатом будет b=1899313536, t=32768 и nl=3.


person Adam Odell    schedule 01.01.2015    source источник
comment
Кстати: хороший правильный тип int c, а не char c.   -  person chux - Reinstate Monica    schedule 02.01.2015


Ответы (4)


Проблема в этой строке:

b, t, nl = 0, 0, 0;

Он использует оператор запятой с обеих сторон присваивания, поэтому только nl инициализируется нулем. Нет побочных эффектов для вычисления b, t слева* и двух завершающих нулей справа от оператора = (обратите внимание, что присваивание имеет более высокий приоритет, чем оператор запятой).

Измените его на:

b = t = nl = 0;

что фактически означает (поскольку оператор = имеет правильную ассоциативность):

b = (t = (nl = 0));

*если только b или t не объявлены как volatile (поскольку чтение такого объекта считается побочным эффектом по стандарту C)

person Grzegorz Szpetkowski    schedule 01.01.2015

b не используется, это выражение неверно

b, t, nl = 0, 0, 0;

он только инициализирует nl, он должен быть

b = t = nl = 0;
person Iharob Al Asimi    schedule 01.01.2015

В отличие от Lua или некоторых других языков, которые позволяют назначать несколько переменных в одном выражении.

v1, v2, v3 = c1, c2, c3; // <<== This is not a valid C syntax.

C требует, чтобы вы назначали их индивидуально:

b = 0;
t = 0;
nl = 0;

Еще лучше, вы можете инициализировать переменные во время объявления, например:

int c, b=0, t=0, nl=0;

Однако причина, по которой ваш текущий код компилируется, немного любопытна: он обрабатывает запятые в вашем коде как операторы запятой, которые допустимы с обеих сторон присваивания.

person Sergey Kalinichenko    schedule 01.01.2015
comment
Комментарий о том, почему это компилируется, полезен, но его можно немного улучшить, показав эквивалентную строку без них. - person dmckee --- ex-moderator kitten; 02.01.2015

Это мусорные значения. Вам необходимо присвоить переменным b, t и nl значение 0 по отдельности.

person Jobs    schedule 01.01.2015