C++ - Spojový seznam - nefunkční Find() a problém s výjimkami
Tak, po frontě jsem tu zas, a se seznamem :D Věc se má tak, že mi z nějakého důvodu nefunguje fce Find, problém dělá přiřazení node=node->next, kde se do node přiřadí 0, ale netuším proč - předpokládal jsem, že když na začátku fce do node přiřadím first, budu moct manipulovat přes node i s nexty...
Tady je kód: mafpzl35-18993
A ohledně výjimek... Pokud mám třeba fci First, která vrací data z hlavy, tak musím ošetřit situaci, kdy je hlava NULL. Normálně jsem to řešil vracením "nepravděpodobné hodnoty", třeba -1, ale to není ok, protože pokud by v hlavě bylo uložené totéž číslo, je s tím problém... Proto jsem chtěl použít nějakou výjimku, která by mi umožnila nevracet nic a vypsat na obrazovku krátkou hlášku o chybě. Bohužel, fprintf(stderr, error) vypíše hlášku, ale za ni ještě počet vytištěných znaků, což mi ve výpisu vadí. Zkusil jsem tedy try-catch, ale tam zase dochází k okamžitému ukončení programu po vytištěné hlášce, popř. to vrací 0 - co s tím? Kód Firstu s výjimkou je zde:
int List::First(){
try{
if(!first){
throw new ListEmptyError();
}else{
return first->data;
}
}catch(...){
cout << endl;
}
}
Opět moc díky za rady, snad už mých dotazů bude postupně ubývat :D
Ok, Add_First jsem přepsal takhle:
Vypadá to, že Find už funguje - jdu mrknout na try-catch :D
Edit: Kontroluješ rychleji, než já stíhám přemýšlet :D
Este tam vidim jeden potencialny problem a to ze ak pri mazani prvku vymazes posledny prvok tak nenastavis last na NULL. Mal by si testovat pri mazani na konci fcie ze ci sa first nastavil na NULL a ak ano tak last nastavit tiez na NULL.
Tak, last jsem ošetřil, teď koukám na ten try-catch. Povedlo se mi to vyřešit takto:
Definice fce:
Volání fce v mainu:
Takhle to funguje, jak bych chtěl, ale napadá mě, jestli by to nešlo řešit nějak elegantněji, ideálně už v rámci funkce?
A co ma ta funkce "elegantene" urobit ked je list prazdny? Ma ti zatelefonovat ze kam ma skocit? Tym catch urcis ze kam sa ma skocit. Ked chces skocit mimo fiunkci tak catch musi byt mimo funkci.
Ked ma fcia vracat hodnotu tak musi vratit hodnotu, ked ziadnu nema tak musi skocit mimo funkci.
Inac sa to da len tak ze si zadefinujes funkci tak ze nevraca hodotu ale nejaky status a hodotu bude plnit do nejakej adresy, napr.
k tomu ale potom nepotrebujes ziadne exceptions, a je to komplikovane testovat to furt po kazdom volani fcie, viz moja uplne prva odpoved. Do try-catch bloku mozes uzavret aj 10volani fcie a nasledne urobit osetrenie chyby len na jednom mieste, tym padom zdrojak neni preplneny ifmi a program je prehladnejsi.
P.S> nemaju vas to nahodou ucit v skole? :D Zdravim neschopnych pedagogov :)
No, objevil se další problém, který jsem nečekal ani já :D Vytvořil jsem funkci Del_last, která by měla mazat poslední prvek seznamu, a tedy i fungovat hodně podobně jako Del_first... Problém je, že pokud ji zavolám, a seznam je pak prázdný, následující find při "throw" nahlásí Segmentation fault. Fakt už nevím proč, kód Del_last vypadá takto:
Celý kód pak vypadá takhle: ktblte55-19005
Opět moc díky za rady, je to nějak náročné :D
necital som cely program ale ked urobis
last = last->prev;
tak nemozes vediet ze ci ten last teraz neni NULL takze nemozes na tu adresu na ktoru ukazuje last pristupovat len tak
last->next = NULL;
ale musis najprv otestovat ci last neni null a pristupovat na tu adresu mozes len ak last neni NULL. Ak je null a chces na tu adresu cosi zapisovat tak "program proved neplatnou operaci". T.j. nemozes menit next u neexistujuceho prvku.
A neni to narocne :)