» »

Analiza kode: goto rabimo po pameti

Analiza kode: goto rabimo po pameti

xkcd.com

Slo-Tech - Eno izmed prvih in najgloblje vcepljenih pravil programiranja je izogibanje stavkov goto. Niso prepovedani, saj jih številni jeziki čisto lepo podpirajo, a sodijo v kategorijo grdega programiranja. Njihova uporaba je nezaželena, ker se ob nebrzdani uporabi program hitro zapaca v nerazumljivo kodo in ker je vzdrževanje takšne programske opreme bistveno težje. Dokazano je, da lahko vsak program napišemo brez stavka goto, če ga primerno strukturiramo.

Kljub temu so stavki goto trmasto ostali in v nekaterih primerih je njihova uporaba smiselna. Zasloveli so seveda v pismu nizozemskega velikana računalništva Edsgerja Dijkstre iz leta 1968, v katerem je stavke goto označil kot škodljive. Debata v naslednjih desetletjih je bila živahna, saj so nastopali argumenti za in proti, tabora pa sta še danes dva. Nekateri bi stavke goto prepovedali, drugi v njih načeloma ne vidijo nič slabega. Dejstvo pa je, da se še danes uporabljajo.

Zato je zanimivo vprašanje, koliko komercialne kode, ki ni ravno vzor elegantnega programiranja, uporablja stavek goto. Skupina raziskovalcev iz ZDA, Kanade, Čila in Japonske je izvedla empirično študijo (članek), v kateri so analizirali približno 11 milijonov vrstic C-jevske kode iz 11 tisoč projektov in ugotovili, da razširjenost stavkov goto ne predstavlja perečega problema. Njegova uporaba je živa, a ga programerji uporabljali v zmernih količinah na primernih mestih. Stavke goto so uporabljali za upravljanje napak (80 %) in čiščenje po koncu procedur. Analiza revizij projektov je pokazala, da stavkov goto po izidu v popravkih programske opreme niso odstranjevali, kar kaže na premišljeno rabo na primernih mestih.

29 komentarjev

Mordecai ::

Ga pogrešam v matlabu ja.

vostok_1 ::

Jah rečeno mi je bilo, da se ga izogibam, in tk delam. Čeprav sem parkrat bil temptan.

japol ::

A se ne dela s tem tudi obfuskacija? Kar je namen da je koda težko berliva?

mjk ::

goto je kar škodljiv ... če je vsaj na črni listi, ga ne bo noben uporabil lahkotno ... kar je prav, ker dela kodo, ki je daljša od 100 vrstic, neberljivo in še dodatno doda možnost napak. Jaz sem na NE GOTO ekipi ;)

čuhalev ::

Posvečen bodi tisti, ki zna programirati brez ukaza JMP. :D

Irbis ::

V C prinese nekaj uporabe goto to, da pri ukazu break ne moreš povedati, koliko nivojev zank bi rad prekinil. Po drugi strani pa se mi zdi, da tudi če bi imel ukaz break-break-break-break, je bolj jasno uporabiti goto in pametno imenovano labelo.

krneki0001 ::

V cobolu ga tudi naj nebi uporabljali, čeprav pa vseeno kdaj prav pride.
Recimo tukaj:
GOTO ABEND.
Asrock X99 Extreme 4 | Intel E5-2683V4 ES | 64GB DDR4 2400MHz ECC |
Samsung 250GB M.2 | Asus 1070 TI | 850W Antec | LC Tank Buster

BigWhale ::

11 milijonov vrstic ni zelo veliko.

Goto sam po sebi ni skodljiv. Ce ga clovek zna uporabiti, potem ni. Ampak vecinoma ga ne zna. Applovci bi znali kaj o tem povedati. :D

Kids, don't try this at home. :)

one too many ::

V enem APIju za zvočno kartico sem videl lepo rabo goto, ravno za upravljanje napak, kot je omenjeno v članku. Preprosto vsakič ko sem videl stavek goto, sem vedel, da to pomeni skok na izhod iz funkcije zaradi napake.

