6 Selektion

I förra avsnittet lärde vi oss hur en upprepning kan ske baserat på olika villkor. Nu kommer vi istället titta på hur man kan få programmet att göra en eller flera olika saker baserat på ett eller flera villkor. Med andra ord ska vi skapa olika “vägar” genom en algoritm. Vi kallar detta för selektion!

Om vi tänker oss ett exempel där beroende på inläst temperatur i en kopp med kaffe så skall texten “Kaffet är varmt!” eller “Kaffet är inte klart.” skrivas ut. Gränsen för varmt kaffe sätter vi på 65 grader C. I form av strukturdiagram ser det då ut såhär:

Strukturdiagram med selektion.

Konstruktionen är densamma som för iteration (diamantstruktur) men texten inuti är annorlunda. Nu anger vi istället “om någonting” istället för “så länge som någonting”. Båda vägar ut ur diamantstrukturen leder också vidare i programmet - inte tillbaka in i samma struktur som tidigare.

Om vi översätter ovanstående strukturdiagram till pseudokod skulle den se ut såhär:

start
    läs in kaffetemp
    om kaffetemp > 65
        skriv ut "Kaffet är varmt!"
    annars
        skriv ut "Kaffet är inte klart."
slut

6.1 Selektion i C#

När vi sedan ska implementera detta (ovanstående algoritm) i källkod med C# så är nyckelordet vi använder if. Man säger ofta att man skriver en if-sats (eller om-sats, villkorssats, selektion). Direkt efter if sätter vi en parantes och inom parantesen det villkor som ska undersökas. Därefter kommer måsvingar {} som innehåller de kodstycken som ska köras om villkoret är sant. Efter måsvingarna kommer nyckelordet else följt av ett nytt par måsvingar. Inom dessa skriver man den kod som ska köras om villkoret är falskt. Såhär skulle det se ut:

Console.Write("Mata in kaffetemp (C): ");
string inlasning = Console.ReadLine();
int kaffetemp = int.Parse(inlasning);
if (kaffetemp > 65)
{
    Console.WriteLine("Kaffet är varmt!");
}
else
{
    Console.WriteLine("Kaffet är inte klart.");
}

Det kan ju givetvis vara så att det finns flera olika villkor som ska undersökas. Vi skulle t.ex. kunna skriva ett program som avgör ifall ett inmatat tal är större än, mindre än eller lika med 100. Det blir då två villkor att undersöka. Först om det är större än 100, sen om det är mindre än 100. Om inget av dessa är sanna så måste det vara lika med 100. Källkoden skulle då kunna se ut såhär:

Console.Write("Mata in ett tal: ");
string inlasning = Console.ReadLine();
int tal = int.Parse(inlasning);
if (tal > 100)
{
    Console.WriteLine(tal + " är större än 100.");
}
else if (tal < 100)
{
    Console.WriteLine(tal + " är mindre än 100.");
}
else
{
    Console.WriteLine("Ditt tal är exakt 100.");
}

Lägg märke till raden med else if. Detta villkor kontrolleras endast om det ovanstående utvärderas till falskt. Dvs. om talet inte är större än hundra, kontrollera då om det är mindre än hundra. Utifall inget av dessa två villkor är sanna då körs kodstycket under else och endast då. Man har möjlighet att lägga till hur många else if som helst men så fort ett villkor som blir sant stöts på så hoppas resten av villkoren över - de kontrolleras inte ens.

Med villkorssatsen bör vi samtidigt lära oss några nya jämförelseoperatorer (vi har redan tittat på < > <= >=). Vi vill kunna jämföra om något är exakt lika med (och endast lika med) eller skilt från (mer om operatorer generellt längre fram i kursen). Att jämföra likhet görs med dubbla likhetstecken == (det enkla likhetstecknet betyder ju tilldelning) och skilt från skrivs med utropstecken och sedan likhetstecken !=.

Vardagligt språk Matematik Källkod
Lika med = ==
Skilt från \(\ne\) !=

Några exempel nedan.

Uttryck Värde
2 == 3 falskt
2 != 3 sant
'a' != 'b' sant
"Martin" == "Martin" sant
5 + 7 == 12 sant
(3 * 3 == 12) == (15 < 12) sant

Dessa uttryck kan göras väldigt långa och komplexa samt innehålla variabler men god praxis är att försöka hålla dom så läsbara som möjligt.

Eftersom att dessa villkor ska undersökas om de är sanna eller falska (inga andra utfall finns) så blir variabler av typen bool något mer användbara, särskilt i kombination med bra variabelnamn. Studera exemplet nedan:

Console.Write("Har du läst Matematik 4? (Ja/Nej): ");
string ma4 = Console.ReadLine();
Console.Write("Har du läst Fysik 2? (Ja/Nej): ");
string fy2 = Console.ReadLine();

bool kanBliIngenjor = false;
if (ma4 == "Ja")
{
    if (fy2 == "Ja")
    {
        kanBliIngenjor = true;
    }
}

if (kanBliIngenjor)
{
    Console.WriteLine("Grattis, du kan bli ingenjör!");
}
else
{
    Console.WriteLine("Du kan tyvärr inte bli ingenjör.");
}

