2010-11-08 8 views
24

Czy możemy umieścić średnik jak while(condition); w C Programming? Jeśli numer while(condition); jest ważny, co to znaczy?Czy kod "while (condition);" ważne i co to znaczy?

+3

Jaki jest stan? –

+4

Tak, niestety, jak dowiedziałem się po kilku straconych godzinach w mojej pierwszej klasie programistycznej. – Chance

+0

Warunek jest nieistotny, wszystkie z nich mają wartość "prawda" lub "fałsz". Oczywiście, można to zrobić w warunkach opisanych poniżej, ale wydaje się, że to pytanie dotyczy głównie składni i/lub zachowania w odniesieniu do pętli. – Chance

Odpowiedz

2

To tylko pusta pętla. Pomoże ci, jeśli wyjaśnisz, jaki jest warunek.

3

podczas gdy() jest pętlą. Prawdopodobnie szukasz pętli "do-while". Pętle do-while działają w tym formacie:

do 
{ 
    // Your process 
    // When something goes wrong or you wish to terminate the loop, set condition to 0 or false 
} while(condition); 

Ten, który wymieniono powyżej, jest jednak pustą pętlą.

podczas gdy pętle() działają prawie tak samo; po prostu nie ma części "do".

Powodzenia!

4

Tak, zgadza się. Zapętli warunek, dopóki nie będzie fałszywy.

while (condition()); 
50
while (condition); 

jest taka sama jak

while (condition) 
{ 
} 

Może być używany do pętli oczekiwania, np:

while (!isLightGreen()); // waits until isLightGreen() returns true 
go(); 
+42

Należy zauważyć, że spowoduje to ciągłe wykonywanie pętli i sprawdzanie warunku, więc proces/wątek faktycznie nie czeka, ale cały czas korzysta z czasu procesora. – TeaDrivenDev

+5

@GCATNM: prawda, ale czasami (np. Aplikacje kontrolerów oczekujące na sygnał) nie ma nic innego, jak tylko czekać. Jeśli nie jest to pożądane zachowanie, korpus pętli powinien zezwalać na przełączanie wątków/zadań (na przykład z wykorzystaniem trybu uśpienia) lub używać innego mechanizmu do oczekiwania (na przykład funkcji oddzwaniania, przerwań); ale to nie było pytanie ... – Curd

+20