Mislim pa, da je ta vojna proti goto predvsem iz zgodovinskih razlogov. Včasih brez goto ni šlo, potem ko so se jeziki razvili, potrebe po goto ni bilo več, še vedno pa je bil velik del programerjev vajenih takega programiranja.
Npr. moj oče se je učil programiranja na začetku 70ih (naj bi bili prva generacija študentov, ki je imela programiranje NA računalniku in ne samo na papirju). Takrat je to izgledalo zelo drugače. Preluknjane kartice, brez monitorja in seveda goto. Ko se je oče po dooolgih letih spet lotil programiranja, se je kar močno videl stari slog. Čeprav goto se je/sem ga odvadil :D.

Problem je, ko postane to nasprotovanje brez razmisleka. Včasih je zato težko najti pomoč, ker bo vsak s 5 minut odveč časa napisal, da se problem reši drugače. Ravno te dni sem imel problem z izračunom (dela) inverza posebne matrike. Ja, Ax=b, se nikoli ne rešuje kot x=(A^-1)b, vendar je precej težko dopovedat, da res rabim inverz. Tu pa se znanje večine konča...

3p ::

mjk je izjavil:

goto je kar škodljiv ... če je vsaj na črni listi, ga ne bo noben uporabil lahkotno ... kar je prav, ker dela kodo, ki je daljša od 100 vrstic, neberljivo in še dodatno doda možnost napak. Jaz sem na NE GOTO ekipi ;)


Goto je včasih, sploh če jezik ne pozna izjem, manjše zlo kot alternativa (dodatni pogoji v zankah, itd).

Z goto menda skačeš le znotraj iste funkcije, in dolžina teh je pomembna. Če imaš funkcije dolge 100 vrstic (ali še več), je tvoj program nepregleden, pa goto gor ali dol.

ciki57 ::

Osebno nikoli ne vidim potrebe, da bi uporabljal GOTO. Če jezik ne pozna exceptionov potem ajde, mogoče kdaj pride prav, drugače pa ni nobene potrebe.

JanK ::

3p je izjavil:

...Če imaš funkcije dolge 100 vrstic (ali še več), je tvoj program nepregleden, pa goto gor ali dol.


To je spet posplosevanje, podobno kot "ne uporabljaj goto".

V svoji C++ kodi za real-time multithreaded aplikacijo, ki zajema zive podatke, jih obdeluje, uporablja razne sorte numericnih algoritmov, nelinearno fitanje, FFT filtriranje,.. imam nekaj funkcij, ki so dolge po 600-800 vrstic in vec. Koda je sicer popolnoma objektno zasnovana, robustna, fault-tolerant, hitra, in povecini so metode klas precej kratke.

Tudi omenjene funkcije so metode v klasah. Ampak vsaka izmed njih opisuje del postopka, ki bi se ga sicer dalo razdrobiti na podfunkcije, bilo pa bi nesmiselno, kajti:

- posamezni kosi kode se pojavljajo samo na enem mestu, se ne ponavljajo
- V postopku priprave vhodov za numericne funkcije, se nabere dovolj spremenljivk in povezave med njimi so dovolj kompleksne, da bi podfunkcije morale imeti po 10 parametrov ali pa bi spremenljivke moral (brez potrebe) narediti kot polja v klasah, kamor ne spadajo
- Z dobrim formatiranjem in sprotnim komentiranjem kode je preglednost popolnoma OK, kot kaze izvlecek kode
    // Linear trend to be subtracted. We just use the interpolating vector (with default values 0)
    std::vector<std::vector<float> > local_linear_trend_vector(cns());
    for( size_t strip = 0; strip < cns(); local_linear_trend_vector[strip++] = std::vector<float>(2,0) );
    std::vector<SWM_Interpolating_Vector> local_linear_trend(cns());
    Intrvl<unsigned> local_linear_trend_interval(0, event->acqdata.number_of_samples());

    // If we actually do subtract, we need to calculate averages
    if( subtract_local_linear_trend_ && subtract_local_linear_trend_seconds_ > 0 ){

      // Intervals
      Intrvl<unsigned> left_avg(std::max(interval.l() - subtract_local_linear_trend_seconds_*event->acqdata.sampling_rate(),0.0f), std::max(interval.l(),0.0f));
      Intrvl<unsigned> right_avg(std::min(interval.r(),1.0f*event->acqdata.number_of_samples()), std::min(interval.r() + subtract_local_linear_trend_seconds_*event->acqdata.sampling_rate(),1.0f*event->acqdata.number_of_samples()));
      local_linear_trend_interval *= Intrvl<unsigned>(left_avg.midpoint(), right_avg.midpoint());

      // Deltas
      std::pair<float, float> delta;

      // Loop over strips
      for( size_t strip = 0; strip < cns(); ++strip ){
        // Call function and check for exceeded deltas
        local_linear_trend_vector[strip] = event->acqdata.linear_trend(channels_, left_avg, right_avg, cmpf_, delta, (one_strip_ ? 0 : &sc_.sc[strip]), &global_linear_trend[strip]);
        if( subtract_linear_trend_max_delta_ && delta.first  > subtract_linear_trend_max_delta_ * delta_yy[strip] ){
          local_linear_trend_vector[strip][0] = 0;
          _delta_exceeded = true;
        }
        if( subtract_linear_trend_max_delta_ && delta.second > subtract_linear_trend_max_delta_ * delta_yy[strip] ){
          local_linear_trend_vector[strip][1] = 0;
          _delta_exceeded = true;
        }
      }
    }

    // Linear trend to be subtracted. We just use the interpolating vector (with default values 0)
    for( size_t strip = 0; strip < cns(); ++strip ){
      local_linear_trend[strip] = SWM_Interpolating_Vector(local_linear_trend_vector[strip], local_linear_trend_interval.length(), local_linear_trend_interval.l());
    }

    // Set timestep
    unsigned d_sample = 1;
    if( auto_timestep_enabled_ ){
      d_sample = auto_timestep_length_ / max_speed * event->acqdata.sampling_rate();
      if( !d_sample ){ d_sample = 1; }
      swu().log(LM_INFO, log_prefix("SWM_M1Weigh_Core::weigh_vehicles()"), "Auto timestep is " + Convert::float2str(1000*auto_timestep_length_/max_speed) + "ms (" + Convert::unsigned2str(d_sample) + " samples)", false);
    }

    // Now we can construct the vectors and matrices needed for SVD.
    // First the x and y (time and signal) and sigma (set to 1)
    std::vector<std::pair<unsigned, float> > x, graph_x;
    std::vector<float> y,sig;
    for( float sample = interval.l(); sample < interval.r(); ++sample ){

      // Loop over strips
      for( size_t strip = 0; strip < cns(); ++strip ){

        // Always add the point for graph and then loop, if we are stepping
        graph_x.push_back(std::pair<unsigned, float>(strip,sample));

        // For Y we need to sum signals
        float yy = 0;
        if( one_strip_ ){
          for( std::set<unsigned>::const_iterator ch = channels_.begin(); ch != channels_.end(); ++ch ){
            if( !event->acqdata.a(*ch).all_ok(true) ){ continue; }
            yy += (event->acqdata.a(*ch)[sample] - event->acqdata.a(*ch).offset(0)) * cmpf_[*ch];
          }
        }
        else{
          for( SWM_Single_Strip_Channels::const_iterator ch = sc_.sc[strip].begin(); ch != sc_.sc[strip].end(); ++ch ){
            if( !event->acqdata.a(ch->first).all_ok(true) ){ continue; }
            yy += (event->acqdata.a(ch->first)[sample] - event->acqdata.a(ch->first).offset(0)) * cmpf_[ch->first] * ch->second/100;
          }
        }
        yy /= channels_size;
        yy -= global_linear_trend[strip].y(sample, true) + local_linear_trend[strip].y(sample, true);
        if( diag_ ){ diag_->a(ach_ + strip*(3+group_.size()))[sample] = yy; }

        // If we are autostepping, we may not do calculation in this point
        if( static_cast<unsigned>(sample) % d_sample ){ continue; }

        // We will do calculations for this point
        x.push_back(std::pair<unsigned, float>(strip,sample));
        y.push_back(yy);
        sig.push_back(1);

      }

    }

    // Then the fitted parameters
    std::vector<float> a(group_.size());

    // Allocate aux matrices and vectors
    std::vector<std::vector<float> > u(x.size());
    for( std::vector<std::vector<float> >::iterator p = u.begin(); p != u.end(); (*p++).resize(group_.size()) );
    std::vector<std::vector<float> > v(group_.size());
    for( std::vector<std::vector<float> >::iterator p = v.begin(); p != v.end(); (*p++).resize(group_.size()) );
    std::vector<float> w(group_.size());

    // Chi square
    float chisqr = 0;

    // If we don't do diags only, proceed with calculation
    draw_diags_ = false;
    if( !diags_only_ ){
      SVD::svdfit(*this, x, y, sig, a, u, v, w, chisqr);
    }

    // Now draw diags
    if( diag_ ){
      draw_diags_ = true;
      std::vector<float> dummy(group_.size());
      for( std::vector<std::pair<unsigned, float> >::const_iterator p = graph_x.begin(); p != graph_x.end(); ++p ){
        funcs(*p, dummy);
      }
    }
