Magnus Lilja
Ulrik Nilsson
Dennis Berling
![]()
Magnus Lilja
Ulrik Nilsson
Dennis Berling


1. Introduktion 6
1.1 Grunder 7
1.2 Datorns funktion 9
1.3 Programstruktur 11
1.4 Om den här boken 12
Repetitionsfrågor 13
Uppgifter 13
2. Introduktion till utvecklingsmiljön
Visual Studio 2019 14
2.1 Visual Studio 15
2.2 Ett första exempel 18
2.3 Ett C#-programs struktur 21
2.4 Olika typer av fel 24
Sammanfattning 25
Repetitionsfrågor 26 Uppgifter 27
3. Variabler 28
3.1 Grunder 29
3.2 Deklaration 31
3.3 Tilldelning 31
3.4 Typomvandlingar 32
3.5 Tal 34
3.6 Text 36
3.7 Tecken 38
3.8 Unicode 39
3.9 Objekt 42
Sammanfattning 44
Repetitionsfrågor 46
Uppgifter 47
4. Felsökning 48
Sammanfattning 53
5. Operatorer 54
5.1 Grunder 55
5.2 Aritmetiska operatorer 55
5.3 Tilldelande aritmetiska operatorer 58
5.4 Förändringsoperatorer 58
5.5 Relationsoperatorer 60
5.6 Logiska operatorer 62
5.7 Prioriteringsregler 65
Sammanfattning 67
Repetitionsfrågor 68 Uppgifter 69
6. Aktivitetsdiagram och pseudokod 70
6.1 Algoritmer och pseudokod 71
6.2 Kontrollstrukturer 72
6.3 Aktivitetsdiagram 72
Sammanfattning 76
Repetitionsfrågor 76 Uppgifter 77
7. Villkorssatser 78
7.1 if-else 79
7.2 if 84
7.3 if – else if 87
7.4 switch-case 90
7.5 Att jämföra strängar 93
7.6* Villkorsoperatorn ? : 95
Sammanfattning 98
Repetitionsfrågor 100 Uppgifter 102
8. Grafiska gränssnitt och grafik 104
8.1 Grafiska gränssnitt 105
8.2 Grafik 112
Sammanfattning 116
Repetitionsfrågor 118
Uppgifter 119
9. Repetition 122
9.1 While 123
9.2 Do-while 126
9.3 For 127
9.4 Nästlade loopar 129
9.5 Continue och break 131
9.6 Fält 132
Sammanfattning 138
Repetitionsfrågor 139
Uppgifter 141
10. Metoder 142
10.1 Att skriva och anropa en metod 143
10.2 Metoder med flera parametrar 146
10.3 Värdeparametrar 148
10.4 Metoder utan returvärde 150
10.5 Referens och out-parametrar 152
10.6 Fält som parameter 156
Sammanfattning 158
Repetitionsfrågor 160
Uppgifter 162
11. Objekt och objektorientering. 164
11.1 Vad är objekt och objektorientering? 165
11.2 Objekt på praktisk nivå 169
11.3 Klasser med C# och Visual Studio 172
11.4 Förbättringar av programmet 179
Sammanfattning 185
Repetitionsfrågor 187
Uppgifter 188
12. Sortering och sökning 190
12.1 Sortering 191
12.2 Bubbelsortering 193
12.3 Sökning 195
Sammanfattning 198
Repetitionsfrågor 199
Uppgifter 199
13. Samlingar 200
13.1 List 201
13.2 Stack 206
13.3 Kö 210
Sammanfattning 214
Repetitionsfrågor 215
Uppgifter 216
14. Rekursiva metoder 218
14.1 Summor och produkter 219
14.2 Talföljder 222
14.3 Fält 225
14.4 Ett grafiskt exempel 228
Sammanfattning 232
Repetitionsfrågor 233
Uppgifter 234
15. Felhantering 236
15.1 Inmatning 237
15.2 Undantagsfel 238
16. Facit till teorifrågor och övningar 242
Register 285



