počet case ve switch

Odpovědět
DavidO
Příspěvky: 1138
Registrován: 01 kvě 2013, 21:27

počet case ve switch

Příspěvek od DavidO »

Jirka píše:Má někdo zjištěno kolik může být v switch (x) { case 0: { } } těch case?
Pokud je to vůbec omezeno jinak než pamětí.
Arduino používá k překladu GCC a to to má omezeno pouze dostupnou pamětí. (norma říká, že pro C++ ten maximální počet není určen, doporučuje aspoň 16384 a zároveň říká, že to je jen doporučení, které se nebere jako povinné, čili toto je přípustné chování)

Nicméně podle mě, pokud je těch různých možností pro switch větší než malé množství, je program napsaný nevhodně. Pravděpodobně to je automat s příliš mnoha stavy, do kterých je zbytečně zakódovaná nějaká hodnota, případně se ručně rozděluje něco, co se dá rozdělit malým počtem jednoduchých podmínek (nebo na malý počet intervalů(*) ) a uvnitř nich použít tu hodnotu pro nějaký výpočet.
A prakticky je taky dobré si uvědomit, že kontrolér, který je použitý v "tom Arduinu", má dost málo paměti; velmi častá je ATmega328, do které se vejde 16 kilo = 16384 instrukcí včetně bootloaderu, takže tam těžko půjde vystavět switch s tolika case, a i kdyby jich nebylo až tolik, tak se switch nejspíš přeloží jako posloupnost testů s následným odskokem, takže i vykonávání bude dlouho trvat.

(*) mimochodem, gcc má oproti normě jazyka rozšíření, že jde do case napsat rozsah, např. case 'A' ... 'H': (viz zde).
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
DavidO
Příspěvky: 1138
Registrován: 01 kvě 2013, 21:27

Re: počet case ve switch

Příspěvek od DavidO »

Vladimir66 píše:nekde jsem cetl, ze nektery kompilator vyhodnocoval "case 110" jako "case 10" , ze nebral tri cislice..
To je nejspíš korektní -byť možná nečekané- chování. Když se překročí rozsah daný implementací, tak není definováno, co se stane :lol: Kompilátor to obvykle dá slušně vědět (ovšem kdo čte warningy, zvlášť když odskrolujou do neznáma, žejo).
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
Jirka
Příspěvky: 55
Registrován: 18 lis 2015, 12:06

Re: počet case ve switch

Příspěvek od Jirka »

DavidO
Příspěvek 29 lis 2016, 20:52

V suučasné době běží program postupně a kontroluje podmínky (case nepoužito ani jednou - nevidím potřebu).
Varianta s case se mi zatím zdá přehlednější a nepochybně rychlejší. Nejsem origo programátor a nechám si poradit.
úkol1 - testovat desku pevné logiky. Ale ne jen dobrá/špatná. Aby výsledkem byl stav kdy se ukáže přímo na vadný jeden konkrétní pin obvodu (ev.dva-navazující signálově, nebo malou skupinu-společný otevřený výstup,není vyvedeno na konektor, ..).
úkol2 - v zásadě to samé. Jen míísto zadávaných signálů (v testu) jsou koncáky a výsledkem nějaká akce.
Uživatelský avatar
gilhad
Příspěvky: 264
Registrován: 29 kvě 2015, 00:36
Kontaktovat uživatele:

Re: počet case ve switch

Příspěvek od gilhad »

Jen bych tu rad podotknul, ze jsou minimalne dva zpusoby, jak implementovat

Kód: Vybrat vše

switch x 
{
case a: A;
case b: B;
case c: C;
....
default: DFLT;
}

1) jako serii if-u (vhodne pro "ridke mapovani" napriklad 'L':doleva, 'P':doprava,'Z':vzad)

Kód: Vybrat vše

if (x==a) goto lab_a 
else if (x==b) goto lab_b
else if (x==c) goto lab_c
...
else goto lab_default
lab_a:A
lab_b:B
lab_c:C
....
lab_default:DFLT
lab_break:
coz je efektivne

Kód: Vybrat vše

if (x==a) goto lab_a 
if (x==b) goto lab_b
if (x==c) goto lab_c
...
goto lab_default
lab_a:A
lab_b:B
lab_c:C
....
lab_default:DFLT
lab_break:
2) jako tabulku rozeskoku (vhodne pro "huste mapovani", napriklad prez vsechny hodnoty enum pro stavovy automat)