"Think about how stupid the average person is,
then realize that 50% are stupider than that"
-George Carlin

cleanac ::

JanK je izjavil:

- Z dobrim formatiranjem in sprotnim komentiranjem kode je preglednost popolnoma OK, kot kaze izvlecek kode


To, da moreš komentirati kaj tvoja koda počne je samo po sebi znak, da koda ni pregledna in berljiva. Koda mora biti berljiva brez komentarjev, ki pojasnjujejo kaj počne. Komentarji se uporabljajo, da obrazložiš zakaj si nekaj naredil, kakor si. Kar počne koda se napiše za posamezno funkcijo, ki pa ima samo eno nalogo ("počne" eno stvar), oz bi naj imela.

FrEaKmAn ::

cleanac je izjavil:

JanK je izjavil:

- Z dobrim formatiranjem in sprotnim komentiranjem kode je preglednost popolnoma OK, kot kaze izvlecek kode


To, da moreš komentirati kaj tvoja koda počne je samo po sebi znak, da koda ni pregledna in berljiva. Koda mora biti berljiva brez komentarjev, ki pojasnjujejo kaj počne. Komentarji se uporabljajo, da obrazložiš zakaj si nekaj naredil, kakor si. Kar počne koda se napiše za posamezno funkcijo, ki pa ima samo eno nalogo ("počne" eno stvar), oz bi naj imela.


se strinjam.. tista koda zgoraj ni ravno za kazat naokoli :)

BigWhale ::

FrEaKmAn je izjavil:

cleanac je izjavil:

JanK je izjavil:

- Z dobrim formatiranjem in sprotnim komentiranjem kode je preglednost popolnoma OK, kot kaze izvlecek kode


To, da moreš komentirati kaj tvoja koda počne je samo po sebi znak, da koda ni pregledna in berljiva. Koda mora biti berljiva brez komentarjev, ki pojasnjujejo kaj počne. Komentarji se uporabljajo, da obrazložiš zakaj si nekaj naredil, kakor si. Kar počne koda se napiše za posamezno funkcijo, ki pa ima samo eno nalogo ("počne" eno stvar), oz bi naj imela.


se strinjam.. tista koda zgoraj ni ravno za kazat naokoli :)