Something mysterious is formed, born in the silent void. Waiting alone and unmoving, it is at once still and yet in constant motion. It is the source of all programs. I do not know its name, so I will call it the Tao of Programming.
If the Tao is great, then the operating system is great.
If the operating system is great, then the compiler is great. If the compiler is great, then the application is great. The user is pleased and there exists harmony in the world.
The Tao of Programming flows far away and returns on the wind of morning.
The Tao of Programming
En dator är en på många sätt fantastisk maskin. Den är olik de flesta andra maskiner som människan använt genom historien. Dessa maskiner har varit konstruerade för att utföra en speciell arbetsuppgift. En del av dem har varit ganska komplicerade och sinnrika, men de har fortfarande bara kunnat användas till en enda sak. Vindmöllorna kunde mala mjöl. Ångmaskinen gav mekanisk kraft och radioapparaterna kunde omvandla radiovågor till ljud.
Hårdvara
En dator däremot är sällan konstruerad för ett speciellt ändamål. Datorer används för att styra andra maskiner, kommunicera, övervaka, underhålla, för att lagra stora mängder information och för många andra ändamål. Men alla dessa datorer, fastän de kommer i olika storlekar och skepnader, är principiellt lika under skalet. De innehåller en eller flera processorer, chip och andra elektroniska komponenter, sådant som vi brukar kalla hårdvara. Men det finns inte många processorer som bara kan visa film, eller bara kan öppna och stänga en dörr. Om man till exempel vill övervaka och styra in- och utpassering genom dörrarna i en byggnad kan man i stora drag köpa vilken dator som helst. Samma dator kan förmodligen dessutom användas till att visa film, skicka e-post och mycket annat.
Mjukvara
För att få en dator att utföra en speciell uppgift krävs ett speciellt program. Program kallas även för mjukvara. Ett program är en mängd instruktioner som talar om vad datorn ska göra. Om en knappsats vid en dörr skickar en sifferkombination till en dator kan processorn till exempel svara med en signal till motorlåset i dörren. Men samma siffror från en film innehåller förmodligen färgen på en pixel. För att en pixel på skärmen ska tändas med denna färg behövs istället ett helt annat program, ett program som skickar en signal till grafikkortet istället för till dörren.
Maskinkod
Det finns bara ett begränsat antal operationer till varje processortyp. Operationerna är väldigt enkla, till exempel ”Flytta tal A till adress 10” där adress 10 kan vara en plats i datorns minne, en pixel på skärmen eller ett motorlås i en dörr, eller någon annan elektronisk krets som är ansluten till datorn. Andra operationer är till exempel ”addera tal A och B” eller ”jämför tal A med B”. Dessa grundläggande operationer kalllas för datorns maskinkod, fast i realiteten består de av siffror. Addera kan ha maskinkoden 03. Genom att kombinera instruktionerna på olika sätt kan man få datorn att utföra en viss uppgift. Att få ett program att visa en enkel figur på skärmen kräver till exempel en hel mängd operationer.
Högnivåspråk
Ett modernt program innehåller hundratusentals eller miljontals maskinspråksinstruktioner. Att skriva ett större program på maskinspråk skulle vara näst intill omöjligt. Därför har man uppfunnit programmeringsspråk vars kommandon liknar vanligt människospråk. De kallas högnivåspråk för att skilja dem från maskinspråk. Man kan till exempel skriva saker som ”A+B” för att addera två tal, eller ”DrawRectangle” för att visa en rektangel på skärmen. Det finns och har funnits ganska många olika högnivåspråk. Ett av de stora är för tillfället C# (uttalas c-sharp på engelska).
C# är en vidareutveckling av Java och C++, som i sin tur är en vidareutveckling av C. Andra kända språk är Visual Basic och Python.
Högnivåspråk skrivs i vanliga textfiler och kallas för källkod. Källkoden måste översättas till maskinspråk innan de kan användas av en processor. Översättningen kan ske i flera steg och kallas kompilering. Kompilering genererar vanligen filer med filändelsen .exe om programmet ska köras på Windows-datorer, eller .app om programmet ska köras på Macintosh-datorer. Om man vill att programmet ska kunna köras på både Windows och Mac (eller andra operativsystem) är det vanligt att låta varje dator som ska köra programmet själv göra det sista översättningssteget. Det kallas för interpretering eller ”just-in-time” kompilering (JIT).
Bilden nedan visar hur översättningen fungerar i Visual C# för ett spel som heter Pacman, bara för att ta ett exempel. CIL betyder Common Intermediate Language och är ett mellansteg mellan källkod och maskinkod.
Programmerarens dator
kompilering
Spelarens dator
Programmet distribueras oftast via internet
Microsoft Visual C# och .NET
Microsoft Visual C# är ett program för att skapa andra program. Communityversionen är gratis och finns att ladda ner från internet. Microsoft Visual C# är en del av en plattform som kallas .NET. Plattformen består av ett antal filer och innehåller bland annat färdigskrivna programbitar. Många uppgifter som ett program ska kunna genomföra är rutinmässiga, som till exempel att spara data till en fil på hårddisken.
För att slippa skriva samma kod varje gång man vill lägga till en spara-funktion använder man istället spara-funktionen i .NET. Det betyder att alla program du skriver i C# är beroende av .NET-plattformen. De går inte att köra på datorer som saknar .NET.
Thus spake the master programmer:
– Without the wind, the grass does not move. Without software, hardware is useless.
The Tao of Programming
Man behöver inte vara någon datortekniker för att kunna programmera, men man måste känna till de tre komponenterna processorn, arbetsminnet och hårddisken.
På hårddisken finns data lagrat i magnetiska spår eller halvledarkomponenter. Datan är uppdelad i filer. Hårddisken är till för att spara data när datorn är avstängd, fast den kan också användas som reserv till arbetsminnet.
När en fil öppnas laddas den till arbetsminnet. I arbetsminnet lagras också all data som strömmar in i datorn från dess olika portar, där till exempel tangentbordet och musen är anslutna. Arbetsminnet kallas även RAM-minne, primärminne eller internminne. Det är direktkopplat till processorn.
Processorn läser data från arbetsminnet, genomför operationer och skickar tillbaka svaret till arbetsminnet. Processorn kan liknas vid datorns hjärna. Men den tänker inte, den följer bara programmets instruktioner.
Låt oss studera hur processorn och arbetsminnet arbetar tillsammans med ett exempel. Antag att du öppnar programmet Kalkylatorn (filen calc.exe) för att räkna ut vad 4 + 3 blir.
Programfönster