Kód: Vybrat vše

jmp_tbl[]={lab_a,lab_b,lab_c,....}
if (x<len(jmp_tbl)):goto jmp_tbl[x]
goto lab_default
lab_a:A
lab_b:B
lab_c:C
....
lab_default:DFLT
lab_break:
pricemz nevim, jak interne se switch preklada (podle optimalizaci prekladac IMHO muze dokonce pouzit jeden nebo druhy pripad, nebo to dokonce preskladat zcela jinak, pokud ma dost huste optimalizace - samozrejme tedy take zalezi na pouzitem prekladaci a jeho parametrech. Nektere jine jazyky tuto konstrukci dokonce muzou resit jeste exoticteji a mit jako navesti vyrazy s promennyma a pripadne jich i provest vic (vsechny, ktere se vyhodnoti jako vhodne))

(break se preklada na goto lab_break)

Takze co to udela konkretne na arduinu a jak efektivni a rychle to bude je asi lepe zkusit a zmerit/zdebugovat prelozeny kod. (Kdyz uz tu mame to extra vlakno)
Jirka
Příspěvky: 55
Registrován: 18 lis 2015, 12:06

Re: počet case ve switch

Příspěvek od Jirka »

od gilhad » 30 lis 2016, 13:48
Ta druhá varianta se mi jeví lepší (v první by procházel podmínky postupně a zdlouhavě).
Jen jsem nevěděl, že mohu tyto funkce dát do pole.
Není to pak ale obdoba toho switch?
DavidO
Příspěvky: 1138
Registrován: 01 kvě 2013, 21:27

Re: počet case ve switch

Příspěvek od DavidO »

Jirka píše:od gilhad » 30 lis 2016, 13:48
Ta druhá varianta se mi jeví lepší (v první by procházel podmínky postupně a zdlouhavě).
Velmi záleží na tom, jak to zoptimalizuje překladač, ve výsledku to může být velmi přeházené až k nepoznání. Každopádně rozeskok pomocí toho pole je v podstatě konstantní záležitost, ale musí to pole být "husté" (tj. aby byly definované všechny použité indexy).
Jirka píše:Jen jsem nevěděl, že mohu tyto funkce dát do pole.
Bacha, ten Gilhadův kód je spíš motivační, než že by to byl kód přeložitelný v nějakém jazyce. Popisuje myšlenku, jak to může fungovat. S těma funkcema (nebo návěštíma pro goto) v poli to nejde zdaleka ve všech programovacích jazycích.
Jirka píše:Není to pak ale obdoba toho switch?
Ano i ne. Ano z pohledu, že si podle hodnoty vybereš jeden z mnoha kusů kódu k vykonání, ne z pohledu jak se takové rozhodování bude skutečně na úrovni strojových instrukcí vykonávat.
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
Uživatelský avatar
gilhad
Příspěvky: 264
Registrován: 29 kvě 2015, 00:36
Kontaktovat uživatele:

Re: počet case ve switch

Příspěvek od gilhad »

Jirka píše:od gilhad » 30 lis 2016, 13:48
Ta druhá varianta se mi jeví lepší (v první by procházel podmínky postupně a zdlouhavě).
Jen jsem nevěděl, že mohu tyto funkce dát do pole.
Muzes tam dat jejich adresy, jak konkretne se to pise je zalezitosti jazyka, tohle je jen hruba idea, jak se to da udelat.
v Ccku muzes klidne mit promennou typu funkce (a pouziva se to pro callbacky napriklad) a tudiz mit klidne pole funkci (idealne nejakeho stejneho typu (tedy se stejnymi parametry a vysledkem), ale i to se da obejit) a volat funkci skrze index v tomto poli. Syntaxi ted z hlavy nedam, ale neni to nic extra zuriveho (zvlast pokud si ten typ funkce pojmenujes).
Jirka píše:Není to pak ale obdoba toho switch?
Jsou to cesty, jak interne ten switch prelozit do strojaku (ci jineho jazyka, pokud se nepreklada rovnou do strojaku).
Myslim, ze jsem se (kdysi, kdesi, na ruznych mistech a v ruznych jazycich) setkal s jednou i druhou variantou prekladu switch.