Prosim, ce dopolnita podatke na forumu, da bomo drugi vedeli koga ne zaposliti v prihodnosti. Hvala. Hkrati bi pa prosil line-by-line analizo zakaj tale koda ni ravno za kazat naokoli.

JanK je pa eden izmed redkih, ki sem ga na forumu videl uporabiti std:: in to si zasluzi extra pohvalo. :>

johnnyyy ::

cleanac je izjavil:

To, da moreš komentirati kaj tvoja koda počne je samo po sebi znak, da koda ni pregledna in berljiva. Koda mora biti berljiva brez komentarjev, ki pojasnjujejo kaj počne. Komentarji se uporabljajo, da obrazložiš zakaj si nekaj naredil, kakor si. Kar počne koda se napiše za posamezno funkcijo, ki pa ima samo eno nalogo ("počne" eno stvar), oz bi naj imela.

Odvisno od kode in algoritma, ki ga hočeš spravit v določeno funkcijo oz. set funkcij. Če je iz matematičnega vidika problem enostaven, potem ni težko pisat berljivih funkcij. Če pa je problem že iz matematičnega stališča težaven in kompleksen, je pa druga zgodba. Lahko ga razbiješ na 100 delov, pa ga čez nekaj let niti sam ne boš razumel.

3p ::

JanK je izjavil:

3p je izjavil:

...Če imaš funkcije dolge 100 vrstic (ali še več), je tvoj program nepregleden, pa goto gor ali dol.


To je spet posplosevanje, podobno kot "ne uporabljaj goto".

V svoji C++ kodi za real-time multithreaded aplikacijo, ki zajema zive podatke, jih obdeluje, uporablja razne sorte numericnih algoritmov, nelinearno fitanje, FFT filtriranje,.. imam nekaj funkcij, ki so dolge po 600-800 vrstic in vec. Koda je sicer popolnoma objektno zasnovana, robustna, fault-tolerant, hitra, in povecini so metode klas precej kratke.

Tudi omenjene funkcije so metode v klasah. Ampak vsaka izmed njih opisuje del postopka, ki bi se ga sicer dalo razdrobiti na podfunkcije, bilo pa bi nesmiselno, kajti:

- posamezni kosi kode se pojavljajo samo na enem mestu, se ne ponavljajo
- V postopku priprave vhodov za numericne funkcije, se nabere dovolj spremenljivk in povezave med njimi so dovolj kompleksne, da bi podfunkcije morale imeti po 10 parametrov ali pa bi spremenljivke moral (brez potrebe) narediti kot polja v klasah, kamor ne spadajo
- Z dobrim formatiranjem in sprotnim komentiranjem kode je preglednost popolnoma OK, kot kaze izvlecek kode


Je posploševanje. Izjeme so ok, če jih znaš utemeljiti.

Res pa je tudi, da ni edin smisel funkcij, da se koda ne ponavlja, ampak tudi poenostavitev zaradi dodatnega nivoja abstrakcije, ko lahko podrobnosti zanemariš - oziroma brez njih razumeš metodo na višjem nivoju abstrakcije.

Nisem se ravno poglabljal v tvojo kodo, ker je več kot očitno kompleksna in na prvi pogled kar kliče po razbitju, mogoče kakem dodatnem razredu. Recimo samo hiter poskus: "// For Y we need to sum signals". Zakaj tole ne more postati sumSignals ali kaj podobnega? Če praviš da ne gre in ne bi bilo bolj pregledno, pač tudi mogoče. Razbijati na dele in potem imeti del1(); del2(); itd. je tudi brezveze. :)

noraguta ::

jadajada, jada, še en refucktoring manijak. razbija se po smiselnih sklopih. karkoli numeričnega ne boš tlačil na silo narazen, razen če si obseden z stylingom.