AnvändarenProcessorn
Arbetsminne
Skrivhuvud
1 Startar programmet Ritar fönstret, reserverar plats i minnet och väntar sedan på input.
2Klickar på knappen 4Lagrar värdet 4 i arbetsminnet (på reserverad plats A).
3Klickar på knappen +Lagrar värdet ’+’ i arbetsminnet (på reserverad plats B).
4Klickar på knappen 3Lagrar värdet 3 i arbetsminnet (på reserverad plats C).
5Klickar på knappen = Undersöker värdet i B.
Väljer operationen ADD och läser in värdena i A och C.
Skickar tillbaka värdet 7 till arbetsminnet (D).
Ritar om fönstret med värdet i D i textrutan.
Hoppar tillbaka i instruktionskön till den plats där den väntar på input.
Lägg märke till följande:
l Programmet calc.exe innehåller instruktionerna till vad processorn ska göra.
l Programmet är händelsestyrt. Om användaren inte gör något händer inget.
l Programmet är sekventiellt. Alla instruktioner genomförs en i taget i en given ordning.
l Programmet är repeterbart. Processorn kan hoppa till olika instruktioner, även bakåt, och på så sätt göra om samma sak många gånger.
l Minnet delas in i mindre platser som kallas för variabler, där varje plats ges ett unikt namn och har utrymme för ett värde.
Som programmerare bryr man sig sällan om vad som händer i processorn, men det är bra att ha lite koll på vad som händer i arbetsminnet när man reserverar plats och skickar runt värden mellan platserna. Hur detta går till beskrivs i kapitlet om variabler, men du kommer förmodligen att förstå programmering mycket bättre om du redan nu lär dig att tänka på en variabel som en minnesplats som innehåller ett värde.
En text är uppbyggd av meningar som delas in i avsnitt med olika rubriker, som i den vänstra spalten nedan. På samma sätt är programkod uppbyggd av satser och programblock, som i den högra spalten. Koden här är inte riktig kod, utan en sorts halvkod som bara visar strukturen. Precis som man avslutar en mening med punkt måste man avsluta en sats med semikolon (;).
Vanlig text
Rubrik 1
Mening 1. Mening 2. Mening 3.
Rubrik 2
Mening 4. Mening 5.
Programkod
Programblock 1 { Sats 1; Sats 2; Sats 3; }
Programblock 2 { Sats 4; Sats 5; }
Lägg märke till att programblocket består av en rubrik som kallas för programblockets huvud, följt av en klammerparentes { } som innehåller programblockets satser.
Mellan satserna kan man ha hur många mellanslag, tabbar eller tomma rader man vill. Mellanslag, tabbar och tomma rader gör det lättare att läsa koden, men de kompileras inte till maskinkoden. Kompilatorn bestämmer vad som tillhör programblocket bara med hjälp av klammerparenteserna.
Eftersom kod är svårare att läsa än vanlig text brukar man göra blockstrukturen lättare att se genom att bara skriva en sats per rad, och dessutom indentera satserna med en tab eller några mellanslag. Då ser det ut så här:
Programblock 1 { Sats 1; Sats 2; Sats 3; }
Programblock 2 { Sats 4; Sats 5; }
Fördelen med indentering blir särskilt tydlig när man har programblock inuti varandra:
Programblock 3 { Sats 1; Sats 2; Programblock 3A { Sats 3; Sats 4; } }
Alla satser i ett programblock utförs i den ordning de står, men programblocken behöver inte köras i ordning. Ett programblock kanske körs när användaren klickar på en knapp i programmets fönster. Ett annat programblock körs när användaren klickar på en annan knapp. Då är det användaren som bestämmer vilken ordning blocken körs i. Därför är det väldigt viktigt att använda indentering så att man lätt ser vilka satser som utförs tillsammans.
Det finns olika sorters programblock. Vissa kan man skriva i en egen fil, medan andra vanligen står inuti ett yttre programblock. Nedanstående översikt ger en tjuvtitt på några olika sorters programblock som du kommer att stöta på i boken.
Metod
En metod innehåller oftast bara variabler och satser.
Klass (class)
En klass innehåller oftast bara variabler och metoder, men kan även innehålla andra klasser, som då kallas nästlade klasser. Vanligen skriver man klasser i separata filer.
Namnrymd (namespace)
En namnrymd innehåller framför allt klasser, men kan även innehålla andra namnrymder. Som programmerare väljer man namn på sina egna klasser, och varje namn måste vara unikt. Det får inte finnas två klasser med samma namn i ett program. I större program med många klasser kan det bli svårt att välja bra och beskrivande namn till alla. Då används namnrymder.
I bokens text står det ibland om användaren. Med användaren menas den person som ska köra programmet, till skillnad från programmeraren som skapar programmet. Det är du som är programmerare, men du blir förstås användare när du testar dina program.
Boken är upplagd så att teori varvas med exempel, övningar och frågor. Övningar är sådana som du ska programmera i Visual Studio. Frågorna behöver du bara fundera över och svara på i boken eller ett anteckningsblock.
I slutet av varje kapitel finns en sammanfatting, repetitionsfrågor och uppgifter. Du gör dem på samma sätt som övningarna inne i kapitlet.
rf 1.1 Vad menas med kompilering?
rf 1.2 Vad innebär det att ett program är händelsestyrt?
rf 1.3 Vad är en variabel?
rf 1.4 Vad har mellanslag, tabbar och rader för betydelse i programkod?
1.1 Nedan finns halvkod som innehåller kodblock och satser. Strukturera upp koden med rader och indentering så att man lätt ser var ett block börjar och slutar, och vilka block satserna tillhör.
a) Programblock 1{Sats 1; Programblock 2{Sats 2; Sats 3;}}
b) Programblock 1{Sats 1; Sats 2; Programblock 2{Sats 3; Sats 4; Programblock 3{Sats 5;} Sats 6;}}



