2010-09-28 3 views

ответ

14

Испытуемая часть петли i++.

Поскольку ++ (или увеличение) является после исправить (написанный после переменной, а не до него), приращение происходит после утверждения оценивается и протестировано. Тест находится на 0, который оценивается как FALSE, поэтому «петля» существует, не будучи запущенной.

Далее, после исправления ++ вступает в силу, изменение i от 0 до 1.

Как @paxdiablo указывалось, после выхода из цикла, i выходит за рамки. Независимо от того, что печатает окончательный printf, он отличается от i, объявленным и заданным значением, которое не отображается в вашем коде.


В других сценариях, если вы начинаете i на 1, то тест всегда верно, и каждый номер печатается (до i перетоков, и возвращается к 0).


И, наконец, если i начинается с -1, тест сначала проходит (-1 ИСТИНА), приращение после исправления происходит, поворачиваясь -1 в 0, и 0 распечатывается.

Цикл запускается снова, на этот раз 0 не проходит тест, контур завершается, происходит приращение после исправления, а другой i (не показан в вашем коде) печатается после окончания цикла.

+3

Осторожно, что 'i' существует только в рамках' for'. Независимо от того, что 'i' распечатывается после того, как цикл является _different_ одним (скрывается, когда выполняется цикл' for'). Цикл будет иметь нулевой эффект на эту переменную. – paxdiablo

+0

превосходный catch @paxdiablo. Я полностью пропустил это. – abelenky

+0

Мне кажется, что некоторые компиляторы с ошибкой все равно позволят вам получить доступ к тому же самому 'i', сделают этот код полезным тестовым примером, хотя я, конечно же, надеюсь, что вам не придется иметь дело с таким компилятором! – Arafangion

6

Цикл for не будет работать даже - i 0 при испытании в условиях, перед тем инкрементируется. Кроме того, если i не определено где-то перед циклом, код не будет компилироваться, потому что i в printfпосле цикл не определен.

Откуда вы взяли этот код? Это очень гротескный способ написать цикл for, и я бы никогда не использовал его за пределами запутанного конкурса кодирования.

+4

Я не удивлюсь, если это будет домашнее задание или вопрос с интервью. Они любят задавать такие хитроумные вещи. – cHao

+1

@cHao: Я просто хочу, чтобы они придерживались юридического, определенного поведения, когда задавали сложные вещи. –

+0

Я все равно буду увеличиваться. (Возможно, это всего лишь плохая формулировка ... Цикл действительно не запускается - и условие проверки действительно проверяется до того, как «i» будет увеличено, но оно по-прежнему увеличивается в соответствии с этим синтаксисом.) Тем не менее, компилятор должен быть способен чтобы оптимизировать это, в данном случае. – Arafangion

1

В for(int i=0 ; i++ ; printf("%d",i)); условие испытания является ложным (поскольку i++ возвращает 0), цикл не будет работать.

Обратите внимание на точку с запятой после цикла. :)

0

Эта петля заканчивается, когда i равно 0. Поэтому, если вы начинаете выше 0, i будет 0 ... после 2^31 или 2^63 итераций.

+1

Вы имеете в виду (2^32 - 1) или (2^64 - 1), так как он будет прокручивать все отрицательные числа тоже ... – cHao

0

++ используется как почтовый индекс. Таким образом, вы, проверяя значение i, будете 0, и вы вообще не входите в цикл.Вне петли вы печатаете значение i, которое сейчас 1

+0

Thnx evry1 для ur help.I получил его. Этот вопрос попал в одну из газет GATE. –

+1

ths s nt cllphone. –

+0

@Brite Roy: Что такое бумага GATE, и почему она настаивает на вызове неопределенного поведения? –

1

Это похоже на искаженный код. Я не могу поверить, что это преднамеренно.

Вторая часть инструкции for() указывает условие завершения цикла. Если условие оценивается как true, цикл завершается, в противном случае выполняется итерация.

В этом случае вторая часть отчета - i++. Обычно это будет в третьем разделе инструкции if(). Поместив вторую часть, вы вынуждаете цикл только выйти, если i++ оценивает значение false, т.е. ноль. Поэтому, если i начинает меньше нуля, вы получите итерации, пока не достигнете нуля, иначе вы получите цикл infinte.