goto ni napačen, napačen je jezik kateri ga potrebuje. ampak ok stvar zgodovine. sej za programerja je fajn za pobe v supportu pa včasih malo manj.
Pust' ot pobyedy k pobyedye vyedyot!

cleanac ::

johnnyyy je izjavil:

cleanac je izjavil:

To, da moreš komentirati kaj tvoja koda počne je samo po sebi znak, da koda ni pregledna in berljiva. Koda mora biti berljiva brez komentarjev, ki pojasnjujejo kaj počne. Komentarji se uporabljajo, da obrazložiš zakaj si nekaj naredil, kakor si. Kar počne koda se napiše za posamezno funkcijo, ki pa ima samo eno nalogo ("počne" eno stvar), oz bi naj imela.

Odvisno od kode in algoritma, ki ga hočeš spravit v določeno funkcijo oz. set funkcij. Če je iz matematičnega vidika problem enostaven, potem ni težko pisat berljivih funkcij. Če pa je problem že iz matematičnega stališča težaven in kompleksen, je pa druga zgodba. Lahko ga razbiješ na 100 delov, pa ga čez nekaj let niti sam ne boš razumel.

Seveda obstajajo izjeme, kot povsod. To ne pomeni da se zdaj moraš tega vedno striktno držati, so le smernice in ne pravila.


@BigWhale > Brez skrbi, ne boš me rabil zaposliti. Sodelujem raje s podjetji, ki nimajo predznačenih bilančnih vrednosti.
Recimo to, da moraš komentirati ime spremenljivke pri deklaraciji je absurd (primer v kodi).

avister ::

"Chi square" je res absurd, ampak nič ni odveč - mogoče nekomu pomaga, kaj pa veš.

Komentarji so za možgane to, kar so indexi za bazo. Dodaten napor pri pisanju omogoči hitrejše iskanje.

+5 za koražjo JanK-ju, ker da svoj umotvor na slo-tech-ovo tnalco.

d_rems ::

Pravzaprav me je šele tale novička spomnila, da zadnjih 10 let odkar uporabljam Ruby sploh nisem pogrešal goto ;-)

Seveda pa uporabljam break in next v zankah, ki so bile glavni razlog za uporabo goto v preteklosti.

TheR

sisemen ::

Ta goto zgodba je čisti BS. Z ali brez, nesposoben developer naredi štalo v kodi. V nekaterih primerih pa je goto izredno koristen in poenostavi kodo (in jo naredi bolj berljivo), npr. pri upostevanju single point of exit.

c00L3r ::

'goto' is always evil - like in 'goto work' or 'goto school' ;)

Kot Anroid/Java developer sem čisto pozabil, da goto sploh obstaja. Ne vem, kje bi mi prav prišel.

Zgodovina sprememb…

  • spremenil: c00L3r ()

BigWhale ::

cleanac je izjavil:

Recimo to, da moraš komentirati ime spremenljivke pri deklaraciji je absurd (primer v kodi).


Nikjer ne pise, da to moras poceti. Tudi ni vedno to smiselno. Vcasih pa je. Nekaj za brez veze posplosujes. Pa se vedno nisi povedal zakaj je tista koda tako zanic.

Trenutno se ti samo zdi, da se spremenljivk ob deklaraciji ne komenitira. Vcasih se jih. Nujno ni, ko bos pa po petih letih pogledal tisto kodo, ti bo pa ze na prvi pogled jasno zakaj je nekaj spremenljivka tam. Kode se prebrati ne bos rabil, da bi to ugotovil, ker bos prebral komentar.

SimplyMiha ::

if(UsingGoto())
{
    goto Hell;
}


No, načeloma goto ni tako slab, vendar se lahko nespretnemu programerju zgodijo precej absurdni bugi. Iskanje bližnjic lahko vodi v še bolj kompliciran položaj.

Ahim ::

one too many je izjavil:

V enem APIju za zvočno kartico sem videl lepo rabo goto, ravno za upravljanje napak, kot je omenjeno v članku. Preprosto vsakič ko sem videl stavek goto, sem vedel, da to pomeni skok na izhod iz funkcije zaradi napake.