Visual Studio 2019 Community är en utvecklingsmiljö som skapats av Microsoft för att skriva program i C#. Tonvikten i detta kapitel ligger på hur denna miljö används för att skapa enkla grafiska program. Kapitlet tar även upp god programmeringsstil och de olika typer av fel du kan råka ut för vid programkonstruktion.
Innan du kan börja skriva dina egna program i C# måste du lära dig använda Visual Studio. Det finns andra utvecklingssystem på marknaden men de flesta fungerar på ungefär samma sätt. Ladda hem Visual Studio Community och installera innan du fortsätter. Den här boken använder Visual Studio 2019 Community, men andra versioner bör gå att använda utan större svårighet. Oberoende av vilket du använder måste följande steg utföras för att skapa ett program.
1. Skapa ett projekt med de filer som innehåller programmets text, källkoden. En fil med text till ett program kallas källfil och den har ändelsen cs. Exempel på ett filnamn kan vara Exempel02-01.cs
2. Kompilera källkoden, d v s översätta den till ett körbart program. Vid kompileringen skapas den körbara filen och den får filändelsen exe, till exempel Exempel02-01. exe
3. Köra programmet. Programkörning kallas också för exekvering
Skapa ett projekt
1. Starta Visual Studio.
2. Välj New Project på File-menyn. I dialogrutan som öppnas anges vilken typ av projekt som ska skapas och vilket namn det ska ha. Välj Windows Forms App (.NET Framework), klicka Next och ge projektet namnet Exempel02-01 och Solutionnamnet MinaProjekt.

Skriv Exempel02-01 i textrutan Project name och MinaProjekt i textrutan Solution Name. I textrutan Location skriver du sökvägen till den mapp där du vill spara dina projekt. Du kan även bläddra dig fram till denna mapp genom att klicka på knappen Browse. Skriver du C:\Programmering1 kommer det att skapas en mapp med namnet Programmering1 direkt på enhet C

När du klickar på Create-knappen visas något liknande detta fönster.

I den vänstra delen finns ett formulär med titeln Form1. Det är detta formulär som visas som ett fönster när du kör ditt program. Fönster kallas för form i Visual Studio.
Du kommer att arbeta mest i denna del av utvecklingsmiljön. Här designar du användargränssnittet och skriver källkoden i C#.
3. Spara projektet genom att välja Save All på File-menyn.
Fönstret Solution Explorer i Visual Studio ser nu ut som på bilden till höger.
Solution ’MinaProjekt’ är en så kallad lösningsfil och den innehåller en referens till ditt projekt. En lösningsfil kan hålla reda på flera projekt.
Exempel02-01 är en projektfil och den håller bland annat reda på de filer som ingår i ditt projekt. Varje projekt är ett program. När man skapar en programsvit som till exempel Office skulle Office kunna vara lösningen och Word, Excel och de övriga programmen som ingår i Office skulle kunna vara de olika projekten.

Form1.cs är en källfil i C# och det är i denna fil du kommer att skriva dina program.
Program.cs är också en källfil i C#. Dess uppgift är att skapa och visa ditt programs huvudfönster.
Om du öppnar mappen MinaProjekt i utforskaren ser du att dess innehåll överensstämmer med listan i Solution Explorer. I mappen finns lösningsfilen MinaProjekt och en mapp med namnet Exempel02-01. Mappen Exempel02-01 innehåller bland annat projektfilen Exempel02-01 och källfilerna Form1.cs och Program.cs
Innan ett program kan köras måste källkoden kompileras. Vid kompileringen översätts källkoden till CIL (Common Intermediate Language) och den lagras i en fil med ändelsen exe. Denna fil kan köras av alla datorer som har .NET.
Du har ännu inte skrivit någon egen källkod men när du gör ett projekt skapas en del källkod automatiskt av Visual C#. Denna kod har till uppgift att skapa och visa ett tomt fönster. Om du högerklickar på formuläret i Visual Studio och väljer View Code ser du den automatskapade koden i filen Form1.cs. För att visa formuläret i designläge igen högerklickar du på källkoden och väljer View Designer.
För att kompilera källkoden väljer du Build Solution på Build-menyn. Då skapas en fil med namnet Exempel02-01.exe och den ligger i mappen Exempel02-01\bin\Debug
Köra programmet
För att köra programmet väljer du Start Debugging på Debug-menyn. Då visas ett tomt fönster med titeln Form1. Programmet kompileras automatiskt om det inte är gjort redan.
Avsluta Visual C# genom att klicka på Exit på File-menyn.
Övning 2.1


Leta upp filen Exempel02-01.exe i mappen Exempel02-01\bin\Debug. Vad händer om du dubbelklickar på filen?
Programmet du ska skriva i detta avsnitt illustreras av de två figurerna nedan. Huvudfönstret har en knapp med texten Klicka här. Vid klick på denna visas en meddelanderuta med texten Mitt första program.