Как я уже говорил, ++, как правило, находится в третьей части инструкции, поэтому на лицевой стороне он выглядит так, как будто кто-то удалил среднюю часть инструкции if(), получил ошибку компиляции и попытался чтобы исправить это, заклинив printf() на конце. Беспорядочный.

-2
for(int i=0 ; i++ ; printf("%d",i)); printf("%d",i); 

эквивалентно

int i = 0; 

while (i++) 
{ 
    printf("%d",i); 
} 

printf("%d",i); 

Когда я = 0 на начальном этапе, я ++ равен 0 (и, следовательно, ложно), поэтому цикл никогда не запускается на выполнение. Но мне присваивается значение 1, поэтому последние printf печатает 1.

Когда i = -1 изначально, тогда i ++ равно -1 (отличное от нуля, так истинно), поэтому тело цикла выполняется. После i ++ i равно 0, поэтому первый printf печатает 0. Теперь мы уменьшили проблему до предыдущего случая, так что остальная часть вывода равна 1. Таким образом, общий результат равен «01», причем 0 и 1 являются правыми рядом друг с другом, потому что вы не помещали пробелы в строку формата printf.

Когда i = 1 изначально, цикл выполняется с i = 1, затем i = 2, затем i = 3, ..., тогда i = 2147483647 (или что-то другое INT_MAX есть), а затем обходит вокруг i = -2147483648, затем i = -2147483647, затем i = -2147483646, а в конечном итоге обертывается до 0 после печати миллиардов чисел.

+0

grrt Пояснение dan04.Thnku так много. –

+2

Прошу прощения, но ваш эквивалентный код _isn't_. Независимо от того, что 'i' печатается во второй строке' printf', это не тот, который печатается в первом (область действия которого ограничена '' for'). Кроме этого, неплохо. Лучше было бы что-то вроде '{int i = 0; while (i ++) {printf ("% d", i); }} printf ("% d", i); – paxdiablo

+1

@Brite Roy: Последний абзац не соответствует стандарту, хотя он будет работать на большинстве современных систем.Подписанное целочисленное переполнение не определено в C и C++. Кроме того, 'i' в последнем' printf' не является 'i' из цикла, если это C или стандартный C++. –

3

Он не должен компилироваться, если только не указано i.

Этот код был бы незаконным в C90, так как не было разрешений, кроме как в начале блоков. В C99 объявление i в цикле for является законным, но его область действия является циклом и не выходит за пределы этого. Это также было бы верно в стандартном C++, но в предстандартном C++ область действия распространялась до конца закрывающего блока. Возможно, конечно, что компилятор не соответствует ни одному опубликованному стандарту, и в этом случае мы не можем сказать, что абсолютно должно произойти.

A для цикла имеет три положения. Первый выполняется в самом начале и нигде, и (на C99 и C++) может быть объявлением. Он устанавливает начальное значение i.

Второе предложение выполняется перед телом петли. Если он оценивает значение false, оператор for заканчивается немедленно. Поскольку i является int, единственным ложным значением является 0. В этом случае i++ возвращает текущее значение i и увеличивает его для последующего использования. Поэтому, если i равно 0, цикл for ничего не делает.Если i равно 1, то i будет увеличиваться до i равно 0 или что-то еще происходит. На самом деле это неопределенное поведение, так как i является подписным интегральным типом, но обычно случается, что он будет увеличиваться до максимально возможного int, а затем превратится в самое отрицательное возможное int, а затем увеличится до тех пор, пока оно не станет 0, а цикл остановится , Если i начинается с -1, то в первом прогоне это не 0, но это будет для второго прогона.

Третье предложение, которое здесь выполняет печать, запускается после корпуса петли. Обычно он используется для увеличения того, что делает цикл, который может выполняться через ряд целых чисел или вниз по цепочке указателей в связанном списке или что-то еще. Он не имеет никакого эффекта, кроме как выполнен.

Корпус петли for пуст, как показано ; сразу же после закрытия круглой скобки. Это означает, что после выполнения первого предложения выполнение будет вторым и третьим чередующимися с остановкой, когда второе предложение будет равно 0.

Это очень странный оператор for, в котором нет тела цикла и приращение выполняется во втором предложении, но оно является законным (если нет арифметического переполнения, которое произойдет, если i положительно начать). Не определено i сразу же нет.

+0

Thnx Sir для этого идеального объяснения .. –

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