Ravno te dni sem imel problem z izračunom (dela) inverza posebne matrike. Ja, Ax=b, se nikoli ne rešuje kot x=(A^-1)b, vendar je precej težko dopovedat, da res rabim inverz. Tu pa se znanje večine konča...


Na sreco danes visokonivojski jeziki poznajo exceptione, torej je ob njihovi uporabi goto za upravljanje napak nepotreben.

In (zopet na sreco, vsaj za tiste, ki so pozabili srednjesolsko matematiko) visokonivojski jeziki, ki poznajo (imajo nekje opisan class) matrike, znajo tudi izracunati njen inverz :)

Apple ::

krneki0001 je izjavil:

V cobolu ga tudi naj nebi uporabljali, čeprav pa vseeno kdaj prav pride.
Recimo tukaj:
GOTO ABEND.


A ni boljš npr. CALL S99ABEND? :D
LP, Apple

krneki0001 ::

Apple je izjavil:

krneki0001 je izjavil:

V cobolu ga tudi naj nebi uporabljali, čeprav pa vseeno kdaj prav pride.
Recimo tukaj:
GOTO ABEND.


A ni boljš npr. CALL S99ABEND? :D



Ja, je. Če imaš tako sprogramirano, pa če imaš module, ki jih lahko kličeš. Če pa sam modul pregledaš, boš pa videl, da ima GOTO notri.
Asrock X99 Extreme 4 | Intel E5-2683V4 ES | 64GB DDR4 2400MHz ECC |
Samsung 250GB M.2 | Asus 1070 TI | 850W Antec | LC Tank Buster

one too many ::

Ahim je izjavil:

one too many je izjavil:

V enem APIju za zvočno kartico sem videl lepo rabo goto, ravno za upravljanje napak, kot je omenjeno v članku. Preprosto vsakič ko sem videl stavek goto, sem vedel, da to pomeni skok na izhod iz funkcije zaradi napake.

Ravno te dni sem imel problem z izračunom (dela) inverza posebne matrike. Ja, Ax=b, se nikoli ne rešuje kot x=(A^-1)b, vendar je precej težko dopovedat, da res rabim inverz. Tu pa se znanje večine konča...


Na sreco danes visokonivojski jeziki poznajo exceptione, torej je ob njihovi uporabi goto za upravljanje napak nepotreben.

In (zopet na sreco, vsaj za tiste, ki so pozabili srednjesolsko matematiko) visokonivojski jeziki, ki poznajo (imajo nekje opisan class) matrike, znajo tudi izracunati njen inverz :)

Hja, tisto je bil C.

Glede inverza pa, ni problem, da ne bi imel metode za inverz. Toda iskal sem čim hitrejši algoritem za inverz matrike posebne oblike, ki bi ga najverjetneje seveda moral tudi sprogramirati. Na vseh forumih pa sem našel samo nasvet, da mi inverza ni potrebno računati. Recimo linearni sistem Ax=b se ne rešuje kot x=(A^-1)b, temveč npr. z LU razcepom.
Saj ne, da so forumi zanesljiv vir informacij, ampak splača se pogooglat, če slučajno tvoj problem ni trivialen ter se na področje ne spoznaš preveč.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Analiza kode: goto rabimo po pameti

Oddelek: Novice / Znanost in tehnologija
2913212 (9772) one too many
»

Kritična ranljivost v GnuTLS neodkrita skoraj devet let (strani: 1 2 3 )

Oddelek: Novice / Varnost
13427671 (23229) jype
»

[Fortran] kje začeti?

Oddelek: Programiranje
242468 (1951) zee
»

[c++] goto,jump

Oddelek: Programiranje
181567 (1350) 64202
»

C++ & goto funkcija

Oddelek: Programiranje
61503 (1408) webblod

Več podobnih tem