Skocz do zawartości

Arduino dla początkujących: instrukcje sterujące w C/C++. Część 3: for, break, switch


ethanak

Pomocna odpowiedź

Nie, nie uważam, że enumy są tylko dla switchy, ale są warte wspomnienia przy switchach szczególnie podczas nauki przy krótkich programikach

edit. ta uwaga była ze względu na pytania, które dostawałem od młodzieży, która zaczynała cokolwiek klepać i widzieli, że w switchach potrafi być od taki tekst...

Edytowano przez BananWszyscy
Link do komentarza
Share on other sites

To o czym jeszcze trzeba by było wspomnieć? I co to miałoby wspólnego z tematem? Artykuł miał na celu dokładniejsze wyjaśnienie jak działają instrukcje sterujące, a nie omawianie wszelkich możliwych postaci zapisu intów, a już na pewno nie ma zastąpić kursu Arduino. Być może powinienem na początku zaznaczyć że trzeba to traktować jako dodatek do tego właśnie kursu? 

 

Link do komentarza
Share on other sites

A jednak goto czasami się przydaje, np.

for(i = 0; i < n; i++) {
  //...
  for(j = 0; j < m; j++) {
    while( /*warunek*/ ) {
      if( /*błąd czy jakis inny powód przerwania wszystkich pętli*/ )
        goto wyjscie
      
      //...
    }
    //...
  }
}

wyjscie:
  printf("o nie, trzeba wyjsc")

Wtedy break nie wystarczy, bo masz sporo zagnieżdżonych pętli. Da się to oczywiście rozwiązać dodając jakąś flagę wyjścia sprawdzana w każdej pętli, ale trzeba wtedy dopisywać po każdej pętli sprawdzanie tego warunku. Kod robi się chyba trochę mniej czytelny, niż z wykorzystaniem goto. Widziałem jeszcze na MSDN propozycje wykorzystania goto do obsługi błędów. Kiedy masz sporo wywołań funkcji, które mogą zwrócić błąd, możesz sprawdzać czy się jakiś błąd nie pojawił, i jeśli by się pojawił to skakać w jedno miejsce, gdzie masz cały kod odpowiedzialny za usunięcie zmiennych alokowanych dynamicznie itp. Ogólnie gdzie sprzątasz po sobie. I wtedy w jednym miejscu masz ładnie wszystko porządkowane. A jak by chcieć to zrobić bez goto skończył byś z masą zagnieżdżonych ifów, albo kilkoma miejscami w kodzie, w których sprzątasz po swoim kodzie. 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

15 minut temu, matiut2 napisał:

A jednak goto czasami się przydaje, np.


for(i = 0; i < n; i++) {
  //...
  for(j = 0; j < m; j++) {
    while( /*warunek*/ ) {
      if( /*błąd czy jakis inny powód przerwania wszystkich pętli*/ )
        goto wyjscie
      
      //...
    }
    //...
  }
}

wyjscie:
  printf("o nie, trzeba wyjsc")

Wtedy break nie wystarczy, bo masz sporo zagnieżdżonych pętli. Da się to oczywiście rozwiązać dodając jakąś flagę wyjścia sprawdzana w każdej pętli, ale trzeba wtedy dopisywać po każdej pętli sprawdzanie tego warunku. Kod robi się chyba trochę mniej czytelny, niż z wykorzystaniem goto. Widziałem jeszcze na MSDN propozycje wykorzystania goto do obsługi błędów. Kiedy masz sporo wywołań funkcji, które mogą zwrócić błąd, możesz sprawdzać czy się jakiś błąd nie pojawił, i jeśli by się pojawił to skakać w jedno miejsce, gdzie masz cały kod odpowiedzialny za usunięcie zmiennych alokowanych dynamicznie itp. Ogólnie gdzie sprzątasz po sobie. I wtedy w jednym miejscu masz ładnie wszystko porządkowane. A jak by chcieć to zrobić bez goto skończył byś z masą zagnieżdżonych ifów, albo kilkoma miejscami w kodzie, w których sprzątasz po swoim kodzie. 

To się zwykle rozwiązuje tworząc funkcję w funkcji, która zwraca wartość/wartości do nadrzędnej... goto jest zbędne 😉 

int A()
{
    for(int i = 0; i < n; i++) {
      //...
      for(int j = 0; j < m; j++) {
        while( /*warunek*/ ) {
          if( /*błąd czy jakis inny powód przerwania wszystkich pętli*/ )
            return 0x10;
          //...
        }
        //...
      }
    }
    
    return 0x0;
}

void B()
{
    int result = A();
    if(result == 0x10)
        printf("o nie, trzeba wyjsc")
}


B();

 

Link do komentarza
Share on other sites

@matiut2 dokładnie to (i parę innych zasad) można wyczytać w wytycznych pisania kodu kernela Linuksa 🙂

39 minut temu, H1M4W4R1 napisał:

To się zwykle rozwiązuje tworząc funkcję w funkcji, która zwraca wartość/wartości do nadrzędnej... goto jest zbędne

Tyle że zamiast goto wprowadzasz inny dodatkowy element - a gdzie zasada KISS?

BTW. ciekawe co miałeś na myśli to pisząc, bo na pewno coś czego nie zauważyłem 😉

A teraz ciekawostka: w pewnym języku programowania break jest instrukcją która zwraca wartość, a wartością może być instrukcja. Tam konstrukcja typu:

if warunek then break break;

przerywa dwie pętle.

Zagadka: jaki to język? ( @deshipu proszę nie odpowiadaj, bo wiem że wiesz i popsułbyś zabawę:) )

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.