Starta Visual Studio. Öppna lösningsfilen MinaProjekt genom att klicka på Open Project i File-menyn. I dialogrutan som öppnas bläddrar du dig fram till filen MinaProjekt och dubbelklickar på den.
Skapa ett nytt projekt genom att högerklicka på Solution 'MinaProjekt' i Solution Explorer. Välj sedan Add New Project som bilden visar. I dialogrutan som visas väljer du Windows Forms App (.NET Framework) och ger projektet namnet Exempel02-02. För att Exempel02-02 ska bli ditt aktiva projekt måste du högerklicka på Exempel02-02 i fönstret Solution Explorer och välja Set as StartUp Project. Detta projekt kommer då att köras när du väljer Start Debugging på Debug-menyn.

Ett fönster har flera egenskaper som storlek, bakgrundsfärg och titel. Egenskaperna sätts i fönstret Properties. För att visa detta fönster klickar du på View i menyraden och väljer Properties Window. Formuläret i detta exempel ska ha titeln Exempel och bredden och höjden kan vara 200 pixlar. För att sätta dessa egenskaper markerar du formuläret genom att klicka på det med musen. Leta sedan upp egenskapen Size i fönstret Properties, klicka på symbolen framför Size och ge egenskaperna Width och Height värdet 200. Ändra på motsvarande sätt egenskapen Text till Exempel.
Kompilera och kör ditt projekt. Fönstret som då visas har de egenskaper du skrivit in.

De objekt ett grafiskt användargränssnitt består av kallas för kontroller eller fönsterkomponenter. Exempel på kontroller är knappar, etiketter och textrutor. I vårt exempel finns det en knapp med texten Klicka här. För att lägga till knappen på formuläret gör du så här.
1. För muspekaren över fliken Toolbox. Då öppnas den så kallade verktygslådan och den innehåller bland annat de kontroller som kan placeras på ett formulär. Som bilden visar finns bland annat kontrollerna Button och CheckBox, det vill säga knapp och kryssruta.
2. Tryck ned vänster musknapp på kontrollen Button och dra den till mitten av formuläret. Det blir enklare att dra kontroller till fönstret om du dockar Toolbox till höger i Visual Studio istället.

För att underlätta programmeringen ska alla kontroller ges ett beskrivande namn. Knappars namn brukar inledas med btn och ett bra namn på denna knapp kan vara btnKlick. Markera knappen genom att klicka på den och ändra sedan egenskapen Name i fönstret Properties till btnKlick. Ändra även egenskapen Text till Klicka här
2. Introduktion till
Kontrollerna som ligger på ett formulär kan kopplas till olika typer av händelser. Ett exempel på en händelse för en knapp är att användaren klickar på den med musen.
För att koppla händelsen musklick till din knapp btnKlick gör du så här.
1. Klicka på knappen btnKlick
2. Klicka på händelseknappen i fönstret Properties. Då visas de händelser knappen kan utsättas för. I fönstret Properties kan du alltså välja mellan att visa knappens egenskaper eller vilka händelser den kan utsättas för.


För att visa händelserna klickar du på händelseknappen.
För att visa egenskaperna klickar du på egenskapsknappen.
3. Dubbelklicka i textrutan till höger om händelsen Click. Då skapas automatiskt en så kallad metod med namnet, btnKlick_Click och det är denna metod som anropas när användaren klickar på knappen. Formuläret växlar även till kodläge så att du kan skriva källkoden i C#.

Skriva källkod
Skriv av de två raderna nedan som börjar med MessageBox. Det är viktigt att metoden btnKlick_Click ser ut exakt som nedan, bortsett från att satsen i blocket kan stå på en rad.. Lägg speciellt märke till det avslutande semikolonet.
private void btnKlick_Click(object sender, EventArgs e) { MessageBox.Show("Mitt första program", "Meddelande", MessageBoxButtons.OK, MessageBoxIcon.Information); }
Kompilera och kör programmet. Om du inte kan köra programmet betyder det att du inte har skrivit av programmet korrekt. Ändra då i källkoden så att den ser ut exakt som ovan.
Då programmet körs visas ditt fönster med en knapp. När du klickar på knappen visas meddelanderutan.
För att avsluta programmet måste du först stänga meddelanderutan genom att klicka på OK-knappen. Sedan stänger du formuläret genom att klicka på krysset i det övre högra hörnet.
Nu ska vi titta närmare på programmet från föregående avsnitt. Källkoden i filen Form1.cs visas i Exempel 2.2.
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 namespace Exempel02_02
10 {
11 public partial class Form1 : Form
12 {
13 public Form1()
14 {
15 InitializeComponent();
16 }
17 private void btnKlick_Click(object sender, EventArgs e)
18 {
19 MessageBox.Show("Mitt första program", "Meddelande",
20 MessageBoxButtons.OK, MessageBoxIcon.Information);
21 }
22 }
23 }
Rad 1–8: Dessa rader läggs automatiskt till källkoden när du skapar ett Windowsprojekt och de gör att du enklare får tillgång till de komponenter som används i programmet. För att visa en meddelanderuta ska man skriva System.Windows.Forms.MessageBox.Show. Om man i stället lägger till using System.Windows.Forms i början av programmet räcker det att skriva MessageBox.Show för att visa meddelanderutan. System.Windows.Forms är en så kallat namnrymd och alla komponenter som är definierade i C# ligger i en namnrymd.
R ad 9–16: Även dessa rader skapas automatiskt av Visual Studio och deras exakta innebörd förklaras i senare kapitel i boken. I nuläget kan du bara acceptera att dessa rader behövs i alla program du skriver men för helhetens skull ges ändå en kortfattad beskrivning. Alla fönsterprogram i C# har samma grundläggande struktur och då det är ett objektorienterat språk bygger det på så kallade klasser. Vårt program består av en klass med namnet Form1. Beskrivningen av klassen inleds med en vänsterklammer på rad 12 och avslutas med en högerklammer på rad 22. Klassen ligger i en namnrymd (namespace) som har fått namnet Exempel02_02, rad 9. På raderna 13 till 16 definieras en så kallad konstruktor och dessa rader körs när fönstret skapas. Anropet InitializeComponent() på rad 15 har till uppgift att sätta egenskaperna för alla kontroller man lagt på sitt formulär. Här får till exempel formuläret titeln Exempel.
Rad 17–21: Här definieras metoden btnKlick_Click och det är denna metod som körs när du klickar på knappen i fönstret. Mellan vänsterklammern, {, på rad 18 och högerklammern, }, på rad 21 står metodens källkod. Den visar meddelanderutan som visas på bilden till höger. Till metoden MessageBox.Show skickas de fyra parametrarna ”Mitt första program”, “Meddelande”, MessageBoxButtons.OK och MessageBoxIcon. Information. Om du jämför dessa med bilden ser du att den första bestämmer texten, den andra titeln, den tredje knappen och den fjärde ikonen.
2. Introduktion

