Noter til C# Programmering

Selektion

Sætninger

Alle sætninger i C# slutter med et semikolon. En sætning kontrollerer sekvensen i programafviklingen, evaluerer et udtryk eller gør ingenting…

Blanktegn

Mellemrum, tabulatorer og ny linje kaldes under ét for blanktegn. Blanktegn ignoreres af kompileren. Dvs. at hver gang man laver et mellemrum, så kan man lige så godt benytte en tabulator eller en ny linje. Blanktegn gør blot koden lettere at læse.

Sammensat sætning

På ethvert sted, hvor man kan placere en sætning kan man placere en sammensat sætning. En sammensat sætning begynder med en venstre-tuborg "{" og slutter med en højre-tuborg "}". Enhver sætning, som er indeholdt i en sammensat sætning, skal slutte med et semikolon, medens den sammensatte sætning selv ikke skal.

Operatorer

Der findes to generelle typer af operatorer:

·         Aritmetiske

·         Relationelle og logiske

Aritmetiske operatorer

Herunder listes nogle af de aritmetiske operatorer

 

Symbol

Operation

Eksempel

Værdi

+

Addition

3 + 5

8

Subtraktion og fortegn

43 - 25

18

*

Multiplikation

4 * 7

28

/

Division

9 / 2

4

% (heltal)

Modulus (Restdivision)

20 % 6

2

‑ ‑  (postfix)

Nedskrivning

6 ‑ ‑

5

++  (postfix)

Opskrivning

6 ++

7

‑ ‑  (prefix)

Nedskrivning

‑ ‑ 6

5

++  (prefix)

Opskrivning

++ 6

7

Bemærk, at hvis divisions-operatoren "/" benyttes i forbindelse med to heltal, så returneres et heltal, idet resten smides bort. (Heltalsdivision)

Eksempel:

int x = 10, y = 3, z;

z = x/y; // z har nu værdien 3

Det unære minus (fortegnsminus), multiplicerer den enlige operand med (‑1).

Eksempel:

int x = 10, y;

y = -x;  // y har nu værdien -10

Bemærk op- og nedskrivningsoperatorerne (increment og decrement). Disse operatorer var oprindeligt enestående for C++, og er nu taget med over i Java-sproget og senest C#. Den kvikke læser kan muligvis nu se, hvordan C++ har fået sit navn, idet C++ er udviklet på baggrund af sproget C.

Eksempel:

x = x + 1;

Kan skrives som

++x; // præfix opskrivning

eller som

x++; // postfix opskrivning

På samme vis for nedskrivningsoperatoren. Post- og præfix-notationen giver mulighed for at påvirke, hvorvidt en op- eller nedskrivning udføres før eller efter at operanden er evalueret. Betragt de to følgende eksempler:

int x = 10, y;

y = ++x;

// værdien af y er nu 11 og værdien af x er også 11

Variablen x opskrives ved præfix-notationen før værdien tildeles variablen y.

int x = 10, y;

y = x++;

// værdien af y er nu 10 og værdien af x er 11

Variablen x opskrives ved postfix-notationen først efter at dens oprindelige værdi er tildelt variablen y.

Det er faktisk muligt, at opskrive en værdi på endnu en måde i C#. Følgende 4 sætninger er ens:

x = x + 1;

x++;

++x;

x += 1;

Det er da forvirrende…?

I lighed med "selvtildelingsoperatoren" +=, så findes følgende: ‑=, *=, /=, %=. Disse fungerer som vist:

x -= 1;          // Svarer til x = x - 1

x *= 2;          // Svarer til x = x * 2

x /= 3;          // Svarer til x = x / 3

x %= 4;          // Svarer til x = x % 4


Operatorerne rangordnes som følger:

 

Rangorden

Operatorer

Højst

( )

 

++   ‑ ‑  (postfix)

 

++   ‑ ‑  (prefix)

 

‑ (unært minus)

 

*  /  %

 

+ 

Lavest

=

Relationelle og logiske operatorer

Følgende relationelle operatorer anvendes til sammenligninger:

 

Symbol

Betydning

Eksempel

Værdi

< 

Mindre end

3 < 5

