2013-09-15 8 views
-2

Почему следующий цикл не работает бесконечно? Я ожидаю, что, достигнув 65535, i должен переполняться до нуля.Почему это бесконечный цикл?

#include<stdio.h> 
int main() 
{ 
    short int i = 0; //(assume short int is 2 bytes) 
    for(i<=5 && i>=-1; ++i; i>0) 
     printf("%u\n", i); 
    return 0; 
} 

EDIT

Что об этом

#include<stdio.h> 
int main() 
{ 
    int x=1, y=1; 
    for(; y; printf("%d %d\n", x, y)) 
    { 
     y = x++ <= 5; 
    } 
    printf("\n"); 
    return 0; 
} 

Он прекрасно работает и печатает

2 1 
3 1 
4 1 
5 1 
6 1 
7 0 

Что делает это прекратить?

+1

Это неопределенное поведение и компилятор может сделать сделать это в своем роде !!! –

+0

Я не думаю, что это неопределенное поведение. Петля заканчивается просто потому, что условие завершения было достигнуто из-за переполнения. –

+1

Re: отредактируйте. «Что заставляет его прекратить?» Тот факт, что 'y' становится' 0'. –

ответ

7

Вы полагаетесь на подписанное переполнение здесь, которое вызывает undefined behvaiour. Компилятор был бы в пределах своих прав оптимизировать это до бесконечного цикла или нет или сделать что-то совершенно другое.

2

Две причины.

Во-первых, как указал Оли Чарлворт, вы вызываете неопределенное поведение.

Затем 65535 до 0 переполнения знака, но у вас есть короткие (подпись) Int, так что вы (мощь!) Есть подписал переполнение от 32767 -32768. Таким образом, ваше состояние if может потерпеть неудачу.

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

... 
32764 
32765 
32766 
32767 
4294934528 <-- this is -32768 
4294934529 <-- this is -32767, we're going backwards... 
4294934530 
4294934531 
... 
4294967295 <-- and this is -1, and your condition fails, and the loop exits. 

Но нет никакой гарантии, что это всегда будет со всеми компиляторами и платформами!

0

Сколько раз выполняется цикл зависит от принятия решений части рамки и в течение цикла эта часть является середина, где вы поставили ++i и вы правы, когда переполнение происходит значение ++i возвращает 0 и 0 является равное false в C. поэтому цикл завершается.

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

#include<stdio.h> 
int main() 
{ 
    short int i = 0; //(assume short int is 2 bytes) 
    for(i<=5 && i>=-1; ;++i ) 
     printf("%u\n", i); 
    return 0; 
} 
+0

Это все еще вызывает неопределенное поведение ... –

+0

Почему это вызывает неопределенное поведение? Он просто запустит бесконечный цикл 0 в короткий предел int при запуске, а затем из-за переполнения он начнет с отрицательного числа (опять короткий предел INT) до положительного короткого интервала int. –

+1

Потому что '++ i' вызывает переполнение подписей, после чего все ставки удаляются технически. –

0

Вы полагаетесь на ограничение короткого int, чтобы ограничить значение, а не ограничивать ограничение самостоятельно? Это очень плохая практика, поскольку у компиляторов нет правил, касающихся обработки ценностей за пределами их границ. Интеллектуальный компилятор просто выкинул бы ошибку после ее переполнения. Не делай этого.

И зачем вам бесконечный цикл?

+0

Я думаю, что это попытка исследовать границу языка, а не делать что-то полезное. – nhahtdh

0

Ваш оператор условия ++ i, когда это возвращает 0, ваш цикл завершается. i> 0 ничего не делает, и ваш инициализатор цикла for ничего не делает.Ваш для цикла эквивалентен

for(; (++i) != 0;) 
Смежные вопросы