Gå til innhold

Anbefalte innlegg

Det går jo an å tenke litt på hva slags datastruktur man har også. Hvorfor bruke et 2d array f.eks? "Samme" kode som HDSoftware har:

const int MAX = 800;
List<string> array = new List<string>(MAX);
for (int i = 0; i <= MAX; ++i)
array.Add(i.ToString());

Console.Write("Søke etter et tall: ");
string number = Console.ReadLine();

if(array.IndexOf(number) == -1)
Console.WriteLine("Tallet {0} ble ikke funnet.", number);
else
Console.WriteLine("Tallet {0} er funnet.", number);
Console.WriteLine("Ferdig med søket");

 

Er ganske enig med Manfred her...bruk aldri goto :p 2 nestede for looper er jo heller ikke akkurat så bra med tanke på optimalisering.

Fordi dette var et eksempel hentet fra MSDN og ikke et reelt eksempel fra mitt prosjekt. I mitt prosjekt er dette av en mye mer komplisert art og handler ikek om et "Gjett tallet" prinsipp. Var bare ute etter en måte å komme meg enkelt ut av en utenforliggende "løkke".

 

Har selv ikke brukt GOTO siden jeg kodet på CBM64 en gang på begynnelsen av 80 tallet så tanken slo meg ikke før Den grusomme Geir nevnte det. Var litt morsomt å se at C# selv i disse .NET dager fortsatt støtter GOTO, og at eksemplet faktisk ga GOTO en god mening. I dette tilfellet synes jeg faktisk GOTO kan være en grei sak. Men jeg er helt enig at GOTO firt kan tukle med programstrukturen og lesbarheten. Men siden vi her benytter LABELS så er ikke dette så kritisk. Viktigste grunnen (tror jheg da) til ikke å bruke GOTO er jo fra gamle dager da vi kodet med linjenummer. Var jo umulig å vite at deler av programmet plutselig kunne finne på å kjøre koden i linje 372. Men i dag bruker man jo Label's og dermed erdet veldig enkelt å se i koden at her kan noe komme til å kalle.....

Lenke til kommentar
Videoannonse
Annonse

Poenget mitt står fortsatt egentlig. Som en gammel lærer sa en gang, "hvis du "må" bruke goto, så har du gjort noe feil i utgangspunktet".

 

Akkurat hvorfor goto eksisterer fortsatt, er jeg forsåvidt litt usikker på selv, men mener å huske å ha hørt at svært mange kall blir optimalisert av kompilatorer til goto statements. Siden det også allerede er tilgjengelig på lavt nivå, så er det vel enkelt å ha støtte for det i alle programmeringsspråk. Er vel også et poeng at folk skal ha mulighet til å gjøre som de vil.

 

Som en liten kuriositet har faktisk PHP løst dette ganske elegant:

for($i=0;$i<10;$i++)
{
for($j=0;$j<10;$j++)
{
	if($j==5)
		break(2);
}
}

Lenke til kommentar
Poenget mitt står fortsatt egentlig. Som en gammel lærer sa en gang, "hvis du "må" bruke goto, så har du gjort noe feil i utgangspunktet".

 

Akkurat hvorfor goto eksisterer fortsatt, er jeg forsåvidt litt usikker på selv, men mener å huske å ha hørt at svært mange kall blir optimalisert av kompilatorer til goto statements. Siden det også allerede er tilgjengelig på lavt nivå, så er det vel enkelt å ha støtte for det i alle programmeringsspråk. Er vel også et poeng at folk skal ha mulighet til å gjøre som de vil.

 

Som en liten kuriositet har faktisk PHP løst dette ganske elegant:

for($i=0;$i<10;$i++)
{
for($j=0;$j<10;$j++)
{
	if($j==5)
		break(2);
}
}

Som tidligere nevnt har jeg støtte for dette i Clarion også, ved å breake mot en label

L1:  Loop i = 1 to 100
L2:	Loop o = 1 to 100
	  if i * o = 50 then break L1.
	 .
   .

 

Til det andre du skriver om omgjøring til GOTO så regner jeg med du sikter til Mnemonic instruksjonen JMP eller Jump. Den går igjen hele tiden i et maskinkode program så det er slett ikke uvanlig med GOTO. Tror "antigoto" heller henger ihop med at språgene blir så avanserte etter hvert at man "liksom" setter bruken av GOTO som unødvendig. Det at man har kodet feil hvis man "må" bruke GOTO er bare tull, men mer en oppfattelse av hva strukturert programmering er for noe. Det har null og niks å si for programmet om man bruker GOTO eller ikke og vil aldri føre til hverken kompilleringsfeil eller fremtidige feil i programmet.

GOTO gjør akkurat det den skal gjøre og, som du hentyder, hvis du dissassembler programmet ditt så vil du finne et mylder av JMP instruksjoner, som nettop ER GOTO.

 