Sand

> 

Større end

4 > 7

Falsk

<=

Mindre end eller lig med

43 <= 25

Falsk

>=

Større end eller lig med

9 >= 2

Sand

==

Lig med

20 == 6

Falsk

!=

Forskellig fra

20 != 6

Sand

 

Følgende logiske operatorer anvendes:

 

Symbol

Betydning

Eksempel

Værdi

&&

AND

(3 < 5) && (4 == 4)

Sand

||

OR

(3 < 5) || (4 != 4)

Sand

!

NOT

!(4 == 4)

Falsk

Operatorerne rangordnes som følger:

 

Rangorden

Operatorer

Højst

! (NOT)

 

>  >=  <  <=

 

==  !=

 

&& (AND)

Lavest

||  (OR)

Bemærk, at aritmetiske operatorer rangordnes højere end relationelle og logiske.

Sandhedstabel

Nedenstående tabel giver et hurtigt overblik over boolsk algebra. To boolske værdier, p og q, evalueres med NOT, AND, OR og XOR, og resultatet gives. I daglig tale svarer AND til "både/og", OR svarer til "og/eller", medens XOR svarer til "enten/eller".

 

p

q

NOT p

p AND q

p OR q

p XOR q

Sand

Sand

Falsk

Sand

Sand

Falsk

Sand

Falsk

Falsk

Falsk

Sand

Sand

Falsk

Sand

Sand

Falsk

Sand

Sand

Falsk

Falsk

Sand

Falsk

Falsk

Falsk

XOR (Exclusive OR) findes godt nok iboende i C#, (^); men man kan også hurtigt lave en metode, der kan foretage en XOR:

<modifikatorer> bool xor(bool a, bool b) {

  return (a || b) && !(a && b);

}

Omskrivninger af boolske udtryk vha. DeMorgans sætning:

 

Oprindeligt udtryk

Omskrevet udtryk

NOT p AND NOT q

NOT(p OR q)

NOT p AND q

NOT(p OR NOT q)

p AND NOT q

NOT(NOT p OR q)

p AND q

NOT(NOT p OR NOT q)

NOT p OR NOT q

NOT(p AND q)

NOT p OR q

NOT(p AND NOT q)

p OR NOT q

NOT(NOT p AND q)

p OR q

NOT(NOT p AND NOT q)

Hvis man vil benytte DeMorgans sætning på den logiske operator AND eller den logiske operator OR og to operander, så skal man negere begge operander bytte om på AND og OR, og sluttelig negere hele udtrykket.

if-sætningen

Programmet afvikles som nævnt linje for linje i den rækkefølge, som det er skrevet i koden. if-sætningen gør det muligt, at evaluere et udtryk, og på baggrund heraf at forgrene programafviklingen til forskellige dele af koden.

Eksempel:

if (stortTal > lilleTal)

  stortTal = lilleTal

Koden sammenligner stortTal og lilleTal. Hvis resultatet er sand, så tildeles variablen stortTal værdien af variablen lilleTal. Herefter fortsætter programafviklingen sekventielt.

else

Man vil ofte have brug for, at programafviklingen forgrener sig til en side, hvis betingelsen i if-parentesen er sand og til en anden side, hvis den er falsk. Dette klan naturligvis gøres ved først at teste en situation og dernæst en anden; men else-nøgleordet giver os mulighed for skrive koden på en lettere og mere læselig måde.

Eksempel:

int tal1, tal2;

Console.Write("Indtast et stort tal: ");

tal1 = int.Parse(Console.ReadLine());

Console.Write("Indtast et lille tal: ");

tal2 = int.Parse(Console.ReadLine());

if (tal1 > tal2)

  Console.WriteLine("Rigtigt!");

else

  Console.WriteLine("Ahæm... det andet tal er størst!");

Console.ReadLine();

Komplekse if-sætninger

Husk, at sætningen, som afvikles efter at betingelsen i if-parentesen er evalueret også kan være en sammensat sætning. Denne sætning kan igen bestå af en if-sætning osv. Se følgende eksempel på en kompleks indlejret if-sætning:

Eksempel:

int tal1, tal2;