Skapa ett projekt med namnet Övning02-02 i Visual Studio. Skriv sedan ett program enligt bilden nedan. På huvudfönstret ska det finnas en knapp med texten Meddelande. När användaren klickar på den ska meddelanderutan visas.

Programmeringsstil

Det är viktigt att de program du skriver är tydliga och lättlästa. Med en bra struktur kommer bl. a. felsökningen av programmet att underlättas avsevärt. Studera därför bokens exempel noggrant och lägg speciellt märke till hur vi använder oss av blanktecken, tomma rader och indenteringar (indrag av text). Kompilatorn bryr sig inte om dessa tecken och de kan därför användas för att göra programmen mer lättlästa. I exempel 2.2 syns det tydligt var btnKlick_Click -metoden börjar och slutar, då det är en tom rad innan btnKlick_Click och genom att MessageBox.Show-metoden har indenterats.
Metoden btnKlick_Click skulle ha kunnat skrivas på följande sätt, men det är inte att rekommendera, då metodens uppbyggnad inte framträder lika tydligt.
private void btnKlick_Click(object sender, EventArgs e){ MessageBox.Show( "Mitt förstaprogram", "Meddelande", MessageBoxButtons.OK, MessageBoxIcon.Information);}
Kommentera källkoden
För att göra koden i ett program tydligare brukar man kommentera den. Kommentarer inleds med teckensekvensen //. Allt som står på samma rad och bakom // hoppas över av kompilatorn. Här kan då förklaringar och andra upplysningar skrivas. I källkoden nedan har två kommentarer lagts till.
// Metoden visar en meddelanderuta. private void btnKlick_Click(object sender, EventArgs e) { // Här visas meddelanderutan. MessageBox.Show( "Mitt förstaprogram", "Meddelande", MessageBoxButtons.OK, MessageBoxIcon.Information); }
Det är endast i undantagsfall som ett lite större program fungerar första gången det körs. Du kommer att upptäcka att du får ägna en hel del tid åt att leta efter fel i dina program. När man rättar till felaktigheter i ett program säger man att man felsöker, eller debuggar, det. Det kan förekomma tre olika typer av fel i ett program:
l kompileringsfel
l exekveringsfel
l logiska fel
Kompileringsfel kallas ibland syntaxfel och är fel som beror på att man inte har följt de språkregler som gäller i C#. Exempel på sådana fel är stavfel och glömda semikolon eller parenteser. De kallas kompileringsfel då de upptäcks vid kompileringen och denna typ av fel är relativt enkla att korrigera då kompilatorn skriver ut felmeddelanden. Tyvärr är felmeddelandena inte alltid helt enkla att tolka och ett annat problem är att ett fel på en rad kan få kompilatorn att upptäcka ”felaktigheter” i efterliggande satser trots att de är korrekta. Börja därför med att rätta ett eller ett par fel du enkelt kan hitta. En korrigerad felaktighet kan nämligen minska antalet felmeddelanden ordentligt.
Som programmerare kommer du att få många kompileringsfel och det är bra att bli bekant med felmeddelandena tidigt. Lägg därför in några fel i övning 2.2 och se om du kan tolka felmeddelandena. Pröva till exempel först med att ta bort den första klammerparentesen, {, i Click-metoden. När du kompilerar programmet hittas flera fel trots att programmet bara innehåller ett. Felen visas i fönstret Error List som ligger under formulärfönstret.
Exekveringsfel är fel som gör att programmet kraschar och ett vanligt fel är division med noll. Jämför med en beräkning med miniräknare, du kan slå in 5/0, men beräkningen avbryts och du får ett felmeddelande.
Logiska fel gör att programmet kan köras men inte ger det förväntade resultatet. Om du vill beräkna summan av två tal men av misstag skriver tal1 – tal2 så har du ett logiskt fel. Exekveringsfel och logiska fel kallas ibland för buggar.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace Exempel02_02
{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } } }
Den grundläggande strukturen hos ett fönsterprogram i C#.
MessageBox.Show("Mitt förstaprogram", "Meddelande", MessageBoxButtons.OK, MessageBoxIcon.Information); Visar meddelanderutan

