Select case használata

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Válasz küldése
Vendég

Select case használata

Hozzászólás Szerző: Vendég »

Hogyan tudom azt megcsinálni, hogy több érték esetén is ugyan az a case ág fusson le, de az értékeket nem lehet behatárolni úgy, hogy kisebb valaminél, vagy nagyobb...
Valami olyasmi kéne hogy:
Select case Scancode
case 12: ...
case 22,34,1: ...
End select.

De ezt így nem lehet... Valakinek ötelete a megoldásra az if-ek egymás után pakolgatása helyett?
Avatar
nobody_hun
Bitfaragó
Hozzászólások: 425
Csatlakozott: 2005. november 14. hétfő, 7:00

Hozzászólás Szerző: nobody_hun »

Üdv,
A Bascom súgója szerint:
Remarks

Var Variable. to test
Test1 Value to test for.
Test2 Value to test for.
You can test for conditions to like:
CASE IS > 2 :
Another option is to test for a range :
CASE 2 TO 5 :

Example
Dim X As Byte

Do
Input "X ? " , X
Select Case X
Case 1 To 3 : Print "1 , 2 or 3 will be ok"
Case 4 : Print "4"
Case Is > 10 : Print ">10"
Case Else : Print "no"
End Select
Loop
End
Azaz gond nélkül lehet használni ezt az utasítást feltétel alapján, valamint két érték közti behatárolásra is.
Vendég

Hozzászólás Szerző: Vendég »

De nekem pont az a gond, hogy nincs behatárolva, hogy a változó két érték közt van, hanem kb 10 "random" számra kellene ugyan azt csinálnia, másik 10-re meg megint mást...
Avatar
nobody_hun
Bitfaragó
Hozzászólások: 425
Csatlakozott: 2005. november 14. hétfő, 7:00

Hozzászólás Szerző: nobody_hun »

Háááát. Az úgy nehéz lesz. Én azt próbálnám meg, hogy az egyezőségeket valamilyen matematikai funkcióval korlátok közé szorítanám.
Mindenképpen a case-t használd az if helyett, kevesebb memóriát eszik. még akár így is:

case 1: valami
case 5: valami
case 8: valami
case 6: masik
case17: masik
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Több utasítás esetén a case mögött gosub-returnal érdemes próbálkozni....
Avatar
Daveeboy
DrótVégénSzéndarab
Hozzászólások: 39
Csatlakozott: 2007. november 21. szerda, 7:00

Hozzászólás Szerző: Daveeboy »

Nem az alap problémához hanem a select case vezérlőszerkezet favorizált használatához szólnák hozzá.

Van egy 14 elágazásos szerkezetem, eredetileg if elseif szerkezettel mert több utasítás van egy részen. Az "ajánlás" szerint lecseréltem select case - gosub return megoldásra és csodálkozva vettem észre hogy 4 bájttal nagyobb lett a kód, a memóriafoglalás pedig nem változott.
Nem igazán értem...
Vélemény?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Else-Elseif szerkezetek nagy hátránya hogy a meóriastack-ba szépen foglal(hat). Illetve könnyen bele lehet gabajodni a feltételrendszerezésbe....

A keletkezett ASM kód teljesen más az egyes esetekben...
Avatar
Daveeboy
DrótVégénSzéndarab
Hozzászólások: 39
Csatlakozott: 2007. november 21. szerda, 7:00

Hozzászólás Szerző: Daveeboy »

Sebesség szempontjából jelenthet valamit?
Értem ezalatt select-case esetén gyorsabban végignézi talán?

Valóban jobban áttekinthető lehet. Bár a sok gosub cimke meg return egy kupacon... Persze jól kell formázni de ennyi erővel az if szerkezet is formázható jól.
Azonban maga a feltételrendszer valóban sokkal áttekinthetőbb.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Néhány tesztet + szimulátort lefuttattam. Bascom 1.11.8.7 alatt.

CASE szerkezet:

Kód: Egész kijelölése

'2313, 4MHZ Q
$sim
Dim A As Byte
A = 0
Select Case A
   Case 1 : Print "1"
   Case 2 To 100 : Print "2"
   Case 101 To 200 : Print "3"
   Case Is > 201 : Print "4"
   Case Else : Print "0"
End Select
End

'msecben
'meret:116HEX
'A=1:0,2145
'A=50:0,21975
'A=150:0,22525
'A=210:0,2275
'A=0:0,2265
If-Then szerkezet:

Kód: Egész kijelölése

'2313, 4MHZ Q
$sim
Dim A As Byte
A = 210
If A = 1 Then Print "1"
If A > 1 And A < 101 Then Print "2"
If A > 100 And A < 201 Then Print "3"
If A > 200 Then Print "4"
If A = 0 Then Print "0"
End
'meret: 118HEX
'A=1:0,228
'A=50:0,228
'A=150:0,228
'A=210:0,2285
'A=0:0,22775