Console.Write("Indtast et tal: ");

tal1 = int.Parse(Console.ReadLine());

Console.Write("Indtast endnu et tal: ");

tal2 = int.Parse(Console.ReadLine());

 

if (tal1 >= tal2) {

  if ((tal1 % tal2) == 0) {

    if (tal1 == tal2)

      Console.WriteLine("Tallene er ens!");

 

    else

      Console.WriteLine("Tallene kan divideres!");

  }

  else

    Console.WriteLine("Tallene kan ikke divideres!");

}

else

  Console.WriteLine("Det andet tal er størst!");

Console.ReadLine();

Læg mærke til brugen af tuborg-klammerne. Brugen af disse samt indryk er med til at gøre koden lettere at læse og forstå. De følgende to eksempler viser, hvorfor brugen af tuborg-klammer er hensigtsmæssig. Prøv at indtaste kodeeksemplerne og kør dem. Hvad går galt i det første eksempel?

Eksempel:

int tal;

Console.Write("Indtast et tal: x, hvor x<10 eller x>100: ");

tal = int.Parse(Console.ReadLine());

 

if (tal > 10)

  if (tal < 100)

    Console.WriteLine("Tallet skal være større end 100, tak!");

  else

    Console.WriteLine("Tallet skal være mindre end 10, tak!");

Console.ReadLine();

 


Eksempel:

int tal;

Console.Write("Indtast et tal: x, hvor x<10 eller x>100: ");

tal = int.Parse(Console.ReadLine());

 

if (tal > 10) {

  if (tal < 100)

    Console.WriteLine("Tallet skal være større end 100, tak!");

}

else

  Console.WriteLine("Tallet skal være mindre end 10, tak!");

Console.ReadLine();

if-else-if stigen

if-else-if stigen er en meget anvendt programstruktur, som kan illustreres vha. af følgende eksempel:

int tal;

Console.Write("Indtast et af flg. tal (0, 1, 2, 3, 4, 5):");

tal = int.Parse(Console.ReadLine());

 

if (tal == 1) Console.WriteLine("Tallet er ét");

else if (tal == 2) Console.WriteLine("Tallet er to");

else if (tal == 3) Console.WriteLine("Tallet er tre");

else if (tal == 4) Console.WriteLine("Tallet er fire");

else Console.WriteLine("Tallet er mindre end 1 eller større end 4");

Console.ReadLine();

Prøv at indtaste det ovenstående eksempel og kør det! Som man vil se, så afvikles programmet oppefra og nedefter. Når en betingelse er opfyldt, så afvikles den tilhørende sætning, og resten af stigen springes over. Hvis ingen betingelser er opfyldte, så afvikles sætningen, som følger efter det sidste else-nøgleord, og alle andre sætninger i stigen overspringes

switch-sætninger

kombinationer af if og elseif kan blive meget uoverskuelig, hvis de indlejres i flere niveauer. Heldigvis findes der et brugbart alternativ i C#: switch, der i modsætning til if tillader, programafviklingen kan forgrene sig på baggrund af et utal af forskellige værdier. Herunder er listet et eksempel

Eksempel:

int tal;

Console.Write("Indtast et tal mellem 0 og 4: ");

tal = int.Parse(Console.ReadLine());

 

switch (number)

{

case 0: Console.WriteLine("Dejligt rundt tal!");

        break;    // Spring ud af strukturen

case 4:

case 3:

case 2:

case 1: Console.WriteLine("Positivt!");

        break;

default: Console.WriteLine("Uden for nummer ... desværre!");

         break;

}

Brugeren bedes indtaste et tal mellem 1 og 4. I switch-parentesen evalueres tallet. Her kan placeres ethvert gyldigt C#-udtryk. case-sætningerne gennemgås nu oppefra og nedefter i søgen efter et tal som matcher tallet i switch-parentesen, dvs. som er lig med dette tal. Herefter udføres sætningen efter case, eller programmet fortsætter sekventielt indtil et break tvinger programafviklingen ud af strukturen. Hvis ingen case matcher, så afvikles koden under default. Prøv at indtaste det ovenstående eksempel og kør det. Opfører programmet sig, som du forventer?