Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

C - Wyjście z pętli w dowolnym momencie

bom109 25 Lut 2014 21:37 2517 25
  • #1 25 Lut 2014 21:37
    bom109
    Poziom 9  

    Witam. Mam problem ponieważ chcę zatrzymać pętlę w dowolnym momencie poprzez wciśnięcie przycisku na pilocie. Dokładnie chodzi mi o: case 0xFF10EF i pętle while. Próbowałem z if na wszelkie sposoby oraz z for w której był if jednak to też nie pomogło. Ma ktoś jakiś pomysł?
    Z góry dzięki.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 25
  • #3 25 Lut 2014 22:19
    bom109
    Poziom 9  

    Niestety to nie działa i jak by pomyśleć to wg. mnie nie ma prawa działać ponieważ pętla przejdzie tylko wtedy gdy idealnie w odpowiednim momencie wcisnę przycisk.

    0
  • #4 25 Lut 2014 22:24
    tadzik85
    Poziom 38  

    Weź się naucz kod formatować jakoś. Tego czytać się nie da.

    0
  • #5 26 Lut 2014 01:48
    McMonster
    Poziom 32  

    Odpowiedzią są najprawdopodobniej przerwania.

    0
  • #6 26 Lut 2014 03:03
    rexina
    Poziom 17  

    Pomijam czytelność kodu. Rozumiem że chcesz wyjść z funkcji loop()? (czy może z pętli while która wykona się w nieskończoność - zauważ że inkrementujesz i poza pętlą?)
    Jeśli chcesz wyjść z pętli to po prostu return;, a jeśli z while'a/for'a to break; - przerywa najbardziej zagnieżdżoną pętlę w której znajduje się ta instrukcja.

    0
  • #7 26 Lut 2014 11:01
    mi14chal
    Poziom 28  

    rexina napisał:
    Jeśli chcesz wyjść z pętli to po prostu return;.


    Return służy do wychodzenia z funkcji, a nie z pętli :)

    0
  • #8 26 Lut 2014 17:11
    rexina
    Poziom 17  

    Przejęzyczyłem się. Chodziło mi o wyjście z funkcji loop() - czyli przerwanie w szczególności wywoływania tej pętli.

    0
  • #9 26 Lut 2014 22:44
    Krzysztof Gustaw
    Poziom 23  

    Witam!
    W przypadku opuszczania kilku pętli naraz (być może w połączeniu z instrukcją switch) najlepiej użyć "bezgranicznie nadużywalnej" instrukcji goto. Jest to jeden z przypadków jej użycia (opisany w kultowej książce "JĘZYK C" B.Kerningham D.Ritchie)
    P.S.
    Oczywiście, Kol. Rexina ma rację co do zmiennej i. Jest poza pętlą while.

    0
  • #10 27 Lut 2014 00:25
    mi14chal
    Poziom 28  

    Goto się nie używa. Są lepsze i ładniejsze sposoby na zrobienie tego.

    0
  • #11 27 Lut 2014 13:10
    Eagle
    Poziom 23  

    mi14chal napisał:
    Goto się nie używa. Są lepsze i ładniejsze sposoby na zrobienie tego.


    Kod: c
    Zaloguj się, aby zobaczyć kod



    Czekam na propozycję jak ładniej z zachowaniem logiki, czytelności i bez mnożenia zmiennych (w których będziesz trzymał tylko flagę "wyjść" , "nie wyjść") oraz dodawania dodatkowych "if", chcesz wybrnąć z takiego przypadku.

    Gdyby goto się nie używało, nie byłoby jej - takie to proste. A nawet znajdziesz goto w najnowszym C++ 11. Co nie zmienia faktu, że w swoich programach może użyłem raz goto a trochę tych programów było.

    0
  • #12 27 Lut 2014 17:59
    mi14chal
    Poziom 28  

    No akurat tutaj switch się nie nadaje do tego co chcesz zrobić.

    0
  • #13 27 Lut 2014 20:57
    Eagle
    Poziom 23  

    A co chcę zrobić, bo przykład z zagnieżdżonymi switch'ami w pętli jest jak najbardziej prawidłowy, w/g ciebie ładniej by wyglądała seria "if - else". Pytanie dotyczyło jak z tego wyjść bez goto, bez pogorszenia czytelności. Odpowiedź brzmi - w tym przypadku tylko przez goto.

    0
  • #14 27 Lut 2014 21:54
    mi14chal
    Poziom 28  

    No to skoro używasz zagnieżdżonych switchy w dodatku jeszcze goto chcesz używać to znaczy, że z kodem jest bardzo źle. Po za tym nie można podchodzić do programowania w ten sposób, że to muszę zrobić na switchach bo tak, bo jak widać autor zrobił właśnie w ten sposób i potem się pojawiają problemy jak wyjść z pętli. No i można zrobić to na if i tam dać po prostu break, albo coś w stylu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wszystko ma swoje plusy i minusy i trza też pomyśleć co kiedy stosować, a nie zasada że ja zawsze stosuje switche i koniec bo to bezsens.

    0
  • #15 28 Lut 2014 00:00
    Krzysztof Gustaw
    Poziom 23  

    Do Kol. Eagle
    Przyjrzyj się kodowi źródłowego jądra LINIXA. Przecież tam często i gęsto stosuje się goto! Powód: ta instrukcja jest bardzo szybka!
    I przede wszystkim - zdrowy rozsądek... Odwracać i badać warunki... Ileż to czasu potrzeba...
    P.S.
    Dijkstra pewnie przewraca się w grobie...

    0
  • #16 28 Lut 2014 11:32
    mi14chal
    Poziom 28  

    Krzysztof Gustaw napisał:
    Przyjrzyj się kodowi źródłowego jądra LINIXA. Przecież tam często i gęsto stosuje się goto! Powód: ta instrukcja jest bardzo szybka!


    Tak to prawda tam się stosuje goto, ale z tego powodu żeby skoczyć do kodu z obsługą błędu i w sumie to jedyny sens użycia goto. Tak przynajmniej było kiedyś, może coś się zmieniło.

    0
  • #17 28 Lut 2014 12:22
    dondu
    Moderator Mikrokontrolery Projektowanie

    Odnośnie GOTO i początkującego lub nawet zaawansowanego programisty: http://mikrokontrolery.blogspot.com/2011/02/instrukcja-goto.html

    ... pętlę while przerywasz za pomocą break: http://mikrokontrolery.blogspot.com/2011/02/petla-while.html

    ... to uwagi tak dla porządku, bo autor tematu chyba już swój problem rozwiązał, gdyż dyskusję skończył ponad 2 dni temu :)

    0
  • #18 28 Lut 2014 18:33
    MrKiel
    Poziom 6  

    Cytat:
    Czekam na propozycję jak ładniej z zachowaniem logiki, czytelności i bez mnożenia zmiennych (w których będziesz trzymał tylko flagę "wyjść" , "nie wyjść") oraz dodawania dodatkowych "if", chcesz wybrnąć z takiego przypadku.


    x = 0;
    continue;

    "goto" nie jest do niczego potrzebne.

    0
  • #19 28 Lut 2014 19:10
    mi14chal
    Poziom 28  

    Pytanie jest o wyjście z pętli, a continue do tego nie służy, tylko do czego innego.

    0
  • #20 28 Lut 2014 21:06
    MrKiel
    Poziom 6  

    mi14chal napisał:
    Pytanie jest o wyjście z pętli, a continue do tego nie służy, tylko do czego innego.

    Wybacz, ale w tym przypadku nie masz racji.
    Słowo kluczowe continue wymusza kolejny obieg pętli - w tym przypadku pętli while. Blok instrukcji pętli while wykonywany jest, o ile jej warunek nie jest zerem. Wyzerowanie warunku sterującego pętlą while oraz wymuszenie jej następnego obiegu, czyli zaproponowana przeze mnie sekwencja instrukcji powoduje opuszczenie pętli. Co więcej taka metoda jest o wiele lepsza od pojedynczej instrukcji goto. Już tłumaczę dlaczego.

    Załóżmy, że analizujesz poniższy kod:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Załóżmy, że blok instrukcji wewnątrz while jest długi i skomplikowany, co więcej nie został napisany przez Ciebie. Brakuje w nim komentarzy, a nazwy zmiennych pochodzą z języka hindu. Innymi słowy nie masz czasu/możliwości/powodu do analizy zawartości bloku instrukcji while. Twoim zadaniem jest przeanalizowanie kilku kolejnych linijek po pętli while. Logika podpowiada, że wyjście z tej pętli zostało spowodowane poprzez wyzerowanie jej warunku. Użycie pojedynczego goto, nie zeruje warunku, zaburza tą logikę i może być (a prędzej czy później będzie!) potencjalnym powodem poważnego błędu.

    Kolega dondu zaproponował użycie break, co w przypadku tak złośliwie zagnieżdżonych while/switch nie zadziała, ale jest standardowym sposobem na opuszczenie każdej pętli.

    EDIT: Faktycznie, chyba niezbyt fortunnie się wyraziłem w poprzednim wpisie, stąd i pewnie to nieporozumienie. Spróbuję więc jeszcze raz: najlepszym sposobem na opuszczenie każdej nawet najbardziej zagmatwanej pętli jest ustawienie wartości logicznej 0 dla warunku jej wejścia i wymuszenie kolejnego obiegu.

    0
  • #21 28 Lut 2014 23:11
    mi14chal
    Poziom 28  

    MrKiel napisał:
    Słowo kluczowe continue wymusza kolejny obieg pętli - w tym przypadku pętli while.


    Zgoda.

    MrKiel napisał:
    Blok instrukcji pętli while wykonywany jest, o ile jej warunek nie jest zerem. Wyzerowanie warunku sterującego pętlą while oraz wymuszenie jej następnego obiegu, czyli zaproponowana przeze mnie sekwencja instrukcji powoduje opuszczenie pętli. Co więcej taka metoda jest o wiele lepsza od pojedyńczej instrukcji goto.


    Zgoda, ale pod warunkiem, że ustawisz zmienną od której jest zależny przebieg. Po za tym continue nie zawsze jest w takiej pętli potrzebne. Załóżmy przypadek, że rzadko będziemy opuszczać pętle czyli najlepiej zrobić tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wtedy nie potrzebujemy żadnego continue.

    MrKiel napisał:

    Kolega dondu zaproponował użycie break, co w przypadku tak złośliwie zagnieżdżonych while/switch nie zadziała, ale jest standardowym sposobem na opuszczenie każdej pętli.


    No tak break opuszcza tę pętlę w której był wywołany. Ale skoro w kodzie jest tyle zagnieżdżonych pętli to nie świadczy to o niczym dobrym i wtedy najlepiej zastanowić się nad zmianą kodu tej funkcji w której to występuje.

    MrKiel napisał:

    EDIT: Faktycznie, chyba niezbyt fortunnie się wyraziłem w poprzednim wpisie, stąd i pewnie to nieporozumienie. Spróbuję więc jeszcze raz : najlepszym sposobem na opuszczenie każdej nawet najbardziej zagmatwanej pętli jest ustawienie wartości logicznej 0 dla warunku jej wejścia i wymuszenie kolejnego obiegu.


    Nie ma czegoś jak najlepszy sposób. Każdy sposób ma swoje wady i zalety i trza wiedzieć kiedy dane rozwiązanie stosować. W jednej sytuacji może być to break w innej twój przykład i w innym jeszcze nawet goto.

    0
  • #22 01 Mar 2014 09:47
    MrKiel
    Poziom 6  

    mi14chal napisał:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Wtedy nie potrzebujemy żadnego continue.

    To, że w kodzie nie występuje słowo kluczowe continue, wcale nie oznacza, że go tam nie ma. Zdeasembluj to sobie i przeanalizuj.

    mi14chal napisał:
    Nie ma czegoś jak najlepszy sposób. Każdy sposób ma swoje wady i zalety i trza wiedzieć kiedy dane rozwiązanie stosować. W jednej sytuacji może być to break w innej twój przykład i w innym jeszcze nawet goto.

    Niektórzy mądrzy ludzie (patrz prace Edsgera Dijkstry i Niklausa Wirtha) w ogóle nie zalecają opuszczania pętli inaczej niż poprzez spełnienie warunku wyjścia. Poza tym, nie wiem czy wiesz, ale takie dyskusje toczono w latach 50tych i doprowadziło to do rozwoju programowania strukturalnego. Nie wydaje mi się, żebyśmy mogli cokolwiek więcej wnieść do tematu.

    0
  • #23 01 Mar 2014 11:12
    mi14chal
    Poziom 28  

    MrKiel napisał:

    To, że w kodzie nie występuje słowo kluczowe continue, wcale nie oznacza, że go tam nie ma. Zdeasembluj to sobie i przeanalizuj.


    W asm nie ma czegoś takiego jak instrukcja continue.

    0
  • #24 01 Mar 2014 13:43
    LordBlick
    VIP Zasłużony dla elektroda

    Instrukcja continue jest tłumaczona do skoku na początek testowania warunku pętli. Natomiast instrukcja break wydawałaby się tu bardziej stosowna. gdyż jest tłumaczona do skoku do następnej instrukcji występującej po pętli.
    P.S. Proszę o bardziej wyrozumiały dla siebie ton dyskusji, nikt nie jest alfą i omegą...

    0
  • #25 05 Mar 2014 17:32
    bom109
    Poziom 9  

    Dziękuje za zainteresowanie tematem, ale coś mam źle jednak nie jestem pewien co oto mój kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Poprawiłem pętlę i wstawiłem if jednak chyba coś miejsca pomyliłem ale nie jestem pewien gdzie....

    0
  • #26 05 Mar 2014 21:27
    mi14chal
    Poziom 28  

    Może tak sformatuj kod żeby choć dało się to czytać bo teraz jest tragedia.

    0