U toho pole je problem, ze jeho velikost musi byt rozdil nejvyssi a nejnizssi mozne hodnoty(plus jedna) a nepouzite diry jen zbytecne zerou pamet a pokud se nejakou chybou do nich trefis, tak je to blbe (cili idealne je zaplnit "prazdnou" funkci, ktera nic nedela, eventualne jde primo na lab_break)

BTW, zrovna takto jsou casto reseny interrupty v pocitaci - mas pole adres (nebo skoku) a kdyz nastane interrupt, tak se jde na prislusnou adresu dle toho pole. A taky se tak resi virtualni funkce v turbo pascalu, kde mas tabulku tech funkci jako soucast popisu typu objektu a prepsanim polozky v te tabulce (pri prekladu) se realizuje prekryti predka potomkem. Kazdy objekt pak ma odkaz na tuhle tabulku, cimz je dan jeho typ. (v podstate se Prvek.Hide();Prvek.Move(); Prvek.Draw(); prelozi na volani 1., 2. resp. 3. adresy z tabulky virtualnich funkci a prekladac se sam stara, aby se vsude za Hide() dosadilo "virtualni funkce cislo 1", za Move() "virtualni funkce cislo 2" atd ...
DavidO
Příspěvky: 1138
Registrován: 01 kvě 2013, 21:27

Re: počet case ve switch

Příspěvek od DavidO »

gilhad píše:v Ccku muzes klidne mit promennou typu funkce (a pouziva se to pro callbacky napriklad) a tudiz mit klidne pole funkci (idealne nejakeho stejneho typu (tedy se stejnymi parametry a vysledkem), ale i to se da obejit) a volat funkci skrze index v tomto poli. Syntaxi ted z hlavy nedam, ale neni to nic extra zuriveho (zvlast pokud si ten typ funkce pojmenujes).
Přesněji řečeno proměnnou typu ukazatel na funkci.
V C a C++ takhle:
Příklad proměnné typu ukazatel na funkci:int (*cosi)(char,long); tím deklaruji, že cosi je ukazatel na funkci, která má dva parametry, jeden typu char, druhý typu long a vrací int.
Deklarace typu: typedef int (*fun_t)(char,long); čímž si pojmenuji, že fun_t je typ "ukazatel na funkci, která má dva..." a pak můžu deklarovat proměnné jako se to dělá s každým jiným typem, tj. když například mám

Kód: Vybrat vše

typedef int (*fun_t)(char,long);
int nejaka_funkce(char c,long l){ return c+l; }
int jina_funkce(char x,long y){ return y-x; }
tak pak třeba můžu napsat

Kód: Vybrat vše

fun_t odkaz;
if (neco > 5)
	odkaz = nejaka_funkce;
else
	odkaz = jina_funkce;
(Důležitý moment je, že tam je napsáno odkaz = nejaka_funkce; bez závorek, protože takhle to znamená přiřazení odkazu na funkci, zatímco kdyby tam byly závorky, třeba odkaz = nejaka_funkce(p,q); tak by to bylo zavolání funkce s patřičnými parametry.)
Pak můžu třeba napsat vysledek = odkaz('A',100); (pokud vysledek je proměnná, do které se dá přiřadit int), to zavolá jednu z těch dvou funkcí podle toho, jestli neco bylo nebo nebylo větší než 5.
No a s polem to pak je už jako s každým jiným polem, např.:

Kód: Vybrat vše

fun_t pole_ukazatelu[] = { nejaka_funkce, jina_funkce };
vysledek = pole_ukazatelu[i]('B',5);
čímž si vytvořím pole inicializované těma dvěma funkcemi a pak zavolám funkci, která je na indexu i. Když by to byla 0, tak nejaka_funkce, když 1, tak jina_funkce (neb pole jsou číslovaná od 0).

(tohle je jen ukázka pro představu, nepopisuje možnosti úplně a použitý příklad pochopitelně nemá reálný smysl. Nicméně možnosti naznačuje. Celé to je součástí zajímavé oblasti C / C++ zvané "pointerová aritmetika", která je obvykle pro začátečníky dost těžká na uchopení a ještě těžší na správné pochopení...)
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
Odpovědět