If-Then-Elseif

Kód: Egész kijelölése

'2313, 4MHZ Q
$sim
Dim A As Byte
A = 0
If A = 1 Then
   Print "1"
      Elseif A > 1 And A < 101 Then
      Print "2"
         Elseif A > 100 And A < 201 Then
         Print "3"
            Elseif A > 200 Then
            Print "4"
               Elseif A = 0 Then
               Print "0"
            End If
End
'meret: 120HEX
'A=1: 0,2145
'A=50: 0,2200
'A=150: 0,2255
'A=210:0,2275
'A=0:0,22775


Eredmény:
- CASE szerkezet a legrövidebb. A leghosszabbhoz képest 4 byte! eltérés (2 ASM utasítás).
- CASE szerkezet gyorsabban fut le picivel. Azonos elágazási helyet figyelve ~0,00025 msec eltérés, ez a 4MHz-s órajel esetén egyetlen, 1ciklusos ASM utasítást jelent.
- A legrosszabbul végzett az időbeli lefutáson a If-Then halmozott szerkezet. Érthető, mert minden egyes feltételvizsgálat lefut.
Avatar
Daveeboy
DrótVégénSzéndarab
Hozzászólások: 39
Csatlakozott: 2007. november 21. szerda, 7:00

Hozzászólás Szerző: Daveeboy »

Jó a teszt! Grat.
Viszont nem teljes.
Arról beszéltem hogy több utasítás van ezért gosubbal kell kiugrani.
No és ekkor lett nagyobb a kód. (ez előtt a 4. hozzászólás(om))

Elvégeztem hát a tesztet.
Megnéztem ugyan azt mint te, az első és utolsó tesztre, és minő meglepő ugyan azt kaptam. :lol: Erre azért volt szükség hogy akár hasonlítható is legyen.

Aztán módosítottam a select case szerkezetet a több utasításosra gosub-return-al
Ime a módosított select-case

Kód: Egész kijelölése

'2313, 4MHZ Q
$sim
Dim A As Byte
A = 210
Select Case A
   Case 1 : Gosub C1
   Case 2 To 100 : Gosub C2
   Case 101 To 200 : Gosub C3
   Case Is > 201 : Gosub C4
   Case Else : Gosub C5
End Select
End

C1:
Print "1"
Return

C2:
Print "2"
Return

C3:
Print "3"
Return

C4:
Print "4"
Return

C5:
Print "0"
Return

'msecben
'meret:12AHEX
'A=1:0,21625
'A=50:0,2215
'A=150:0,227
'A=210:0,22925
'A=0:0,22825
Ez hasonlítható az If-Then-Elseif szerkezettel egy-az egyben mert az is több utasítást tud egy leágazásnál.
A select-case bizony nagyobb és lassabb...
Nem mondom semelyikre hogy jobb vagy rosszabb, de minden esetre érdekes. Ez a gosubos select nem biztos hogy a tuti.
Vélemény?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Tényleg ez kimaradt:).

Case is tud több utasítást! Csak persze nincsen igazán leírva.... hasonlóan mint az If-Then...

Kód: Egész kijelölése

'2313, 4MHZ Q 
$sim 
Dim A As Byte 
A = 210 
Select Case A 
   Case 1 
      Gosub C1 
      Print "1"
   Case 2 To 100
      Gosub C2 
      Print "2"
   Case 101 To 200
      Gosub C3 
      Print "3"
   Case Is > 201
      Gosub C4 
      Print "4"
   Case Else
      Gosub C5 
      Print "0"
End Select 
End  

C1: 
Return 

C2: 
Return 

C3: 
Return 

C4: 
Return 

C5: 
Return 

'msecben 
'meret:12AHEX 
'A=1:0,21625 
'A=50:0,2215 
'A=150:0,227 
'A=210:0,22925 
'A=0:0,22825
Idők ugyanazok maradnak.
Most még el lehet játszani, hogy mi van, ha Call-lal oldod meg:) (kb. SUB-onként 15-30 plusz utasítás a regiszterek, állapotok mentése miatt).

Na szépen körbevárva:)
Az IfThenElseif ugyanaz lehet belül, mint a select-case kialakítás....

Most ezek alapján melyiket használjuk?:)
Nálam ha valami ismétlődő, akkor az megy a Gosub-Return részbe.
Az IF után logikai kifejezés használata (If A > 100 And A < 201 Then Print "3" ) csak az újabb bascomban használható, a régebbiek nem szeretik!
Avatar
Daveeboy
DrótVégénSzéndarab
Hozzászólások: 39
Csatlakozott: 2007. november 21. szerda, 7:00

Hozzászólás Szerző: Daveeboy »

Szóval a select case ágainál ílyen módon több utasítást is meg lehet adni.... hmm ja kérem szépen, így már egészen más a leányzó fekvése. :lol:
Ma is okosabb lettem. Thx az infót.
Válasz küldése