© 2006, Flemming Koch Jensen
Alle rettigheder forbeholdt
Kontrolstrukturer

 

 

Kontrolstrukturerne i C# lægger sig generelt meget op ad de tilsvarende i C++/Java; hvilket ikke kan overraske, da det netop har været et designmål for C#, at det skulle ligne C++/Java for at gøre det let at lære.
I det følgende vil vi primært fokusere på hvad der er specielt i C#.
goto tilbage En ting vi måske allerede bør løft sløret for, er at C# genindfører goto, efter at Java ellers havde afskaffet den. Af samme grund har C# ikke labeled break og continue som det er kendt fra Java, da goto bruges i de situationer hvor disse ellers ville blive anvendt.

 

1. Selektion

 

1.1 if-sætningen

if-sætningen (og if-else-sætningen) er hurtigt overstået - den er fuldstændig som i C++/Java.

 

1.2 switch-sætningen

C# har også en switch-sætning, og den er i alt væsentlighed også som den tilsvarende i C++/Java - men den kan lidt mere!

Som altid kunne det være ønskeligt at man kunne anføre andet end numeriske konstanter i case-sætningerne (hvilket er begrænsningen i C++/Java). I C# er det også muligt at anføre tekststrenge som konstanter. F.eks.:
string s = null;

switch ( s ) {
  case null:
    Console.WriteLine( "Hej - eller hva?" );
    break;
  case "dansk":
    Console.WriteLine( "Hej verden" );
    break;
  case "engelsk":
    Console.WriteLine( "Hello World" );
    break;
  default:
    Console.WriteLine( "11001001" );
    break;
}
Hej - eller hva?
Bemærk at man kan anvende null.
Kan ikke glemme break Hvis man i C++/Java glemmer det berømte break, vil udførelsen fortsætte ned i den efterfølgende case osv. En irriterende fejl, da den kan være svær at se i koden. I C# har man taget konsekvensen, og det bliver ganske enkelt regnet som en compileringsfejl hvis man glemmer det (selv for default!).
Hvis vi f.eks. havde glemt break efter default, i ovenstående eksempel, kunne vi få en fejl i stil med:
switch_test.cs(10,1): error CS0163: Control cannot fall through from one case
        label ('default:') to another
Man kan dog stadig kombinere flere case's, da det kun regnes som en fejl hvis en case-sætning indeholder sætninger. F.eks. er følgende tilladt, da case 1 ikke har nogen sætninger:
int i = 1;

switch ( i ) {
  case 1:
  case 3:
    Console.WriteLine( "Ulige" );
    break;
  case 2:
    Console.WriteLine( "Lige" );
    break;
  default:
    Console.WriteLine( "ukendt værdi" );
    break;
}
Selvom vi i disse eksempler har anført default, er det (som i C++/Java) frit om man vil.
Historien om break er ikke helt slut med det, da det er muligt at anvende andet end break.
goto case <konstant udtryk>
Dette giver mulighed for at man kan springe fra en case til en anden

Andre jump-sætninger
Det er muligt at anvende alle andre, såkaldte jump-sætninger. Disse er return, throw, continue og almindelig goto.

Det betyder at en af disse (eller break) skal afslutte en case - ellers er det en fejl.

 

1.3 ?: - Den tertiære operator

Den tertiære operator ?: fungerer fuldstændig som i C++/Java.

 

2. Iteration

 

2.1 while-sætningen

while-sætningen fungerer fuldstændig som i C++/Java.

 

2.2 do-while-sætningen

do-while-sætningen fungerer fuldstændig som i C++/Java.

 

2.3 for-sætningen

for-sætningen fungerer fuldstændig som i C++/Java.
for-sætningen har en variant, der hedder foreach. Vi har allerede set i kapitlet Introduktion; hvordan den kan bruges til at gennemløbe et array, og vi vil studere forudsætningerne for at kunne bruge den i kapitlet Collection klasser.

 

2.4 break og continue

break og continue i relation til iterative kontrolstrukturer og switch fungerer som i C++/Java. Labeled break og continue findes ikke i C# - i stedet har vi goto:

 

3. goto

Det er måske lidt provokerende at placere omtalen af goto i slutningen at et kapitel om kontrolstrukturer - strukturer hvis primære formål er at erstatte goto med noget der er lettere at læse og vedligeholde.
Da man lavede Java fjernede man goto. Vi skal ikke her fordybe os i alle problemerne med goto - de er åbenbare for de fleste. goto fungerer på samme måde som i C++.
Da kontrolstrukturer skal erstatte anvendelsen af goto, er det nærliggende at gå den anden vej, når man skal illustrere goto for læsere der allerede kender kontrolstrukturer.
Følgende while-sætning:
int i=0;

while ( i<5 ) {
  Console.WriteLine( i );
  i++;
}
kan laves med goto på følgende måde:
int i=0;

again:
if ( !(i<5) )
  goto slut;

Console.WriteLine( i );
i++;
goto again;

slut:;
goto springer til label Ovenfor er der to goto-sætninger. Når en goto-sætning udføres, fortsætter programmet sin udførelse fra det sted hvor det tilhørende label er placeret. Når f.eks. goto again udføres vil programmet forsætte fra det sted, der står again:.
Et label angives ved at skrive dets navn, efterfulgt af et kolon. Et label skal tilknyttes en sætning; hvilket er grunden til det ekstra semikolon efter det sidste label (slut). Det første label (again) er tilknyttet if-sætningen.
Man bemærker at kørselsbetingelsen fra while-sætningen skal negeres for at konstruktionen med goto fungerer.