logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Instrukcja Switch w [C] działająca na przedziałach

Fredy 10 Maj 2011 17:19 4071 17
  • #1 9492111
    Fredy
    Poziom 27  
    Witam;

    W bascomie jest instrukcja wyboru Select, która jest bardzo uniwersalna. Można wybierać punktowo, ale można też robić selekcję w przedaiałach.
    Przykładowo mamy taki kod:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Pisząc w C mamy też podobną instrukcję switch .Tylko że w tej funkcji nie można wpisywać przedziałów.
    Jak sobie z tym poradzić w sposób sensowny, bo stosowanie dodatkowych ifów jest według mnie słabym rozwiązaniem.
  • #2 9492161
    kult
    Poziom 16  
    Fredy napisał:
    stosowanie dodatkowych ifów jest według mnie słabym rozwiązaniem.

    Dlaczego? Porownaj asm ze switcha bascoma z gcc.
  • #4 9492212
    Fredy
    Poziom 27  
    No dobra troche źle zadałem pytanie. Załóżmy że mam pomiar z ADC. Wynik mamy w zmiennej pomiar.

    Zmienna pomiar osiąga wartości od 0 do 1023.

    Chcę przykładowo aby dla napięć od 0 do 500 program wykonał funckję pierwszą, dla zakresu od 51 do 1000 inną a powyżej 1000 jeszcze inną.
    Jak zrobić to najbardziej elegancko wykorzystując Switcha ?
    Nie chodzi mi o rozwiązanie ifami, chodzi mi o switcha bo w moim programie mam bardzo dużo różnych zakresów i zastosowanie ciągnącego się ifa jest mocno bałaganiarskie.
    Chciałoby się aby była możliwość tak jak w Bascomie zrobić wybór od do a nie tylko punktowo.
  • #5 9492213
    Andrzej__S
    Poziom 28  
    Zdaje się, że gcc oferuje rozszerzenie obsługujące zakresy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #6 9492235
    Fredy
    Poziom 27  
    ANdrzej S - ten kod niestety Codevision nie łyka.
    Jesteś pewien że GCC go przyjmie?
  • #7 9492242
    kult
    Poziom 16  
    Fredy napisał:

    Chcę przykładowo aby dla napięć od 0 do 500 program wykonał funckję pierwszą, dla zakresu od 51 do 1000 inną

    to którą ma wykonać dla np 200?
  • Pomocny post
    #8 9492251
    Andrzej__S
    Poziom 28  
    Nie napisałeś jakiego kompilatora używasz, dlatego zaznaczyłem, że to rozszerzenie gcc. U mnie działa :)

    EDIT:
    ... przy czym, jak słusznie zauważył mój przedmówca, zakresy nie mogą się na siebie nakładać :(
    No i ja nie operuję na tak dużych zakresach, więc nie wiem jak będzie z wydajnością takiego kodu. Być może w Twoim przypadku bardziej optymalne będzie użycie if .. else.

    Range extension
  • #9 9492611
    drzasiek
    Specjalista CNC
    Witam. A w jakim sensie switch jest mniej bałaganiarski od if?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Czemu takie rozwiązanie jest złe?
  • #10 9492775
    McMonster
    Poziom 32  
    W kontekście wyglądu kodu to chyba tylko nieznacznie większą czytelnością, szczególnie gdy chodzi o proste warunki w rodzaju "gdy x jest równe 1, 2, 3...".
  • #11 9493303
    Fredy
    Poziom 27  
    Andrzej__S napisał:
    Nie napisałeś jakiego kompilatora używasz, dlatego zaznaczyłem, że to rozszerzenie gcc. U mnie działa :)

    EDIT:
    ... przy czym, jak słusznie zauważył mój przedmówca, zakresy nie mogą się na siebie nakładać :(
    No i ja nie operuję na tak dużych zakresach, więc nie wiem jak będzie z wydajnością takiego kodu. Być może w Twoim przypadku bardziej optymalne będzie użycie if .. else.

    Range extension


    rzeczywiście źle napisałem przedziały - oczywiście nie mogą nachodzić na siebie.
    Używam CodeVision .
  • #12 9494400
    tmf
    VIP Zasłużony dla elektroda
    [quote="drzasiek"]Witam. A w jakim sensie switch jest mniej bałaganiarski od if?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Czemu takie rozwiązanie jest złe?[/quote

    Nie jest złe. IMHO swich jest bardziej czytelne, ale co kto lubi. Naotmiast jest jeden istotny powód - optymalizacja. Dla switch łatwiej jest zbudować lookup tables, w efekcie dla wartości porządkowych nie ma wielokrotnych instrukcji tylko odczyt adresu procedury wyliczony na podstawie wartości parametru. Dla wielokrotnych if też da się tak zrobić, ale kompilator ma o wiele trudniej, w efekcie może taka optymalizacja zostać pominięta.
    Drugi powód - if/else to nie to samo co switch/case. W pierwszym przypadku instrukcje po else zostaną wykonane tylko kiedy if ma wartość false. Dla switch/case kolejne instrukcje zostaną wykonane o ile kolejny warunek daje warunek true, a poprzedni blok nie zakończył się instrukcją break. W efekcie switch/case jest bardziej elastyczne. Masz też pozycję default.
  • #13 9494931
    drzasiek
    Specjalista CNC
    No tak, ale autorowi nie chodziło o optymalizację lecz o wygląd kodu
    Fredy napisał:

    Nie chodzi mi o rozwiązanie ifami, chodzi mi o switcha bo w moim programie mam bardzo dużo różnych zakresów i zastosowanie ciągnącego się ifa jest mocno bałaganiarskie.

    Dlatego z ciekawości zapytałem w jaki sposób ify bardziej nabałaganią skoro schemat będzie taki sam i nawet tyle samo linii. No ale skoro tak woli.
  • #14 9495218
    Fredy
    Poziom 27  
    Idąc tokiem rozumowania to też pętle For, While , Do można zastąpić ifami .
    Niemal każdą instrukcję można czymś zastąpić. Tylko nie o to w tym wszystkim chodzi.
    Switch w całęj swej konstrukcji jest pięknym narzędziem, porządkującym program, zajmując mało pamięci ,dlatego szkoda mi było rezygnować z niego w przypadku operacji na zakresach a nie punktach.
  • #15 15261774
    Bobiiik
    Poziom 10  
    Może nie jest to idealna odpowiedź, ale przynajmniej ładnie wygląda i łatwo zmieniać przedziały, bo nie są rozstrzelone po całym case.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #16 15262003
    BlueDraco
    Specjalista - Mikrokontrolery
    Bobiiik napisał:
    Może nie jest to idealna odpowiedź, ale przynajmniej ładnie wygląda i łatwo zmieniać przedziały, bo nie są rozstrzelone po całym case.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wygląda bez sensu, bo po sprawdzeniu, że pomiar jest < 500 następnie sprawdzasz, czy przypadkiem nie jest jednak większy od 500.

    Ciut poprawniej:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #17 15262016
    michalko12
    Specjalista - Mikrokontrolery
    Bobiiik napisał:
    Może nie jest to idealna odpowiedź, ale przynajmniej ładnie wygląda i łatwo zmieniać przedziały, bo nie są rozstrzelone po całym case.


    Nie wykopuj bez powodu 100 letnich tematów!
    Do tego twoja propozycja jest przykładem bezsensownego stylu programowania którego nie powinno się rozpowszechniać. Na razie sam ucz się i nie ucz innych.
  • #18 15358268
    markolsrz
    Poziom 12  
    A ja się podłączę, bo to ciekawy, choć stary temat.
    Można to zrealizować tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Trzeba tylko pamiętać by ostatnia granica nie była mniejsza od maksimum osiąganego przez zmienną dana_wejsciowa bo program zareaguje w sposób nieprzewidywalny na taką sytuację.
REKLAMA