Możliwe duplikaty:
While vs. Do While
Kiedy należy używać pętli do-while zamiast pętli while?
Od jakiegoś czasu zajmuję się programowaniem (2 lata pracy + 4,5 roku studiów + 1 rok przed college'u) i nigdy nie korzystałem z pętli „do-while” na kursie Wprowadzenie do programowania. Mam coraz większe poczucie, że programuję źle, jeśli nigdy nie napotkam czegoś tak fundamentalnego.
Czy to możliwe, że po prostu nie natknąłem się na właściwe okoliczności?
Jakie są przykłady, w których należałoby użyć czasu do zrobienia zamiast chwili?
(Moja nauka była prawie w całości w C / C ++, a moja praca jest w C #, więc jeśli jest inny język, w którym ma to absolutnie sens, ponieważ do-whiles działa inaczej, te pytania tak naprawdę nie mają zastosowania).
Aby wyjaśnić ... znam różnicę między a while
i a do-while
. Podczas sprawdza warunek wyjścia, a następnie wykonuje zadania. do-while
wykonuje zadania, a następnie sprawdza warunek zakończenia.
Odpowiedzi:
Jeśli zawsze chcesz, aby pętla została wykonana przynajmniej raz. To nie jest powszechne, ale używam go od czasu do czasu. Jednym z przypadków, w którym możesz chcieć go użyć, jest próba uzyskania dostępu do zasobu, który może wymagać ponownej próby, np
do { try to access resource... put up message box with retry option } while (user says retry);
źródło
do-while jest lepsze, jeśli kompilator nie jest kompetentny w optymalizacji. Do-while ma tylko jeden skok warunkowy, w przeciwieństwie do for i while, które mają skok warunkowy i skok bezwarunkowy. W przypadku procesorów, które działają w trybie potokowym i nie przewidują rozgałęzień, może to mieć duży wpływ na wydajność ścisłej pętli.
Ponadto, ponieważ większość kompilatorów jest wystarczająco sprytnych, aby wykonać tę optymalizację, wszystkie pętle znalezione w zdekompilowanym kodzie będą zwykle działały do-while (jeśli dekompilator w ogóle zadaje sobie trud rekonstrukcji pętli z wcześniejszych lokalnych elementów gotowych).
źródło
Użyłem tego w funkcji TryDeleteDirectory. To było coś takiego
do { try { DisableReadOnly(directory); directory.Delete(true); } catch (Exception) { retryDeleteDirectoryCount++; } } while (Directory.Exists(fullPath) && retryDeleteDirectoryCount < 4);
źródło
while
?Funkcja Do while jest przydatna, gdy chcesz wykonać coś przynajmniej raz. Jeśli chodzi o dobry przykład użycia funkcji do while vs. while, powiedzmy, że chcesz wykonać następujące czynności: Kalkulator.
Możesz podejść do tego, używając pętli i sprawdzając po każdym obliczeniu, czy dana osoba chce wyjść z programu. Teraz możesz prawdopodobnie założyć, że po otwarciu programu osoba chce to zrobić przynajmniej raz, więc możesz wykonać następujące czynności:
do { //do calculator logic here //prompt user for continue here } while(cont==true);//cont is short for continue
źródło
continue
to słowo kluczowe; D== true
nie jest potrzebne.cont == true
jeśli cont jest prawdziwe, zwraca prawdę. To całkowicie bezużyteczne.To w pewnym sensie odpowiedź pośrednia, ale to pytanie skłoniło mnie do zastanowienia się nad logiką, która za nim stoi, i pomyślałem, że warto się tym podzielić.
Jak wszyscy powiedzieli,
do ... while
pętli używasz, gdy chcesz przynajmniej raz wykonać body. Ale w jakich okolicznościach chciałbyś to zrobić?Cóż, najbardziej oczywistą klasą sytuacji, o których przychodzi mi do głowy, byłaby sytuacja, w której początkowa („niewzbudzona”) wartość warunku sprawdzenia jest taka sama, jak przy wyjściu . Oznacza to, że musisz raz wykonać treść pętli, aby zaliczyć warunek do wartości nieistniejącej, a następnie wykonać rzeczywiste powtórzenie w oparciu o ten warunek. Ponieważ programiści są tak leniwi, ktoś postanowił zawrzeć to w strukturze kontrolnej.
Na przykład odczyt znaków z portu szeregowego z limitem czasu może mieć postać (w Pythonie):
response_buffer = [] char_read = port.read(1) while char_read: response_buffer.append(char_read) char_read = port.read(1) # When there's nothing to read after 1s, there is no more data response = ''.join(response_buffer)
Uwaga powielania kodu:
char_read = port.read(1)
. Gdyby Python miałdo ... while
pętlę, mógłbym użyć:do: char_read = port.read(1) response_buffer.append(char_read) while char_read
Dodatkowa korzyść dla języków, które tworzą nowy zakres dla pętli:
char_read
nie zanieczyszcza przestrzeni nazw funkcji. Ale pamiętaj również, że istnieje lepszy sposób na zrobienie tego, a jest to użycieNone
wartości Pythona :response_buffer = [] char_read = None while char_read != '': char_read = port.read(1) response_buffer.append(char_read) response = ''.join(response_buffer)
Więc oto sedno mojego punktu: w językach z pustych rodzaju sytuacja
initial_value == exit_value
powstaje znacznie rzadziej, a to może być, dlaczego nie spotykamy go. Nie mówię, że to się nigdy nie zdarza, ponieważ wciąż są chwile, kiedy funkcja wróci,None
aby oznaczyć ważny warunek. Ale w mojej pospiesznej i krótko przemyślanej opinii zdarzyłoby się to znacznie częściej, gdyby używane języki nie pozwalały na wartość, która oznacza: ta zmienna nie została jeszcze zainicjowana.Nie jest to doskonałe rozumowanie: w rzeczywistości, teraz, gdy wartości zerowe są powszechne, po prostu tworzą jeszcze jeden element zbioru prawidłowych wartości, które zmienna może przyjąć. Praktycznie jednak programiści mają sposób na rozróżnienie między zmienną będącą w stanie rozsądnym, który może obejmować stan wyjścia pętli, a stanem niezainicjalizowanym.
źródło
None
,while
wersja poprawnie nie dodaje nic do bufora odpowiedzi, ale twojado
wersja zawsze coś dodaje.read()
nigdy nie powinien wrócićNone
. Jeśli korzystasz z biblioteki, w której tak jest, przesłanka nie ma zastosowania (tj. Wartość wartownika nie znajduje się w zestawie możliwych wartości kontrolnych).''
zamiast tego powinienem był powiedziećNone
. Jakaś wartość, której wynikiem jest fałsz. Podkreśl to, że nie znamread
funkcji Pythona .read()
zwraca''
, nic nie zostanie dodane do ciągu, jest puste.Używałem ich dość często, kiedy byłem w szkole, ale od tamtej pory nie tak bardzo.
Teoretycznie są przydatne, gdy chcesz, aby treść pętli została wykonana raz przed sprawdzeniem warunków zakończenia. Problem polega na tym, że w kilku przypadkach, w których nie chcę najpierw sprawdzić, zazwyczaj chcę, aby kontrola wyjścia znajdowała się na środku ciała pętli, a nie na samym końcu. W takim przypadku wolę używać dobrze znanego
for (;;)
z rozszerzeniemif (condition) exit;
gdzieś w organizmie.W rzeczywistości, jeśli jestem trochę niepewny warunku zakończenia pętli, czasami uważam, że przydatne jest rozpoczęcie pisania pętli jako
for (;;) {}
z instrukcją zakończenia w razie potrzeby, a kiedy skończę, mogę zobaczyć, czy to możliwe. wyczyszczone ”przez przeniesienie inicjalizacji, warunków wyjścia i / lub kodu inkrementacji wewnątrzfor
nawiasów.źródło
for(;;)
z „nieskończoną pętlą”, podczas gdywhile(true)
muszę się zatrzymać i pomyśleć. Być może dlatego, że kodowałem C, zanim pojawił się pliktrue
. Kiedyś mieliśmy tylkoTRUE
makro, a jeśli coś było wadliwe, musiałbym sam przekonać się, że makro nie zostało w0
jakiś sposób przedefiniowane (tak się stało!). Zefor(;;)
nie ma szans na to. Jeśli nalegasz na formę while, prawie wolałbym zobaczyćwhile (1)
. Oczywiście niektórzy mogą się zastanawiać, czy to nie jest litera l ...codeify
tekstem, możesz po prostu wpisać go bezpośrednio w polu komentarza. Widziałem, jak niektórzy ludzie umieszczali hiperłącza, ale to dla mnie zbyt trudne.Sytuacja, w której zawsze trzeba uruchomić fragment kodu raz i, w zależności od wyniku, prawdopodobnie więcej razy. To samo można również uzyskać za pomocą zwykłej
while
pętli.rc = get_something(); while (rc == wrong_stuff) { rc = get_something(); } do { rc = get_something(); } while (rc == wrong_stuff);
źródło
do while
jest jeśli chcesz uruchomić blok kodu przynajmniej raz.while
z drugiej strony nie zawsze będzie działać w zależności od określonych kryteriów.źródło
To takie proste:
warunek wstępny a warunek końcowy
Teraz, gdy znasz sekret ... używaj ich mądrze :)
źródło
Widzę, że odpowiedź na to pytanie jest wystarczająca, ale chciałbym dodać ten bardzo konkretny scenariusz użycia. Możesz zacząć używać do ... while częściej.
do { ... } while (0)
jest często używany dla #defines wieloliniowych. Na przykład:
#define compute_values \ area = pi * r * r; \ volume = area * h
Działa to dobrze w przypadku:
-ale- jest gotcha na:
if (shape == circle) compute_values;
ponieważ rozszerza się to do:
if (shape == circle) area = pi *r * r; volume = area * h;
Jeśli zawiniesz go w pętlę do ... while (0), to poprawnie rozwinie się do pojedynczego bloku:
if (shape == circle) do { area = pi * r * r; volume = area * h; } while (0);
źródło
Dotychczasowe odpowiedzi podsumowują ogólne użycie określenia „do czasu”. Ale OP poprosił o przykład, więc oto jeden: Uzyskaj dane wejściowe użytkownika. Ale dane wejściowe użytkownika mogą być nieprawidłowe - więc pytasz o dane wejściowe, sprawdzaj je, kontynuuj, jeśli są prawidłowe, w przeciwnym razie powtórz.
Z do-while, otrzymujesz dane wejściowe, gdy dane wejściowe są nieprawidłowe. W przypadku zwykłej pętli while otrzymujesz dane wejściowe raz, ale jeśli jest nieprawidłowe, otrzymujesz je wielokrotnie, aż będzie prawidłowe. Nietrudno zauważyć, że ta pierwsza jest krótsza, bardziej elegancka i prostsza w utrzymaniu, jeśli korpus pętli staje się bardziej złożony.
źródło
break
wtedy, gdyby dane wejściowe były poprawne.Użyłem go do czytnika, który czyta tę samą strukturę wiele razy.
using(IDataReader reader = connection.ExecuteReader()) { do { while(reader.Read()) { //Read record } } while(reader.NextResult()); }
źródło
Użyłem
do while
kiedy czytam wartości wskaźnikowych na początku pliku, ale poza tym, nie sądzę, że to nienormalne, że struktura ta nie jest zbyt powszechnie used--do-while
s są bardzo sytuacyjne.-- file -- 5 Joe Bob Jake Sarah Sue -- code -- int MAX; int count = 0; do { MAX = a.readLine(); k[count] = a.readLine(); count++; } while(count <= MAX)
źródło
Oto moja teoria, dlaczego większość ludzi (w tym ja) preferuje pętle while () {} do wykonania {} while (): pętlę while () {} można łatwo dostosować do wykonywania pętli do..while (), podczas gdy jest odwrotnie to nie jest prawda. Pętla while jest w pewnym sensie „bardziej ogólna”. Również programiści lubią łatwe do uchwycenia wzorce. Pętla while mówi na samym początku, jaki jest jej niezmiennik i to jest fajna rzecz.
Oto, co mam na myśli, mówiąc o „bardziej ogólnej” rzeczy. Zrób to ... w trakcie pętli:
do { A; if (condition) INV=false; B; } while(INV);
Przekształcenie tego w pętlę while jest proste:
INV=true; while(INV) { A; if (condition) INV=false; B; }
Teraz bierzemy model pętli while:
while(INV) { A; if (condition) INV=false; B; }
I przekształcić to w pętlę do..while, daje to potworność:
if (INV) { do { A; if (condition) INV=false; B; } while(INV) }
Teraz mamy dwa sprawdzenia na przeciwnych końcach i jeśli niezmienne zmiany, musisz zaktualizować je w dwóch miejscach. W pewnym sensie to ... a jednocześnie jest jak specjalistyczne śrubokręty w skrzynce narzędziowej, których nigdy nie używasz, ponieważ standardowy śrubokręt robi wszystko, czego potrzebujesz.
źródło
Programuję około 12 lat i dopiero 3 miesiące temu spotkałem się z sytuacją, w której użycie do-while było naprawdę wygodne, ponieważ zawsze potrzebna była jedna iteracja przed sprawdzeniem warunku. Więc zgadnij, że twój wielki czas jest przed nami :).
źródło
do
while
było lepsze rozwiązanie bez żalu?Nie mogę sobie wyobrazić, jak długo nie korzystałeś z domeny
do...while
pętli.W tej chwili jest jeden na innym monitorze, aw tym programie jest wiele takich pętli. Wszystkie mają postać:
do { GetProspectiveResult(); } while (!ProspectIsGood());
źródło
Jest to dość powszechna struktura w serwerze / konsumencie:
DOWHILE (no shutdown requested) determine timeout wait for work(timeout) IF (there is work) REPEAT process UNTIL(wait for work(0 timeout) indicates no work) do what is supposed to be done at end of busy period. ENDIF ENDDO
REPEAT UNTIL(cond)
byciado {...} while(!cond)
Czasami oczekiwanie na pracę (0) może być tańsze z punktu widzenia procesora (nawet wyeliminowanie obliczania limitu czasu może być poprawą przy bardzo wysokich wskaźnikach dotarcia). Ponadto istnieje wiele wyników teorii kolejkowania, które sprawiają, że liczba obsługiwana w okresie o dużym natężeniu ruchu jest ważną statystyką. (Zobacz na przykład Kleinrock - tom 1.)
Podobnie:
DOWHILE (no shutdown requested) determine timeout wait for work(timeout) IF (there is work) set throttle REPEAT process UNTIL(--throttle<0 **OR** wait for work(0 timeout) indicates no work) ENDIF check for and do other (perhaps polled) work. ENDDO
gdzie
check for and do other work
umieszczenie w głównej pętli może być niebotycznie drogie lub może jądro, które nie obsługuje wydajnejwaitany(waitcontrol*,n)
operacji typu, lub może sytuacja, w której kolejka z priorytetami może zagłodzić inną pracę, a przepustnica jest używana jako kontrola głodu.Ten rodzaj balansowania może wydawać się hackem, ale może być konieczny. Ślepe użycie pul wątków całkowicie zniweczyłoby korzyści wydajnościowe wynikające z użycia wątku dozorcy z prywatną kolejką dla skomplikowanej struktury danych o wysokiej szybkości aktualizowania, ponieważ użycie puli wątków zamiast wątku opiekuna wymagałoby implementacji bezpiecznej dla wątków.
Naprawdę nie chcę wdawać się w debatę na temat pseudokodu (na przykład, czy żądane zamknięcie powinno być testowane w UNTIL) lub wątków opiekuna kontra pule wątków - ma to po prostu nadać posmak szczególnemu przypadkowi użycia strukturę przepływu sterowania.
źródło
To moja osobista opinia, ale to pytanie prosi o odpowiedź zakorzenioną w doświadczeniu:
Programuję w C od 38 lat i nigdy nie używam pętli
do
/while
w zwykłym kodzie.Jedynym przekonującym zastosowaniem tej konstrukcji są makra, w których można zawijać wiele instrukcji w jedną instrukcję za pośrednictwem pliku
do { multiple statements } while (0)
Widziałem niezliczone przykłady pętli
do
/while
z fałszywym wykrywaniem błędów lub nadmiarowymi wywołaniami funkcji.Moje wyjaśnienie dla tej obserwacji jest takie, że programiści mają tendencję do nieprawidłowego modelowania problemów, gdy myślą w kategoriach
do
/while
pętli. Albo przegapią ważny warunek końcowy, albo przegapią możliwą porażkę warunku początkowego, który przenoszą do końca.Z tych powodów doszedłem do wniosku, że tam
do
while
, gdzie jest pętla / , jest błąd i regularnie wzywam początkujących programistów do pokazania mido
/while
pętli , w której nie mogę znaleźć błędu w pobliżu.Tego typu pętli można łatwo uniknąć: użyj a
for (;;) { ... }
i dodaj niezbędne testy zakończenia, jeśli są one odpowiednie. Dość często potrzeba więcej niż jednego takiego testu.Oto klasyczny przykład:
/* skip the line */ do { c = getc(fp); } while (c != '\n');
To się nie powiedzie, jeśli plik nie kończy się znakiem nowej linii. Trywialnym przykładem takiego pliku jest plik pusty.
Lepsza wersja to:
int c; // another classic bug is to define c as char. while ((c = getc(fp)) != EOF && c != '\n') continue;
Alternatywnie ta wersja ukrywa również
c
zmienną:for (;;) { int c = getc(fp); if (c == EOF || c == '\n') break; }
Spróbuj wyszukać
while (c != '\n');
w dowolnej wyszukiwarce, a znajdziesz błędy takie jak ta (pobrano 24 czerwca 2017 r.):Na ftp://ftp.dante.de/tex-archive/biblio/tib/src/streams.c , function
getword(stream,p,ignore)
, mado
/while
i na pewno wystarczające co najmniej 2 błędy:c
jest zdefiniowany jako achar
iwhile (c!='\n') c=getc(stream);
Wniosek: unikaj
do
/while
zapętlonych i szukaj błędów, gdy je zobaczysz.źródło
while() {}
pętli, ponieważ są one bezpieczniejsze z punktu widzenia wstępnych kontroli, więc zazwyczaj wprawiają Cię w „odstresowanie”, leniwe myślenie o lepszym algorytmie, nakładanie mnóstwa nieoczekiwanego sprawdzania błędów itd. „Brakdo{}while()
użycia” to oznaką złego (bezmózgiego) lub początkującego programisty, produkującego niższą jakość i wolniejszy kod. Więc najpierw zadaję sobie pytanie „Czy jest to przypadek ściśle while () {}?” Jeśli nie - po prostu spróbuję napisać do pętli while, mimo że może to wymagać więcej przemyśleń i dokładności danych wejściowychbreak
lubreturn
instrukcje. Przekształcenie pętlido
/while
wfor(;;)
pętlę będzie bardziej spójne IMHO. Mój ostracyzm wobec tego stwierdzenia jest podobny do mojej odmowy użyciastrncpy()
nawet w rzadkich przypadkach, w których byłoby to właściwe narzędzie: nie pozwól przypadkowym czytelnikom wyobrazić sobie, że te konstrukcje są nieszkodliwe, ponieważ w większości przypadków są źródłem trudnych do znalezienia błędów .while
pętle sprawdzają stan przed pętlą,do...while
pętle sprawdzają stan po pętli. Jest to przydatne, jeśli chcesz oprzeć warunek na efektach ubocznych uruchomionej pętli lub, jak powiedzieli inni plakaty, jeśli chcesz, aby pętla uruchomiła się co najmniej raz.Rozumiem, skąd pochodzisz, ale
do-while
jest to coś, czego najczęściej używam rzadko, a ja nigdy nie używałem siebie. Nie robisz tego źle.Nie robisz tego źle. To tak, jakby powiedzieć, że ktoś robi to źle, ponieważ nigdy nie używał
byte
prymitywu. Po prostu nie jest tak powszechnie używany.źródło
Najczęstszym scenariuszem, na który napotykam, w którym używam pętli
do
/while
, jest mały program konsolowy, który działa w oparciu o pewne dane wejściowe i będzie powtarzany tyle razy, ile chce użytkownik. Oczywiście nie ma sensu, aby program konsoli działał bez czasu; ale poza pierwszym razem to zależy od użytkownika - stąddo
/while
zamiast tylkowhile
.Dzięki temu użytkownik może w razie potrzeby wypróbować kilka różnych wejść.
do { int input = GetInt("Enter any integer"); // Do something with input. } while (GetBool("Go again?"));
Podejrzewam, że programiści używają
do
/while
coraz mniej w dzisiejszych czasach, teraz, gdy praktycznie każdy program pod słońcem ma jakiś rodzaj GUI. Ma to większy sens w przypadku aplikacji konsolowych, ponieważ istnieje potrzeba ciągłego odświeżania danych wyjściowych w celu dostarczania instrukcji lub monitowania użytkownika o nowe informacje. Natomiast w przypadku GUI tekst dostarczający użytkownikowi tych informacji może po prostu znajdować się na formularzu i nigdy nie musi być powtarzany programowo.źródło
Podczas wczytywania plików cały czas używam pętli do-while. Pracuję z wieloma plikami tekstowymi, które zawierają komentarze w nagłówku:
# some comments # some more comments column1 column2 1.234 5.678 9.012 3.456 ... ...
użyję pętli do-while, aby przeczytać wiersz „kolumna1 kolumna2”, aby móc wyszukać interesującą nas kolumnę. Oto pseudokod:
do { line = read_line(); } while ( line[0] == '#'); /* parse line */
Następnie zrobię pętlę while, aby przeczytać resztę pliku.
źródło
if (line[0]=='#') continue;
zaraz poread_line
wywołaniu w głównej pętli while ...Będąc prymusem programistą, wiele moich szkolnych projektów programistycznych wykorzystywało interakcje oparte na menu tekstowym. Praktycznie wszyscy używali czegoś podobnego do następującej logiki dla głównej procedury:
do display options get choice perform action appropriate to choice while choice is something other than exit
Od czasów szkolnych stwierdziłem, że częściej używam pętli while.
źródło
Jedną z aplikacji, które widziałem, jest Oracle, kiedy patrzymy na zestawy wyników.
Gdy już masz zestaw wyników, najpierw pobierasz z niego (wykonaj) i od tego momentu .. sprawdź, czy pobieranie zwróci element, czy nie (gdy element został znaleziony ..). To samo może mieć zastosowanie do każdego innego " fetch-like ”.
źródło
Użyłem go w funkcji, która zwróciła następną pozycję znaku w ciągu utf-8:
char *next_utf8_character(const char *txt) { if (!txt || *txt == '\0') return txt; do { txt++; } while (((signed char) *txt) < 0 && (((unsigned char) *txt) & 0xc0) == 0xc0) return (char *)txt; }
Zauważ, że ta funkcja jest napisana z pamięci i nie jest testowana. Chodzi o to, że i tak musisz zrobić pierwszy krok i musisz to zrobić, zanim będziesz mógł ocenić stan.
źródło
*(unsigned char *)txt-0x80U<0x40
.Dowolny rodzaj danych wejściowych konsoli działa dobrze z do-while, ponieważ pytasz za pierwszym razem i ponownie pytasz, gdy weryfikacja danych wejściowych nie powiedzie się.
źródło
Mimo że odpowiedzi jest tutaj wiele, to moja opinia. Wszystko sprowadza się do optymalizacji. Pokażę dwa przykłady, w których jeden jest szybszy niż drugi.
Przypadek 1:
while
string fileName = string.Empty, fullPath = string.Empty; while (string.IsNullOrEmpty(fileName) || File.Exists(fullPath)) { fileName = Guid.NewGuid().ToString() + fileExtension; fullPath = Path.Combine(uploadDirectory, fileName); }
Przypadek 2:
do while
string fileName = string.Empty, fullPath = string.Empty; do { fileName = Guid.NewGuid().ToString() + fileExtension; fullPath = Path.Combine(uploadDirectory, fileName); } while (File.Exists(fullPath));
Więc tam dwóch zrobi dokładnie to samo. Ale jest jedna fundamentalna różnica, a mianowicie, że chwila wymaga dodatkowego oświadczenia, aby wprowadzić chwilę. Co jest brzydkie, ponieważ powiedzmy, że każdy możliwy scenariusz tej
Guid
klasy został już przyjęty z wyjątkiem jednego wariantu. Oznacza to, że będę musiał5,316,911,983,139,663,491,615,228,241,121,400,000
powtarzać czas. Za każdym razem, gdy dotrę do końca mojego oświadczenia while, będę musiałstring.IsNullOrEmpty(fileName)
sprawdzić. Zajmie to trochę, mały ułamek pracy procesora. Ale zrób to bardzo małe zadanie razy możliwe kombinacjeGuid
klasy i mówimy o godzinach, dniach, miesiącach lub dodatkowym czasie?Oczywiście jest to skrajny przykład, ponieważ prawdopodobnie nie zobaczyłbyś tego w produkcji. Ale jeśli pomyślimy o algorytmie YouTube, jest bardzo prawdopodobne, że napotkaliby generację identyfikatora, w którym niektóre identyfikatory zostały już pobrane. Sprowadza się więc do dużych projektów i optymalizacji.
źródło
Lubię je rozumieć jako:
while
-> „powtarzaj do”,do ... while
-> „powtarzaj, jeśli”.źródło
Natknąłem się na to, szukając właściwej pętli do wykorzystania w sytuacji, w której się znalazłem. Wierzę, że to w pełni zaspokoi typową sytuację, w której pętla do .. while jest lepszą implementacją niż pętla while (język C #, ponieważ stwierdziłeś, że jest to Twój podstawowy element do pracy).
Generuję listę ciągów na podstawie wyników zapytania SQL. Obiekt zwracany przez moje zapytanie to SQLDataReader. Ten obiekt ma funkcję o nazwie Read (), która przesuwa obiekt do następnego wiersza danych i zwraca wartość true, jeśli był inny wiersz. Zwróci false, jeśli nie ma innego wiersza.
Korzystając z tych informacji, chcę zwrócić każdy wiersz do listy, a następnie zatrzymać się, gdy nie ma więcej danych do zwrócenia. Pętla Do ... While działa najlepiej w tej sytuacji, ponieważ zapewnia, że dodanie pozycji do listy nastąpi PRZED sprawdzeniem, czy jest inny wiersz. Powodem, dla którego należy to zrobić PRZED sprawdzeniem while (warunek) jest to, że gdy sprawdza, to również się rozwija. Użycie pętli while w tej sytuacji spowodowałoby pominięcie pierwszego wiersza ze względu na charakter tej konkretnej funkcji.
W skrócie:
To nie zadziała w mojej sytuacji.
//This will skip the first row because Read() returns true after advancing. while (_read.NextResult()) { list.Add(_read.GetValue(0).ToString()); } return list;
To będzie.
//This will make sure the currently read row is added before advancing. do { list.Add(_read.GetValue(0).ToString()); } while (_read.NextResult()); return list;
źródło
Read()
i powinien być pętlą while, ponieważ pierwszeRead()
wywołanie uzyskuje dostęp do pierwszego wiersza. Zewnętrzny wywołujeNextResult()
i powinien być do czasu, ponieważ pierwszy wynikowy zestaw danych jest aktywny przed pierwszymNextResult()
wywołaniem. Fragmenty kodu nie mają większego sensu, zwłaszcza, że komentarze nie pasują do kodu i są błędne.Console.WriteLine("hoeveel keer moet je de zin schrijven?"); int aantal = Convert.ToInt32(Console.ReadLine()); int counter = 0; while ( counter <= aantal) { Console.WriteLine("Ik mag geen stiften gooien"); counter = counter + 1;
źródło