To się nazywa [Spinlock] (http: //en.wikipedia.org/wiki/Spinlock) – Brian

1

Jeśli ocena stanu nie modyfikuje wartość, która wpływa na sam stan, while(condition); jest pustą nieskończoną pętlą, co oznacza, że ​​nigdy się nie zakończy (i nigdy nie zrobi niczego poza zużycie czasu procesora).

+4

Chyba, że ​​czekasz na coś z innego wątku lub rejestru, aby się zmienić (lub coś podobnego). Myślę, że nadto uogólniłeś to. –

+2

Dotyczy to programu z pojedynczym gwintem, ale wartość warunku może zostać zmieniona przez inne wątki. – Francesco

+2

Jeśli warunek jest fałszywy, nie będzie w ogóle pętli. – GreenMatt

10

Ponieważ stan może rzeczywiście mieć skutki uboczne, taki konstrukt jest dozwolony. Rozważmy następujący:

while (*p && *p++ != ' '); 

Byłoby to przesunąć wskaźnik p do pierwszego znaku, który jest przestrzeń.

Możesz nawet użyć operatora przecinek mieć zwykłe oświadczenia wewnątrz warunek:

while (do_something(), do_something_else(), i < n); 

Ponieważ oświadczenia związane z operatorem przecinkami ocenić na skrajnej prawej oświadczenia, w tym przypadku i < n, powyższe jest identyczna:

do { 
    do_something(); 
    do_something_else(); 
} while (i < n); 
5

Będzie sprawdzać warunek, dopóki nie będzie fałszywy. To pętla bez ciała.

Programiści często spację przed średnikiem, tj

while(condition) ; 

lub puste szelki:

while(condition) {} 

pokazać pusty korpus jest zamierzone i nie tylko literówka. Jeśli czytasz jakiś istniejący kod źródłowy i zastanawiasz się, dlaczego jest tam pusta pętla, powinieneś przeczytać także kilka następnych linii, aby zobaczyć, czy średnik rzeczywiście powinien tam być, czy nie (np. Kilka następnych linii wygląda jak ciało pętla czy nie?).

27

Oznacza to, że treść pętli jest pusta. Zazwyczaj ten wzór jest używany, gdy sam warunek działa.

Na przykład ta pętla może skopiować bajtów w stanie:

while ('\0' != (*pt++ = *ps++)) 
      ; 

Jeśli używasz średnik, że to dobry pomysł, aby umieścić go w osobnej linii tak, że wygląda mniej jak pomyłkę . Osobiście zwykle używam pustych nawiasów klamrowych - {}, a czasami komentarza, że ​​pusty blok jest zamierzony.

Edit:

W drugim komentarzu, Tom Anderson zauważa poprawę w stosunku lone średnikiem. Google's C++ style guide zaleca albo to, albo {}.

while ('\0' != (*pt++ = *ps++)) 
      continue; 
+8

+1 dla wyjaśnienia, że ​​jest to przydatne, gdy warunek pętli ma efekt uboczny. -100000 za umieszczenie średnika w osobnej linii! Okropny! FWIW, na stronie comp.lang.java.programmer/comp.lang.c znajduje się dobry crosssposted flamewar o tym, jak zaprojektować ten konstrukt, co może być interesujące. –

+8

'while (warunek) kontynuuj;' (z podziałem wiersza przed kontynuacją i/lub nawiasy klamrowe, jak wolisz) zostało zasugerowane jako czytelna i rozsądnie nieskontrolowana forma. –

+2

Jak już wspomniałem, używam nawiasów klamrowych zamiast średnika. K & R użył średnika w osobnej linii. Wzór "kontynuuj" wydaje się być lepszym rozwiązaniem. Nie uważam, że stopy flamandru na drobnym materiale są wartościowe. –

10

Tak, można. Oznacza to tylko, że pętla while będzie pętla aż do momentu, gdy condition będzie fałszywa. Na przykład:

#include<stdio.h> 

int x = 10; 
int func() 
{ 
    printf("%d\n", x); 
    return --x; 
} 

int main() 
{ 
    while(func()); 
    return 0; 
} 

Ale generalnie ludzie tego nie robią, ponieważ logiczne byłoby umieszczenie logiki w ciele pętli.

Edit:

Istnieje kilka przykładów tego w użyciu, na przykład, kopiowanie NUL łańcuch:

char dest[256]; 
char *src = "abcdefghijklmnopqrstuvwxyz"; 
while(*(dest++) = *(src++)); 
+2

+1 dla przykładu –

+1

Chociaż może to być przykład pustej pętli ciała, jest to również przykład źle zaprojektowanego kodu (stąd trochę mniej użyteczne IMHO). –

+0

@ Lee-Man - Dokładnie, nawet zwracam uwagę, że to nie jest dobry pomysł, logika należy do ciała pętli. Mój drugi przykład jest trochę lepszy, choćby dlatego, że jest to dość powszechny wzorzec i większość programistów C natychmiast go rozpozna. –

3

Oznacza to, że zaglądać stan aż ją oceniać na fałszywej

3

kluczem do zrozumienia jest to, że składnia pętli while w „C” jest następujący:

while (condition) statement 

Gdzie oświadczenie może być dowolny prawidłowy "C" oświadczenie. Poniżej znajdują się wszystkie ważne "C" oświadczenia:

{ statements } // a block statement that can group other statements 

statement; // a single statement terminated by a ; 

; // a null statement terminated by a ; 

Więc przez regułom pętli while The oświadczenie część (null oświadczenie w przykładzie) wykona (zrobić nic) tak długo, jako stan jest prawda. Jest to użyteczne, ponieważ odpowiada oczekiwaniom, aż stan zmieni się na fałszywy. Nie jest to dobry sposób na czekanie, ale mimo to użyteczny. Możesz użyć tej konstrukcji, na przykład, jeśli chcesz poczekać na inny wątek (lub procedurę obsługi sygnału), aby ustawić zmienną na pewną wartość przed przejściem do przodu.

1

To jest absolutnie poprawne. oznacza to brak robienia niczego w pętli, po prostu odpytywanie warunku.I to jest powszechne w kodach systemów wbudowanych.

-1

Kolejny zwyczaj nie opisane tutaj:

do 
{ 
    if(out_of_memory) 
    break; 

    if(file_does_not_exist) 
    break; 

    return ok; 

} while(0); 

return error; 

Pozwala to uniknąć wielu połączeń zwrotnych lub goto oświadczenia.

+1

Uważam to za anty-wzór. Na litość boską, po prostu użyj zwrotu, lub nawet goto, gdzie jest to lepsze skonstruowanie. Nie pisz kodu z maskaradą goto jako zorganizowaną. –

1

jej tylko pętla natomiast bez ciała wykonawczego

while(condition); 

jest taka sama jak

while(condition) 
{ 
    } 
+0

Mamy standard kodowania w pracy, który zawsze wymaga od nas używania nawiasów klamrowych nawet dla prostych instrukcji if/while/for. To może być dobry powód, dla którego; drugie zdanie jest o wiele jaśniejsze. – Chance

3

Zawsze piszę to jako:

while (condition()) 
    continue; 

Tak, że to oczywiste, że to nie było pomyłka. Jak powiedzieli inni, ma to sens tylko wtedy, gdy condition() ma efekty uboczne.

+0

warunek bez efektów ubocznych ma również sens, jeśli sprawdza zmienną zmienną, gdy tylko czeka na zdarzenie asynchroniczne. – Vovanium

2

Kod while(condition); jest całkowicie prawidłowym kodem, chociaż jego użycie jest znikome. Domyślam się, że condition jest zmienną, a nie funkcją — inne tutaj omawiają funkcjonalność condition.

Jednym z zastosowań while(condition); może być blokowanie podczas czekania na signal np. SIGHUP, gdzie moduł obsługi sygnału zmienia zmienną condition. Jednak zazwyczaj nie jest to najlepszy sposób oczekiwania na sygnał. Zwykle używa się w pętli sleep, tj. while(condition) { sleep(1); }.

Brak jakiegokolwiek numeru sleep oznacza, że ​​pętla będzie nieprzerwanie przetwarzana w międzyczasie i prawdopodobnie będzie trwać cykle przetwarzania. O ile proces nie ma zarządzanych zasobów (a nawet tam ...), myślę, że jest to odpowiednie tylko wtedy, gdy pętla musi zostać przerwana w odstępie mniejszym niż szczegółowość dostępnego polecenia sleep (tzn. Sen jest granulowany przez drugi, ale potrzebujesz kodu po wyglądzie wykonanym z sekundowym czasem odpowiedzi). Mówiąc w ten sposób, rura lub gniazdo blokujące może być lepsze niż sygnały, ale nie mam żadnych danych emperycznych, aby to zepsuć, i podejrzewam, że wydajność może się znacznie różnić w zależności od platformy.

Jeden mógłby mieć condition zmodyfikowany przez równoległym wątku tego samego procesu, ale ja myślę, że trzeba wolą to zrobić w drodze mutex lub semafora (tj condition konieczne może być czymś więcej niż zwykłą zmienną).

Mam nadzieję, że to pomocne, a przynajmniej jedzenie do przemyślenia!