Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C ja paluu useiden aliohjelmakutsujen jälkeen

jopelo [18.11.2009 18:40:31]

#

C-kielellä ohjelmoidessa jumituin tällaiseen ongelmaan, johon en nyt millään keksi ratkaisua. Main-funktiosta kutsutaan aliohjelmaa, jossa taas kutsutaan useita sisäkkäisiä aliohjelmia. Nyt jos jossain kohti tapahtuu virhe pitäisi palata takaisin ensimmäiseen aliohjelmaan. Miten tämän voisi toteuttaa?

Return-lauseella tietysti pääsee takaisin edelliseen aliohjelmaan, mutta jos ollaan jo hyvin "kaukana" ensimmäisestä aliohjelmasta (eli on tapahtunut jo useita peräkkäisiä aliohjelmakutsuja), tämä menee vähän hankalaksi. Tällöin joutuisi palaamaan return-lauseella aina yhden "pykälän" taaksepäin ja selvittämään if-lauseella aliohjelmakutsun jälkeen, tapahtuiko virhe (jolloin palataan taas return-lauseella) vai jatketaanko eteenpäin.

En nyt oikein osannut tätä fiksusti selittää, mutta toivottavasti joku ymmärsi.

jlaire [18.11.2009 18:46:59]

#

C:ssä ei ole poikkeuksia, mutta setjmp ja longjmp voivat jossain määrin ajaa saman asian.

Itse olen tyytynyt käyttämään juuri selittämääsi if-lausetta ja erityisiä paluuarvoja virhetilanteissa (esim. -1). Tai jos ohjelma on todella hankala toteuttaa C:llä, käytän jotain toista kieltä.

Metabolix [18.11.2009 19:24:47]

#

Kannattaa tuossa pitää aika tarkkaan huoli, etteivät kyseiset funktiot jätä resursseja (muistia, tiedostoja yms.) vapauttamatta. Esimerkiksi seuraava funktio toimii aika kriittisesti väärin: vaikka tiedosto avataan alussa ja suljetaan lopussa aivan oikein, virhetilanteessa se jääkin auki!

void virhefunktio() {
  FILE *f = fopen("tiedosto.txt", "r");
  // Koodia...
  if (virhe) {
    return;
  }
  // Koodia...
  fclose(f);
}

Myös keskellä funktiota return-lauseen seurana pitäisi olla fclose.

Kray [27.11.2009 07:51:20]

#

Metabolix kirjoitti:

Kannattaa tuossa pitää aika tarkkaan huoli, etteivät kyseiset funktiot jätä resursseja (muistia, tiedostoja yms.) vapauttamatta. Esimerkiksi seuraava funktio toimii aika kriittisesti väärin: vaikka tiedosto avataan alussa ja suljetaan lopussa aivan oikein, virhetilanteessa se jääkin auki!

void virhefunktio() {
  FILE *f = fopen("tiedosto.txt", "r");
  // Koodia...
  if (virhe) {
    return;
  }
  // Koodia...
  fclose(f);
}

Myös keskellä funktiota return-lauseen seurana pitäisi olla fclose.

Tämä on erinomainen esimerkki siitä missä on hyvä käyttää gotoa. Eli virhetilanteessa goto virhe; ja funktion lopussa sijaitsevan labelin virhe: jälkeen tulee kaikkien resurssien siivous.

os [27.11.2009 18:56:12]

#

Siis tarkemmin ajatellen erinomainen esimerkki siitä, minkä takia kannattaa suosia näppärämpiä kieliä kuin C. Veikkaisin että täälläkin ainakin 90% C-kieleen (tai C++:aan) liittyviä kysymyksiä esittävistä on tekemässä jotakin, joka onnistuisi paljon helpommin jollakin muulla kielellä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta