Introduktion till programmering



Relevanta dokument
1 Språket C Valet av språket C++ för kompendiet. 1.2 Språket. 1.3 Att programmera. 1.4 Hello World Börja programmera

float Mindre rella tal ( floating point number ) double Rella tal/flyttal ( double precision floating point number )

1 Datorn som miniräknare. 1.1 Räkneoperationer. 1.2 Variabler

System.out.println("Jaså du har "+ antalhusdjur+ " husdjur"); if ( antalhusdjur > 5 ) System.out.println("Oj det var många);

TDIU01 - Programmering i C++, grundkurs

En villkorssats är den konstruktion som finns i C++ för att göra en selektion av två alternativa sekvenser. Formen för if satsen är

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

1 Funktioner och procedurell abstraktion

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Enkla datatyper minne

( ostream ) << ( annan datatyp ) : ostream

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

OBS! All teori i detta och följande dokument kompletteras med genomgångar på lektionerna. Så det är viktigt att närvara och göra egna anteckningar.

Programmeringsteknik med C och Matlab

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

SMD 134 Objektorienterad programmering

TDIU01 - Programmering i C++, grundkurs

Objektorienterad Programmering (TDDC77)

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

F4. programmeringsteknik och Matlab

Programmering A. Johan Eliasson

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Objektorienterad programmering Föreläsning 4

Programmering för språkteknologer I, VT2012. Rum

1 Texthantering. 1.1 Typen char. Exempel, skriv ut alfabetet

För att skriva data till skärmen ( konsolen) används objektet System.out tillsammans med metoden println eller print.

TDDC77 Objektorienterad Programmering

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Klassdeklaration. Metoddeklaration. Parameteröverföring

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

C++ - En introduktion

Objektorienterad Programmering (TDDC77)

Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten Programmering: att instruera en maskin att utföra en uppgift, kräver olika språk:

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

Introduktion C-programmering

Instuderingsfrågor till Steg 1

1 Iteration. 1.1 for-satsen

E02 "The Review" Föreläsning 2, HT2013 Grunderna, repetition. Johan Leitet. Kurs: 1dv403 Webbteknik I

Programmering B med Visual C

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Övningsuppgifter till föreläsning 2 Variabler och uttryck

Användarhandledning Version 1.2

Föreläsning 7. Nyckelord I Java. Uttryck. Uttryck, Operatorer Och Kontrollflöden

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Labb i Datorsystemteknik och programvaruteknik Programmering av kalkylator i Visual Basic

Föreläsning 3: Typomvandling, villkor och val, samt textsträngar

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

Repetition C-programmering

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Det finns många flaggor till g++,

Programstruktur och terminologi. Programmet producerar följande utskrift i terminalfönstret: Ett Javaprogram består av en eller flera klasser

PROGRAMMERING 2 GRUNDLÄGGANDE SEMANTIK 4

Data, typ, selektion, iteration

Inledande programmering med C# (1DV402) Ditt första C#-program med Visual Studio

Grundläggande programmering med C# 7,5 högskolepoäng

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

Variabler och konstanter

Introduktion till algoritmer - L0 - Grunder i C++ Matematikgymnasiet, Läsåret L0 - Grunder i C++

TDDC77 Objektorienterad Programmering

Föreläsning 3. Programmering, C och programmeringsmiljö

TDIU01 (725G67) - Programmering i C++, grundkurs

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Strukturdiagram. Styra. Algoritmer. Val

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Föreläsning 2 Programmeringsteknik och Matlab DD1312. Programspråk. Utskrift på skärmen

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

Inledande programmering med C# (1DV402) 27+15=42 1 (22)

Objektorienterad programmering i Java

2.1 Variabler. 2.2 Regler för namngivning i C. Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten Föreläsning 2

i LabVIEW. Några programmeringstekniska grundbegrepp

Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.

En kort text om programmering i C.

Tentamen ID1004 Objektorienterad programmering October 29, 2013

Parameteröverföring. Exempel. Exempel. Metodkropp

Föreläsning 2. Variabler, tilldelning och kodblock{} if-satsen Logiska operatorer Andra operatorer Att programmera

Föreläsning 3: Booleans, if, switch

DD1314 Programmeringsteknik

Laboration 1 Introduktion till Visual Basic 6.0

Lathund. C för inbyggda system

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

Visual Basic, en snabbgenomgång

C++ Lektion Tecken och teckenfält

Operatorer Tilldelning Kodblock { } if satsen Logiska uttryck Att programmera

TUTORIAL: KLASSER & OBJEKT

Lathund. Pacific C för MS-DOS

Introduktionslaboration

F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander

Tentamen , Introduktion till Java, dtaa98, dtea53

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

TDIU01 - Programmering i C++, grundkurs

Föreläsning 3.1: Datastrukturer, en översikt

Transkript:

Introduktion till programmering v. 1.12-2007-02-10 Mittuniversitetet Institutionen för Informationsteknologi och medier Datateknik

Innehållsförteckning 1 Inledning...4 2 Språket C++...5 2.1 Valet av språket C++ för kompendiet...5 2.2 Språket...5 2.3 Att programmera...5 2.4 Hello World...5 2.5 Att skapa ett program, kompilering och länkning...8 2.6 main()...8 3 Datorn som miniräknare...10 3.1 Räkneoperationer...10 3.2 Variabler...10 4 Datatyper och Uttryck...13 4.1 Datatyper...13 4.2 Deklarationer...13 4.3 Identifierare...14 4.4 Uttryck och operationer...17 5 Inmatning och utskrift...25 5.1 Utskrift till skärm...25 5.2 Inmatning från tangentbordet...27 6 Villkor och styrsatser...31 6.1 Villkorssatsen if...31 6.2 Logiska villkor...33 6.3 Iteration...37 7 Texthantering...45 7.1 Typen char...45 7.2 Fältvariabler...47 7.3 In och utmatning...48 7.4 Texthanteringsfunktioner...52 7.5 Datatypen string...55 8 Funktioner och procedurell abstraktion...57 8.1 Funktioner...57 8.2 Funktioner som behöver indata...60 8.3 Funktioner som returnerar värden...63 8.4 Speciella datatyper för funktionsargument...65 9 Fältteori...69 9.1 Fält av andra datatyper än char...69 10 Standardalgoritmer...73 10.1 Swap funktion...73 10.2 Sök minsta värdet i en array...73 10.3 Array sortering...74 10.4 Övrigt...75 11 Operatorprioriteter...76 12 Teckenkoder Asciitabell...77 2

3

1 Inledning Detta kompendium är tänkt att fungera som ett förberedande material och komplement till föreläsningar inom teoretiska studier av grundläggande programmering. Programmeringsspråket som är valt för kompendiet är C++ men det mesta utav teorin är applicerbar på de flesta strukturerade och objektorienterade programspråk, såsom Pascal, c, Java, Fortran, JavaScript(ECMA skript). Texten förutsätter inga förkunskaper annat än gymnasiekompetens och datorvana. Texten läses med fördel vid en dator där man har möjlighet att testa de olika program och konstruktioner som dyker upp i texten. 4

2 Språket C++ 2.1 Valet av språket C++ för kompendiet 2.2 Språket Språket C++ är ett språk som utvecklats för storskalig objektorienterad utveckling av sofistikerade och komplexa system. Det ligger då i sakens natur språket har flera vinklar och vrår som inte kommer att vara viktiga under studier av grundläggande programmering, men som än dock kommer att påverka den praktiska programmeringen. Det kommer att dyka upp flera exempel på saker som inte har någon naturlig förklaring bland den del av språket som texten behandlar, saker som då kan kännas obekväma eller onödiga. Men tanken är att en stor andel av er som använder detta kompendium kommer att fortsätta studera programmering i C++. C++ är ett av de mest omfattande programmeringsspråk som finns, men det är samtidigt förmodligen det mest uttrycksfulla språk, trots det är den del som berörs i denna text i all väsentlighet snarlik de flesta andra datorspråk. C++ är en blandning av ett objektorienterat språk och ett strukturerat språk, en sk hybrid, och har troligtvis en större marknadsandel av komersiella applikationer än något annat språk. C++ är ett relativt nytt språk, standardiseringen gjordes sent 1998. Språket har tidigare funnits i olika former och dialekter sedan tidigt 80-tal. Bjarne Strostrup är den ursprunglige konstruktören (eller uppfinnaren) av C++. Han har skrivit flera böcker som i det närmaste erhållit bibelstatus bland C++ programmerare, bla "The C++ programming language", Addison-Wesley. 2.3 Att programmera För att kunna programmera behöver du en dator (duh?) och en utvecklingsmiljö ( en kompilator och en textredigerare ). För kompendiet har valts Microsoft Visual C++ 6.0 (VC) som testmiljö eftersom den används på Mitthögskolan och är dessutom en vanlig professionell miljö för programvaruutvecklning på PC. För eget bruk finns VC (Visual C++) med studentlicens för under tusenlappen. Ett annat alternativ är ett gratispaket som heter DJGPP som finns att hämta på nätet http://www.delorie.com/djgpp/. Det finns dessutom en grafisk gratismiljö som heter Dev-C++ som finns på http://www.bloodshed.net/devcpp.html. 2.4 Hello World Då man först introduceras till ett nytt programspråk eller en ny programmeringsmiljö bör man först se till att man behärskar proceduren att skapa ett körbart program. Det sker väldigt ofta med Hello World. Syftet med Hello World programmet är att se hur allting fungerar då man ska skapa ett program. 5

2.4.1 Börja programmera För att komma igång att programmera börjar man med att starta programmet VC 6.0 (om det är VC man använder:-) Inställningarna är snarlika i VS.NET För att kunna börja skriva ett program i VC måste man skapa ett projekt. I denna kurs kommer vi uteslutande att skapa textbaserade program i projekt av typen Win32 Console application. 1. Menyalternativ File / New... 2. Dialogrutan New / flik Projects, välj Win32 Console application. 3. Ange projektets namn i rutan för detta. Det kommer att skapas en katalog med detta namn. Lämpligt namn kan vara tex "HelloWorld". 4. Peka ut var någonstans på hårddisken du vill att projektet ska skapas. Detta kan vara väldigt viktigt att det görs rätt om du arbetar i en labbsal, fråga din handledare. 5. Välj Ok då du är nöjd med dina val. Win32 Console Application Wizard - Välj Empty project, tryck Finish / Ok I VS.NET finns det en extra flik med inställningar där du fyller i detta. 6

#include<iostream> using namespace std; I varje C++ miljö är ett program indelat i en eller flera filer där den vanligaste filtypen är källkodsfiler eller cpp filer. Man kallar dem cpp filer eftersom de har suffixet.cpp. För att kunna börja skriva programmet ska programmets huvudfil skapas. Det görs genom att man går till menyn File / New, väljer C++ source file och anger namnet ( i rutan File Name ) till förslagsvis main. Filen du nu skapar kommer alltså att få namnet main.cpp. Nu är det dags att mata in programmet. I det nya textfönstret som dykt upp ( editorn ) kan vi nu mata in följande int main() cout<<"hello World"<<endl; return 0; Programmet körs genom att i VC 6.0 välja menyn Build / Execute här ges en statusrapport av miljön som beskriver hur den arbetar med att bygga programmet Hello World. I VC ser det ut som --------------------Configuration: HelloWorld - Win32 Debug----- ----------- Compiling... main.cpp Linking... HelloWorld.exe - 0 error(s), 0 warning(s) Om du inte får 0 fel och 0 varningar har du med all sannolikhet matat in programmet fel, gå då tillbaka till inmatningen och kontrollera att du matat in varje tecken, bokstav som specialtecken på exakt rätt sätt. Ögonblicket efter du ser rapporten att allt går bra startas ditt program. I VC 6.0 Ser du då ett konsolfönster med texten Hello World Press any key to continue I andra miljöer är det ofta så att programmet körs utan att man får uppmaningen att trycka på en knapp för att fortsätta. Då kan det hända att det ingenting syns, eller att det blinkar till, på skärmen. Det som då hänt är att programmet körts och avslutats innan man han se resultatet. Det är oftast helt normalt. Du har nu skapat ditt första körbara C++ program. Hur programmet fungerar gås igenom i detalj längre fram. 7

2.5 Att skapa ett program, kompilering och länkning Det som du skrev in i utvecklingsmiljöns editor var C++ källkod, dvs programrader med C++ satser. Datorn förstår inte dessa satser naturligt utan måste först översätta dem till ett för datorn förståeligt språk, s.k. objektkod. Den objektkod som skapas måste därefter sättas ihop till ett körbart program. Dessa procedurer kallas kompilering respektive länkning. 2.5.1 Kompilering 2.5.2 Länkning 2.6 main() När ett program kompileras kontrolleras först att dess syntax är riktig. Det innebär att kompilatorn ser till att de programrader som är skrivna i källkoden följer de regler som finns för språket C++. Ungefär på samma sätt som en modern ordbehandlare kan kontrollera stavning, avstavning och andra språkregler. Då felkontrollsproceduren är avklarad ( den sker egentligen i flera steg ) börjar översättningen till objektkod. Resultatet av översättningen är vanligvis en fil som i vårt exempel heter HelloWorld.obj eller något liknande. I den filen finns lösryckta fragment av för datorn förståelig programkod. Dessa måste nu sättas ihop för att kunna köras som ett program. Det görs av länkaren. När objektfilerna skapats tar länkaren vid för att skapa ett körbart program. Det gör den genom att foga ihop det skrivna programmet med andra befintliga objektfiler s.k. biblioteksfiler. Bland annat kommer vårt Hello World programs objektfil att kopplas ihop med funktioner för att skriva ut text på skärmen. Resultatet av länkningen läggs i exemplet i en fil med namnet HelloWorld.exe som är ett helt vanligt Windowsprogram 1. Man kan i alla miljöer göra en kompilering utan att göra en länkning med ett compile kommando, hur detta görs varierar från miljö till miljö. Man kan dessutom utföra en länkning utan att behöva köra programmet med ett build kommando. Syftet med dessa kommandon är vanligtvis att kontrollera eventuella fel. 2.6.1 Hello World programmet rad för rad Ett C++ program läses och körs som regel uppifrån och ned. Datorn tar den första C++ satsen den stöter på, tolkar och utvärderar resultatet, och utför därefter nästa sats. Hello World programmet har faktiskt bara en enda programsats som datorn ska utföra. Det övriga i källkoden är till för att kompilering och länkning ska fungera. 1 I vissa sammanhang ser man benämningen DOS-program. Den benämningen är i de allra flesta fall helt felaktig 8

Rad 1: #include<iostream> Rad 2: using namespace std; Rad 4: int main() Rad 5: Dessa två rader hör ihop rad ett säger att vi ska använda oss av en fil döpt "iostream". Filen iostream är en s.k. headerfil som innehåller fördefinierade funktioner, exempelvis att skriva text till skärmen. Rad två säger att dessa funktioner tillhör C++ standarden. Namnet std i using namespace std; är till för att undvika hopblandning med äldre varianter av C++, dvs C++ innan standardiseringen. Rad 4 anger programstart. Detta är en överenskommelse som finns till länkaren att man anger programmets start på detta sätt. Raden är en "definition av en funktion döpt main()". En funktion är en samling programsatser som kan utföras som en enhet. Rad 5 anger att här börjar programsatserna för main funktionen. Varje tecken i ett C++ program har ett motsvarande tecken. Dessa klamrar grupperas på samma sätt som parenteser i räkneuttryck. Rad 6: cout<<"hello World"<<endl; Detta är den enda programsats som finns i programmet. Det är programsatserna som körs och uträttar något konkret i ett program. Man känner igen en sats genom att den avslutas med ett semikolon ;. Denna sats innehåller 4 olika delar 1. cout läses se-aout, bokstäverna står för "Console OUT", där console är just det vi kallar för konsolfönstret och out anger output eller utmatning. 2. << - kallas utströmsoperator och används för att skicka det som står till höger om operatorn till det som står till vänster. Symbolen dyker upp i olika sammanhang men anger alltid att den information som står till höger skall skickas till enheten ( eller strömmen ) som står till vänster. 3. "Hello World" textsträngar anges i C++ som text omgiven av " tecken. 4. endl läses ut som endline, är ett namn för ett specialtecken som anger att en radmatning ska skrivas i textfönstret. Semikolon avslutar satsen. Hela satsen kan alltså läsas ut som: Skicka texten "Hello World" till cout. Skicka sen ett radmatningstecken till cout. Satsen return 0; är en sats som avslutar programmet. Nollan är vårt sätt att berätta för den process som startar programmet (i det här fallet operativsystemet) att allt gått bra. Den sista raden anger slutet på main funktionen och därför slutet på programmet. I de första program vi kommer att skriva skall alla programsatser skrivas innanför mainfunktionens och klamrar för att fungera. För att testa lösryckta programavsnitt skrivna i texten kan man foga in dessa mellan klamrarna och kör programmet på nytt. 9

3 Datorn som miniräknare I detta avsnitt tas upp hur man kan skriva program som utför enkla räkneoperationer och skriver resultat på skärmen. Syftet är i huvudsak att se hur flera C++ satser kan bygga upp ett C++ program utan att behöva fördjupa oss i djupa teoretiska resonemang. 3.1 Räkneoperationer a = 2 + 3 * 4; I C++ kan man utföra de vanliga räkneoperationerna som addition, subtraktion, multiplikation och division med ungefär samma syntax ( skrivsätt ) som i algebran. Exempel: 3.2 Variabler int a; Är en giltig C++ sats som ger en variabel döpt a värdet 14. Notera att den måste avslutas med ett semikolon. Räknereglerna är desamma som i algebran dvs. först utförs operationen 3 * 4 (12) därefter utförs operationen 2 + 12. Likhetstecknet skiljer sig en hel del från algebran. I C++ kallas likhetstecknet = tilldelningsoperator och innebär att man för över innehållet från högersidan (14) till variabeln på vänstersidan. Då satsen är utförd kommer variabeln a att innehålla värdet 14. I exemplet ovan används namnet a för att ange en variabel, en slags behållare för ett värde, snarlik variabler inom algebra. För att kunna använda en variabel i C++ måste den deklareras. I deklarationen anger man vilken typ av information som variabeln innehåller. För variabeln i exemplet som ska innehålla ett numeriskt värde kan deklarationen se ut som Denna deklaration säger att a är ett heltal ( int, förkortning för integer, heltal). Man kan se det som att en deklaration skapar en variabel med ett visst namn. En deklaration måste alltid komma före det att man använder variabeln. Det data som a refererar till kallas för en instans av ett heltal ( int ). 10

#include<iostream> using namespace std; int main() Exempel, enkelt räkneprogram: int a; int b; b = 4; a = b * 3 + 2; cout<<"variabeln a har värdet "; cout<<a; cout<<" och variabeln b har värdet "; cout<<b<<endl; return 0; Om programmet inte går att köra kontrollerar du att du matat in rätt programkod. Vi känner igen de första raderna från Hello World programmet. På rad 6 finns en deklaration utav en variabel döpt a som första programsatsen i main(). Rad 7 skapar ytterligare en variabel döpt b. Nästa sats tilldelar b värdet 4. Variabeln b innehåller hädanefter värdet 4. Rad 8: a = b * 3 + 2; Rad 10: cout<<a; Rad 8 använder värdet av variabeln b I uträkningen av värdet för variabeln a. Uttrycket till höger om tilldelningsoperatorn = kan alltså läsas ut som, 4 * 3 + 2 (14). Eftersom variabeln b tidigare tilldelades värdet 4. Rad 9 fungerar på samma sätt som utmatningen av texten "Hello World" i Hello World programmet men utan radmatningstecken. Denna sats anger också att vi skall skriva något till skärmen, men nu skriver vi inte ut någon text som vi angivit utan istället skriver vi ut innehållet i variabeln a. Variabeln a är deklarerad som ett heltal och därför kommer det att skrivas ut ett heltal på skärmen. Eftersom a tilldelades värdet 14 på Rad 8 kommer siffran 14 att skrivas ut. Utskriften sker direkt efter texten från rad 9 eftersom vi inte skrivit ut något radmatningstecken, endl. Prova och se vad som händer om man ändrar Rad 10 till cout<<"a";. Rad 11 skriver ut texten direkt efter siffran 14. Notera blanksteget i början av texten. Rad 12 fungerar på samma sätt rad 10 men det skrivs även ut ett radmatningstecken efter värdet för b. 11

3.2.1 Sammansatta utskriftssatser #include<iostream> using namespace std; int main() I programmet ovan kan det bli en smula skrymmande att använda 4 programkodsrader för att skriva ut en rad med text. Man kan kombinera utströmsoperatorerna för att åstadkomma utskriften på en enda rad. Den satsen skulle då ersätta satserna Rad 9 till Rad 12. Programmet skulle då se ut som int a; int b; b = 4; a = b * 3 + 2; cout<<"variabeln a har värdet "<<a<< " och variabeln b har värdet "<<b<<endl; Return 0; Notera hur man kan byta rad mitt i en sats eftersom man avslutar den med ett semikolon. Prova att utföra andra beräkningar genom att använda räkneoperatorerna för division / och subtraktion -. Prova dessutom att byta värden på siffrorna för att göra andra beräkningar. Divisionsoperationer kan ge oväntade resultat, mer om det i avsnittet tolkning av uttryck 12

4 Datatyper och Uttryck 4.1 Datatyper I räkneprogrammet tidigare såg vi att C++ kräver deklarationer av alla variabler som används. I räkneprogrammet användes bara variabler av heltalstyp, int, men det finns naturligtvis andra typer av variabler som kan användas i C++. I kompendiet "Datorsystem och programhantering" finns ett kapitel om intern datarepresentation som med fördel läses innan detta avsnitt. De vanligaste datatyperna är int Heltal ( integer ) short int Mindre heltal ( short integer ) long int Stort heltal ( long integer ) float Mindre rella tal ( floating point number ) double Rella tal/flyttal ( double precision floating point number ) char Tecken ( character) bool Logiskt värde ( boolean ) void Tomrum/ingenting För variationerna long int och short int kan ordet int utelämnas. För heltalstyperna och teckentypen char finns även en icke teckensatt form som anges med unsigned unsigned int unsigned short int unsigned char unsigned int a; a = -3; Dessa datatyper kallas med ett gemensamt namn för enkla datatyper. En variabel som deklareras som unsigned kan inte anta negativa värden. Dvs satserna: Ger ett oväntat resultat. 4.2 Deklarationer Deklarationer görs alltid på formen datatyp variabelnamnslista; En variabelnamnslista består av ett eller flera variabelnamn åtskilda av kommatecken. En lista är ett återkommande begrepp som omfattar fler saker än just variabelnamn. Generellt är en lista noll, ett eller flera element åtskilda av kommatecken. 13

4.3 Identifierare Det finns flera typer av identifierare där variabelnamn är en av dessa typer. De variabelnamn vi sett hittills har varit enstaka bokstäver, C++ tillåter emellertid ganska utförliga namn på variabler. Ett annat exempel på identifierare är funktionsnamn tex. main Reglerna för namngivning av identifierare är Det första tecknet måste vara en bokstav eller tecknet '_' (understreck/ underscore). Efterföljande tecken kan vara bokstäver eller siffror Tecknen å, ä och ö är ej tillåtna 4.3.1 Godkända identifierare / variabelnamn Namnen kan vara i princip hur långa som helst. 4096 tecken är en vanlig övre gräns. hello HeLlO _x _12 _hello_dude_2 number_of_variables_in_my_program Observera att man skiljer på versaler och gemener i identifierare. Variabeln a är inte samma variabel som variabeln A. 4.3.2 Icke godkända identifierare 2dudes hello dude x-y "hel" poäng man får inte börja med en siffra mellanslag är inte tillåtna i variabelnamn tecknet är ej tillåtet " är inte tillåtet, anger dessutom texten hel ä är inte ett tillåtet tecken När man skriver ett C++ program är det inte tillåtet att använda åäö i variabelnamn. Det kan därför vara en smula bökigt att använda svenska ord som variabelnamn, även fast det kan vara enklare att associera svenska ord med olika betydelser i programmet. Författaren använder av den anledningen uteslutande engelska identifierare i "skarp" programkod. Det är dessutom en betydande del av jordens befolkning som inte förstår svenska variabelnamn. I detta kompendium har jag däremot försökt att använda mig av identifierare med svenska namn för enkelhetens skull. 4.3.3 Initieringssatser En initiering är att ge en deklarerad variabel ett startvärde. Då en variabel deklareras med ex. int i; har variabeln i ett okänt startvärde. För att i ska få ett meningsfullt värde måste man göra en tilldelning. En variation på tilldelningar är initieringar, som är en kombination av en deklaration och en tilldelning. Syntaxen ser ut som 14

datatyp variabelnamn = startvärde; 4.3.4 Exempel på giltiga satser med variabeldeklarationer och intieringar int n; int i, j; double x; // i, j är en variabellista med två element // x deklareras som ett flyttal unsigned long int number_of_paalokas, number_of_cards; // två positiva heltalsvariabler deklareras bool logic_1, logic2, illogical; // tre variabler som kan anta värdet sant och falskt char c; // variabel som innehåller tecken ex 'A' double my_float_number = 2.3203; // initierad variabel int magic_number = 42; // initierad variabel Då man väljer variabelnamn för variabler i programmet ska man se till att använda så utförliga namn som möjligt. 4.3.5 Nyckelord Det finns i språket en uppsättning fördefinierad ord med speciella betydelser som inte får användas som identifierare, dessa kallas nyckelord. asm auto bad_cast bad_typeid bool break case catch char class const const_cast continue default delete do double dynamic_cast else enum except explicit extern false finally float for friend goto if inline int long mutable namespace new operator private protected public register reinterpret_cast return short signed sizeof static static_cast struct switch template this throw true try type_info typedef typeid typename union unsigned using virtual void volatile while 4.3.6 Datatypernas egenskaper Man använder variabler av olika datatyper till olika syften, och man måste välja datatyp med omsorg då man deklarerar sina variabler. 4.3.7 Lagring av enkla datatyper I en 32-bitarsmiljö ( vanlig processor ) lagras heltalstyperna enligt 15

char, unsigned char, signed char short, unsigned short int, unsigned int long, unsigned long float double 1 byte 2 bytes 4 bytes 4 bytes 4 bytes 8 bytes Då en variabel av typen int lagras i datorns minne kommer den således att uppta 4 bytes minne. Man kan enkelt räkna fram vilka talområden detta ger för heltalstyperna om man följer metoden i kompendiet "Datorsystem och programhantering", avsnitt intern datarepresentation. Samma avsnitt anger dessutom hur talområdet för flyttalen ska tolkas. char +- 127 short +- 32 767 int +- 2 147 483 647 long +- 2 147 483 647 float E+-37, 6 siffrors noggrannhet double E+-308, 15 siffrors noggrannhet #include<iostream> using namespace std; Heltalstyperna är de enklaste av datatyperna. Det är ofta tydligt när man ska använda sig av heltalstyper. Flyttalstyperna kan vara lite krångligare men med lite vana blir även det en ganska smal sak. Exempel räkneprogram med olika datatyper int main() int antal_bananer, antal_apelsiner; double medel_antal; antal_bananer = 89; antal_apelsiner = 56; medel_antal = (antal_bananer + antal_apelsiner) / 2.0; cout<<"du har i snitt "<< medel_antal << " frukter av varje sort"<<endl; return 0; Det är en god vana att använda beskrivande variabelnamn. Notera att det går utmärkt att använda åäö i texter, inom citat tecken. Rad 1-5 är de vanliga satserna för att påbörja huvudprogrammet. Rad 6 skapar två heltal med namnen antal_bananer och antal_apelsiner. 16

Rad 7 skapar ett flyttal, dvs ett tal med decimaldel som ex 3.14159265. Flyttalet medel_antal deklareras som double trots att talområdet för float mer än väl räcker till. Motivet till att välja float skulle vara att en double ansågs ta upp för mycket minne. Floatdeklarationen påverkar emellertid ytterst sällan programmets storlek i någon väsentlig grad, därför väljer man alltid double av bekvämlighet. Rad 9 och 10 är vanliga tilldelningar. Rad 12: medel_antal = (antal_bananer + antal_apelsiner) / 2.0; Parenteser används för att additionen ska utföras innan divisionen (annars blir det ju inget medelvärde). Därefter sker division med 2.0. Det inskrivna värdet 2.0 ska betraktas som att vara av typen float medan ett värde skrivet som 2 ska betraktas som att vara av typen int. Prova att ändra värdet 2.0 till värdet 2. Blir det någon skillnad vid programkörning? Rad 14: cout<<"du har i snitt "<<medel_antal<< " frukter av varje sort"<<endl; Här verkar utströmsoperatorn på en variabeln medel_antal som är av typen double, variabeln skrivs därför ut som ett flyttal till skärmen. Längre fram i programmeringsstudierna är det viktigt att inse skillnaden mellan den interna representationen av heltal och flyttal (dess bitmönster i minnet) och dess representation på skärmen. På skärmen är det en textrepresentation som syns och i minnet är det en heltalsrepresentation respektive en flyttalsrepresentation som finns. Resultatet av programkörning blir Medelpoõngen av dina prov õr 72.5 Press any key to continue Som synes innehåller 72.5 en decimaldel som inte hade kunnat erhållits om vi deklarerat medel_antal som heltal. (Tecknen åäö blir ofta förvanskade i konsolfönster. Det har att göra med att Windows och C++ är inte helt överens vilken teckentabell som ska användas.) 4.4 Uttryck och operationer Ett uttryck är en speciell syntaktisk konstruktion i C++. De flesta programsatser är i sig själva ett uttryck, eller innehåller ett uttryck. Vi har redan sett flera exempel på uttryck med operatorer. Vi har bland annat sett: Uttryck 1: antal_bananer = 89; och 17

Uttryck 2: medel_antal = (antal_bananer + antal_apelsiner) / 2.0; och Uttryck 3: cout<<"variabeln a har värdet "; Deklarationssatserna räknas inte till uttryck Uttryck 1 och 3 är enkla uttryck medan uttryck 2 är ett sammansatt uttryck. Vi kan se att de enkla uttrycken 1 och 3 består utav en operator, = för 1, << för 3, och två operander vardera. antal_bananer och 89 är operanderna för Uttryck 1, cout och "variabeln a har värdet" är operanderna för uttryck 3. Det sammansatta uttrycket är flera hopslagna enkla uttryck. 4.4.1 Binära operationer Den vanligaste formen av enkla uttryck är just en binär operator och dess operander. Operatorn kallas binär eftersom den alltid behöver två operander. De binära operatorerna i C++ är: 18

Aritmetiska operatorer + Addition Subtraktion * Multiplikation / Division % Modulus += Addition med tilldelning = Subtraktion med tilldelning *= Multiplikation med tilldelning /= Division med tilldelning %= Modulus med tilldelning Strömoperatorer << Utströmsoperator >> Inströmsoperator Tilldelningsoperator = Tilldelning Logiska operatorer!= Icke lika med < Mindre än <= Mindre än lika med == Lika med > Större än >= Större än lika med && Logiskt AND Logiskt OR Bitoperatorer ^ Exklusivt OR & Bitvis AND Bitvis OR ^= Exklusivt OR med tilldelning &= Bitwise AND med tilldelning = Bitvis OR med tilldelning De enkla räkneoperatorerna har behandlats tidigare, förutom modulusoperatorn. Varje räkneoperator har en tilldelningsvariant, exempelvis har + operatorn en variant +=. Denna operator är en ren bekvämlighet. I program stöter man ofta på situationer när en variabel ska öka eller minska i värde. Exempelvis int i; i = 65; cout << " i har nu värdet 65 "<< endl; i = i + 8; cout << " i har nu värdet 73 "<< endl; Exemplet är ett lösryckt programavsnitt som måste fogas in i main() funktionen för att fungera som program. 19

Rad 4 i exemplet kan man alltså läsa ut som: Tilldela variabeln i det tidigare värdet på i plus 8. Mer korrekt ses satsen som att den består utav två operationer, där operation 1 är i + 8 med resultatet 73 av typen int, operation 2 är i = 73, i tilldelas värdet 73. Att öka värdet på en variabel på detta sätt är så vanligt att man har skapat en operator som utför denna sammansatta sats i en enda operation +=. Det lösryckta programavsnittet ovan omskrivet med += operatorn ser då ut som int i; i = 65; cout << " i har nu värdet 65 "<< endl; i += 8; cout << " i har nu värdet 73 "<< endl; En marginell skillnad kan tyckas, men man lär sig snabbt att trivas med detta skrivsätt. Dessutom blir det väldigt tydligt då man läser programkoden. Fler exempel på räkneoperatorer kombinerade med tilldelning int i; i = 65; cout << " i har nu värdet 65 "<< endl; i -= 15; cout << " i har nu värdet 50 "<< endl; i /= 5; cout << " i har nu värdet 10 "<< endl; i *= 2; cout << " i har nu värdet 20 "<< endl; Modulusoperatorn kan tänkas vara en ny bekantskap. En modulusoperation beräknar resten vid heltalsdivision. Heltalsdivision får man då man dividerar två värden av typen int och anger resultatet som ett heltal, ex 7 / 2 = 3. Divisionen 7 / 2 går inte jämt upp utan det korrekta svaret borde varit 7 / 2 = 3.5. Men eftersom det är fråga om heltalsdivision anger man inte decimaldelen av kvoten utan bara heltalsdelen. Istället anger man en rest för den del av kvoten som inte gick jämt upp som 7 / 2 = 3 rest 1. Resten kan beräknas ur heltalskvot * nämnare + rest = täljare, eller rest = täljare heltalskvot * nämnare. Modulusoperatorn har ett antal speciella användningsområden som kommer att framgå senare av exempel. 4.4.2 Unära räkneoperatorer Det finns ytterligare aritmetiska operatorer som är av unär typ. Dessa operatorer tar alltså bara en operand. ++ prefix inkrement, operator placeras före operand ++ postfix inkrement, operator placeras efter operand -- prefix dekrement, operator placeras före operand -- postfix dekrement, operator placeras efter operand Dessa operatorer ökar respektive minskar värdet på en numerisk variabel med ett. Den prefixa varianten sätts före variabelnamnet och den postfixa sätts efter variabelnamnet. 20

int a; a = 8; ++a; // prefix cout << a har värdet 9"<<endl; a++; // postfix cout << a har värdet 10"<<endl; --a; // prefix a--; // postfix cout << "a har värdet 8"<<endl; Skillnaden mellan prefix och postfix märks först om man sätter in operationerna i sammansatta uttryck. Den prefixa operationen ger som resultat det värde som variabeln har efter operationen, den postfixa ger det värde variabeln hade före operationen. int a; int i; a = 8; i = ++a; // prefix ++a utvärderas till värdet 9 cout << a har värdet 9 och i har värdet 9"<<endl; i = a++; // postfix ++a utvärderas till värdet nio cout << a har värdet 10 och i har värdet 9"<<endl; i = --a; // prefix uttrycket - a ger värdet 9 i = a--; // postfix uttrycket a - ger värdet 9 cout << "a har värdet 8 i har värdet 9"<<endl; Det som är skrivet i programkoden ovan efter tecknen // är kommentarer. En kommentar som skrivs på en rad startar med // och slutar då raden slutar. Det som står efter kommentartecknen kommer kompilatorn inte att bry sig om. Kommentarer står också ofta ensamma på en rad. int a; // Nu är variabeln a deklarerad. Kompilatorn bryr sig inte om denna rad Kommentarer är otroligt användbara som minnesanteckningar i programkod. Man kan även Skriva kommentarblock som sträcker sig över flera rader med symbolerna /* och */ ( observera ordningen). Tänk på att inte av misstag råka skriva några programsatser som ska utföras i ett kommentarblock. int a; /* */ a = 8; Nu är variabeln a deklarerad. Kompilatorn bryr sig inte om raderna inuti kommentarblocket. Som tar slut nu. 4.4.3 Tolkning av uttryck Funktionen hos ett binärt uttryck bestäms exakt av dess operator och dess operanders datatyper. Exempelvis Uttryck 1: antal_bananer = 98; Tilldelningsoperatorn tillsammans med variabeln av typen int och siffran 98 av typen int anger att siffra 98 ( bestående av 4 bytes) ska kopiera (tilldela) dessa 4 bytes till variabeln antal_bananer. 21

Operationen som utförts kan beskrivas som (int ) = ( int ) Observera att detta inte är programsatser utan bara ett sätt att beskriva uttryck. Varje operation ger som resultat ett värde som kallas returvärde, detta värde har en datatyp som kallas returtyp eller resultattyp. Man får en exakt beskrivning av operationen om man dessutom anger returtypen som för Uttryck 1 är int ( egentligen en variant av int som int behandlats än, mer om det senare). Detta kan man skriva som (int ) = (int ): int Generellt: ( datatyp operand till vänster ) operator ( datatyp operand till höger ) : returtyp Det som står till vänster om kolon kallas för operationens signatur. I tilldelningssatsen utnyttjas inte returvärdet. Det gör det däremot i den sammansatta satsen i Uttryck 2. medel_antal = (antal_bananer + antal_apelsiner) / 2.0; Satsen är sammansatt av tre enkla uttryck med var sin operator =, + och /. För att exakt hur satsen tolkas delar man upp den i dess enkla uttryck och utvärderar dom i tur och ordning. Denna ordning bestäms av operatorprioriteter som är angivna i bilaga operatorprioriteter. I korthet kan sägas att de flesta operatorer ska läsas från vänster till höger. Tilldelningsoperatorn = är ett tydligt undantag då den läses från höger till vänster. Uppenbara undantag finns också i aritmetiska uttryck som 3 + 4 * 5. Uttrycket 4*5 beräknas före additionen med 3, detta kommer sig av just operatorprioriteten. Utvärderingsordningen för operatorer kan alltid ändra med hjälp av parenteser. Jämför: ( 3 + 4 ) * 5 I tur och ordning utvärderas antal_bananer + antal_apelsiner denna operation är en addition mellan två heltal, och resultatet är ett heltal alltså ( int ) + ( int ) : int Då operationen är utförd har 89 och 56 adderats och resultatet 145 av typen int erhållits. Därefter utvärderas nästa operation, / operationen. Den kan man läsa ut som eller 145 / 2.0 (int ) / ( double ): double 22

Resultatet av en division med flyttal är ett flyttal. Av denna operation erhålls resultatet 72.5 av typen double. Därefter utförs operationen = eller medel_antal = 72.5 ( double )= ( double ) : double För räkneoperatorerna gäller allmänt att om någon av operanderna är av flyttalstyp kommer resultatet vara av flyttalstyp, och omvänt, om båda operanderna är av heltalstyp kommer resultatet att vara av heltalstyp. Exempelvis ( double ) + ( double ) : double En addition av två flyttal ger resultat av flyttalstyp ( double ) - ( int ) : double En subtraktion av ett flyttal och ett heltal ger resultat av flyttalstyp. Egentligen omvandlas heltalet först till ett flyttal innan subtraktionen. Regeln för typer vid räkneoperationer kan ge en del oväntade resultat, i synnerhet vid division. Division mellan två heltal ger resultat av typen heltal ( int ) / ( int ) : int Exempelvis ger divisionen 13 / 5 resultatet 2. Betrakta: #include<iostream> using namespace std; int main() int i, j; i = 14; j = 19; double resultat; resultat = j / i; cout << " 19 / 14 = "<< resultat << endl; return 0; 23

Vid programkörning skrivs på skärmen 19 / 14 = 1 Press any key to continue Detta trots att variabeln resultat deklarerats som double. Eftersom operationen ( int ) / (int ) ger resultattyp int kommer variabeln resultat att innehålla värdet 1. Om vi stället hade skrivit Rad 10: resultat = double( j ) / i; Skulle variabeln j omvandlats till flyttal och divisionsoperationen skulle då vara ( double ) / ( int ) : double Och värdet på variabeln resultat skulle då vara 1.35714 Uttycket double( j ) är ett exempel på typomvandling. 24

5 Inmatning och utskrift Inmatning från tangentbord och utskrift till skärm sker i C++ med hjälp av strömmar. Vi har tidigare sett exempel på utskrift. Vi kommer i det här avsnittet även ta upp inmatning från tangentbordet så att vi kan skapa program som kommunicerar med en användare istället för att använda värden inskrivna i programkoden. 5.1 Utskrift till skärm För att skriva data till skärmen ( konsolen) används variabeln cout tillsammans med strömoperatorn <<. Denna binära operator fungerar på samma sätt som andra binära operatorer dvs. den tar två operander och ger ett resultat. Variabeln cout är deklarerad i filen iostream med datatypen ostream (output stream, utström). Operationen << ser generellt ut som ( ostream ) << ( annan datatyp ) : ostream Vi har tidigare sett bland annat int a; a = 6; cout<< a har värdet "<< a << endl; double x; x = 3.202; cout<< x har värdet << x << endl; Om vi betraktar rad 3 cout<< a har värdet "<< a << endl; ser vi att utströmsoperatorn finns på tre ställen, satsen är alltså sammansatt av tre enkla uttryck. Den operation som utförs först är den längst till vänster. eller cout<< "a har värdet" ( ostream ) << ( text ):ostream Returvärdet från operationen är variabeln cout. ( operationen ger operanden som resultat ) Nästa operation kan alltså läsas ut som cout<< a Även denna operation ger operanden cout som resultat. Den sista operationen kan därför läsas ut som cout<< endl 25

Med utströmsoperatorn kan man alltså med en enda sats skriva ut så många variabler och texter som man vill. Det är ändå oftast en god ide att hålla raderna så pass korta att de blir lättlästa. Det brukar som regel innebära maximalt 2 3 variabler och en kortare text. 5.1.1 Formatering av utmatning #include<iostream> using namespace std; Man vill gärna att den utskrift som programmet gör på skärmen ska vara snygg och lättläst. Tyvärr blir det inte alltid som man tänkt sig, i synnerhet då värden på flyttalsvariabler ska skrivas ut på skärmen. Exempel, valutaomvandling int main() double kron_dollar_kurs = 10.43; double kronor = 345.50; double dollars; dollars = kronor / kron_dollar_kurs; cout << kronor << " svenska kronor blir "; cout << dollars << " amerikanska dollar" << endl; Resultatet av programkörningen blir 345.5 svenska kronor blir 33.1256 amerikanska dollar Press any key to continue Det är inte speciellt snyggt att få fyra decimaler på dollarkursen. På vissa kompilatorer kan man få ännu mer svårlästa utskrifter ex 3.455E+02 svenska kronor blir 3.31256E+1 amerikanska dollar Press any key to continue Siffrorna ska läsas som 3.455 * 10 2 och 3.31256* 10 1. För att råda bot på detta finns det ett antal knep man kan ta till. För att få ett visst antal decimaler kan man skriva cout.setf(ios::showpoint); // visa alltid decimalpunkt cout.precision( 2 ); // med två flyttalsdecimaler Skriv denna dessa två rader som egna satser innan flyttalen skrivs ut. Obs detta påverkar inte på något sätt flyttalsvariablernas precision utan endast hur de skrivs på skärmen. För att få en decimalpunkt istället för E notationen ovan skriver man 26

cout.setf(ios::fixed ); setf och precision är funktioner( eller metoder ) kopplade till utströmmen cout. Det som ges innanför parenteserna ( ios::fixed och heltalet 2 )kallas funktionsargument. Ett annat sätt att formatera utskriften är att ange hur många positioner ett uttryck ska uppta. Comment [KP1]: Borde vara en utskrift, eller cout.width( 20 ); #include<iostream> using namespace std; Ger att nästföljande utströmsoperation kommer att ta minst 20 teckenpositioner till sitt förfogande. Om talet eller texten är kortare fogas tillräckligt antal blanksteg in. Observera att den angivna bredden bara gäller för den utströmsoperation till cout som kommer direkt efter cout.width( ) Sammantaget kan då programmet se ut som: int main() double kron_dollar_kurs = 10.43; double kronor = 345.50; double dollars; dollars = kronor / kron_dollar_kurs; cout.setf(ios::showpoint); cout.precision( 2 ); cout.setf(ios::fixed ); cout << kronor << " svenska kronor blir "; cout << dollars << " amerikanska dollar" << endl; return 0; 5.2 Inmatning från tangentbordet Inmatning görs med strömmar, på ett liknande sätt som utmatningen. Man använder sig av en inströmsoperator>> istället för utströmsoperatorn<<, och inströmmen kallas cin istället för cout. Den stora skillnaden är att en inströmsoperation stannar tillfälligt programmet i väntan på inmatning ifrån tangentbordet. Inströmsoperationen har liknande form som utströmsoperationen ( istream ) >> ( någon datatyp ) : istream Datatypen istream ( input stream, inström) och cin är båda definierade och deklarerade i iostream. För att ta emot inmatning av ett heltal från tangentbordet kan man skriva: 27

int i; cin >> i; Inströmsoperationen liknar till viss del en tilldelningsoperation, men med den stora skillnaden att värdet som variabeln i får bestäms av användaren som kör programmet. Programmet väntar i inströmsoperationen tills det att användaren faktiskt matat in ett värde. Denna egenhet gör att man för varje inmatningssats ( inströmsoperation från cin ) måste se till att användaren blir varskodd att programmet väntar på inmatning. Det görs ganska enkelt genom att skriva ut lite ledtext på skärmen. int i; cout << "Mata in ett heltal och tryck på return"<<endl; cin >> i; #include<iostream> using namespace std; Glömmer man att lägga till ledtext till inmatningen, eller kanske rentav råkar lägga den efter inmatningen, kommer programmet att vänta på en inmatning från användaren, och användaren kommer i sin tur att inte ha en aning om att programmet väntar tålmodigt på en inmatning. Dollarkursprogrammet tidigare blir betydligt mer användbart om man lägger till en inmatningsprocedur int main() double kron_dollar_kurs = 10.43; double kronor; double dollars; // ange ledtext direkt före inmatning cout << "Ange hur många kronor du har:"<<endl; cin >> kronor; // resultatet beror på vad som matats in dollars = kronor / kron_dollar_kurs; cout.setf(ios::showpoint ); cout.precision( 2 ); cout.setf(ios::fixed ); cout << "Dina "<< kronor << " svenska kronor blir "; cout << dollars << " amerikanska dollar" << endl; En programkörning kan då se ut som 28

Ange hur mõnga kronor du har: 6500 Dina 6500.00 svenska kronor blir 623.20 amerikanska dollar Press any key to continue Programmet skriver först ut ledtexten, väntar på inmatningen, 6500[Enter]. [Enter] anger att tangenten Enter/Return/Vagnretur skall tryckas. Sedan skrivs resultatet av beräkningen ut. Inströmsoperationen kan i likhet med utströmsoperationen ta emot flera inmatningar i en sats. double variabel1, variabel2; cout<<"skriv in två flyttal, avsluta med return"; cin>> variabel1 >> variabel2; Inmatningen till denna sats kan antingen göras genom att man skriver två tal och trycker return mellan varje tal, eller kan man separera talen med blanksteg eller tab och avsluta inmatningen med return. Se även om vittecken i avsnittet Texthantering, in och utmatning. Problemet med denna typ av inmatning är att man inte kan skriva ut någon ledtext mellan varje inmatning. Utan man kan bara ge ledtexter typ "Ange 4 tal". Det kan därför vara ett bättre alternativ att dela upp det så att man bara har en inmatning per sats, och ledtext till varje inmatning. 5.2.1 Exempelprogram Beräkna area och omkrets hos en rektangel. 29

#include<iostream> using namespace std; int main() double sida; double bredd; double omkrets; // ange ledtexten cout << "Ange längden på rektangeln:"<<endl; cin >> sida; // ny ledtext cout << "Ange bredden på rektangeln:"<<endl; cin >> bredd; omkrets = sida*2 + bredd*2; cout.setf(ios::showpoint ); cout.precision( 2 ); cout.setf(ios::fixed ); cout <<"Omkretsen på rektangeln är "<< omkrets<< endl; cout <<"Rektangeln har arean "; // sida*bredd är arean cout << sida*bredd<<endl; // observera att beräkningen görs före utströmsoperationen // * har högre prioritet än << Return 0; 5.2.2 Övning: Skriv ett program som frågar efter hur gammal du är, och därefter berättar hur många dagar du levat. Dela upp lösningen i olika steg. Börja med att fundera på hur du vill att beräkningen ska gå till. Då du vet hur du vill att beräkningen ska fungera tänker du ut hur användardialogen (programkörningen med in och utmatningar) ska se ut. Därefter kan du börja skriva programmet genom att titta på tidigare exempel. Tänk särskilt på vilka variabler du behöver och vilka datatyper dessa variabler bör ha. 30

6 Villkor och styrsatser I de program vi sett tidigare har programkörning inneburit att sats efter sats utförts i den ordning de skrivits i källkoden. Vi har inte kunna ändra programmets uppförande beroende på inmatningar eller beräkningsresultat. Vi kallar en sådan samling satser för en sekvens, eftersom de utförs en efter en. Sekvens: Start: Sats1 -> sats 2 -> sats 3 -> sats 4 Slut. Vi ska nu titta på en ny struktur som kallas för selektion. Selektion innebär att programmet kan under programkörning fatta beslut om vilken av en, två eller flera alternativa sekvenser som ska utföras. 6.1 Villkorssatsen if En villkorssats är den konstruktion som finns i C++ för att göra en selektion av två alternativa sekvenser. Formen för if- satsen är alternativt if ( logiskt_uttryck ) sats / satsblock else sats / satsblock if ( logiskt_uttryck ) sats / satsblock Det logiska uttrycket anger ett villkor som är antingen sant eller falskt. Den första sats/satsblocksdelen är det programavsnitt som ska utföras om villkoret är sant. Den andra sats/satsblocksdelen är det som ska utföras om villkoret är falskt. else och det efterföljande sats/satsblock är valfritt. Några enkla exempel: int antal_husdjur; cout << "Ange hur många husdjur du har hemma"<<endl; cin >> antal_husdjur; cout << "Jaså du har "<< antal_husdjur<< " husdjur"<<endl; if ( antal_husdjur > 5 ) cout << "Oj det var många"<<endl; cout << "slut"<< endl; Programavsnittet måste fogas in i en main() funktion för att fungera. Detta program har nu två möjliga vägar att gå: 31

1. Villkoret är sant. Användaren har matat in en siffra större än 5. Ange hur många husdjur du har hemma 12 Jaså du har 12 husdjur Oj det var många slut 2. Villkoret är falskt. Användaren har matat in en siffra som är 5 eller lägre. Ange hur många husdjur du har hemma 2 Jaså du har 2 husdjur slut 6.1.1 Satsblock Villkorssatsen i exemplet utnyttjar att else delen av if satsen är valfri. Dessutom läggs det en sats och inte ett satsblock efter if satsen. if satsen väljer bara den sats som ligger direkt efter villkoret. Notera indragningen av satsen cout<<"oj det var många"<<endl; Indragningen är densamma som ses efter klammern efter main(). Syftet med indragningen är att då man läser programmet ska man enkelt kunna se vilken eller vilka satser som hör till villkoret. Indraget bör vara ungefär 3-4 mellanslag. För att kunna utföra flera satser styrda av ett villkor konstruerar man ett satsblock. Ett satsblock är helt enkelt en sekvens av satser omgärdade av och klamrar. Funktionen main() har också ett satsblock, klamrarna och som anger början respektive slut på programmet. Ett liknande program med satsblock och else satser int antal_husdjur; cout << "Ange hur många husdjur du har hemma"<<endl; cin >> antal_husdjur; if ( antal_husdjur > 5 ) cout << "Oj det var många hela "; cout << antal_husdjur << " stycken"; cout << endl; else cout << Jaså du har bara"; cout << antal husdjur << " stycken"; cout << endl; cout<<"slut"<<endl; Observera hur indraget ( kallad indentering ) går över hela satsblocken. Programmet kommer nu att välja endast en av vägarna efter if satsen. Om villkoret är uppfyllt utförs satsblocket direkt efter villkoret, annars utförs satsblocket efter else. 32

6.1.2 Övning: Sätt in ovanstående exempel i ett komplett program och provkör. Blev resultatet det du förväntade dig? Rätta till indenteringen i föregående program. Ett vanligt fel är att man råkar lägga en ensam sats mellan if satsen och satsblocket. Kompilatorn har svårt att ge en rimlig felbeskrivning för detta fel. Ett annat vanligt fel är att man påbörjar satsblocket innan villkorssatsen eller else. Satsblocket blir då som regel betydelselöst. if ( antal_husdjur > 5 ) // FEL! Satsblocket börjar inte direkt efter villkoret cout << "Oj det var många hela "; cout << antal_husdjur << " stycken"; cout << endl; else cout << Jaså du har bara"; // FEL! Satsblocket börjar inte direkt efter else satsen. cout << antal husdjur << " stycken"; cout << endl; Det händer också att man ibland råkar sätta ett semikolon direkt efter if satsens villkor. if ( längd < 30.7 ); // FEL! cout << "kort längd"; Detta får till följd att en tom sats direkt efter villkoret styrs av if satsen. Eftersom satsen är tom påverkar den inte programmet på något sätt. cout satsen däremot som var tänkt att påverkas av villkoret utförs oavsett resultatet på villkoret eftersom if satsen tar slut i och med semikolonet. 6.2 Logiska villkor I och med villkorssatsen stöter vi på en ny typ at uttryck, de logiska. De logiska uttrycken följer samma mönster som de tidigare operationerna vi sett med den skillnaden att resultatet av en logisk operation alltid är ett booleskt(logiskt) värde, sant eller falskt. Operatorerna som ger logiska resultat kallas, logiskt nog, logiska operatorer. 33

Logiska binära operatorer == Lika med!= Icke lika med < Mindre än <= Mindre än lika med > Större än >= Större än lika med && Logiskt AND Logiskt OR and Borttaget ur C++: Logiskt AND synonymt med && or Borttaget ur C++: Logiskt OR synonymt med I villkoret i exemplet ovan användes den logiska operatorn > på formen ( int ) > ( int ) : bool Varje logisk operation ger ett resultat av typen bool. Man kan använda sig av variabler deklarerade med typen bool för att lagra logiska värden. Villkoret i exemplet ovan hade kunnat skrivas utförligare som: bool manga_husdjur; manga_husdjur = antal_husdjur > 5; if ( manga_husdjur ) // satsblocken som tidigare med samma betydelse. Variabeln manga_husdjur kan alltså anta värdena true eller false. Om ett logiskt värde av typen bool i något uttryck kan betraktas som ett heltal kommer värdet true att vara värdet 1, och false kommer att vara värdet 0. De flesta logiska operationer är tämligen rättframma. Här följer några exempel på hur uttrycken kan se ut: Antag att förekommande variabler är deklarerade med en rimlig datatyp ( vikt < 60.0 ) ( antal_hundar== 2 ) ( antal_valar!= 2 ) // motsatsen till ovan ( antal*2 >= 52 ) // räkneoperationen utvärderas först Man kan dessutom kombinera uttryck med de logiska operatorerna && ( OCH ) och (ELLER). Dessa operatorer har formen ( bool ) && ( bool ): bool ( bool ) ( bool ): bool Man använder alltså dessa operatorer på logiska värden eller uttryck 34

( antal == 2 && vikt < 20.0 ) // Jämförelserna utvärderas först och // därefter utvärderas && // båda jämförelserna måste vara sanna för // att hela uttrycket ska vara sant ( antal == 2 vikt < 20.0 ) // om någon av jämförelserna är sanna // är uttrycket sant Det finns även en unär logisk operator! eller not. Operatorn fungerar så att den vänder ett sant värde falskt, och tvärtom. Exempel (!( 3 > 4 ) ) // är sant ( not( 7 == 12 ) ) // är sant (! (4==4) ) // är falskt Det bör sägas ett varningens ord om likhetsjämförelser av flyttal. Om man har två flyttal är det ofta svårt att kontrollera om de är lika, eftersom jämförelsen kräver att de är exakt lika i varje bit. Då varningar utfärdas får man inte glömma bort att varna för en viss typ av sammansatta jämförelser. Betrakta följande programavsnitt int hur_gammal; cout << "Ange din ålder "<<endl; cin >> hur_gammal; // kolla om tonåring, äldre än 12 och yngre än 20 år if ( 12 < hur_gammal < 20 ) // FEL! cout << "Du är tonåring"<<endl; Villkoret kan till en början se riktigt ut, kompilatorn upptäcker troligtvis inget fel. Faktum är att skrivsättet är väldigt vanligt inom algebra. Om man däremot ser i detalj vad villkoret utvärderar ser man ett problem. Den första operationen som utförs är jämförelsen ( från vänster till höger ) 12 < hur_gammal resultatet av denna operation är av typen bool och används som vänster operand i nästa < operation. Resultatet av uttrycket är antingen 0 eller 1, nästa jämförelse blir därför 1 < 20 om hur_gammal var större än 12 annars 0 < 20 Båda dessa villkor är sanna och hela uttrycket är i princip värdelöst. För att skriva jämförelsen på ett riktigt sätt måste man dela upp den i två jämförelser, dels 12 < hur_gammal och dels i hur_gammal < 20 kombinerade med && (and). 35