Странное поведение C для цикла с i ++ в качестве условия - PullRequest
0 голосов
/ 08 октября 2018

У меня есть следующий код:

int main()
{
    char i = 0;

    for (; i++; printf("%d", i));

    printf("%d", i);

    return 0;
}

Он успешно компилируется и печатает 1.Я новичок в C, и я не понимаю этого.Я думал, что i ++ всегда будет верным, и поэтому это будет бесконечный цикл.

Может кто-нибудь объяснить мне это?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018
    for (; i++; printf("%d", i));

является допустимым C-кодом, но не является идиоматическим C-кодом.Настоящие программисты на Си никогда не пишут подобного кода (но могут понять, что происходит).Прочитайте n1570 (это практически стандарт C) §6.8.5.3 для значения for:

6.8.5.3 Формула for

1Оператор

      for ( clause-1 ; expression-2 ; expression-3 ) statement

ведет себя следующим образом: Выражение выражение-2 является управляющим выражением, которое вычисляется перед каждым выполнением тела цикла.Выражение expression-3 оценивается как пустое выражение после каждого выполнения тела цикла.Если условие-1 является объявлением, область действия любых идентификаторов, которые оно объявляет, является оставшейся частью объявления и всего цикла, включая два других выражения;оно достигается в порядке выполнения до первой оценки управляющего выражения.Если условие-1 является выражением, оно оценивается как пустое выражение перед первой оценкой управляющего выражения. 158)

2 Как условие-1, так и выражение-3 могут быть опущены.Пропущенное выражение-2 заменяется ненулевой константой.

Сноски

158) Таким образом, пункт-1 задает инициализацию для цикла, возможно, объявляя одну или несколько переменных для использования в цикле;управляющее выражение expression-2 определяет оценку, выполненную перед каждой итерацией, так что выполнение цикла продолжается до тех пор, пока выражение не сравнится равным 0;а выражение-3 задает операцию (например, приращение), которая выполняется после каждой итерации.

Таким образом, в вашем случае управляющее выражение («expression-2» в стандарте C)(неправильно) i++.Это ложно в первый раз, когда выполняется цикл.

Если вы замените i++ на ++i, то условие останется истинным 255 раз на моем компьютере с Linux (так как у меня есть неподписанные символы на 8 битах).

Если ваш компьютер имеет подписанные символы, у вас технически есть некоторое неопределенное поведение , потому что у вас переполнение со знаком.Так что будьте очень напуганы и читайте блог Латтнера на UB!

Я новичок в C и не понимаю этого,

Затем вы должны прочитать какой-нибудь справочный сайт C , иногда обратиться к стандарту C11 n1570 , прочитать хорошие книги по программированию на C (возможно, даже прочитать хорошее введениек программированию, например SICP - который не использует C), и , как отлаживать небольшие программы .Если вы используете какой-то компилятор GCC , обязательно включите все предупреждения и отладочную информацию, поэтому скомпилируйте с gcc -Wall -Wextra -g.

0 голосов
/ 08 октября 2018

i++ - это постинкремент .Таким образом, во время проверки выписки значение i равно 0, то есть false.Следовательно, цикл разрывается.

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