private void btnKlick_Click(object sender, EventArgs e) { } Händelsemetod
// Kommentar Kommentarer i koden inleds med //
rf 2.1 Vilka tre fel finns i programmet nedan?
private void btnKlick_Click(object sender, EventArgs e) MessageBox.show("Det finns tre fel", "Meddelande", MessageBoxButtons.OK, MessageBoxIcon.Information) }
rf 2.2 Vilka tre olika typer av fel kan uppstå då man konstruerar ett program?
rf 2.3 Hur ser meddelanderutan ut när nedanstående sats körs?
MessageBox.Show( "Vill du spara filen?", "Spara", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
2.1 Skriv ett program som visar fönstret nedan. Formulärets bakgrundsfärg är röd när programmet startar. Vid klick på knappen Blå ska bakgrundsfärgen bli blå och vid klick på knappen Röd ska bakgrundsfärgen bli röd.
Kontrollernas egenskaper visas i tabellen nedan. Ställ in egenskaperna i fönstret
Properties
KontrollEgenskapVärde
FormName
BackColor Text Form1 Red Uppgift
ButtonName Text btnRöd Röd
ButtonName Text btnBlå Blå

För att ändra formulärets färg vid programkörningen till blå skrivs raden nedan på lämpligt ställe i programkoden.
BackColor = Color.Blue;
2.2 Skriv ett program som visar fönstret nedan. Det innehåller två knappar och en etikett (label). När man klickar på knappen Höger ska etiketten flytta sig åt höger och när man klickar på Vänster ska den flytta sig åt vänster.
Kontrollernas egenskaper visas i tabellen nedan. Ställ in egenskaperna i fönstret Properties.
KontrollEgenskapVärde
FormName Text Form1 Uppgift
ButtonName Text btnVänster Vänster
ButtonName Text btnHöger Höger
LabelName Text lblFlytta Vänster eller höger

För att flytta etiketten åt höger vid programkörningen skrivs raden nedan på lämpligt ställe i programkoden.
lblFlytta.Left = lblFlytta.Left + 10;





Att försöka förutse möjliga fel som kan uppträda när ett program körs och hantera dem är viktigt för att göra programmet stabilt.
Förutom att krascha programmet, eller i värsta fall hela datorn, kan en bugg innebära att programmet ger felaktiga resultat. Beroende på vad programmet används till kan det vara mer eller mindre allvarligt, men oavsett vilket är det alltid fruktansvärt irriterande för användaren.
Bra och stabil kod ska vara ”idiotsäker”. Det ska inte spela någon roll vad användaren skriver på tangentbordet, programmet ska aldrig krascha. Betrakta följande exempel på ett program där användaren kan mata in en sträcka och en tid. Genom att trycka på en knapp räknas hastigheten ut.
public void btnBeräkna_Click ( object sender, EventArgs e ) {
float sträcka = float.Parse( tbxSträcka.Text ); float tid = float.Parse( tbxTid.Text );
float hastighet = sträcka / tid;
tbxHastighet.Text = hastighet.ToString(); }
De två översta satserna anropar metoden Parse, som tar en text, till exempel ”35” och omvandlar den till flyttalsvärdet 35.0. Men om användaren skriver ”asf” kommer metoden Parse att generera ett fel som talar om att asf har fel format, för det finns inget motsvarande tal.
Det finns ett alternativ till Parse som heter TryParse. Den tar en sträng och omvandlar till motsvarande talvärde, om det finns något. I så fall returnerar den true. Om det inte gick att tolka strängen som ett tal returneras false. Eftersom returvärdet är en bool så används i stället en out-parameter för att lagra talvärdet.
Det ser ut så här:
float sträcka; bool sträckaOK = float.TryParse( "3,5", out sträcka );
Variabeln sträckaOK ovan skulle bli true och variabeln sträcka skulle få flyttalsvärdet 3.5f. Från och med version 7 av C# kan man deklarera talvariabeln direkt i parentesen:
bool sträckaOK = float.TryParse( ”3,5”, out float sträcka );
Ifall omvandlingen inte lyckas och TryParse returnerar false, så kommer outparametern att innehålla ett odefinierat värde och ska inte användas.
En bättre version av Exempel 15.1a ovan skulle kunna se ut som på följande sida.
public void btnBeräkna_Click ( object sender, EventArgs e ) {
bool sträckaOK = float.TryParse( tbxSträcka.Text, out float sträcka ); if ( ! sträckaOK ) { MessageBox.Show( "Var god skriv ett tal." ); return; }
bool tidOK = float.TryParse( tbxTid.Text, out float tid ); if ( ! tidOK ) { MessageBox.Show( "Var god skriv ett tal." ); return; }
float hastighet = sträcka / tid;
tbxHastighet.Text = hastighet.ToString(); }
I stället för att krascha programmet om användaren skriver något i textrutorna som inte kan tolkas som tal, visas nu ett meddelandefönster som uppmanar användaren att skriva in ett tal. Notera att det står return direkt efter det att meddelandet visats. Det är för att kodraden där variablerna används i en division inte ska exekvera om någon av variablerna har ett ogiltigt värde. Användaren får i stället ändra i textrutan och klicka på knappen igen.
Exemplet är fortfarande inte helt felsäkert, för användaren kan skriva in tiden 0, och division med 0 ska undvikas. Det skulle visserligen inte krascha programmet, för variabeln hastighet skulle få värdet NaN (Not a Number), men det är dåligt ändå. Det vore bra med ytterligare en if-sats som efter inmatningen kontrollerar värdet på variabeln tid. Om tid är 0 kan man visa ett meddelandefönster igen och sedan avbryta koden med return, så att divisionen aldrig genomförs. Det är alltid en god idé att kontrollera nämnaren innan en division.
De flesta fel som uppstår under en programkörning genererar så kallade undantagsfel, på engelska exceptions. Ett undantagsfel är ett fel som gör att programmet inte bör köra vidare utan att felet hanteras. Vanliga fel är att programmet försöker komma åt odefinierade delar av minnet, till exempel genom att skriva ett värde till den sjunde platsen i ett fält som bara har fem element, eller genom att använda en referens som är null
Om sådana fel inte hanteras är det oftast bättre att avsluta programmet. För användaren ser det ut som om programmet har kraschat, vilket man kan säga att det har. Men notera att en programkrasch inte är det värsta som kan hända. Det värsta som kan hända är att programmet kör vidare med felaktiga resultat, eller oavsiktligt skriver över data på fel plats i minnet utan att man märker det. Ibland är det bättre att låta programmet krascha. Ännu bättre är det förstås att fånga upp undantagsfel och hantera dem så att programmet kan fortsätta.
Ett vanligt undantagsfel är att försöka komma åt ett element i en lista på en plats som inte finns. Programmet nedan har två knappar och tre textrutor. Knappen Generera slumpar fram det antal heltal som står angivet i textrutan Antal. Knappen Visa värde visar värdet på det index som står angivet i textrutan Index:

Exempel 15.2
private int[] lista; Random generator = new Random();
private void btnGenerera_Click( object sender, EventArgs e ) { // Läs in antal: bool antalOK = int.TryParse( tbxAntal.Text, out int antal );
// Kontrollera inmatning: if ( antalOK && antal > 0 ) lista = new int[antal]; else { MessageBox.Show( "Ange ett tal över 0" ); return; }
// Generera slumptal från 1 till 6: for ( int i=0 ; i<antal ; i++ )
{ lista[i] = generator.Next( 1, 7 ); } }
public void btnVisa_Click ( object sender, EventArgs e ) { // Läs in index: bool indexOK = int.TryParse( tbxIndex.Text, out int index );
// Kontrollera inmatning: if ( ! indexOK ) { MessageBox.Show( "Ange ett tal." ); return; }
// Visa talet på indexet: try{ tbxVärde.Text = lista[index].ToString(); } catch ( Exception error ) { MessageBox.Show( error.Message ); } }
Lägg märke till de två nya kodblocken try{ } och catch{ }. I try-blocket står den eller de satser som kan generera undantagsfel. Undantagsfelet är ett objekt av typen Exception, och innehåller information om felet. Catch-blocket fångar upp felet, här kallat error, och visar ett felmeddelande.
Utan try-catch skulle exemplet ovan generera ett fel och sedan ”krascha”. Med try-catch bestämmer du som programmerare hur felet ska hanteras. I det här fallet är det en bra åtgärd att låta användaren veta att ett fel inträffade och varför, så att hon kan ändra inmatningen i textrutan och prova igen. I övrigt finns det ingen risk med att låta programmet köra vidare.
Observera att automatiskt genererade felmeddelanden som det här ofta är obegripliga för den vanlige användaren. Här skulle man istället kunna visa felmeddelandet
"Ange ett tal mellan 0 och " + (lista.Length-1)"
Övning 12.3 är ett program som påminner om exemplet ovan. Gå tillbaka till den övningen och felsäkra den så mycket du kan. Du behöver inte göra om den om du redan gjort den. Modifiera den till uppdaterad version. Använd try-catch och se till att programmet inte går att krascha även om man försöker. När du är klar, låt en kompis testa och se om det går att krascha.
Den här boken riktar sig mot nybörjaren i programmering.
Det krävs inga förkunskaper annat än lite datorvana för att kunna installera nödvändig programvara. Det finns gratis programvara som kan användas för att arbeta med boken t.ex. Visual Studio Community 2022. Boken är främst avsedd att användas som kurslitteratur till gymnasieämnet Programmering nivå 1. Boken kan också vara till god hjälp för den som vill lära sig programmering på egen hand.
Denna tredje upplaga av boken har kompletterats med ett nytt kapitel om felhantering för att bättre motsvara ändringarna i 2025 års gymnasiereform.
Extra lärarmaterial finns som digitalt lärarmaterial. Extramaterialet består av färdiga programfiler till samtliga exempel, övningar och uppgifter, provförslag m.m. och kan hämtas digitalt.
Det kan bespara läraren en hel del arbete med att förbereda presentationer eller demonstrationer av bokens innehåll.
Författare till Programmering 1 C# är Magnus Lilja, Ulrik Nilsson och Dennis Berling. Alla tre har mångårig erfarenhet av att undervisa i programmering.