Det har liksom blitt fy og skam å bruke GOTO bare fordi noen "bedrevitere" har sagt at det er slik.

C# støtter ikke terminering av utenforliggende løkker på annen måte enn å bruke GOTO og da er GOTO helt greit for meg. Dessuten er også GOTO den eneste måten å kombinere CASE behandlinger på i en SWITCH så dermed er det faktisk to veldig gode grunner til GOTO hvis man kommer i en slik situasjon.

Hvis - altså ;-)

Lenke til kommentar
  • 1 måned senere...

Noen "bedrevitere"? Tror ikke jeg vet om noen utviklere som ville funnet på å foreslå å bruke goto. Muligens hardcore BASIC-utviklere, men jeg vet ikke om det finnes noen slike lenger. ;)

 

Goto er et helvete. Det finnes et vell av måter å håndtere programflyt som fungerer veldig bra, og jeg kommer ikke på en eneste god grunn til å skulle bruke goto. Eksempelet fra MSDN er vel nærmest det eneste tilfellet hvor bruk av goto ikke fremkaller kvalmefornemmelser, men det var mye fordi eksempelet var latterlig simpelt. Og ærlig talt, at kode blir kompilert til et vell av JMP-instruksjoner er irrelevant. Det er tross alt ikke assembly-koding vi holder på med...

 

Det handler vel så mye om å skrive elegant og forståelig kode. Goto er nærmest antitesen. Og tro meg, skulle du etterlate deg et prosjekt hvor du har brukt goto, så vil de som tar over prosjektet etter deg anta at dine programmeringssynder er mange og koden din vil bli mistenkeliggjort ved ethvert problem som oppstår. De vil også baksnakke deg i lang tid fremover. Goto.. det gjør man bare ikke. Du har blitt advart... Og hadde du vært på mitt team, ville jeg alvorlig vurdert å få deg byttet ut, om mulig.

 

Og i forhold til ytelse. Godt mulig goto sparer deg noen instruksjoner, uten at jeg har satt meg inn i hvilke maskininstruksjoner vi faktisk ender opp med, men det er svært sjeldent man faktisk har behov for å spare inn de få millisekundene. Tiden man sparer står ikke i forhold til andre ting som tar mye mer tid, som nettverksoverføring, ressurshåndtering, etc. Spesielt i forretningsapplikasjoner, som er det de fleste vil jobbe med. Man burde dermed heller bruke tid på å optimalisere slike ting, enn å forkludre koden med goto. Og skriver man ytelseskritisk programvare, har man uansett tatt et veldig galt valg i utgangspunktet ved å gå for .NET og C#...

 

Til slutt, terminering av utenforliggende løkker håndterer man ved hjelp av flagg. Det er ikke ofte man har behov for det, og det er neppe noe du vil se bli håndtert noen gang i fremtiden av kompilatoren. Og føler du behov for å kombinere case-blokker i en switch, burde du kanskje vurdere en "if-else if" istedenfor. Bruker du goto for å kombinere case-blokker, øker du samtidig kompleksiteten mer enn du aner og smeller lesbarheten i bånn. Det ser tilforlatelig ut i utgangspunktet, men slike ting har en tendens til å eskalere. Det som startet som en enkel switch, har plutselig blitt et tre-hodet monster. Når du så skal vedlikeholde koden om et år vil du forbanne idéen om å bruke goto, når du blir nødt til å nøste opp i labelene du har rundt omkring i koden og hvor labelene blir brukt... Til slutt sitter du igjen med å måtte steppe igjennom koden for å i det hele tatt ha snøring på hva som foregår.

 

Ja, jeg HATER goto. :)

Lenke til kommentar

Den er sikkert kjekk den i php (break(2); altså) men sånn jeg ser det, så er også dette en goto med et annet navn.

Den bryter programflyten like mye som en goto ville gjort.

 

for(int i = 0; i < 100; i++)
 for(int j = 0; j < 100; j++)
if(j == 50)
  break(2);

 

Ville faktisk vært hakket verre en dette i mine øyne:

 

for(int i = 0; i < 100; i++)
 for(int j = 0; j < 100; j++)
if(j == 50)
  goto end_loop;
end_loop:

 

Begge to bryter programflyten fullstendig.

 

for(int i = 0; i < 100; i++)
 for(int j = 0; j < 100; j++)
if(j = 50)
{
  i = 100;
  break;
}

 

bool flag = true;
for(int i = 0; i < 100 && flag; i++)
 for(int j = 0; j < 100; j++)
if(j == 50)
{
  flag = false;
  break;
}

 

Jeg stemmer for sistnevnte, fordi den forklarer bra hva som skjer, og programflyten er fortsatt intakt

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...