Introduktion till programmering - Mittuniversitetet
Introduktion till programmering - Mittuniversitetet
Introduktion till programmering - Mittuniversitetet
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Introduktion</strong><br />
<strong>till</strong><br />
<strong>programmering</strong><br />
v. 1.12- 2007-02-10<br />
<strong>Mittuniversitetet</strong><br />
Institutionen för Informationsteknologi och medier<br />
Datateknik<br />
Martin Kjellqvist
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Innehållsförteckning<br />
1 Inledning ....................................................................................................................................4<br />
2 Språket C++ ..............................................................................................................................5<br />
2.1 Valet av språket C++ för kompendiet.................................................................................5<br />
2.2 Språket ..................................................................................................................................5<br />
2.3 Att programmera..................................................................................................................5<br />
2.4 Hello World..........................................................................................................................5<br />
2.5 Att skapa ett program, kompilering och länkning .............................................................8<br />
2.6 main()....................................................................................................................................8<br />
3 Datorn som miniräknare.......................................................................................................10<br />
3.1 Räkneoperationer ...............................................................................................................10<br />
3.2 Variabler .............................................................................................................................10<br />
4 Datatyper och Uttryck ...........................................................................................................13<br />
4.1 Datatyper ............................................................................................................................13<br />
4.2 Deklarationer......................................................................................................................13<br />
4.3 Identifierare ........................................................................................................................14<br />
4.4 Uttryck och operationer.....................................................................................................17<br />
5 Inmatning och utskrift...........................................................................................................25<br />
5.1 Utskrift <strong>till</strong> skärm...............................................................................................................25<br />
5.2 Inmatning från tangentbordet............................................................................................27<br />
6 Villkor och styrsatser.............................................................................................................31<br />
6.1 Villkorssatsen if .................................................................................................................31<br />
6.2 Logiska villkor ...................................................................................................................33<br />
6.3 Iteration...............................................................................................................................37<br />
7 Texthantering..........................................................................................................................45<br />
7.1 Typen char..........................................................................................................................45<br />
7.2 Fältvariabler .......................................................................................................................47<br />
7.3 In och utmatning ................................................................................................................48<br />
7.4 Texthanteringsfunktioner ..................................................................................................52<br />
7.5 Datatypen string .................................................................................................................55<br />
8 Funktioner och procedurell abstraktion.............................................................................57<br />
8.1 Funktioner ..........................................................................................................................57<br />
8.2 Funktioner som behöver indata.........................................................................................60<br />
8.3 Funktioner som returnerar värden.....................................................................................63<br />
8.4 Speciella datatyper för funktionsargument ......................................................................65<br />
9 Fältteori....................................................................................................................................69<br />
9.1 Fält av andra datatyper än char .........................................................................................69<br />
10 Standardalgoritmer................................................................................................................73<br />
10.1 Swap funktion ....................................................................................................................73<br />
10.2 Sök minsta värdet i en array..............................................................................................73<br />
10.3 Array sortering ...................................................................................................................74<br />
10.4 Övrigt..................................................................................................................................75<br />
11 Operatorprioriteter................................................................................................................76<br />
12 Teckenkoder – Asciitabell .....................................................................................................77<br />
2
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
3
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
1 Inledning<br />
Detta kompendium är tänkt att fungera som ett förberedande material och komplement<br />
<strong>till</strong> föreläsningar inom teoretiska studier av grundläggande <strong>programmering</strong>.<br />
Programmeringsspråket som är valt för kompendiet är C++ men det mesta utav teorin<br />
är applicerbar på de flesta strukturerade och objektorienterade programspråk, såsom<br />
Pascal, c, Java, Fortran, JavaScript(ECMA skript).<br />
Texten förutsätter inga förkunskaper annat än gymnasiekompetens och datorvana.<br />
Texten läses med fördel vid en dator där man har möjlighet att testa de olika program<br />
och konstruktioner som dyker upp i texten.<br />
4
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
2 Språket C++<br />
2.1 Valet av språket C++ för kompendiet<br />
2.2 Språket<br />
Språket C++ är ett språk som utvecklats för storskalig objektorienterad utveckling av<br />
sofistikerade och komplexa system. Det ligger då i sakens natur språket har flera<br />
vinklar och vrår som inte kommer att vara viktiga under studier av grundläggande<br />
<strong>programmering</strong>, men som än dock kommer att påverka den praktiska<br />
<strong>programmering</strong>en.<br />
Det kommer att dyka upp flera exempel på saker som inte har någon naturlig förklaring<br />
bland den del av språket som texten behandlar, saker som då kan kännas obekväma<br />
eller onödiga. Men tanken är att en stor andel av er som använder detta kompendium<br />
kommer att fortsätta studera <strong>programmering</strong> i C++. C++ är ett av de mest omfattande<br />
<strong>programmering</strong>sspråk som finns, men det är samtidigt förmodligen det mest<br />
uttrycksfulla språk, trots det är den del som berörs i denna text i all väsentlighet snarlik<br />
de flesta andra datorspråk.<br />
C++ är en blandning av ett objektorienterat språk och ett strukturerat språk, en sk<br />
hybrid, och har troligtvis en större marknadsandel av komersiella applikationer än<br />
något annat språk. C++ är ett relativt nytt språk, standardiseringen gjordes sent 1998.<br />
Språket har tidigare funnits i olika former och dialekter sedan tidigt 80-tal.<br />
Bjarne Strostrup är den ursprunglige konstruktören (eller uppfinnaren) av C++. Han<br />
har skrivit flera böcker som i det närmaste erhållit bibelstatus bland C++<br />
programmerare, bla "The C++ programming language", Addison-Wesley.<br />
2.3 Att programmera<br />
För att kunna programmera behöver du en dator (duh?) och en utvecklingsmiljö ( en<br />
kompilator och en textredigerare ). För kompendiet har valts Microsoft Visual C++ 6.0<br />
(VC) som testmiljö eftersom den används på Mitthögskolan och är dessutom en vanlig<br />
professionell miljö för programvaruutvecklning på PC. För eget bruk finns VC (Visual<br />
C++) med studentlicens för under tusenlappen. Ett annat alternativ är ett gratispaket<br />
som heter DJGPP som finns att hämta på nätet http://www.delorie.com/djgpp/. Det<br />
finns dessutom en grafisk gratismiljö som heter Dev-C++ som finns på<br />
http://www.bloodshed.net/devcpp.html.<br />
2.4 Hello World<br />
Då man först introduceras <strong>till</strong> ett nytt programspråk eller en ny <strong>programmering</strong>smiljö<br />
bör man först se <strong>till</strong> att man behärskar proceduren att skapa ett körbart program. Det<br />
sker väldigt ofta med Hello World. Syftet med Hello World programmet är att se hur<br />
allting fungerar då man ska skapa ett program.<br />
5
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
2.4.1 Börja programmera<br />
För att komma igång att programmera börjar man med att starta programmet VC 6.0<br />
(om det är VC man använder:-) Inställningarna är snarlika i VS.NET<br />
För att kunna börja skriva ett program i VC måste man skapa ett projekt. I denna kurs<br />
kommer vi uteslutande att skapa textbaserade program i projekt av typen Win32<br />
Console application.<br />
1. Menyalternativ File / New ...<br />
2. Dialogrutan New / flik Projects, välj Win32 Console application.<br />
3. Ange projektets namn i rutan för detta. Det kommer att skapas en<br />
katalog med detta namn. Lämpligt namn kan vara tex "HelloWorld".<br />
4. Peka ut var någonstans på hårddisken du vill att projektet ska<br />
skapas. Detta kan vara väldigt viktigt att det görs rätt om du arbetar<br />
i en labbsal, fråga din handledare.<br />
5. Välj Ok då du är nöjd med dina val.<br />
Win32 Console Application Wizard - Välj Empty project, tryck Finish / Ok<br />
I VS.NET finns det en extra flik med inställningar där du fyller i detta.<br />
6
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
I varje C++ miljö är ett program indelat i en eller flera filer där den vanligaste filtypen<br />
är källkodsfiler eller cpp filer. Man kallar dem cpp filer eftersom de har suffixet .cpp.<br />
För att kunna börja skriva programmet ska programmets huvudfil skapas. Det görs<br />
genom att man går <strong>till</strong> menyn File / New … , väljer C++ source file och anger namnet (<br />
i rutan File Name ) <strong>till</strong> förslagsvis main. Filen du nu skapar kommer alltså att få<br />
namnet main.cpp.<br />
Nu är det dags att mata in programmet.<br />
I det nya textfönstret som dykt upp ( editorn ) kan vi nu mata in följande<br />
int main()<br />
{<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
2.5 Att skapa ett program, kompilering och länkning<br />
Det som du skrev in i utvecklingsmiljöns editor var C++ källkod, dvs programrader<br />
med C++ satser. Datorn förstår inte dessa satser naturligt utan måste först översätta<br />
dem <strong>till</strong> ett för datorn förståeligt språk, s.k. objektkod. Den objektkod som skapas<br />
måste därefter sättas ihop <strong>till</strong> ett körbart program. Dessa procedurer kallas kompilering<br />
respektive länkning.<br />
2.5.1 Kompilering<br />
2.5.2 Länkning<br />
2.6 main()<br />
När ett program kompileras kontrolleras först att dess syntax är riktig. Det innebär att<br />
kompilatorn ser <strong>till</strong> att de programrader som är skrivna i källkoden följer de regler som<br />
finns för språket C++. Ungefär på samma sätt som en modern ordbehandlare kan<br />
kontrollera stavning, avstavning och andra språkregler.<br />
Då felkontrollsproceduren är avklarad ( den sker egentligen i flera steg ) börjar<br />
översättningen <strong>till</strong> objektkod. Resultatet av översättningen är vanligvis en fil som i vårt<br />
exempel heter HelloWorld.obj eller något liknande. I den filen finns lösryckta fragment<br />
av för datorn förståelig programkod. Dessa måste nu sättas ihop för att kunna köras<br />
som ett program. Det görs av länkaren.<br />
När objektfilerna skapats tar länkaren vid för att skapa ett körbart program. Det gör den<br />
genom att foga ihop det skrivna programmet med andra befintliga objektfiler s.k.<br />
biblioteksfiler. Bland annat kommer vårt Hello World programs objektfil att kopplas<br />
ihop med funktioner för att skriva ut text på skärmen. Resultatet av länkningen läggs i<br />
exemplet i en fil med namnet HelloWorld.exe som är ett helt vanligt<br />
Windowsprogram 1 .<br />
Man kan i alla miljöer göra en kompilering utan att göra en länkning med ett compile<br />
kommando, hur detta görs varierar från miljö <strong>till</strong> miljö. Man kan dessutom utföra en<br />
länkning utan att behöva köra programmet med ett build kommando. Syftet med dessa<br />
kommandon är vanligtvis att kontrollera eventuella fel.<br />
2.6.1 Hello World programmet rad för rad<br />
Ett C++ program läses och körs som regel uppifrån och ned. Datorn tar den första C++<br />
satsen den stöter på, tolkar och utvärderar resultatet, och utför därefter nästa sats. Hello<br />
World programmet har faktiskt bara en enda programsats som datorn ska utföra. Det<br />
övriga i källkoden är <strong>till</strong> för att kompilering och länkning ska fungera.<br />
1 I vissa sammanhang ser man benämningen DOS-program. Den benämningen är i de allra<br />
flesta fall helt felaktig<br />
8
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Rad 1: #include<br />
Rad 2: using namespace std;<br />
Rad 4: int main()<br />
Rad 5: {<br />
Dessa två rader hör ihop rad ett säger att vi ska använda oss av en fil döpt "iostream".<br />
Filen iostream är en s.k. headerfil som innehåller fördefinierade funktioner, exempelvis<br />
att skriva text <strong>till</strong> skärmen. Rad två säger att dessa funktioner <strong>till</strong>hör C++ standarden.<br />
Namnet std i using namespace std; är <strong>till</strong> för att undvika hopblandning med äldre<br />
varianter av C++, dvs C++ innan standardiseringen.<br />
Rad 4 anger programstart. Detta är en överenskommelse som finns <strong>till</strong> länkaren att man<br />
anger programmets start på detta sätt. Raden är en "definition av en funktion döpt<br />
main()". En funktion är en samling programsatser som kan utföras som en enhet. Rad 5<br />
anger att här börjar programsatserna för main funktionen. Varje { tecken i ett C++<br />
program har ett motsvarande } tecken. Dessa klamrar grupperas på samma sätt som<br />
parenteser i räkneuttryck.<br />
Rad 6:<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
3 Datorn som miniräknare<br />
I detta avsnitt tas upp hur man kan skriva program som utför enkla räkneoperationer<br />
och skriver resultat på skärmen. Syftet är i huvudsak att se hur flera C++ satser kan<br />
bygga upp ett C++ program utan att behöva fördjupa oss i djupa teoretiska<br />
resonemang.<br />
3.1 Räkneoperationer<br />
a = 2 + 3 * 4;<br />
I C++ kan man utföra de vanliga räkneoperationerna som addition, subtraktion,<br />
multiplikation och division med ungefär samma syntax ( skrivsätt ) som i algebran.<br />
Exempel:<br />
3.2 Variabler<br />
int a;<br />
Är en giltig C++ sats som ger en variabel döpt a värdet 14. Notera att den måste<br />
avslutas med ett semikolon.<br />
Räknereglerna är desamma som i algebran dvs. först utförs operationen 3 * 4 (12)<br />
därefter utförs operationen 2 + 12. Likhetstecknet skiljer sig en hel del från algebran. I<br />
C++ kallas likhetstecknet = <strong>till</strong>delningsoperator och innebär att man för över innehållet<br />
från högersidan (14) <strong>till</strong> variabeln på vänstersidan. Då satsen är utförd kommer<br />
variabeln a att innehålla värdet 14.<br />
I exemplet ovan används namnet a för att ange en variabel, en slags behållare för ett<br />
värde, snarlik variabler inom algebra. För att kunna använda en variabel i C++ måste<br />
den deklareras. I deklarationen anger man vilken typ av information som variabeln<br />
innehåller. För variabeln i exemplet som ska innehålla ett numeriskt värde kan<br />
deklarationen se ut som<br />
Denna deklaration säger att a är ett heltal ( int, förkortning för integer, heltal). Man kan<br />
se det som att en deklaration skapar en variabel med ett visst namn. En deklaration<br />
måste alltid komma före det att man använder variabeln. Det data som a refererar <strong>till</strong><br />
kallas för en instans av ett heltal ( int ).<br />
10
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
}<br />
Exempel, enkelt räkneprogram:<br />
int a;<br />
int b;<br />
b = 4;<br />
a = b * 3 + 2;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
3.2.1 Sammansatta utskriftssatser<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
}<br />
I programmet ovan kan det bli en smula skrymmande att använda 4 programkodsrader<br />
för att skriva ut en rad med text. Man kan kombinera utströmsoperatorerna för att<br />
åstadkomma utskriften på en enda rad. Den satsen skulle då ersätta satserna Rad 9 <strong>till</strong><br />
Rad 12. Programmet skulle då se ut som<br />
int a;<br />
int b;<br />
b = 4;<br />
a = b * 3 + 2;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
4 Datatyper och Uttryck<br />
4.1 Datatyper<br />
I räkneprogrammet tidigare såg vi att C++ kräver deklarationer av alla variabler som<br />
används. I räkneprogrammet användes bara variabler av heltalstyp, int, men det finns<br />
naturligtvis andra typer av variabler som kan användas i C++.<br />
I kompendiet "Datorsystem och programhantering" finns ett kapitel om intern<br />
datarepresentation som med fördel läses innan detta avsnitt.<br />
De vanligaste datatyperna är<br />
int Heltal ( integer )<br />
short int Mindre heltal ( short integer )<br />
long int Stort heltal ( long integer )<br />
float Mindre rella tal ( floating point number )<br />
double Rella tal/flyttal ( double precision floating<br />
point number )<br />
char Tecken ( character)<br />
bool Logiskt värde ( boolean )<br />
void<br />
Tomrum/ingenting<br />
För variationerna long int och short int kan ordet int utelämnas. För heltalstyperna och<br />
teckentypen char finns även en icke teckensatt form som anges med unsigned<br />
unsigned int<br />
unsigned short int<br />
unsigned char<br />
unsigned int a;<br />
a = -3;<br />
Dessa datatyper kallas med ett gemensamt namn för enkla datatyper.<br />
En variabel som deklareras som unsigned kan inte anta negativa värden. Dvs satserna:<br />
Ger ett oväntat resultat.<br />
4.2 Deklarationer<br />
Deklarationer görs alltid på formen<br />
datatyp variabelnamnslista;<br />
En variabelnamnslista består av ett eller flera variabelnamn åtskilda av kommatecken.<br />
En lista är ett återkommande begrepp som omfattar fler saker än just variabelnamn.<br />
Generellt är en lista noll, ett eller flera element åtskilda av kommatecken.<br />
13
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
4.3 Identifierare<br />
Det finns flera typer av identifierare där variabelnamn är en av dessa typer. De<br />
variabelnamn vi sett hit<strong>till</strong>s har varit enstaka bokstäver, C++ <strong>till</strong>åter emellertid ganska<br />
utförliga namn på variabler. Ett annat exempel på identifierare är funktionsnamn tex.<br />
main<br />
Reglerna för namngivning av identifierare är<br />
<br />
<br />
<br />
<br />
Det första tecknet måste vara en bokstav eller tecknet '_'<br />
(understreck/ underscore).<br />
Efterföljande tecken kan vara bokstäver eller siffror<br />
Tecknen å, ä och ö är ej <strong>till</strong>åtna<br />
4.3.1 Godkända identifierare / variabelnamn<br />
Namnen kan vara i princip hur långa som helst. 4096 tecken är en<br />
vanlig övre gräns.<br />
hello<br />
HeLlO<br />
_x<br />
_12<br />
_hello_dude_2<br />
number_of_variables_in_my_program<br />
Observera att man skiljer på versaler och gemener i identifierare. Variabeln a är inte<br />
samma variabel som variabeln A.<br />
4.3.2 Icke godkända identifierare<br />
2dudes<br />
hello dude<br />
x-y<br />
"hel"<br />
poäng<br />
man får inte börja med en siffra<br />
mellanslag är inte <strong>till</strong>åtna i variabelnamn<br />
tecknet – är ej <strong>till</strong>åtet<br />
" är inte <strong>till</strong>åtet, anger dessutom texten<br />
hel<br />
ä är inte ett <strong>till</strong>åtet tecken<br />
När man skriver ett C++ program är det inte <strong>till</strong>åtet att använda åäö i variabelnamn.<br />
Det kan därför vara en smula bökigt att använda svenska ord som variabelnamn, även<br />
fast det kan vara enklare att associera svenska ord med olika betydelser i programmet.<br />
Författaren använder av den anledningen uteslutande engelska identifierare i "skarp"<br />
programkod. Det är dessutom en betydande del av jordens befolkning som inte förstår<br />
svenska variabelnamn. I detta kompendium har jag däremot försökt att använda mig av<br />
identifierare med svenska namn för enkelhetens skull.<br />
4.3.3 Initieringssatser<br />
En initiering är att ge en deklarerad variabel ett startvärde. Då en variabel deklareras<br />
med ex. int i; har variabeln i ett okänt startvärde. För att i ska få ett meningsfullt värde<br />
måste man göra en <strong>till</strong>delning. En variation på <strong>till</strong>delningar är initieringar, som är en<br />
kombination av en deklaration och en <strong>till</strong>delning. Syntaxen ser ut som<br />
14
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
datatyp variabelnamn = startvärde;<br />
4.3.4 Exempel på giltiga satser med variabeldeklarationer och intieringar<br />
int n;<br />
int i, j;<br />
double x;<br />
// i, j är en variabellista med två element<br />
// x deklareras som ett flyttal<br />
unsigned long int number_of_paalokas, number_of_cards;<br />
// två positiva heltalsvariabler deklareras<br />
bool logic_1, logic2, illogical;<br />
// tre variabler som kan anta värdet sant och falskt<br />
char c;<br />
// variabel som innehåller tecken ex 'A'<br />
double my_float_number = 2.3203;<br />
// initierad variabel<br />
int magic_number = 42;<br />
// initierad variabel<br />
Då man väljer variabelnamn för variabler i programmet ska man se <strong>till</strong> att använda så<br />
utförliga namn som möjligt.<br />
4.3.5 Nyckelord<br />
Det finns i språket en uppsättning fördefinierad ord med speciella betydelser<br />
som inte får användas som identifierare, dessa kallas nyckelord.<br />
asm auto bad_cast bad_typeid bool break<br />
case catch char class const<br />
const_cast continue default delete do double<br />
dynamic_cast else enum except explicit<br />
extern false finally float for friend<br />
goto if inline int long mutable<br />
namespace new operator private protected public<br />
register reinterpret_cast return short signed<br />
sizeof static static_cast struct switch<br />
template this throw true try type_info<br />
typedef typeid typename union unsigned using<br />
virtual void volatile while<br />
4.3.6 Datatypernas egenskaper<br />
Man använder variabler av olika datatyper <strong>till</strong> olika syften, och man måste välja<br />
datatyp med omsorg då man deklarerar sina variabler.<br />
4.3.7 Lagring av enkla datatyper<br />
I en 32-bitarsmiljö ( vanlig processor ) lagras heltalstyperna enligt<br />
15
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
char, unsigned char, signed char<br />
short, unsigned short<br />
int, unsigned int<br />
long , unsigned long<br />
float<br />
double<br />
1 byte<br />
2 bytes<br />
4 bytes<br />
4 bytes<br />
4 bytes<br />
8 bytes<br />
Då en variabel av typen int lagras i datorns minne kommer den således att uppta 4<br />
bytes minne.<br />
Man kan enkelt räkna fram vilka talområden detta ger för heltalstyperna om man följer<br />
metoden i kompendiet "Datorsystem och programhantering", avsnitt intern<br />
datarepresentation. Samma avsnitt anger dessutom hur talområdet för flyttalen ska<br />
tolkas.<br />
char +- 127<br />
short +- 32 767<br />
int +- 2 147 483 647<br />
long +- 2 147 483 647<br />
float<br />
E+-37, 6 siffrors<br />
noggrannhet<br />
double<br />
E+-308, 15 siffrors<br />
noggrannhet<br />
#include<br />
using namespace std;<br />
Heltalstyperna är de enklaste av datatyperna. Det är ofta tydligt när man ska använda<br />
sig av heltalstyper. Flyttalstyperna kan vara lite krångligare men med lite vana blir<br />
även det en ganska smal sak.<br />
Exempel räkneprogram med olika datatyper<br />
int main()<br />
{<br />
int antal_bananer, antal_apelsiner;<br />
double medel_antal;<br />
antal_bananer = 89;<br />
antal_apelsiner = 56;<br />
medel_antal = (antal_bananer + antal_apelsiner) / 2.0;<br />
}<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Rad 7 skapar ett flyttal, dvs ett tal med decimaldel som ex 3.14159265. Flyttalet<br />
medel_antal deklareras som double trots att talområdet för float mer än väl räcker <strong>till</strong>.<br />
Motivet <strong>till</strong> att välja float skulle vara att en double ansågs ta upp för mycket minne.<br />
Floatdeklarationen påverkar emellertid ytterst sällan programmets storlek i någon<br />
väsentlig grad, därför väljer man alltid double av bekvämlighet.<br />
Rad 9 och 10 är vanliga <strong>till</strong>delningar.<br />
Rad 12: medel_antal = (antal_bananer + antal_apelsiner) / 2.0;<br />
Parenteser används för att additionen ska utföras innan divisionen (annars blir det ju<br />
inget medelvärde). Därefter sker division med 2.0. Det inskrivna värdet 2.0 ska<br />
betraktas som att vara av typen float medan ett värde skrivet som 2 ska betraktas som<br />
att vara av typen int.<br />
Prova att ändra värdet 2.0 <strong>till</strong> värdet 2. Blir det någon skillnad vid programkörning?<br />
Rad 14: cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Uttryck 2: medel_antal = (antal_bananer + antal_apelsiner) / 2.0;<br />
och<br />
Uttryck 3: cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Aritmetiska operatorer<br />
+ Addition<br />
– Subtraktion<br />
* Multiplikation<br />
/ Division<br />
% Modulus<br />
+= Addition med <strong>till</strong>delning<br />
–= Subtraktion med <strong>till</strong>delning<br />
*= Multiplikation med <strong>till</strong>delning<br />
/= Division med <strong>till</strong>delning<br />
%= Modulus med <strong>till</strong>delning<br />
Strömoperatorer<br />
> Inströmsoperator<br />
Tilldelningsoperator<br />
= Tilldelning<br />
Logiska operatorer<br />
!= Icke lika med<br />
< Mindre än<br />
Större än<br />
>= Större än lika med<br />
&&<br />
Logiskt AND<br />
|| Logiskt OR<br />
Bitoperatorer<br />
^<br />
Exklusivt OR<br />
&<br />
Bitvis AND<br />
| Bitvis OR<br />
^= Exklusivt OR med <strong>till</strong>delning<br />
&=<br />
Bitwise AND med <strong>till</strong>delning<br />
|= Bitvis OR med <strong>till</strong>delning<br />
De enkla räkneoperatorerna har behandlats tidigare, förutom modulusoperatorn. Varje<br />
räkneoperator har en <strong>till</strong>delningsvariant, exempelvis har + operatorn en variant +=.<br />
Denna operator är en ren bekvämlighet. I program stöter man ofta på situationer när en<br />
variabel ska öka eller minska i värde. Exempelvis<br />
int i;<br />
i = 65;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Rad 4 i exemplet kan man alltså läsa ut som: Tilldela variabeln i det tidigare värdet på i<br />
plus 8. Mer korrekt ses satsen som att den består utav två operationer, där operation 1<br />
är i + 8 med resultatet 73 av typen int, operation 2 är i = 73, i <strong>till</strong>delas värdet 73.<br />
Att öka värdet på en variabel på detta sätt är så vanligt att man har skapat en operator<br />
som utför denna sammansatta sats i en enda operation +=. Det lösryckta<br />
programavsnittet ovan omskrivet med += operatorn ser då ut som<br />
int i;<br />
i = 65;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
int a;<br />
a = 8;<br />
++a;<br />
// prefix<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Operationen som utförts kan beskrivas som<br />
(int ) = ( int )<br />
Observera att detta inte är programsatser utan bara ett sätt att beskriva uttryck.<br />
Varje operation ger som resultat ett värde som kallas returvärde, detta värde har en<br />
datatyp som kallas returtyp eller resultattyp. Man får en exakt beskrivning av<br />
operationen om man dessutom anger returtypen som för Uttryck 1 är int ( egentligen en<br />
variant av int som int behandlats än, mer om det senare). Detta kan man skriva som<br />
(int ) = (int ): int<br />
Generellt:<br />
( datatyp operand <strong>till</strong> vänster ) operator ( datatyp operand <strong>till</strong> höger ) : returtyp<br />
Det som står <strong>till</strong> vänster om kolon kallas för operationens signatur.<br />
I <strong>till</strong>delningssatsen utnyttjas inte returvärdet. Det gör det däremot i den sammansatta<br />
satsen i Uttryck 2.<br />
medel_antal = (antal_bananer + antal_apelsiner) / 2.0;<br />
Satsen är sammansatt av tre enkla uttryck med var sin operator =, + och / .<br />
För att exakt hur satsen tolkas delar man upp den i dess enkla uttryck och utvärderar<br />
dom i tur och ordning. Denna ordning bestäms av operatorprioriteter som är angivna i<br />
bilaga operatorprioriteter. I korthet kan sägas att de flesta operatorer ska läsas från<br />
vänster <strong>till</strong> höger. Tilldelningsoperatorn = är ett tydligt undantag då den läses från<br />
höger <strong>till</strong> vänster. Uppenbara undantag finns också i aritmetiska uttryck som 3 + 4 * 5.<br />
Uttrycket 4*5 beräknas före additionen med 3, detta kommer sig av just<br />
operatorprioriteten. Utvärderingsordningen för operatorer kan alltid ändra med hjälp av<br />
parenteser. Jämför: ( 3 + 4 ) * 5<br />
I tur och ordning utvärderas<br />
antal_bananer + antal_apelsiner<br />
denna operation är en addition mellan två heltal, och resultatet är ett heltal alltså<br />
( int ) + ( int ) : int<br />
Då operationen är utförd har 89 och 56 adderats och resultatet 145 av typen int<br />
erhållits. Därefter utvärderas nästa operation, / operationen.<br />
Den kan man läsa ut som<br />
eller<br />
145 / 2.0<br />
(int ) / ( double ): double<br />
22
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Resultatet av en division med flyttal är ett flyttal. Av denna operation erhålls resultatet<br />
72.5 av typen double. Därefter utförs operationen =<br />
eller<br />
medel_antal = 72.5<br />
( double )= ( double ) : double<br />
För räkneoperatorerna gäller allmänt att om någon av operanderna är av flyttalstyp<br />
kommer resultatet vara av flyttalstyp, och omvänt, om båda operanderna är av<br />
heltalstyp kommer resultatet att vara av heltalstyp.<br />
Exempelvis<br />
( double ) + ( double ) : double<br />
En addition av två flyttal ger resultat av flyttalstyp<br />
( double ) - ( int ) : double<br />
En subtraktion av ett flyttal och ett heltal ger resultat av flyttalstyp. Egentligen<br />
omvandlas heltalet först <strong>till</strong> ett flyttal innan subtraktionen.<br />
Regeln för typer vid räkneoperationer kan ge en del oväntade resultat, i synnerhet vid<br />
division. Division mellan två heltal ger resultat av typen heltal<br />
( int ) / ( int ) : int<br />
Exempelvis ger divisionen 13 / 5 resultatet 2.<br />
Betrakta:<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
int i, j;<br />
i = 14;<br />
j = 19;<br />
double resultat;<br />
resultat = j / i;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Vid programkörning skrivs på skärmen<br />
19 / 14 = 1<br />
Press any key to continue<br />
Detta trots att variabeln resultat deklarerats som double. Eftersom operationen ( int ) /<br />
(int ) ger resultattyp int kommer variabeln resultat att innehålla värdet 1. Om vi stället<br />
hade skrivit<br />
Rad 10: resultat = double( j ) / i;<br />
Skulle variabeln j omvandlats <strong>till</strong> flyttal och divisionsoperationen skulle då vara<br />
( double ) / ( int ) : double<br />
Och värdet på variabeln resultat skulle då vara 1.35714…<br />
Uttycket double( j ) är ett exempel på typomvandling.<br />
24
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
5 Inmatning och utskrift<br />
Inmatning från tangentbord och utskrift <strong>till</strong> skärm sker i C++ med hjälp av strömmar.<br />
Vi har tidigare sett exempel på utskrift. Vi kommer i det här avsnittet även ta upp<br />
inmatning från tangentbordet så att vi kan skapa program som kommunicerar med en<br />
användare istället för att använda värden inskrivna i programkoden.<br />
5.1 Utskrift <strong>till</strong> skärm<br />
För att skriva data <strong>till</strong> skärmen ( konsolen) används variabeln cout <strong>till</strong>sammans med<br />
strömoperatorn
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Med utströmsoperatorn kan man alltså med en enda sats skriva ut så många variabler<br />
och texter som man vill. Det är ändå oftast en god ide att hålla raderna så pass korta att<br />
de blir lättlästa. Det brukar som regel innebära maximalt 2 – 3 variabler och en kortare<br />
text.<br />
5.1.1 Formatering av utmatning<br />
#include<br />
using namespace std;<br />
Man vill gärna att den utskrift som programmet gör på skärmen ska vara snygg och<br />
lättläst. Tyvärr blir det inte alltid som man tänkt sig, i synnerhet då värden på<br />
flyttalsvariabler ska skrivas ut på skärmen.<br />
Exempel, valutaomvandling<br />
int main()<br />
{<br />
double kron_dollar_kurs = 10.43;<br />
double kronor = 345.50;<br />
double dollars;<br />
dollars = kronor / kron_dollar_kurs;<br />
}<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
cout.setf(ios::fixed );<br />
setf och precision är funktioner( eller metoder ) kopplade <strong>till</strong> utströmmen cout. Det<br />
som ges innanför parenteserna ( ios::fixed och heltalet 2 )kallas funktionsargument.<br />
Ett annat sätt att formatera utskriften är att ange hur många positioner ett uttryck ska<br />
uppta.<br />
Comment [KP1]: Borde vara<br />
en utskrift, eller<br />
cout.width( 20 );<br />
#include<br />
using namespace std;<br />
Ger att nästföljande utströmsoperation kommer att ta minst 20 teckenpositioner <strong>till</strong> sitt<br />
förfogande. Om talet eller texten är kortare fogas <strong>till</strong>räckligt antal blanksteg in.<br />
Observera att den angivna bredden bara gäller för den utströmsoperation <strong>till</strong> cout som<br />
kommer direkt efter cout.width( … )<br />
Sammantaget kan då programmet se ut som:<br />
int main()<br />
{<br />
double kron_dollar_kurs = 10.43;<br />
double kronor = 345.50;<br />
double dollars;<br />
dollars = kronor / kron_dollar_kurs;<br />
cout.setf(ios::showpoint);<br />
cout.precision( 2 );<br />
cout.setf(ios::fixed );<br />
}<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
int i;<br />
cin >> i;<br />
Inströmsoperationen liknar <strong>till</strong> viss del en <strong>till</strong>delningsoperation, men med den stora<br />
skillnaden att värdet som variabeln i får bestäms av användaren som kör programmet.<br />
Programmet väntar i inströmsoperationen <strong>till</strong>s det att användaren faktiskt matat in ett<br />
värde. Denna egenhet gör att man för varje inmatningssats ( inströmsoperation från cin<br />
) måste se <strong>till</strong> att användaren blir varskodd att programmet väntar på inmatning. Det<br />
görs ganska enkelt genom att skriva ut lite ledtext på skärmen.<br />
int i;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Ange hur mÕnga kronor du har:<br />
6500<br />
Dina 6500.00 svenska kronor blir 623.20 amerikanska dollar<br />
Press any key to continue<br />
Programmet skriver först ut ledtexten, väntar på inmatningen, 6500[Enter]. [Enter]<br />
anger att tangenten Enter/Return/Vagnretur skall tryckas. Sedan skrivs resultatet av<br />
beräkningen ut.<br />
Inströmsoperationen kan i likhet med utströmsoperationen ta emot flera inmatningar i<br />
en sats.<br />
double variabel1, variabel2;<br />
cout variabel1 >> variabel2;<br />
Inmatningen <strong>till</strong> denna sats kan antingen göras genom att man skriver två tal och<br />
trycker return mellan varje tal, eller kan man separera talen med blanksteg eller tab och<br />
avsluta inmatningen med return. Se även om vittecken i avsnittet Texthantering, in och<br />
utmatning.<br />
Problemet med denna typ av inmatning är att man inte kan skriva ut någon ledtext<br />
mellan varje inmatning. Utan man kan bara ge ledtexter typ "Ange 4 tal". Det kan<br />
därför vara ett bättre alternativ att dela upp det så att man bara har en inmatning per<br />
sats, och ledtext <strong>till</strong> varje inmatning.<br />
5.2.1 Exempelprogram<br />
Beräkna area och omkrets hos en rektangel.<br />
29
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
double sida;<br />
double bredd;<br />
double omkrets;<br />
// ange ledtexten<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
6 Villkor och styrsatser<br />
I de program vi sett tidigare har programkörning inneburit att sats efter sats utförts i<br />
den ordning de skrivits i källkoden. Vi har inte kunna ändra programmets uppförande<br />
beroende på inmatningar eller beräkningsresultat. Vi kallar en sådan samling satser för<br />
en sekvens, eftersom de utförs en efter en.<br />
Sekvens:<br />
Start: Sats1 -> sats 2 -> sats 3 -> sats 4… Slut.<br />
Vi ska nu titta på en ny struktur som kallas för selektion. Selektion innebär att<br />
programmet kan under programkörning fatta beslut om vilken av en, två eller flera<br />
alternativa sekvenser som ska utföras.<br />
6.1 Villkorssatsen if<br />
En villkorssats är den konstruktion som finns i C++ för att göra en selektion av två<br />
alternativa sekvenser.<br />
Formen för if- satsen är<br />
alternativt<br />
if ( logiskt_uttryck )<br />
sats / satsblock<br />
else<br />
sats / satsblock<br />
if ( logiskt_uttryck )<br />
sats / satsblock<br />
Det logiska uttrycket anger ett villkor som är antingen sant eller falskt. Den första<br />
sats/satsblocksdelen är det programavsnitt som ska utföras om villkoret är sant. Den<br />
andra sats/satsblocksdelen är det som ska utföras om villkoret är falskt. else och det<br />
efterföljande sats/satsblock är valfritt.<br />
Några enkla exempel:<br />
int antal_husdjur;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
1. Villkoret är sant. Användaren har matat in en siffra större än 5.<br />
Ange hur många husdjur du har hemma<br />
12<br />
Jaså du har 12 husdjur<br />
Oj det var många<br />
slut<br />
2. Villkoret är falskt. Användaren har matat in en siffra som är 5 eller lägre.<br />
Ange hur många husdjur du har hemma<br />
2<br />
Jaså du har 2 husdjur<br />
slut<br />
6.1.1 Satsblock<br />
Villkorssatsen i exemplet utnyttjar att else delen av if satsen är valfri. Dessutom läggs<br />
det en sats och inte ett satsblock efter if satsen. if satsen väljer bara den sats som ligger<br />
direkt efter villkoret. Notera indragningen av satsen cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
6.1.2 Övning:<br />
Sätt in ovanstående exempel i ett komplett program och provkör. Blev resultatet<br />
det du förväntade dig?<br />
Rätta <strong>till</strong> indenteringen i föregående program.<br />
Ett vanligt fel är att man råkar lägga en ensam sats mellan if satsen och satsblocket.<br />
Kompilatorn har svårt att ge en rimlig felbeskrivning för detta fel. Ett annat vanligt fel<br />
är att man påbörjar satsblocket innan villkorssatsen eller else. Satsblocket blir då som<br />
regel betydelselöst.<br />
{ if ( antal_husdjur > 5 )<br />
// FEL! Satsblocket börjar inte direkt efter villkoret<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Logiska binära operatorer<br />
== Lika med<br />
!= Icke lika med<br />
< Mindre än<br />
Större än<br />
>= Större än lika med<br />
&&<br />
Logiskt AND<br />
|| Logiskt OR<br />
and Borttaget ur C++: Logiskt AND synonymt med &&<br />
or Borttaget ur C++: Logiskt OR synonymt med ||<br />
I villkoret i exemplet ovan användes den logiska operatorn > på formen<br />
( int ) > ( int ) : bool<br />
Varje logisk operation ger ett resultat av typen bool. Man kan använda sig av variabler<br />
deklarerade med typen bool för att lagra logiska värden.<br />
Villkoret i exemplet ovan hade kunnat skrivas utförligare som:<br />
bool manga_husdjur;<br />
manga_husdjur = antal_husdjur > 5;<br />
if ( manga_husdjur )<br />
// satsblocken som tidigare<br />
med samma betydelse. Variabeln manga_husdjur kan alltså anta värdena true eller<br />
false. Om ett logiskt värde av typen bool i något uttryck kan betraktas som ett heltal<br />
kommer värdet true att vara värdet 1, och false kommer att vara värdet 0.<br />
De flesta logiska operationer är tämligen rättframma. Här följer några exempel på hur<br />
uttrycken kan se ut:<br />
Antag att förekommande variabler är deklarerade med en rimlig datatyp<br />
( vikt < 60.0 )<br />
( antal_hundar== 2 )<br />
( antal_valar != 2 ) // motsatsen <strong>till</strong> ovan<br />
( antal*2 >= 52 ) // räkneoperationen utvärderas först<br />
Man kan dessutom kombinera uttryck med de logiska operatorerna && ( OCH ) och ||<br />
(ELLER). Dessa operatorer har formen<br />
( bool ) && ( bool ): bool<br />
( bool ) || ( bool ): bool<br />
Man använder alltså dessa operatorer på logiska värden eller uttryck<br />
34
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
( antal == 2 && vikt < 20.0 ) // Jämförelserna utvärderas först och<br />
// därefter utvärderas &&<br />
// båda jämförelserna måste vara sanna för<br />
// att hela uttrycket ska vara sant<br />
( antal == 2 || vikt < 20.0 ) // om någon av jämförelserna är sanna<br />
// är uttrycket sant<br />
Det finns även en unär logisk operator ! eller not. Operatorn fungerar så att den vänder<br />
ett sant värde falskt, och tvärtom. Exempel<br />
( !( 3 > 4 ) ) // är sant<br />
( not( 7 == 12 ) ) // är sant<br />
( ! (4==4) ) // är falskt<br />
Det bör sägas ett varningens ord om likhetsjämförelser av flyttal. Om man har två<br />
flyttal är det ofta svårt att kontrollera om de är lika, eftersom jämförelsen kräver att de<br />
är exakt lika i varje bit.<br />
Då varningar utfärdas får man inte glömma bort att varna för en viss typ av<br />
sammansatta jämförelser. Betrakta följande programavsnitt<br />
int hur_gammal;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
// kolla om tonåring, äldre än 12 och yngre än 20 år<br />
if ( 12 < hur_gammal && hur_gammal < 20 ) // RÄTT !<br />
{<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Exempel, enkel sortering av två tal<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
double tal1, tal2;<br />
// ledtext<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
6.3.1 for-satsen<br />
2. Sats som påverkar iterationsvillkoret, tar iterationen närmare<br />
slutförandet. ( 2.2: Bläddra <strong>till</strong> nästa sida )<br />
3. Den sats som ska itereras. ( 2.1: Läs en sida )<br />
Man skulle även kunna ta med den första satsen 1: Öppna boken, som möjliggör<br />
iterationen. Denna typ av sats som förbereder iterationen kallas för initieringssats.<br />
När man diskuterar iterationssatser i programkod kallar man dom ofta för "loopar". De<br />
iterationssatser som finns i kan delas in i två kategorier, nämligen<br />
<br />
<br />
Räknande loopar<br />
Villkorsloopar<br />
Exemplet ovan är ett typiskt exempel på en stegande loop. Man kan betrakta det som<br />
att man tar steg från sidan 1 <strong>till</strong> sidan 2 <strong>till</strong> sidan 3 osv. <strong>till</strong> den sista sidan i boken.<br />
Skillnaden mellan dessa två typer av loopar är i huvudsak satsen som påverkar<br />
iterationsvillkoret. I exemplet är det satsen att bläddra <strong>till</strong> nästa sida, dvs. ta ytterligare<br />
ett steg i boken, som påverkar iterationsvillkoret.<br />
En for-sats är en av de vanligaste satserna i programkod och är mycket viktigt att<br />
behärska. Syftet med for-satsen är att skapa räknande loopar. Formen för en for-sats är<br />
for ( initieringslista; iterationsvillkor;<br />
inkrementsatslista )<br />
sats / satsblock<br />
Man kan i formen skönja flera likheter med if satsen. Den stora skillnaden ligger i<br />
initieringslistan och inkrementlistan, och naturligtvis det faktum att for-satsen är<br />
iterativ. Kom ihåg att en lista är noll, ett eller flera element separerade med<br />
kommatecken.<br />
Vi kan nu visa på bokexemplet först schematiskt med en forsats:<br />
for(öppna bok; om det finns sidor kvar att läsa; bläddra <strong>till</strong> nästa sida )<br />
Läs en sida;<br />
Stäng bok;<br />
Lämna <strong>till</strong>baka boken <strong>till</strong> biblioteket;<br />
Detta är principen bakom varje forsats. Denna typ av kod kallas för pseudokod och<br />
används med fördel om man vill diskutera programkodslösningar. En C++ kompilator<br />
förstår naturligtvis inte pseudokod, använd penna och papper istället.<br />
Bokexemplet som ett komplett program<br />
Det går att skapa ett enkelt komplett program av bokexemplet, om man på förhand<br />
bestämmer antalet sidor i boken. Vi fastställer härmed att antalet sidor är 12.<br />
38
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
int antal_sidor = 12;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Satserna i programmet utförs i exakt samma ordning som i det första schematiska<br />
bokexemplet utan for-sats.<br />
Övning: Övertyga dig själv om att det första schematiska exemplet fungerar på samma<br />
sätt som for-satsen i exemplet ovan<br />
Iterationsvariabeln<br />
Betrakta programavsnittet<br />
for( int i=0; i< 10;i++)<br />
{<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Rad 2: Initieringssatsen låter värdet på i börja med 1 eftersom summeringen skulle<br />
börja med termen 1.<br />
Rad 2: Iterationsvillkoret ska medge att satsblocket utförs för värdet i = 100 men inte i<br />
= 101, villkoret avbryter nu vid jämförelsen 101 < 101.<br />
Rad 4: Operatorn += används för att öka på värdet på variabeln total_summa med<br />
värdet av i.<br />
Kom ihåg utvärderingsordningen: initiering, villkor, satsblock, inkrement, villkor,<br />
satsblock, inkrement, villkor, satsblock, inkrement, villkor …<br />
Resultatet blir:<br />
summan är:5050<br />
Man kan även skriva for-satsen med båda variabeldeklarationerna i initieringslistan<br />
for ( int total_summa = 0, int i = 0; i < 101; i++)...<br />
6.3.2 Övning<br />
med samma resultat. Man bör undvika att lägga onödiga deklarationer i initeringslistan<br />
<strong>till</strong> for-satsen eftersom det kan försämra läsbarheten hos programmet.<br />
Skriv ett program som skriver ut treans multiplikationstabell upp <strong>till</strong> 10.<br />
Programutskrift<br />
1*3 3<br />
2*3 6<br />
3*3 9<br />
…<br />
Tips: Skriv ut varje värde som en utmatning i en for-sats, låt iterationsvariabeln stega<br />
från 1 <strong>till</strong> 10. Tecknen "*3 " på varje rad kan skrivas ut som vanlig text. Formatera<br />
utskriften med cout.width( … ).<br />
6.3.3 while och do while- satserna<br />
Den andra typen av iterationssatser är villkorsloopar. Skillnaden mellan dessa satser<br />
och for- satsen är att de används när man inte utför en räknande iteration, i synnerhet<br />
då man på förhand inte känner <strong>till</strong> hur många iterationer som ska utföras. Ett vanligt<br />
förekommande sammanhang för dessa iterationer är för felkontroll av inmatningar från<br />
användaren.<br />
Villkorslooparna kommer två olika varianter, en med preevaluering , while, och en<br />
med postevaluering, do while. Preevaluering innebär att ett villkor utvärderas innan ett<br />
satsblock utförs medan postevaluering innebär att ett villkor utvärderas efter ett<br />
satsblock utförs.<br />
41
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
While-satsen<br />
While-satsen använder preevaluering dvs. först utvärdera villkor därefter utförs<br />
<strong>till</strong>hörande satsblock. Formen på en while-sats är följande<br />
while ( iterationsvillkor )<br />
sats / satsblock<br />
Funktionen hos satsen är densamma som hos for-satsen, men den saknar både<br />
initieringslista och inkrementsatslista.<br />
Exempel, inmatning av en födelsemånad.<br />
Programmet ska ta emot en inmatning om vilken månad som användaren är född i och<br />
därefter konstatera om användaren föddes tidigt på året eller sent på året. Programmet<br />
innehåller en felkontroll av inmatad månad. En programkörning kan se ut som<br />
Vilken månad är du född? Ange ett tal mellan 1 och 12.<br />
19<br />
Du har angett ett felaktigt tal, försök igen!<br />
-4<br />
Du har angett ett felaktigt tal, försök igen!<br />
2<br />
Du är född tidigt på året.<br />
Programlösning<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
int fodelse_manad;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
For-satsen som while-sats<br />
For-satsen och while-satsen skiljer sig bara på for-satsens initieringslista och dess<br />
inkrementlista. Eftersom en lista kan bestå av inget element är det syntaktiskt korrekt<br />
att helt utelämna dessa satser. Gör man det får man exakt samma funktion som hos<br />
while-satsen. Exemplet ovan hade även kunnat skrivas med for-sats genom att byta ut<br />
while-satsen mot<br />
for ( ; fodelse_manad < 1 || fodelse_manad > 12 ; )<br />
{ ... som tidigare<br />
Observera att for-satsens semikolon inte får utelämnas.<br />
Do while-satsen<br />
#include<br />
using namespace std;<br />
Do while-satsen har ett samma funktion som while-satsen med den skillnaden att den<br />
använder sig av postevaluering, villkoret om att fortsätta iterationen utförs efter det<br />
<strong>till</strong>hörande satsblocket. Det får <strong>till</strong> följd att satsblocket <strong>till</strong> en do while-sats alltid<br />
kommer att utföras minst en gång. Formen på en do while-sats är<br />
int main()<br />
{<br />
int fodelse_manad;<br />
do<br />
sats / satsblock<br />
while ( iterationsvillkor );<br />
Exemplet ovan skrivet med en do while-sats kan bli<br />
do {<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
Exempel, nästlade loopar, multiplikationstabellen<br />
På samma sätt som en villkorssats kan innehålla vilken annan sats som helst kan<br />
iterationssatser även innehålla iterationssatser. Det blir då en sk. nästlad iteration. Ett<br />
tydligt exempel på hur det kan fungera är multiplikationstabellen<br />
int main()<br />
{<br />
for( int i = 1; i
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
7 Texthantering<br />
I detta avsnitt tas det upp två sätt att arbeta med text i C++ program. Det första sättet<br />
som behandlas är hanteringen av textfält. Texter i C++ består utav en serie med enstaka<br />
tecken av typen char. Dessa serier med tecken kallas fält eller arrayer.<br />
7.1 Typen char<br />
#include<br />
using namespace std;<br />
Variabler av datatypen char representerar ett tecken som exempelvis bokstaven 'A'.<br />
Datatypen char är i grund och botten ett heltal bestående av en enda byte, alltså med ett<br />
väldigt litet talområde. Skillnaden mellan variabler av chartyp och heltalsvariabler<br />
visar sig när man skriver ut dem <strong>till</strong> skärmen. När en char-variabel skrivs ut <strong>till</strong><br />
skärmen visas ett tecken exempelvis 'A', när en heltalsvariabel skrivs <strong>till</strong> skärmen visas<br />
ett tal.<br />
Programexempel med char-variabler.<br />
int main()<br />
{<br />
char tecken_1, tecken_2, tecken_3;<br />
tecken_1 = 'H';<br />
tecken_2 = 'e';<br />
tecken_3 = 'j';<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
for (char c='A'; c
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
char min_text[] = "Hello World";<br />
här skapas ett fält bestående av 12 tecken, och variabeln min_text kallas för en<br />
fältvariabel.<br />
Operatorn [], kallad indexeringsoperator, anger att det är frågan om ett fält.<br />
Vid deklarationer används indexeringsoperatorn för att ange en storlek på fältet. I 1<br />
ovan behövs inte det eftersom storleken är antydd av texten "Hello World" = 11 tecken<br />
+ nolltecknet = 12 tecken. Fältet min_text är således 12 tecken(bytes) stort.<br />
2:<br />
char tom_text[12];<br />
här skapas ett fält bestående av 12 ej initierade char instanser. Det faktum att de ej är<br />
initierade som i 1, gör att innehållet inte är definierat eller, om man så vill, innehåller<br />
skräp. Denna typ av deklaration har ett liknande syfte som en vanlig<br />
variabeldeklaration typ int i; dvs. att fungera som en behållare för texter.<br />
7.2 Fältvariabler<br />
En fältvariabel fungerar inte riktigt på samma sätt som en vanlig variabel. Man ska<br />
betrakta en fältvariabel som att den anger var fältet börjar. En fältvariabel pekar ut<br />
det första tecknet i fältet, eller mer korrekt, den första char instansen. Den anger vilken<br />
minnescell, adress, som den första instansen befinner sig i. Man kan i ett schematiskt<br />
diagram åskådliggöra deklarationen char min_text[]="Hello World"; som<br />
Variabel: min_text<br />
Adress: 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217<br />
Innehåll: 206 H e l l o W o r l d \0<br />
Numreringen av cellerna är påhittad och är olika från programkörning <strong>till</strong><br />
programkörning.<br />
Ett enklare men lika användbart diagram ser ut som<br />
min_text<br />
H e l l o W o r l d \0<br />
En egenskap hos fältvariabler är att de refererar alltid <strong>till</strong> samma fält. Detta innebär att<br />
47
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
char min_text[]="Hello World";<br />
char tom_text[12];<br />
// <strong>till</strong>delning?<br />
tom_text = min_text; // o<strong>till</strong>åtet, kan inte referera <strong>till</strong> nytt fält<br />
tom_text = "Hello World"; // o<strong>till</strong>åtet, samma operation som ovan<br />
inte fungerar. Man ska betrakta denna <strong>till</strong>delning som att man försökt låta pilen för<br />
tom_text peka på min_text fältet.<br />
min_text<br />
H e l l o W o r l d \0<br />
tom_text<br />
Detta är alltså ej <strong>till</strong>åtet eftersom man "slarvar bort" det ursprungliga tomma<br />
fältet.<br />
7.2.1 Hantering av enstaka fältelement<br />
En fältvariabel <strong>till</strong>åter genom indexeringsoperatorn att man manipulerar enstaka<br />
element.<br />
char hej_text[4]; // tomt<br />
hej_text[0] = 'H'; // obs första elementet är element 0<br />
hej_text[1] = 'e';<br />
hej_text[2] = 'j';<br />
hej_text[3] = 0; // alternativt skrivsätt = '\0'<br />
Programraderna resulterar i att det fält som deklarerats att innehålla 4 char element<br />
<strong>till</strong>delas tecken för tecken innehållet. Obs, tecknet H är element nummer 0.<br />
min_text<br />
H e j \0<br />
7.3 In och utmatning<br />
Man kan använda de vanliga in och utströmsoperatorerna på samma sätt som man gör<br />
för enkla variabler ex<br />
char in_text[256];<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Hej vad heter du?<br />
Gunvald<br />
Hejsan Gunvald!<br />
Inmatningen fyller då de 8 första elementen i fältet in_text med texten "Gunvald" +<br />
nolltecken.<br />
Ett problem med denna typ av inmatning dyker upp om användaren skriver fler än ett<br />
ord per inmatning, exempelvis om programkörningen sett ut som<br />
Hej vad heter du?<br />
Gunvald Larsson<br />
Hejsan Gunvald!<br />
Det är inte utströmsoperatorn som felar utan det är sättet som inströmsoperatorn<br />
fungerar på som är o<strong>till</strong>räckligt. Det som händer är samma sak som tidigare att in_text<br />
fylls med texten "Gunvald" + nolltecken och texten Larsson lämnas kvar i<br />
inmatningsbufferten för senare inläsning.<br />
Inströmsoperatorn ser alltså "Gunvald Larsson" som två texter eftersom de är åtskilda<br />
med ett så kallat vittecken (eng. whitespace). All inmatning med >> operatorn, sk.<br />
formaterad inmatning, skiljer element med vittecken. Vittecken är blankstegstecken,<br />
tab tecken, nyrad tecken och vagnreturtecken. Jämför sidan 51, inmatning av två<br />
flyttal.<br />
Det finns två sätt att komma runt denna egenskap hos inströmsoperatorn<br />
1. Gör två inmatningar<br />
2. Använd medlemsfunktionen getline<br />
Exempel getline<br />
char in_text[256];<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Exempel, in och utmatning med teckenfält<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
char hej[]="Välkommen <strong>till</strong> 10000 kronorsfrågan";<br />
char fraga[]="Ange ditt för och efternamn";<br />
char fornamn[80], efternamn[80];<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
<br />
<br />
<br />
<br />
<br />
Rad 10: Variabeln idx (index) initieras <strong>till</strong> noll, vilket kan ses som att iterationen<br />
börjar på fältets första element. Jämför avsnitt Hantering av enstaka fältelement<br />
ovan.<br />
Rad 10: source[idx]!=0, iterationsvillkoret anger att repetionen skall fortgå <strong>till</strong>s<br />
nolltecknet (textslut) påträffas. Detta är en väldigt viktig egenskap att komma ihåg<br />
för alla textfält. Eftersom ett fält inte innehåller någon information om storleken på<br />
fältet har man alltid ett nolltecken som avslutar varje textfält.<br />
Rad 10: idx++ nästa tecken i fälten<br />
Rad 11: för över det tecken som finns på position idx i source fältet <strong>till</strong> samma<br />
position i target fältet.<br />
Rad 12: Iterationen slutar innan nolltecknet förs över. Satsen garanterar att även<br />
target avslutas med ett nolltecken.<br />
7.3.3 Övning:<br />
Tänk igenom programexekvering rad för rad, sats för sats, och se <strong>till</strong> att du förstår<br />
meningen hos varje programrad. Detta är en standardkonstruktion av en for-sats för fält<br />
som du måste behärska.<br />
Exempel, att räkna längden på en text.<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
char in_text[255];<br />
//<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
7.4 Texthanteringsfunktioner<br />
I det tidigare avsnittet visades hur for-satser var nödvändiga för att göra vanliga<br />
textoperationer. Naturligtvis har man sett ett behov av att göra detta på en enklare sätt.<br />
Det finns ett bibliotek eller headerfil som heter cstring (string.h på äldre kompilatorer)<br />
där många texthanteringsfunktioner finns för att göra de vanligaste funktionerna.<br />
Funktioner i cstring (urval)<br />
strcpy string copy <strong>till</strong>delning<br />
strcat string concatenate konkatenering<br />
(ihopslagning)<br />
strcmp string compare alfabetisk<br />
jämförelse<br />
strlen string length textlängd<br />
Syntax funktioner i cstring<br />
strcpy(char * target, const char * source):char * den kopierade<br />
texten<br />
strcat(char * target, const char * source):char * den<br />
konkatenerade texten<br />
strcmp(const char * txt1, const char * txt2):int se nedan<br />
strlen(const char * ):int<br />
längden,<br />
antal tecken<br />
Typen char * i tabellen ovan är en variant av char-fält som vi kan betrakta som<br />
likvärdiga variabler som deklarerats som<br />
char text[80];<br />
dvs ett vanligt textfält. (Typen char * är en pekartyp, en pekare är en variabel som<br />
pekar ut olika positioner i minnet, som här; början på texten/första tecknet i texten).<br />
Typen const char innebär en garanti att inget tecken i texten kommer att ändras.<br />
strcat: Att konkatenera texterna "Hello " och "World" ger resultatet "Hello World".<br />
strcmp: Det heltal som anges som returvärde kan anta tre olika slags värden<br />
<br />
<br />
<br />
0: txt2 kommer före txt1.<br />
52
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Syntaxtabellen ska tolkas som ex Funktionen strcmp tar 2 argument av textfältstyp,<br />
returvärdet är ett heltal. Ett lösryckt avsnitt kan då se ut som:<br />
char passwd[80];<br />
cin>>passwd;<br />
if( strcmp(passwd, "hemligt") == 0)<br />
{ cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Exempel, användning av texthanteringsfunktioner.<br />
#include<br />
#include // för texthanteringsfunktioner<br />
using namespace std;<br />
int main()<br />
{<br />
char namn1[255];<br />
char namn2[255];<br />
//<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
for-satsen i exemplet, att räkna längden på en text, är förbluffande lik det<br />
underprogram som utförs då funktionen strlen anropas.<br />
Teknisk not:<br />
Jämför gärna funktioner och operatorer. Ex<br />
och<br />
strcat( txt1, txt2 ): resultat<br />
tal1 + tal 2: resultat<br />
en giltig omskrivning av tal1 + tal 2 skulle vara<br />
operator+ (tal1, tal2 ): resultat<br />
Där enda skillnaden är funktionsnamnet strcat respektive operator+ och dess<br />
datatyper.<br />
Skillnaden mellan funktioner och operatorer är språkmässigt mest syntaktisk. Det finns<br />
en viss fast uppsättning operatorer +,-, * osv. medan funktionsnamn och funktioner kan<br />
skapas helt efter behov. Annars är den bakomliggande principen densamma. Det finns<br />
en operator ( ) funktionsoperatorn (se operatortabell i bilaga) som utvärderas på samma<br />
sätt som övriga operatorer, sånär som på det syntaktiska.<br />
7.5 Datatypen string<br />
Det finns i moderna C++ miljöer en datatyp speciellt utvecklad för att handskas med<br />
text som en enkel datatyp. För denna datatyp fungerar de enkla operatorerna på ett<br />
naturligt och enkelt sätt. Datatypen heter string och är en sk. klasstyp. Det innebär att<br />
typen är skapad med de enkla datatyperna som bas men med funktioner och operatorer<br />
omskrivna så att de kan användas på ett naturligt sätt. Typen är definierad i en header<br />
string. Headern cstring behövs inte om man använder typen string.<br />
55
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Exempel, operationer för text av typen string<br />
#include<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
string text1 ="Hello World"; // deklaration + initiering<br />
string text2; // deklaration<br />
text2 = text1; // enkel <strong>till</strong>delning, ingen strcpy<br />
if ( text2== text1) // sant, jämför textinnehållet<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
8 Funktioner och procedurell abstraktion<br />
Det som gör programkonstruktion hanterlig och övergripbar och överhuvudtaget<br />
genomförbar är möjligheten att dela upp program i olika avsnitt, i underprogram. Vår<br />
förmåga att hantera ett stort komplext problem bygger <strong>till</strong> stor del på vår förmåga att<br />
dela upp problemet i mindre delar och därefter lösa var del för sig. Detta är kärnan i<br />
procedurell abstraktion.<br />
Procedurell abstraktion – förenkling genom uppdelning<br />
Man kan enkelt ge exempel på procedurell abstraktion i vardagslivet<br />
Exempel, frukost<strong>till</strong>agning medelst procedurell abstraktion<br />
1 Koka kaffe<br />
2 Stek två ägg<br />
3 Gör en skinkmacka<br />
Detta är en anständig beskrivning av <strong>till</strong>agningen av en frukost. Beskrivningen består<br />
av tre olika procedurer. Beskrivningen är abstrakt, det vill säga förenklad.<br />
Förenklingen/abstraktionen består i att man inte beskriver varje enskild detalj i<br />
exempelvis proceduren Koka kaffe. Denna förenkling kan ske på flera olika nivåer.<br />
Den enklaste kan vara att helt enkelt ange Laga frukost. En mindre abstrakt variant är<br />
de tre stegen som är beskrivna ovan. En ännu mindre abstrakt variant vore om man<br />
ytterligare beskrev de olika stegen, ex<br />
1. Koka kaffe: Ta fram kaffepulver, häll 5 dl vatten i bryggaren, mät<br />
upp 7 mått kaffepulver i filtret, slå på bryggaren, vänta 2 minuter.<br />
Denna förfining kan dras in absurdum såsom exempelvis att ange exakt vila<br />
armrörelser och benrörelser man ska utföra föra att hälla 5 dl vatten i någon speciell<br />
kaffebryggare. Om man utformar dessa procedurer mer och mer exakt kommer<br />
samtidigt beskrivningen att bli mer och mer specialiserad. En angivelse av benrörelser<br />
fungerar troligtvis bara för ett speciellt kök, med speciellt placerade köksverktyg,<br />
medan den första beskrivningen fungerar i de flesta kök.<br />
Vid <strong>programmering</strong> kommer man aldrig att behöva förfina mer än att det direkt går att<br />
översätta <strong>till</strong> programsatser, eller <strong>till</strong> välkända lösningar på standardproblem.<br />
För att åstadkomma denna uppdelning i procedurer eller underprogram skriver man<br />
funktioner.<br />
8.1 Funktioner<br />
Av de funktioner vi redan stött på kan vi utläsa på vilket sätt funktioner kommer att<br />
anropas. En funktion/ett funktionsanrop representerar ett återanvändbart<br />
programavsnitt som utförs då programmet stöter på ett anrop.<br />
57
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Utdrag ur Exempel för användning av texthanteringsfunktioner<br />
// <strong>till</strong>delning namn1 -> namn1och2<br />
strcpy( namn1och2, namn1 );<br />
// lägg <strong>till</strong> texten ", "<br />
strcat(namn1och2, ", ");<br />
// lägg <strong>till</strong> namn2<br />
strcat(namn1och2, namn2);<br />
strcpy( namn1och2, namn1 ); är ett funktionsanrop <strong>till</strong> en redan skriven funktion som<br />
utför det arbete som funktionen strcpy antyder, att genom en iteration kopiera över alla<br />
tecken i texten namn1 <strong>till</strong> textfältet namn1och2. Det är en liknande iteration som vi såg<br />
göras av en for-sats vid <strong>till</strong>delningsoperationen för ett textfält på sidan 51.<br />
8.1.1 Funktionsdeklaration och funktionsdefintion<br />
En funktion består huvudsakligen av två delar<br />
1. en deklaration som berättar hur funktionen ska användas i ett program<br />
2. en definition som beskriver vilken programkod som ska utföras vid<br />
anropet.<br />
En deklaration har följande form<br />
returtyp funktionsnamn(argumenttypslista );<br />
I vårt tidigare skrivsätt för operationer skulle detta se ut som<br />
funktionsnamn( argumentlista): returtyp<br />
En definition har följande form<br />
returtyp funktionsnamn(argumentdeklarationslista)<br />
sats/satsblock;<br />
Returtyperna och argumentlistorna måste stämma överens exakt med avseende på<br />
datatyperna.<br />
Den enklaste datatypen är void (ingenting) den använder man om man inte vill ge<br />
något värde <strong>till</strong> eller från funktionen. De funktioner som har returtyp void ger alltså<br />
inget returvärde. Dessa funktioner är av en speciell kategori funktioner kallade<br />
procedurer. Författaren anser att distinktionen mellan sk. void-funktioner(procedurer)<br />
och icke void-funktioner (funktioner) är onödig, men eftersom många andra gör denna<br />
distinktion vill jag påpeka att den förekommer. Det finns däremot anledning att först i<br />
en text behandla void-funktioner eftersom de är den syntaktiskt enklaste typen.<br />
Den enklast möjliga funktionsdeklarationen ser ut som<br />
58
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
// dra_linje ritar ett streck med - tecken<br />
void dra_linje();<br />
Kommentaren krävs förstås inte av kompilatorn men det är en god vana att<br />
kommentera varje funktionsdeklaration, så att man enkelt kan läsa ut syftet med<br />
funktionen.<br />
En enkel definition för deklarationen kan se ut som<br />
void dra_linje()<br />
{<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Resultatet blir:<br />
----------------------------------------------<br />
Hello World<br />
----------------------------------------------<br />
Press any key to continue<br />
8.1.2 Övning:<br />
int dra_linje()<br />
Prova att i din utvecklingsmiljö ändra definitionens första rad <strong>till</strong><br />
int dra_linje();<br />
Observera vilka fel som rapporteras vid kompilering / länkning<br />
Ändra <strong>till</strong>baka definitionen <strong>till</strong> det ursprungliga och ändra istället deklarationen <strong>till</strong><br />
Observera vilka fel som rapporteras vid kompilering / länkning<br />
Funktionsnamn är om möjligt ännu viktigare än variabelnamn. Använd utförliga och<br />
tydliga funktionsnamn som beskriver dess syften väl.<br />
En funktion som aldrig anropas körs aldrig. Det kan mycket väl tänkas att du skrivit<br />
dina funktion korrekt i ditt program, men programmet gör ändå inte som du vill. Ibland<br />
beror det på att du glömt anropet av funktionen. Detta är ett fel som kompilatorn inte<br />
kan upptäcka.<br />
8.2 Funktioner som behöver indata<br />
Vi har sett tidigare i samband med texthanteringen hur vi kunde berätta för funktionen<br />
att den skulle göra beräkningar på någon viss variabel, exempelvis den tidigare satsen<br />
int len = strlen( namn_1 );<br />
utför en beräkning på variabeln namn_1 för att kontrollera hur många tecken som<br />
texten innehåller. Denna data meddelas genom argumenttyper och argumentnamn<br />
Den tidigare funktionen dra_linje() som drar ett streck av minustecken är inte vidare<br />
flexibel. Man kan <strong>till</strong> exempel inte ange hur långt strecket ska vara. Det kan man enkelt<br />
åstadkomma med funktionsargument.<br />
Detta skulle i huvudprogrammet kunna se ut som:<br />
60
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
int main()<br />
{<br />
dra_linje( 12 ); // skriv tolv minustecken<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
I ett komplett program kan de båda funktionerna skrivas och användas som<br />
// dra_linje ritar ett streck med - tecken<br />
void dra_linje();<br />
// dra_linje(int ) ritar ett streck med ett visst antal – tecken<br />
void dra_linje(int );<br />
int main()<br />
{<br />
dra_linje(); // anropa funktion<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
När funktionens satsblock tar slut upphör variablerna antal_minus och index att vara<br />
meningsfulla, och de förstörs därför. Man säger att de har sin räckvidd (eng. scope)<br />
inom funktionen. Funktionen styr programflödet <strong>till</strong>baka <strong>till</strong><br />
<br />
<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
double bredd, hojd, yta;<br />
bredd= 5.0;<br />
hojd= 2.5;<br />
yta= area( bredd, hojd );<br />
Funktionen utvärderas som ett flyttal och tar två flyttal som argument. Deklarationen<br />
blir då<br />
double area( double, double);<br />
Funktionsdefinitionen innehåller en enkel multiplikation.<br />
double area( double b, double h)<br />
{<br />
double a = b * h;<br />
return a;<br />
}<br />
Alternativt kan man skriva funktionen på ett enklare (men mindre tydligt) sätt som<br />
double area( double b, double h)<br />
{<br />
return b*h;<br />
}<br />
return satsen anger alltså vilket värde som funktionen ska utvärderas <strong>till</strong>. Datatypen för<br />
uttrycket i return satsen måsta vara av samma datatyp som, eller kunna omvandlas <strong>till</strong>,<br />
returtypen angiven i deklaration och definition. Satsblocket som hör <strong>till</strong> en funktion<br />
kallas ofta funktionens implementation. Då man talar om implementering eller<br />
implementation avser man programkoden eller skrivandet av programkoden.<br />
Funktioner ska skrivas med målet att de ska fungera i så många situationer som<br />
möjligt. Man talar om generella funktioner. Det leder oss direkt in på ett mycket<br />
vanligt nybörjarmisstag vid implementation av funktioner.<br />
En funktion ska aldrig innehålla in eller utmatningssatser om det inte<br />
uttryckligen är funktionens syfte.<br />
Area funktionen i tidigare exempel fungerar bra för att visa på nackdelarna med detta.<br />
Antag att man skrivit funktionen som<br />
64
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
//Deklaration<br />
double area();<br />
//Definition<br />
double area()<br />
{<br />
double b,h;<br />
coutb;<br />
couth;<br />
return b*h;<br />
}<br />
Funktionen kan mycket väl vara lämpad för uppgiften i ett speciellt fall, men den är<br />
långt ifrån så generell som den tidigare area beräkningen. Antag att programmet redan<br />
kände <strong>till</strong> värden för bredd och höjd. Då skulle inmatningssatserna förmodligen göra<br />
programmet väldigt förvirrande för användaren, om inte rent obrukbart. Undantaget är<br />
alltså funktioner som uttryckligen är <strong>till</strong> för in och utmatning. Typexempel är<br />
funktioner typ dra_linje ovan. Funktioner för utmatning är väldigt ofta void-funktioner<br />
(procedurer).<br />
8.4 Speciella datatyper för funktionsargument<br />
8.4.1 Fälttyper<br />
#include<br />
using namespace std;<br />
Man kan ge textfält som argument <strong>till</strong> funktioner på samma sätt som man ger vanliga<br />
variabler som argument. Det man måste hålla i minnet är att fältvariabeln inte<br />
representerar själva texten utan bara vart texten börjar. Detta får vissa konsekvenser för<br />
texter i funktioner. Betrakta programmet<br />
void skriv_10_ggr(char []);<br />
int main()<br />
{<br />
char text1[]="Ett";<br />
char text2[]="Två";<br />
skriv_10_ggr( text1 );<br />
skriv_10_ggr( text2 );<br />
return 0;<br />
}<br />
void skriv_10_ggr( char txt[])<br />
{<br />
for(int i = 0;i
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
EttEttEttEttEttEttEttEttEttEttTvåTvåTvåTvåTvåTvåTvåTvåTvåTvåPres<br />
s<br />
any key to continue<br />
Det aktuella argumentet i första funktionsanropet är alltså adressen <strong>till</strong> den minnescell<br />
som innehåller tecknet 'E' i texten Ett. Argumentet är alltså ett slags heltal. Detta<br />
innebär att den information som behöver föras över <strong>till</strong> funktionen inte är hela texten,<br />
vilket skulle kunna bli väldigt resurskrävande om texten var lång, utan bara adressen<br />
<strong>till</strong> textens första tecken. Variabeln txt och variablerna text1 och text2 representerar<br />
alltså inte bara lika texter utan samma texter vid respektive funktionsanrop. Alltså<br />
txt==text1 sedan txt==text2, text1 och text2 är naturligtvis aldrig lika.<br />
Detta har ytterligare en effekt, förutom att vara resurseffektivt. Man kan nämligen<br />
manipulera innehållet i fältet inuti funktionen.<br />
Se exempelvis funktionen och anropet<br />
void mata_in_textrad(char txt[]);<br />
void mata_in_tal( int );<br />
int main()<br />
{<br />
char inmatningsyta[200];<br />
int talet;<br />
mata_in_textrad( inmatningsyta );<br />
mata_in_tal( talet ); // går ej<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
const double PI = 3.14159265358;<br />
const int NOLL = 0;<br />
const char ALFABET[] = "abcdefghijklmnopqrstuvwxyzåäö";<br />
Konstanter har ofta identifierare som bara består av versaler. Den sista deklarationen<br />
skall läsas som ett fält bestående av const char. Tecknen i fältet får inte ändras. Att<br />
deklarera en variabel som konstant gör att man inte har <strong>till</strong>åtselse att ändra variabelns<br />
värde. Samtliga följande satser är o<strong>till</strong>åtna<br />
PI = 3.14;<br />
NOLL += 1;<br />
ALFABET[3] = 'D';<br />
// o<strong>till</strong>åtet för const double<br />
// o<strong>till</strong>åtet för const int<br />
// o<strong>till</strong>åtet för const char<br />
För funktioner innebär det att om den tidigare funktionen mata_in_textrad( char [] )<br />
istället skulle skrivits som<br />
void mata_in_textrad(const char txt[]);<br />
// och definition<br />
void mata_in_textrad(const char txt[])<br />
{<br />
cin.getline(txt, 80);<br />
}<br />
8.4.3 Referenser<br />
int i = 3;<br />
int & ref = i;<br />
är det en o<strong>till</strong>åten operation att ändra värdet på tecknen i fältet. cin.getline( txt, 80) är<br />
då en o<strong>till</strong>åten operation, kompilatorn ger felmeddelande, eftersom satsen ändrar<br />
innehållet i fältet. Jämför deklarationerna av texthanteringsfunktionerna i cstring.<br />
En annan speciell deklaration får man om man deklarerar en variabel som referens.<br />
Detta ser ut som<br />
Rad 2: Deklarerar identifieraren ref att vara en så kallad referens. En referensvariabel<br />
är en synonym <strong>till</strong> en redan existerande variabel. Referensen fungerar på exakt samma<br />
sätt som den ursprungliga variabeln. Genom referensen får man alltså här två<br />
variabelnamn/identifierare att referera <strong>till</strong> exakt samma data.<br />
Betrakta<br />
int i = 3;<br />
int j = 4;<br />
int & ref = i;<br />
ref = j; // obs <strong>till</strong>delning värdet i j kopieras <strong>till</strong> ref/i<br />
i++;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Programsnutten ger resultatet<br />
i:5<br />
j:4<br />
ref:5<br />
i:6<br />
j:4<br />
ref:6<br />
Detta kommer sig alltså av att ref och i representerar samma instans (samma faktiska<br />
heltal). Tilldelningssatsen på rad 4 ger alltså endast värdet av j <strong>till</strong> instansen i/ref. Med<br />
tanke på att referenser är synonymer <strong>till</strong> redan existerande instanser måste de initieras i<br />
samband med en deklaration, detta görs automatiskt om man gör dem <strong>till</strong><br />
funktionsargument (de initieras då med de aktuella argumenten), men inte om man<br />
deklarerar dem som ovan. Följande sats är o<strong>till</strong>åten eftersom den inte refererar <strong>till</strong><br />
något existerande heltal.<br />
int & j;<br />
int & k = 4; // o<strong>till</strong>åtet 4 är ingen heltalsvariabel<br />
I exempel som detta är det svårt att se nyttan med referenser. Nyttan blir tydligare om<br />
man visar hur det fungerar för ett funktionsargument. Betrakta funktionen och<br />
programmet<br />
void mata_in_tal( int& , int &);<br />
int main()<br />
{<br />
int tal1, tal2;<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
9 Fältteori<br />
9.1 Fält av andra datatyper än char<br />
Vid beräkningar med större datamängder än några enstaka tal är det bekvämt att kunna<br />
betrakta en talmängd som en enhet. Detta åstadkommer man genom att deklarera fält<br />
av taltyper som exempelvis<br />
int i_array[10]; // deklarera ett heltalsfält<br />
double x_array[10]; // flyttalsfält<br />
int j_array[]={ 1, 3, 5, 7, 9, 11, 13, 15}; // initierat fält 8 element<br />
Andra datatyper går naturligtvis också bra.<br />
För dessa fält gäller samma som för vanliga variabler, dvs är de inte initierade kan<br />
vilka värden som helst finnas bland heltalen/flyttalen. Det som skiljer dessa fält från<br />
textfältet är att det inte är meningsfullt med någon "nolltecken". På samma sätt som för<br />
textfälten anger fältvariabeln vart fältets element börjar i minnet.<br />
Den skarpsinte noterar att ett textfält kan initieras som<br />
char text[]= {'H','e','l','l',''o',' ','W','o','r','l','d','\0'};<br />
eller för all del med teckenkoderna motsvarande tecknen 'H', 'e', 'l' etc.<br />
Exempel, inmatning och beräkning av medelvärdet av 10 flyttal<br />
#include<br />
using namespace std;<br />
int main()<br />
{<br />
double talserie[10];<br />
for (int tal_nr = 0; tal_nr
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Resultatet av en programkörning kan bli<br />
Mata in tal nr:0<br />
1.0<br />
Mata in tal nr:1<br />
4.0<br />
Mata in tal nr:2<br />
7.0<br />
Mata in tal nr:3<br />
6.0<br />
Mata in tal nr:4<br />
7.0<br />
Mata in tal nr:5<br />
13.3<br />
Mata in tal nr:6<br />
12.98<br />
Mata in tal nr:7<br />
5.4<br />
Mata in tal nr:8<br />
3.3<br />
Mata in tal nr:9<br />
3.2<br />
Medelvõrdet õr:6.318<br />
Press any key to continue<br />
Flera saker måste klargöras för exemplet. Det första flyttal som matas in är element<br />
nummer noll dvs flytttalsinstansen talserie[0] därför initieras tal_nr <strong>till</strong> 0. Tänk på en<br />
komplett utvärdering av cin>>satsen på rad 11 ger <strong>till</strong> slut (istream)>>(double).<br />
Medelvärdet beräknas först genom att först beräkna summan och därefter dividera med<br />
antalen termer i summan. Observera att iterationsvillkoren i for-satserna är tal_nr < 10<br />
och inte som i fallet med textfält en nollteckenkontroll.<br />
70
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
#include<br />
using namespace std;<br />
Förbättrad version med procedurell abstraktion.<br />
Flera av delarna i programmet ovan kan delas upp i funktioner.<br />
void mata_in_flyttal( double [], int);<br />
double medel( const double [], int );<br />
void skriv_ut_array( const double [], int);<br />
int main()<br />
{<br />
const int ANTAL_TAL = 10;<br />
double talserie[ ANTAL_TAL ];<br />
mata_in_flyttal( talserie, ANTAL_TAL );<br />
// beräkna medelvärdet<br />
double medel_tal = medel( talserie, ANTAL_TAL );<br />
cout
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
Analysera exemplet noga. Det är ett gott exempel på hur ett relativt komplicerat<br />
huvudprogram kan delas upp i mindre uppgifter, och hur resultatet blir ett överskådligt<br />
huvudprogram med klara avsikter. Funktionerna är dessutom generella och kan<br />
återanvändas i någon annan del av programmet eller i något annat program. En<br />
heltalskonstant används för att på ett säkert sätt ange antalet element i fältet. Notera<br />
gärna att programmet i denna andra tappning är mycket enklare att göra ändringar i och<br />
dessutom mycket enklare att upptäcka fel i.<br />
Funktionerna som inte ändrar innehållet i fältet är const deklarerade för att garantera att<br />
fältets element inte ändrar värden. const deklarationen påverkar inte direkt funktionen<br />
hos programmet men är en viktig del i god <strong>programmering</strong>ssed. Om du inte har<br />
<strong>till</strong>gång <strong>till</strong> källkoden <strong>till</strong> exemplen bör du mata in programmet i din utvecklingsmiljö.<br />
Studera funktionen hos programmet och hur ändringar påverkar programkörning.<br />
Programmet är uppbyggt av algoritmer som du måste känna <strong>till</strong>, exempelvis<br />
summaberäkningen.<br />
Se även avsnittet standardalgoritmer för andra exempel med numeriska fält.<br />
72
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
10 Standardalgoritmer<br />
10.1 Swap funktion<br />
int i = 4;<br />
int j = 9;<br />
En swapfunktion är en funktion som byter innehållet i två variabler. Funktionen kan<br />
anropas som<br />
swap( i, j); // byt plats<br />
// j innehåller 4, i innehåller 9<br />
funktionen är användbar för i synnerhet heltalsvariabler och flyttalsvariabler<br />
// Deklaration:<br />
void swap( int & a1, int & a2);<br />
// Definition:<br />
void swap( int & a1, int & a2)<br />
{<br />
int tmp = a1; // spara a1 <strong>till</strong>fälligt<br />
a1 = a2;<br />
a2 = tmp;<br />
}<br />
10.1.1 Övning:<br />
Se <strong>till</strong> så att du förstår funktionen hos swap-funktionen. Se avsnitt Funktioner/Speciella<br />
datatyper/Referenser.<br />
Skriv om swap funktionen så att den fungerar för flyttal, datatypen string och char-fält<br />
10.2 Sök minsta värdet i en array<br />
En funktion som söker efter det minsta värdet i en array av flyttal. Funktionen<br />
returnerar det index som det minsta talet befinner sig på. Principen är att<br />
<br />
<br />
antag att det minsta talet befinner sig på den första positionen<br />
iterera igenom övriga element, om ett mindre tal än det minsta upptäcks, låt det<br />
nya talet representera det minsta talet. Då arrayen är genomlöpt har det minsta<br />
elementet funnits.<br />
funktionen är användbar för i synnerhet heltalsvariabler och flyttalsvariabler<br />
73
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
// Deklaration:<br />
void find_min( double [], int);<br />
// Definition:<br />
void find_min( const double arr[], int size);<br />
{<br />
int min_idx = 0; // minsta finns på position 0<br />
}<br />
for(int i = 0; i< size; i++)<br />
{<br />
if ( arr[ i ]< arr[min_idx]) // jämför element i med det minsta<br />
min_idx = i;<br />
}<br />
return min_idx;<br />
10.2.1 Övning:<br />
Skriv om funktionen så att den kan hantera heltal och fält av datatypen string.<br />
Skriv en funktion som letar det största talet find_max<br />
10.3 Array sortering<br />
En enkel metod att sortera element i en array är metoden sök-minsta-byt. Metoden går<br />
ut på att man börjar med att leta igenom hela arrayen efter det minsta elementet i<br />
arrayen, man tar då det minsta elementet och byter plats med elementet sist i arrayen.<br />
Man kan nu betrakta detta minsta sista element som att vara sorterat.<br />
Den osorterade delen av arrayen är nu alla element utom det sista. Den kvarvarande<br />
sorteringsuppgiften är alltså att sortera en array som består av ett färre element än<br />
tidigare. Proceduren upprepas på denna mindre array, <strong>till</strong>s bara ett element återstår.<br />
Detta ensamma element är även det i ordning. Metoden sorterar arrayen i fallande<br />
ordning. Funktionen kräver att funktionerna swap(double &, double &) och find_min(<br />
duoble [], int); är definierade.<br />
Deklaration:<br />
void sort_array( double [], int);<br />
Definition:<br />
void sort_array( double arr[], int size)<br />
{<br />
for( ; size>0; size--)<br />
{<br />
int min_idx = find_min( arr, min );<br />
int last_idx = size-1;<br />
swap( min_idx, last_idx);<br />
}<br />
}<br />
10.3.1 Övning:<br />
Skriv om funktionen så att den sorterar i stigande ordning, sort_ascending( double [],<br />
int ). Skriv om funktionen så att den sorterar textsträngar av datatypen string<br />
74
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
10.4 Övrigt<br />
Det finns i texten beskrivet flera funktioner som är av yttersta vikt att kunna använda,<br />
förstå och kunna skapa på egen hand. Bland annat<br />
<br />
<br />
<br />
7.3.2 Exempel, <strong>till</strong>delning av textfält. Skriv rad 10 - 12 som en funktion.<br />
Standardfunktionen heter strcpy ur <br />
7.3.3 Exempel, att räkna längden på en text. Skriv rad 11 som en funktion.<br />
Standardfunktionen heter strlen ur <br />
s 71 Medelvärdesfunktion double medel( double[], int)<br />
75
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
11 Operatorprioriteter<br />
Högsta prioritet överst, höger kolumn anger utvärderingsriktning<br />
[ ] ( ) . –> postfix ++ och postfix –– Vänster <strong>till</strong> höger<br />
prefix ++ och prefix ––<br />
Vänster <strong>till</strong> höger<br />
sizeof & * + – ~ ! Höger <strong>till</strong> vänster<br />
typomvandlingar<br />
Höger <strong>till</strong> vänster<br />
* / % Vänster <strong>till</strong> höger<br />
+ – Vänster <strong>till</strong> höger<br />
> Vänster <strong>till</strong> höger<br />
< > = Vänster <strong>till</strong> höger<br />
== != Vänster <strong>till</strong> höger<br />
&<br />
Vänster <strong>till</strong> höger<br />
^<br />
Vänster <strong>till</strong> höger<br />
| Vänster <strong>till</strong> höger<br />
&&<br />
Vänster <strong>till</strong> höger<br />
|| Vänster <strong>till</strong> höger<br />
? : Höger <strong>till</strong> vänster<br />
= *= /= %= += –= = &= ^= |= Höger <strong>till</strong> vänster<br />
, Vänster <strong>till</strong> höger<br />
76
<strong>Introduktion</strong> <strong>till</strong> <strong>programmering</strong><br />
Martin Kjellqvist<br />
12 Teckenkoder – Asciitabell<br />
Tecken Dec Hex<br />
NUL 0 00<br />
SOH 1 01<br />
STX 2 02<br />
ETX 3 03<br />
EOT 4 04<br />
ENQ 5 05<br />
ACK 6 06<br />
BEL 7 07<br />
BS 8 08<br />
HT 9 09<br />
LF 10 0A<br />
VT 11 0B<br />
FF 12 0C<br />
CR 13 0D<br />
SO 14 0E<br />
SI 15 0F<br />
DLE 16 10<br />
DC1 17 11<br />
DC2 18 12<br />
DC3 19 13<br />
DC4 20 14<br />
NAK 21 15<br />
SYN 22 16<br />
ETB 23 17<br />
CAN 24 18<br />
EM 25 19<br />
SUB 26 1A<br />
ESC 27 1B<br />
FS 28 1C<br />
GS 29 1D<br />
RS 30 1E<br />
US 31 1F<br />
Tecken Dec Hex<br />
SP 32 20<br />
! 33 21<br />
" 34 22<br />
# 35 23<br />
$ 36 24<br />
% 37 25<br />
& 38 26<br />
' 39 27<br />
( 40 28<br />
) 41 29<br />
* 42 2A<br />
+ 43 2B<br />
, 44 2C<br />
- 45 2D<br />
. 46 2E<br />
/ 47 2F<br />
0 48 30<br />
1 49 31<br />
2 50 32<br />
3 51 33<br />
4 52 34<br />
5 53 35<br />
6 54 36<br />
7 55 37<br />
8 56 38<br />
9 57 39<br />
: 58 3A<br />
; 59 3B<br />
< 60 3C<br />
= 61 3D<br />
> 62 3E<br />
? 63 3F<br />
Tecken Dec Hex<br />
@ 64 40<br />
A 65 41<br />
B 66 42<br />
C 67 43<br />
D 68 44<br />
E 69 45<br />
F 70 46<br />
G 71 47<br />
H 72 48<br />
I 73 49<br />
J 74 4A<br />
K 75 4B<br />
L 76 4C<br />
M 77 4D<br />
N 78 4E<br />
O 79 4F<br />
P 80 50<br />
Q 81 51<br />
R 82 52<br />
S 83 53<br />
T 84 54<br />
U 85 55<br />
V 86 56<br />
W 87 57<br />
X 88 58<br />
Y 89 59<br />
Z 90 5A<br />
[ Ä 91 5B<br />
\ Ö 92 5C<br />
] Å 93 5D<br />
^ 94 5E<br />
_ 95 5F<br />
Tecken Dec Hex<br />
` 96 60<br />
a 97 61<br />
b 98 62<br />
c 99 63<br />
d 100 64<br />
e 101 65<br />
f 102 66<br />
g 103 67<br />
h 104 68<br />
i 105 69<br />
j 106 6A<br />
k 107 6B<br />
l 108 6C<br />
m 109 6D<br />
n 110 6E<br />
o 111 6F<br />
p 112 70<br />
q 113 71<br />
r 114 72<br />
s 115 73<br />
t 116 74<br />
u 117 75<br />
v 118 76<br />
w 119 77<br />
x 120 78<br />
y 121 79<br />
z 122 7A<br />
{ ä 123 7B<br />
| ö 124 7C<br />
} å 125 7D<br />
~ 126 7E<br />
DEL 127 7F<br />
NUL = Null<br />
SOH = Start of Heading<br />
STX = Start of Text<br />
ETX = End of Text<br />
EOT = End of Transmission<br />
ENQ = Enquiry<br />
ACK = Acknowledge<br />
BEL = Bell<br />
BS = Backspace<br />
HT = Horizontal Tabulation<br />
LF = Line Feed<br />
VT = Vertical Tabulation<br />
FF = Form Feed<br />
CR = Carriage Return<br />
SO = Shift Out<br />
SI = Shift In<br />
DLE = Data Link Escape<br />
DC = Device Control<br />
NAK = Negative Acknowledge<br />
SYN = Synchronous Idle<br />
ETB = End of Transm. Block<br />
CAN = Cancel<br />
EM = End of Medium<br />
SUB = Substitute<br />
ESC = Escape<br />
FS = File Separator<br />
GS = Group Separator<br />
RS = Record Separator<br />
US = Unit Separator<br />
SP = Space (Blank)<br />
DEL = Delete<br />
77