Jak vracet chybu funkce – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak vracet chybu funkce – C / C++ – Fórum – Programujte.comJak vracet chybu funkce – C / C++ – Fórum – Programujte.com

 

Lukáš
~ Anonymní uživatel
301 příspěvků
5. 1. 2015   #1
-
0
-

Jsem C/C++ začátečník. Přečetl jsem už dost výukových textů, ale narazil jsem na problém, který nevím jak EFEKTIVNĚ řešit. Je to druh problému, který se většinou ve výukových textech neřeší. Ke studiu z cizích zdrojových textů jsem se zatím nedostal.
Jde o to, jak v C vracet případnou chybu, která nastala v mé funkci. Mějme např. funkci: 

double deleni(const double delenec, const double delitel) {
  return delenec / delitel;
}

Co když funkci předám jako dělitele nulu? Je mi jasný, že před samotným výpočtem musím dělitel zkontrolovat. Pokud bude nula, tak co? Funkce musí vracet double (takže vrátit třeba string nemůžu) a printnout to na standardní výstup nechci (nechci tím třeba prudit uživatele, když to není jeho chyba). Vrátit 0.0 nemůžu, protože to je normální výsledek (jako např. pro 0 / 1). Výjimky v C nejsou, takže tu vyhodit taky nemůžu. Jak se tento problém v C nejběžněji řeší?
Mě napadlo jen vytvořit globální proměnnou (třeba strukturu) a v případě chyby tam info o chybě zapsat. Ale zase mě přijde blbý něco typu: 

clear_myerror();
double vysledek = deleni(100, 0);
if (myerror.errno > 0) {
  // neco
}
// pokracovani v pripade uspechu

Toto je jen příklad - stejně tak můžu mít funkci na nějaké třídění dat (ale nemám data) nebo cokoli jiného.

Nahlásit jako SPAM
IP: 212.4.134.–
Satik0
Stálý člen
5. 1. 2015   #2
-
0
-
Nahlásit jako SPAM
IP: 77.87.240.–
Lukáš
~ Anonymní uživatel
301 příspěvků
5. 1. 2015   #3
-
0
-

#2 Satik
První variantu neznám a určitě prozkoumám (teda pokud je to standardní vlastnost všech překladačů - nejen něco pro Win nebo tak).

Druhá varianta zní lépe a je škoda, že mě to nenapadlo :)

Díky! :)

Nahlásit jako SPAM
IP: 212.4.134.–
Lukáš
~ Anonymní uživatel
301 příspěvků
5. 1. 2015   #4
-
0
-

Aha, tak to je fakt jen pro Windows (windows.h), ale narazil jsem na "errno" a u toho si uvědomuji, že jsem to někde četl. Takže to by mohlo být přenositelnější řešení.

Přesto bude asi předání výsledku nebo chyby pointerem vhodnější.

Nahlásit jako SPAM
IP: 212.4.134.–
Satik0
Stálý člen
5. 1. 2015   #5
-
0
-
Nahlásit jako SPAM
IP: 77.87.240.–
Lukáš
~ Anonymní uživatel
301 příspěvků
6. 1. 2015   #6
-
0
-

Jasný, už v tom mám jasno. Díky moc :)

Nahlásit jako SPAM
IP: 212.4.134.–
vitamin+8
Grafoman
6. 1. 2015   #7
-
0
-

#1 Lukáš
Mozes vratit NaN:

double deleni(const double delenec, const double delitel) {
  if(delitel == 0)return 0.0/0.0;	//NaN
  return delenec / delitel;
}

edit: float/double moze okrem normalnych cisiel obsahovat aj kladnu a zapornu nulu, kladne a zaporne nekonecno a NaN (Not a number)

Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Lukáš
~ Anonymní uživatel
301 příspěvků
6. 1. 2015   #8
-
0
-

#7 vitamin
Kladnou a zápornou nulu bych vracel norm +0.0 a -0.0 ? A to nekonečno vych vracel jak?

A pokud nych vracel NaN pomocí (0.0 / 0.0), tak jak bych pak výsledek funkce testoval? 

double vysledek = deleni(3, 0);
if (vysledek == (0.0 / 0.0))

Nebo by to šlo i nějak líp? Třeba něco jako má JavaScript (isNaN())?

Nahlásit jako SPAM
IP: 212.4.134.–
vitamin+8
Grafoman
6. 1. 2015   #9
-
0
-

#8 Lukáš
skus isnan neviem ci je aj v C.

Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Lukáš
~ Anonymní uživatel
301 příspěvků
6. 1. 2015   #10
-
0
-

Je tam :) 

printf("%i/%i\n", isnan(0.0), isnan(0.0 / 0.0));

vrací 0/1. Díky!

Nahlásit jako SPAM
IP: 212.4.134.–
PH
~ Anonymní uživatel
2 příspěvky
6. 1. 2015   #11
-
0
-

#1 Lukáš

V obecném případě je nejlepší vracet vedle výsledku i chybovou hodnotu, v C typicky takto:

int err; int result = func(some_arg, &err);

Tím se vyřeší předání dodatečné hodnoty a není nutné řešit alokaci paměti (vše je na zásobníku). Místo int se dá využít v případě potřeby struktura.

Nahlásit jako SPAM
IP: 46.135.3.–
Lukáš
~ Anonymní uživatel
301 příspěvků
6. 1. 2015   #12
-
0
-

#11 PH
Jojo, to mě právě napadlo. Pokud bych tu err proměnnou měl globální, tak ji ani nemusím předávat té funkci.

Ale vidím, že možností je dost - a věřím, že se pro různé případy hodí všechny.

Ještě jednou díky všem :)

Nahlásit jako SPAM
IP: 212.4.134.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 20 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý