2016-10-01 13 views
6

Odpowiedzi na ostatnie pytanie dotyczące pętli for(;;){} (What does a for (;;) loop do) nie były dla mnie odpowiedzią, więc pomyślałem, że spróbuję nieco uściślić pytanie. W szczególności, nie wiedząc, że pętle bez warunkowania są nieskończonymi pętlami, chciałbym wiedzieć, dlaczego są one nieskończonymi pętlami.Dlaczego pętle (;;) zachowują się jak nieskończone pętle?

W oświadczeniu for (;_;){}, _ jest wyrażeniem warunkowym. Moim pierwszym przypuszczeniem byłoby, że puste wyrażenie może ocenić na 0 lub NULL. Ale jeśli przetestujesz:

for (;;){} 

to nieskończona pętla, jak wszyscy zauważyli.

for (;1;){} 

to nieskończona pętla.

Ale żaden z tych organów pętli wykonać w ogóle:

for (;0;){} 
for (;NULL;){} 

Zatem pusty wyrażenie warunkowe nie wydaje się, aby ocenić albo 0 lub NULL.

Moje pytanie brzmi: czy zachowanie pętli for (;;){} jest artefaktem sposobu, w jaki C ocenia wyrażenia, czy jest to tylko specjalny przypadek zdefiniowany w ramach implementacji, ponieważ ciało pętli, które nigdy nie jest wykonywane, nie jest zbyt użyteczne?

UPDATE: Po przeczytaniu komentarzy i odpowiedzi, zdaję sobie sprawę, że moje pytanie nie było tak jasno sformułowane, jak mogło być. Przypuszczam, że pytanie było dwojakie:

  1. jest zachowanie for(;;){} pętli ściśle wynikiem sposób, że C ocenia wyrażeń w ogóle, czy to zachowanie charakterystyczne dla sposobu, w jaki C ocenia for oświadczenia? Okazuje się, że druga z tych alternatyw ma miejsce, a po dalszej refleksji ma to sens. Zwykle brakujące wyrażenie uruchamia błąd kompilatora. Na przykład while(){} nie będzie się kompilował.

  2. Dlaczego to zachowanie zostało wybrane dla pętli for bez wyrażeń warunkowych? Początkowo sugerowałem, że po prostu nie jest bardzo przydatna pętla for z ciałem, która nigdy nie zostanie wykonana. Ale zdaję sobie sprawę, że jeśli błędnie opuścisz warunkowe z oświadczenia for, zgodnie z zasadami standardu, twój program prawdopodobnie ulegnie awarii w nieskończonej pętli. To może być zaskakujące, ale przynajmniej wiesz, gdzie się rozbił. Ale jeśli alternatywne zachowanie było regułą, twój program pomijałby ciało for, prawdopodobnie prowadząc do jakichś bardzo nieprzyjemnych niespodzianek, które-zna-gdzie. Zatem, stosując zasadę najmniejszego zaskoczenia, zachowanie w nieskończonej pętli jest bardziej pożądane. Jak zauważył @martin, jest to po prostu rozsądna wartość domyślna dla pętli for.

Dziękuję wszystkim za komentarze i odpowiedzi oraz za pomoc w wyjaśnieniu sobie mojego pytania.

+2

Czy możesz wymyślić bardziej opisowy tytuł pytania? Idealnie byłoby, gdyby tytuł pomógł innym osobom w tej samej kwestii dotrzeć do nas w przyszłości. –

+0

Komentarz do targów, @matt - Zmieniłem tytuł. Czy to jest bardziej przydatne? –

+0

"Moim pierwszym przypuszczeniem byłoby, że puste wyrażenie może ocenić wartość" 0 "lub" NULL "- dlaczego? Ani C, ani C++ nie mają pojęcia "puste wyrażenie". Co od razu oznacza, że ​​pusta przestrzeń zamiast warunku "for" wymaga specjalnej obróbki, którą podaje się w specyfikacji zachowania 'for'. – AnT

Odpowiedz

19

Zarówno C jak i C++ gwarantuje to zachowanie.


[C99: 6.8.5.3/1]: Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant.


[C++14: 6.5.3/1]: The for statement

for (for-init-statement conditionopt; expressionopt) statement 

is equivalent to

{ 
    for-init-statement 
    while (condition) { 
     statement 
     expression ; 
    } 
} 

[..]

[C++14: 6.5.3/2]: Either or both of the condition and the expression can be omitted. A missing condition makes the implied while clause equivalent to while(true) .

+0

Fantastyczna odpowiedź, @lightness. Tak więc zachowanie jest zdefiniowane w standardach. –

+0

@DavidBowling: Tak. Ta składnia jest dozwolona i dobrze zdefiniowana, tak jak to zauważyłeś. –

+0

Dziękuję, @lightness. Myślę, że w ten weekend może będę potrzebował zwinąć kopię standardu C99;) –

0

Wyrażenie warunkowe sprawdza jeśli pętla ma być kontynuowany tak, a domyślna funkcja pętli jest .. pętli. Jeśli nie był to specjalny przypadek z pustym testowym wyrażeniem i kontynuował pętlę w tym przypadku, byłby to odwrotny przypadek (jak już zauważyłeś) i przerwanie pętli, co powoduje, że całe oświadczenie for jest mniej potężne, a nawet nadmiarowe.

Stosowana tutaj technika nazywa się rozsądnymi/rozsądnymi wartościami domyślnymi.

+0

Dziękuję za odpowiedź na tę część pytania. Zobacz moją aktualizację oryginalnego pytania. –

+0

Tak. Zajęło mi trochę czasu zrozumienie tego, co widzisz jako wyjątkowego (i to, że twoja obserwacja jest poprawna) i już wtedy wiedziałem, że dostanę awanse, ponieważ nie każdy tym razem to zrobi. ;) –