Raden if (kanBliIngenjör) går ju att läsa upp på ren svenska/engelska - lättförståeligt för andra som läser våra program! Vi behöver inte jämföra om variabler av typen bool är lika med true eller false eftersom att det är de enda två värden som kan lagras och även de enda två värden som ett villkor kan utvärderas till - dvs. variabeln ÄR ju redan true eller false.

6.1.1 Flera villkor & logiska operatorer

Utöver jämförelseoperatorerna finns det också ett par logiska operatorer vi kan använda för att bygga mer komplexa villkorsuttryck.

Operator Betydelse
! Icke/negation
|| Eller
&& Och
  • Icke (!) betyder helt enkelt motsatsen till uttrycket. Det som är sant görs falskt och det som är falskt görs sant.
  • Eller (||) innebär att ett av två uttryck ska vara sant för att hela uttrycket ska bli sant. Antingen det ena eller det andra.
  • Och (&&) medför att båda två uttryck måste vara sanna för att uttrycket som helhet ska bli sant. Det ena och det andra.

Vi tar några exempel:

Uttryck Värde
!true falskt
!false sant
true || false sant
true && false falskt
5 == 1 || -1 < 0 sant
5 == 1 && -1 < 0 falskt
2 < 3 || 5 > 4 sant
2 < 3 && 5 > 4 sant

Med följande variabelvärden kan vi även titta på ytterligare exempel:

  • int a = 7;
  • int b = 10;
  • int c = -3;
  • int d = 0;
  • bool e = true;
Uttryck Värde
a > b falskt
a != b sant
b + c == a sant
(a != c) && (b + c != a) falskt
e || (b < a) sant
!(c > d) sant
((a + b + c) > d) && !e falskt

6.2 Övningar

Genomför övningarna i tre steg: strukturdiagram, pseudokod och sedan källkod.

  1. Läs in två tal och skriv ut vilket av dem som är störst.
  2. Läs in två tal och skriv ut vilket av två tal som är minst. Om talen är lika skall detta skrivas ut.
  3. Läs in mönsterdjupet på ett däck (mm). Om mönsterdjupen är större än 1,6 mm skall texten ”Lagligt” skrivas ut, annars skrivs en text ut som berättar hur mycket som fattas för att det ska räknas som lagligt.
  4. Lagra ett lösenord i en variabel. Låt användaren skriva in ett ord. Kontrollera om lösenordet är rätt eller fel.
  5. Vad blir kostnaden för ett inköp om en affär ger 10 % rabatt på lösviktsgodis om vikten överstiger 5 hg? Läs in vikt i hg och priset per hg.

Nedanstående uppgifter behöver du endast lösa med källkod.

  1. Läs in två tal och undersök om det första talet är jämnt delbart med det andra (tänk på att delat med-operatorn utför heltalsdivision).
  2. Testkör de två kodstyckena nedan.
int tal = 11;
if (tal > 1)
{
    Console.WriteLine("Större än 1.");
}
else if (tal > 10)
{
    Console.WriteLine("Större än 10.");
}
else if (tal > 100)
{
    Console.WriteLine("Större än 100.");
}
int tal = 11;
if (tal > 1)
{
    Console.WriteLine("Större än 1.");
}
if (tal > 10)
{
    Console.WriteLine("Större än 10.");
}
if (tal > 100)
{
    Console.WriteLine("Större än 100.");
}

Vad skriver respektive program ut? Vad beror skillnaden på?

  1. Skriv ut om en golfspelare klarar att undvika en vattenfylld damm. För att undvika dammen måste golfspelaren slå ett slag som är kortare än 150 meter eller längre än 190 meter.
  2. Läs in ålder och skriv ut vad bussbiljetten kostar. Biljetten är gratis för barn under 4 år, från 4 till 17 år kostar den 16 kr. och om man är äldre än 17 kostar den 25 kr.
  3. Du ska registrera ålder vid en mässa. Beroende på ålder så ska besökarna få olika färger på sin bricka. Skriv ett program som svarar med rätt färg enligt tabellen:
Ålder Färg
0-12 vit
13-18 grön
19-25 röd
26-99 blå
Övriga åldrar Skriv ut “Ogiltig ålder”
  1. Gör ett program som frågar efter ett tal. Efter inmatning undersöker programmet tecknet på talet och skriver ut om talet är positivt, 0 eller negativt.
  2. Skriv ett program som fungerar som en enkel miniräknare. Användaren får mata in två tal samt ett räknesätt och programmet svarar med resultat. Om något annat tecken än + - * / matas in på räknesätt så skrivs texten “Okänt räknesätt.” ut.

Exempelkörning av miniräknaren.

  1. För att slå klubbrekord i en längdhoppstävling måste hoppet vara längre än 7,92 meter och vindstyrkan högst 2,0 m/s. Skriv ett program som låter användaren mata in värden och som skriver ”Grattis, nytt rekord!” om det är ett nytt rekord. Om det inte är ett nytt rekord skriver programmet ut ”Tyvärr, inget nytt rekord!”. (Tips: Man kan skriva if-satser inuti if-satser)
  2. Företaget AB Rikspucko söker nya anställda. För att få en tjänst måste två av tre villkor vara uppfyllda: vara man, vara yngre än 30 år och inte ha några barn. Skriv ett program som ställer tre frågor och som sedan visar om man är kvalificerad för en tjänst eller inte.

Exempelkörning av AB Rikspucko.