4.
Programkod
2. Variabler.
3. Tilldelning.
7. Inmatning från tangentbord.
10. Typomvandling.
11. Datatypen char.
12. Sammansatta deklarationssatser.
13. Förkortningar vid beräkning och tilldelning.
Medan vi lär oss programspråket C++ gör vi program av en enkel typ, nämligen program för in- och ut-matning av text. Inmatningen kan ske från tangentbordet, och utmatningen till bildskärmen i form av ett Dos-prompt-fönster. Detta är precis det vi gjorde i förra kapitlet, när vi skrev ut texten "Hello World". Vi kommer senare i kursen att arbeta med in och utmatning från och till filer.
Vi börjar med ett enkelt exempel. Först accepterar vi bara två saker. Det ena är hur den övergripande strukturen för ett enkelt C++ program med text in- och ut-matning ser ut:
#include
<iostream.h>
void main()
{
...
}
De tre punkterna ska naturligtvis ersättas med programkod. Vi ska efterhand lära oss hur man konstruerar programkod, men först ska vi ta och acceptera den andra saken. Utmatning av text i C++ sker med hjälp av nedanstående syntax:
cout << "Text som ska skrivas ut\n\n";
Lägg märke till att Text som ska skrivas ut ska bytas ut mot den text som man vill ska skrivas på skärmen. Man anger att det är en text genom att skriva texten mellan dubbla citattecken (tryck på tangenterna skift och 2). Det som står på slutet, ‘\n\n’, ska vi diskutera senare.
Till sist avslutar man programsatsen med ett semikolon.
Definition: Programkoden är indelad i programsatser. En programsats är en beskrivning av ett bearbetningssteg i programmet. Programsatsen avslutas med ett semikolon. |
Därmed kan vi lätt skriva det program som vi såg i föregående kapitel.
Övningsuppgift
4.1.1:
·
Skapa ett nytt projekt Namn.
·
Skriv ett program som skriver ut ditt namn.
En dators styrka är att den kan hålla reda på många olika saker samtidigt. Det man vill hålla reda på är i regel olika typer av uppgifter. Dessa uppgifter kallas med ett samlingsnamn för ‘data’. Det är därför en maskin avsedd att hantera sådana uppgifter kallas för en ‘dator’.
Data kan lagras på flera olika sätt, disketter och hårddiskar, magnetband, CD-skivor etc. Om datorn ska kunna bearbeta data på något sätt måste det dock först finnas i det så kallade ‘primärminnet’, även kallat ‘arbetsminnet’. Här representeras data som elektriska spänningar i IC-kretsar, vilket i och för sig kan vara intressant att fördjupa sig i, men här är vi bara intresserade av att se hur vi kan lagra och bearbeta data i dessa IC-kretsar med hjälp av instruktioner i vårt program.
Datorn håller reda på var i minnet data finns lagrat genom att varje cell i minnet har en numerisk adress, det vill säga en siffra motsvarar en plats där ett tecken kan lagras.
Definition: En variabel är en namngiven plats i minnet, avsedd att innehålla en viss typ av data. |
Det program som översätter vår text, källkod, till maskinkod i en objektsfil, kallas som sagt kompilatorn. Denna kompoilatorn tar hand om våra variabler, så till vida att vi bara behöver skriva vad vi behöver för sorts variabel, så sköter kompilatorn resten.
Kompilatorn behöver veta två saker när vi deklarerar en variabel:
· Vilken typ av data som ska lagras i minnet.
· Det namn vi tänker använda i vårt program, när vi använder variabeln, när vi refererar till den.
Den första punkten är viktig eftersom datatypen avgör hur stor plats i minnet en variabel tar, en, två, fyra eller åtta bytes. Det är också nödvändigt att kompilatorn vet hur data ska tolkas respektive lagras på denna plats, samt att den kan göra lämpliga kontroller så att vi inte försöker lagra data av fel typ på platsen.
Den andra punkten, namnet, är viktig för att vi sedan ska kunna tala om vilken variabel vi vill använda i t.ex. en utskrift eller en beräkning. Man kan alltså ha många variabler, bara de har olika namn. Namnet bestämmer den som skriver programmet, och det bör vara valt på ett sådant sätt att man lättare förstår programmet. En variabel avsedd att innehålla en ränta bör inte heta ‘r’, för det kan lika gärna stå för ‘Rad’ eller ‘Ruta’. Kalla den i stället för t.ex. ‘fRanta’. Det är en god sed att använda prefix. Prefixet i ‘fRanta’ är ‘f’ och talar om för den som läser variabelnamnet att det är av datatypen ‘float’. Mer om det senare.
Observera även att det inte är tillåtet med svenska tecken i variabelnamn. Tillåtna tecken är alla engelska bokstäver, stora och små, samt alla siffror, Ett variabelnamn får inte börja med en siffra.
Man deklarerar en variabel, det vill säga talar om för kompilatorn att vi vill ha en variabel, genom att skriva en deklaration, det vill säga datatypen och namnet, samt avsluta med ett semikolon:
int iTal;
Här ovan har jag deklarerat en variabel avsedd att användas för heltal. Variabeln heter ‘iTal’. Heltal heter på engelska ‘integer’ och förkortas i programspråket C++ till ‘int’. Lägg märke till att även en deklarationssats avslutas med ett semikolon.
Definition: En deklarationssats deklarerar en variabel. Först skrivs datatypen, sedan variabelns namn. Avsluta deklarationssatsen med ett semikolon. |
Vi kan prova att deklarera en variabel i vårt program, och sedan skriva ut den med hjälp av cout. Observera att cout själv känner igen datatypen och gör en korrekt utskrift. Ersätt den text som skrevs ut med variabelns namn (ta även bort citationstecknen).
#include
<iostream.h>
void main()
{
int iTal;
cout << iTal;
}
När vi sedan ‘kör’ programmet ser vi att någonting inte står rätt till. För det första så blev det en massa konstiga siffror. För det andra kom texten ‘Press any key to continue’ på samma rad som siffrorna, utan mellanrum. Så här blev utskriften:
Vi kan börja med att konstatera att en variabel som vi inte tilldelat något värde kan ha ett slumpvis valt värde. I fallet ovan är det 4276756.
Vi kan även se att man behöver en eller flera radframmatningar för att texten ‘Press any key to continue’ ska hamna på en rad för sig själv. Detta kan vi lätt fixa till. Det konstiga slutet på texten ‘Hello World’ är egentligen två så kallade ‘Escape’-tecken. Tecknet ‘\’ betyder att efterföljande tecken inte ska skrivas ut, utan att det ska användas för att styra utskriften på skärmen. Tecknet ‘n’ står för ‘ny rad’. Teckenföljden ‘\n\n’ är helt enkelt två stycken radframmatningar. De får samma effekt som om man tryckt två gånger på vagnretur på en vanlig skrivmaskin.
Vi bör alltså avsluta de flesta av våra program med programsatsen:
cout << "\n\n";
Övningsuppgift 4.2.1:
· Skapa ett projekt Variabel.
· Den första satsen i main() ska vara en deklarationssats. Deklarera heltalsvariabeln ‘iHeltal’.
· Den andra satsen ska vara en programsats som skriver ut variabelns värde.
· Den sista satsen ska mata fram två rader enligt ovan. Så här ska det bli, även om siffrorna kan variera från fall till fall:
Det finns flera operatorer för tilldelning i C++. Den vanligaste är ett vanligt likhetstecken. Vi ska titta mer på de andra senare.
En programsats som innehåller en tilldelning kallas en tilldelningssats. En tilldelning kan även ingå som en del i en programsats, men det kommer vi att studera närmare senare. Viktigt är att tänka på att det alltid sker en tilldelning om man använder en tilldelningsoperator. Den får alltså inte användas för t.ex. jämförelser, vilket vi också kommer att se senare.
En tilldelningssats verkar från höger till vänster, vilket i vårt enkla fall betyder att värdet står till höger om tilldelningsoperatorn, och variabeln till vänster. Så här kan vi t.ex. tilldela variabeln iTal värdet 5:
iTal = 5;
Övningsuppgift 4.3.1:
· Öppna projektet Variabel.
· Tilldela variabeln iHeltal värdet 27 genom att skriva en tilldelningssats mellan deklarationssatsen och den programsats som skriver ut variabelns värde (‘utskriftssats’).
· Så här ska utskriften se ut:
Observera att tilldelningssatsen inte är att jämställa med en matematisk likhet, en ekvation. Innan tilldelningssatsen utförs har variabeln något värde, antagligen något annat än det vi tänker tilldela den. Efter satsen har variabeln det värde vi tilldelat den.
Definition: En variabel sägs ha det värde som finns inskrivet i datorns minne på den plats som associerats med variabelns namn. |
Det som står till höger i en tilldelningssats behöver inte vara endast ett värde som ska tilldelas variabeln till vänster. Det kan t.ex. vara en beräkning. Vid beräkningar används bland annat de vanliga matematiska operatorerna för aritmetik, t.ex. de fyra räknesätten. Man kan tilldela variabeln iTal summan av 12 och 27 genom att skriva:
iTal = 12 + 27;
Övningsuppgift 4.4.1:
· Öppna projektet Variabel om det inte redan är öppet.
· Ändra tilldelningssatsen så att den tilldelar variabeln iHeltal produkten av talen 5 och 12.
· Så här ska utskriften se ut:
Det som står till höger om likhetstecknet kallas för ett uttryck (eng. expression). Uttrycket består i detta fall av två operander (operands) och en operator (operator). Operatorn är i detta fall ett plustecken, och operanderna är två heltalskonstanter.
Operanderna måste inte vara heltalskonstanter. Det kan även vara variabler. Det går t.ex. att arbeta vidare med iTal genom att dividera resultatet med tre:
iTal = iTal / 3;
Övningsuppgift 4.4.2:
· Öppna projektet Variabel om det inte redan är öppet.
· Lägg till en tilldelningssats efter den föregående och före utskriftssatsen. Den nya tilldelningssatsen ska tilldela iHeltal kvoten mellan iHeltal och 3.
· Så här ska utskriften se ut:
Hittills har vår utmatning varit minst sagt fattig, eftersom vi bara skrivit ut ett enda heltal. Vi vet ju sedan tidigare att man måste ha "\n" i slutet av en text för att utmatningen ska flytta fram till nästa rad. Om vi gör en utmatning utan detta nyradstecken kommer alltså utskriften att fortsätta på samma rad. Vi kan t.ex. skriva så här:
cout << "(12
+ 27) / 3 = ";
cout <<
iTal;
För att få en ‘formaterad’ utskrift:
(12 + 27) / 3 = 13
Teckenkombinationen ‘<<‘ kallas för en strömningsoperator. Tanken är att den ska ge en rent visuell association till att det som står till höger flyttas till objektet cout, vilken har hand om utskriften. Nu är det dock så att cout kan hantera flera strömningsoperatorer i en och samma programsats, så att vi i stället för de ovanstående två raderna kan skriva alltsammans på en rad:
cout << "(12 + 27) / 3 = " << iTal;
Övningsuppgift 4.5.1:
· Öppna projektet Variabel om det inte redan är öppet.
· Ändra utskriftssatsen så att iHeltal skrivs ut formaterat.
· Så här ska utskriften se ut:
Som du säkert redan gissat är det viktigt att programsatserna står i rätt ordning. Dessutom har du säkert kommit på att de utförs en i taget i den ordning de står. Vad har vi då hitintills åstadkommit? Först deklareras en variabel iTal. Det kan man förstå att man måste göra innan den kan användas, annars skulle ju kompilatorn inte veta var den skulle göra av talet vid vår första tilldelning. Skulle man försöka att använda en variabel innan den deklarerats får man ett kompileringsfel.
Övningsuppgift 4.6.1:
· Öppna projektet Variabel om det inte redan är öppet.
· Flytta deklarationssatsen och placera den sist i kodavsnittet till main().
· Kompilera.
1. Skriv de felmeddelanden du fick här nedan.
2. Prova att dubbelklicka på ett felmeddelande, vad hände? Skriv nedan!
3. Ställ markören på felmeddelandets felkod och tryck på F1. Vad hände? Skriv nedan!
· Återställ källkoden.
1) ________________________________________________________
________________________________________________________
________________________________________________________
2) ________________________________________________________
________________________________________________________
________________________________________________________
3) ________________________________________________________
________________________________________________________
________________________________________________________
Om man skriver flera utskriftssatser ska man alltså placera dem i den ordning som de ska presenteras på skärmen. Dessutom, om utskriftssatsen skriver ut värdet i någon variabel, måste den sats som tilldelar variabeln det värde som ska skrivas ut stå före utskriftssatsen. Tänk steg för steg: deklarera variabel, tilldela värde, skriv ut etc.
Övningsuppgift 4.6.2:
· Öppna projektet Variabel om det inte redan är öppet.
· Ändra programmet så att variabeln iHeltal skrivs ut två gånger, först efter den första tilldelningen, sedan efter den andra. För att detta ska komma på varsin rad måste man lägga till ett nyradstecken efter första utmatningen. Använd strömningsoperatorn en tredje gång i samma utskriftssats för att lägga till nyradstecknet.
· Så här ska det se ut:
Definition: Ett program består av ett antal programinstruktioner, vilka skrivs i programsatser. Programsatserna utförs i den ordning de står skrivna. Med hjälp av programsatsernas ordning väver man programmets logik. |
7. Inmatning från tangentbord.
Nu när vi har möjlighet att bearbeta variabler och skriva ut dem på skärmen, och även skriva ut fasta texter på skärmen, kunde det vara trevligt om man kunde mata in värden i våra variabler från tangentbordet. Detta låter sig göras med hjälp av objektet ‘cin’:
cin >> iTal;
I detta fall stannar programmet vid denna programsats och väntar på att användaren ska mata in något som passar i en heltalsvariabel (iTal var ju deklarerad som ‘int’, det vill säga heltal). När användaren matat in ett heltal lagrar objektet cin detta tal i variabeln iTal. Lägg märke till att strömningsoperatorn nu pekar åt höger. Detta för att ge ett visuellt intryck av att den är avsedd att flytta data från vänster till höger.
Övningsuppgift 4.7.1:
· Skapa ett projekt Intal.
· Deklarera en heltalsvariabel iHeltal.
· Använd cout för att skriva ut texten "Skriv ett tal: ".
· Använd cin för att mata in ett heltal i variabeln iHeltal.
· Skriv ut värdet i iHeltal tillsammans med en ledtext enligt nedanstående körexempel:
Övningsuppgift 4.7.2:
· Skapa ett projekt Alder.
· Programmet ska fråga efter din ålder och sedan lagra den i en heltalsvariabel.
· Därefter ska programmet skriva ut åldern i en utskrift enligt nedan:
Hoppsan! De svenska tecknen ‘å’ och ‘ä’ blir fel! Detta tittar vi på i nästa avsnitt.
Som vi såg i föregående övningsuppgift blev de svenska tecknen ‘å’ och ‘ä’ fel. Det gäller även ‘ö’, samt versalerna, ‘Å’, ‘Ä’ och ‘Ö’. Detta beror av att DOS och Windows inte använder samma teckenstandard. Vill man ha tecknen rätt får man använda en DOS-anpassad redigerare som t.ex. Edit. Dessa använder en teckenuppsättning som kallas ASCII. Developer Studio och Anteckningar är windowsprogram och kan inte förstå alla ASCII-koder. De använder en standard som heter ANSI i stället. Skillnaden mellan ASCII och ANSI märks först när man använder specialtecken.
Det bästa vi kan göra nu är att redigera vår källkod från DOS-Edit. Vill vi göra det lätt för oss kan vi använda Developer Studios förmåga att lägga till verktyg i Tools-menyn. Det går dessutom att ange att Edit ska öppna den fil som just nu är öppen i Developer Studios redigerare. Så här gör man:
· Välj menyvalet [Tools - Customize...]. Dialogrutan ‘Customize’ öppnas.
· Välj fliken ‘Tools’.
· Klicka på knappen ‘Add...’. Dialogrutan ‘Add Tool’ öppnas.
· Klicka på ‘Browse...’. Filvalsdialogrutan öppnas.
· Leta upp filen Edit.com, vilken brukar ligga i Windows-katalogen. Observera att filvalsdialogrutan har fel filter, så att endast filer med filnamnstillägget ‘exe’ visas. Ändra detta så att du ser ‘com’-filer.
· Dubbelklicka på Edit.com, eller klicka en gång på Edit.com och sedan på ‘OK’. Filvalsdialogrutan stängs och vi är tillbaka vid ‘Add Tool’.
· Klicka på ‘OK’. Add tool stängs och vi är tillbaka vid ‘Tools’.
· Ändra ‘Menu text:’ från ‘Edit’ till DOS-Edit.
· Klicka på pilen till höger om textrutan ‘Arguments:’. En PopUp-meny visas. Välj ‘File Name’. Upprepa, men välj denna gång ‘File Ext’.
·
Klicka på pilen till höger om textrutan ‘Initial
directory:’. En annan PopUp-meny visas. Välj ‘Worksapce directory’.
Är allt rätt gjort är det bara att klicka på ‘Close’, men jämför först det du gjort med nedanstående bild:
Övningsuppgift 4.8.1:
· Lägg till DOS-Edit i Tools-menyn enligt ovanstående instruktioner.
· Öppna projektet Alder om det inte redan är öppet, och öppna filen Alder.cpp för redigering.
· Välj [Tools - DOS-Edit] och rätta alla svenska tecken i alla utskriftssatser.
När man sedan stänger DOS-Edit reagerar Developer Studio på att någon har ändrat i en fil som är öppen för redigering, och vill då veta vad som ska gälla:
Klicka på ‘Ja’, så ser du ändringarna:
Nu ser det inte så kul ut i redigeraren, men om vi kompilerar och länkar så ser vi att det blir rätt vid körningen:
Nu kan vi väl vara nöjda?
Övningsuppgift
4.8.2:
·
Skapa ett projekt som heter Division.
·
Skriv ett program som frågar efter två tal och svarar med talens kvot.
·
Spara källkoden under namnet Division.cpp.
·
Lägg Division.cpp till
projektet.
·
Kompilera, länka och testa.
·
Spara detta projekt, du behöver det i kapitel 6.
Hittills har vi bara använt en datatyp, int, vilken används för heltal. Detta innebär att vi talat om för kompilatorn att reservera utrymme för ett heltal och associera detta utrymme med ett namn vi angivit, till exempel iTal. Att vi angivit datatypen ‘int’ innebär att programmet kommer att lagra data enligt de regler som gäller för hur heltal lagras i minnet, och att det data som finns där tolkas som heltal när vi använder vår variabel.
Överkurs: Minnet består som tidigare nämnts av IC-kretsar. Dessa IC-kretsar innehåller transistorer eller liknande elektroniska halvledarkomponenter för att lagra information. Vanligen är en transistor antingen ‘laddad’ med elektroner, eller så är den urladdad. Kringliggande elektronik kan ladda respektive ladda ur transistorn, samt läsa av huruvida den är laddad. På så sätt kan en minnescell, vilken utgörs av transistorn, inta ett tillstånd av två, och kallas därför binär. Därför brukar man säga att datorn bara ‘förstår’ ettor och nollor. Det är inte effektivt att arbeta med en transistor, minnescell eller ‘bit’, i taget. Därför började man tidigt att slå samman dem i grupper om 8. (Enklare specialdatorer kunde använda grupper om 4.) Utvecklingen har lett till att man numera grupperar 16, 32 eller 64 bitar i stället. En grupp om 4 kallas nibble, en grupp om 8 byte, 16 bits kallas word och 32 bits kallas ett longword. En byte, 8 bitar, kan alltså innehålla ett antal ettor och nollor. Man kan beräkna antalet möjliga kombinationer som 28 = 256 stycken. Vad dessa olika kombinationer sedan ska betyda är programmets ensak. Man kan t.ex. deklarera en variabel så att de 256 olika kombinationerna representerar heltal från -128 till +127. Om man inte behöver negativa tal, men väl lite större tal, kan man låta de 256 kombinationerna representera heltal från 0 till 255 i stället. Överkursuppgift 4.9.1: · Om man använder ett word för heltal, vilket blir det talomfång variabeln kan representera? · Om man använder en nibble för endast positiva heltal, vilket blir då det största värde variabeln kan innehålla? _____________________________ |
Hur mycket blir fem delat med två? Två och en halv, eller hur? Nu har vi dock endast lärt oss att använda heltalsvariabler, så vi kanske skulle säga att det blir två, och så blir det ett över. Det finns faktiskt ett femte räknesätt, vilket på sätt och vis hör till division. Detta räknesätt ger just det tal som ‘blir över’ vid division. Operationen kallas modulusdivision, och den utförs med en operator som kallas modulusoperatorn. Modulusoperatorn betecknas med ett procenttecken. Vill vi ha ett mera korrekt resultat när vi frågar efter 5/2 kan vi göra till exempel så här:
#include
<iostream.h>
void main()
{
int iSvar;
int iRest;
cout << "Fråga: Vad blir 5/2?\n\n";
iSvar = 5 / 2;
iRest = 5 % 2;
cout << "Svar: " << iSvar << '\n';
cout << "Rest: "
<< iRest;
cout << "\n\n";
}
Övningsuppgift 4.9.2:
· Skapa projektet Modulus.
· Skriv ett program liknande ovanstående, men låt användaren ange två tal. För detta behöver du två heltalsvariabler till.
· Så här kan det se ut när man kör programmet:
Ibland behöver man ange mycket stora eller mycket små tal. Några exempel:
· Jordens ekvatorialradie..... : 3678172 m.
· Solens ekvatorialradie...... : 696001231 m.
· Vintergatans diameter....... : 9454256280102569 m.
· Solens utstrålade effekt.... : 390102300104512312189754962 W.
· Elektronens laddning........ : 0,000000000000000000160210 As.
· Elektronens massa........... : 0,00000000000000000000000000000091091 kg.
Förutom att två av talen inte är heltal, ser vi även att en del tal har många siffror. Det tar inte bara mer plats på papperet, det tar även mer plats i datorns minne, om man nu behöver lagra dessa tal där. De två första exemplen kan man kanske lagra i ett heltal som tar 32 bits (4 bytes), eftersom 232 = 4294967296. I den version av C++ som vi använder klarar en vanlig int detta, medan äldre versioner har 2 bytes i en vanlig int. I de äldre versionerna kan man använda nyckelordet long för att deklarera en int med 4 bytes.
Det tredje exemplet får en dock att undra litet. Är det verkligen meningsfullt att ange vintergatans diameter på metern när? Svaret är naturligtvis nej. Vi kan inte mäta den så noggrant (jag har själv hittat på siffrorna på slutet). Den ändras dessutom helt säkert hela tiden. Jag har använt en för hög precision på talet. Egentligen skulle det räcka med att ange talet 9454256000000000. Nu är precisionen 7 siffror. Men egentligen har vi inte vunnit plats i minnet, eller på papperet heller för den delen, eftersom alla nollor skrivs ut. Det vore bättre att ange hur många nollor det ska vara i stället. Matematiker använder ett speciellt sätt för sådana stora tal, de anger i formen en siffra plus ett antal decimaler, och talar därefter om hur många gånger man måste multiplicera talet med 10 för att det ska bli rätt. Talet ovan skulle i så fall se ut så här: 9,454256 * 1015. Genom att alltid ange bara en siffra före decimalkommat ser man direkt talets storleksordning genom att titta på exponenten, som i detta fall är 15. Detta skrivsätt kallas exponentiell form. Exponenten skrivs med mindre siffror och högre upp än de övriga siffrorna. 1015 betyder 10 * 10 *10 *10 *10 *10 *10 *10 *10 *10 *10 *10 *10 *10 *10. Talet före exponenten, i ovanstående fall 9,454256 kallas mantissa.
Övningsuppgift 4.9.3:
· Skriv 6 och en halv miljon i exponentiell form: _____________________
· Skriv 35600 i exponentiell form: _____________________
· Skriv 16 miljarder i exponentiell form: _____________________
· Skriv 25 i exponentiell form: _____________________
Skrivmaskiner, dos-fönster etcetera klarar inte att skriva i detta format, eftersom de inte har ett typsnitt som kan skriva mintre, upphöjda siffror. Problemet är gammalt, det fanns på de datorer som inte hade typsnitt över huvud taget. Därför skapades ett nytt skrivsätt just för exponenter. I stället för till exempel 1015 skrev man E15. Det gäller naturligtvis alla tal. 2,33 * 106 skrivs som 2,33E6. Vi använder ju dos-fönster, och därför använder vi denna nya form. Dessutom är det så att engelsmännen föredrar decimalpunkt i stället för decimalkomma, och detta har föranlett att vi måste använda decimalpunkt i våra program. Vi ska inte fördjupa oss i hur man kan omvandla mellan de två systemen, utan vi håller oss helt till decimalpunkt.
Övningsuppgift 4.9.4:
· Använd det nya skrivsättet för nedanstående tal.
· Skriv 6 och en halv miljon i exponentiell form: _____________________
· Skriv 35600 i exponentiell form: _____________________
· Skriv 16 miljarder i exponentiell form: _____________________
· Skriv 25 i exponentiell form: _____________________
Naturligtvis kan man lagra data i denna form. Datatypen kallas float. Float använder 4 bytes i minnet, och av dessa används en del till mantissan och en del till exponenten. Observera att en bit reserverats för tecknet. Man kan alltså även ha väldigt stora negativa tal.
De två sista exemplen i listan med stora tal ovan, var egentligen mycket små tal: elektronens laddning respektive massa. Även dessa kan med fördel uttryckas i exponentiell form. För att göra talen mindre än ett använder man en negativ exponent. Elektronens laddning kan då uttryckas som 1,160210 * 10-19 As och dess massa som 9,1091 * 10-31 kg. Härigenom reserveras ytterligare en bit, den för exponentens tecken. Man kan uppfatta exponentens tecken som en information om åt vilket håll decimaltecknet ska flyttas för att talet ska bli rätt.
Det finns två sorters flyttal i C++ standard:
typ bytes värdeområde precision
float 4 +/-
3.4E +/- 38 7 siffror
double 8 +/-
1.7E +/- 308 15 siffror
Slå upp nedanstående hjälpanvisning och läs om de olika datatyperna:
? Visual C++
Books->C/C++->Language Quick Reference->Reference Tables->Data Type
Ranges.
Om vi nu försöker tilldela en variabel av typen float ett heltal som vi skriver in i källkoden, en numerisk konstant, och det talet är ett heltal, så får vi faktiskt en varning från kompilatorn:
float fTal;
fTal = 7; //
Warning C4244: '=' : conversion from 'const int'
// to 'float', possible loss of data
Om man läser varningsmeddelandet så ser man att problemet ligger i att 7:an uppfattas som ett heltal, medan fTal är ett flyttal. Givetvis går det att lagra värdet 7 i ett flyttal, men kompilatorn är styvnackad i detta avseende: data av olika typer får inte blandas hur som helst. Det går dock att skriva talet så att det uppfattas som ett flyttal, man skriver bara 7.0 i stället för 7. Nu finns det dock (minst) två olika typer av flyttal, float och double. Skriver man 7.0 uppfattar kompilatorn det som en double. Man kan styra detta genom att skriva ett ‘f’ eller ett ‘F’ efter talet. Bokstaven efter talet kallas för suffix.
float fTal;
fTal = 7.0F; // OK.
Man kan få liknande problem om man har olika typer av variabler:
int iTal;
float fTal;
fTal = 7.0f;
iTal = fTal; //
warning C4244: '=' : conversion from 'float' to
// 'int', possible loss of data
Här kan inte ett suffix hjälpa oss. Däremot kan man använda en så kallad typomvandling. Denna görs med typomvandlingsoperatorn, (cast operator). Den kan skrivas på två sätt. Det vanligaste är att man skriver den nya typen inom parantes före det som ska typomvandlas:
int iTal;
float fTal;
fTal = 7.0f;
iTal = (int)fTal; // OK, men om fTal innehåller decimaler så
// förlorar du dessa.
Ibland kan det vara snyggare att sätta parantesen runt det som ska typomvandlas i stället. Detta gäller speciellt om man gör en beräkning:
iTal = int(fTal * 3);
Här blir resultatet av beräkningen fTal * 3 typomvandlat till heltal. Om man i stället skriver:
iTal = (int)fTal * 3;
…kommer bara fTal att typomvandlas. I detta fall gör det ingen skillnad, men ibland måste man vara noga med att typomvandla just resultatet av en beräkning. Nu är vi nog redo för ett par övningar.
Övningsuppgift 4.10.1:
· Skriv ett program Division2 som dividerar 5 med 2.
· Talen 5 och 2 ska stå som flyttalskonstenter i ett uttryck.
· Resultatet mellanlagras i en flyttalsvariabel fSvar.
· Skriv ut resultatet i en formaterad utskriftssats.
· Så här ska det se ut:
Övningsuppgift 4.10.2:
· Öppna projektet Division2.
· Lägg till två flyttalsvariabler fTal1 och fTal2.
· Ändra i programmet så att det ber användaren mata in två flyttal.
· Ändra så att programmet dividerar fTal1 med fTal2 i stället för de två flyttalskonstanterna.
· Så här kan det se ut:
Övningsuppgift 4.10.3:
· Öppna projektet Division2.
· Ta bort flyttalsvariabeln fSvar.
· Lägg till heltalsvariabeln iSvar.
· Ändra så att programmet använder iSvar i stället för fSvar.
· Tänk på att du kan behöva typomvandla.
· Så här kan det se ut:
Observera att ovanstående resultat erhålls endast om man typomvandlar resultatet av beräkningen. Om man typomvandlar fTal1 och fTal2 var och en för sig blir resultatet annorlunda.
Övningsuppgift 4.10.4:
· Öppna projektet Division2.
· Se till att du typomvandlar resultatet av beräkningen (nu behöver du inte sätta parantes runt ordet ‘int’, det räcker med att sätta parantes runt beräkningen).
· Testa med siffrorna i ovanstående exempel och kontrollera att du får samma resultat.
· Ändra till att typomvandla fTal1 och fTal2 en i taget.
· Testa med samma siffror.
· Så här ska det se ut:
Vi har talat om att datorer hanterar data, och provat detta genom att bearbeta siffror. Hur är det med bokstäver då? För dem finns en datatyp som kallas char. Vi kommer senare att diskutera bits och bytes som överkurs, men just nu nöjer vi oss med att veta att en char kan innehålla 256 olika värden, det vill säga vi kan representera 256 olika värden med en variabel av typen char.
Alfabetet har 27 bokstäver. Om vi sedan tänker på att det finns stora och små bokstäver så behöver vi 54 av de olika värdena för att representera alfabetet. Vi kan kalla dessa värden för teckenkoder (character codes). Det finns alltså en kod för varje tecken vi kan skriva ut på skärmen (i ett dos-fönster). Tittar vi på tangentbordet ser vi andra tecken som kan skrivas ut. Symboler av olika slag, till exempel matematiska symboler som likhetstecken, plus och minus. Även skrivsymboler som till exempel parenteser, klamrar, hakparenteser och skiljetecken. Observera att flera av dessa tecken genereras genom att man trycker på en kombination av tangenter där skift, Ctrl eller Alt-tangenterna ingår. Förutom de tecken som kan skrivas från tangentbordet finns specialtecken som kan kombineras ihop till ramar etcetera på skärmen.
Om vi nu ser på tangentbordet så finner vi även siffror. Dessa kan alltså representeras i datorn på två olika sätt. Antingen en siffra i taget som olika variabler av typen char, eller som vi tidigare angivit, som numeriska variabler i hel eller flyttalsvariabler. Det är alltså viktigt att man håller reda på hur data lagras och tolkas i minnet. Siffervärdet 2 lagras till exempel som värdet 2 i en heltalsvariabel, men som koden 41 i en teckenvariabel, en char. Gör man fel här när man utför beräkningar får man ‘konstiga’ fel.
Objekten cin och cout däremot innehåller funktioner som kontrollerar datatyper, och kan själva avgöra hur data ska tolkas. När man till exempel skriver ut en heltalsvariabel omvandlar cout denna till en eller flera teckenvariabler, en för varje siffra. Heltalet 25 omvandlas till två teckenvariabler med innehållet 41 respektive 44, vilka kan skrivas ut på skärmen. Endast teckenvariabler kan skrivas ut på bildskärmen.
Om man nu vill tilldela en variabel av typen char ett värde, så kan man använda en konstant i programmet. När vi angav heltalskonstanter skrev vi bara ett tal i källkoden. Nu ska vi skriva ett tecken. Ett tecken anges inom enkla citattecken, för att skilja till exempel heltalskonstanten 5 från teckenkonstanten ‘5’. Så här kan man initiera en teckenvariabel cBokstav till ‘Q’:
cBokstav = ´Q´;
Observera att vi inte har någon datatyp för texter, en variabel av typen char tar bara ett tecken.
Övningsuppgift 4.11.1:
· Skriv ett program Tecken.
· Programmet ska innehålla en variabel av typen char. Kalla variabeln cTecken.
· Initiera cTecken med ett stort ‘A’.
· En formaterad utskrift ska visa värdet i cTecken.
· Så här ska det se ut:
12. Sammansatta deklarationssatser.
Tidigare har vi deklarerat en variabel i taget, och sedan tilldelat dem värde i en separat tilldelningssats för var och en va variablerna. Man kan förenkla detta på två sätt:
1. Multipel deklaration av variabler som har samma typ.
2. Tilldelning vid deklaration.
3. Multipel tilldelning.
Multipel deklaration gör man genom att skriva datatypen följt av en lista med variabelnamn. Variabelnamnen ska separeras med kommatecken:
int iTal1, iTal2, iTal3; // Deklarerar tre heltalsvariabler.
float fTal1, fTal2; // Deklarerar två flyttalsvariabler.
char cTecken, cBokstav; // Deklarerar två teckenvariabler.
Tilldelning vid deklaration gör man genom att kombinera deklarationssatsen med tilldelningssatsen:
int iTal = 5; // Deklarerar iTal och tilldelar värdet 5.
Char cTkn = '5' // Deklarerar cTkn och tilldelar värdet '5'.
float fTal = 3.4F; // Deklarerar iTal och tilldelar värdet 3,4.
Multipel tilldelning medger att flera variabler tilldelas samma värde (variablerna deklareras separat):
int iTal1, iTal2, iTal3; // Deklarerar tre heltalsvariabler.
float fTal1, fTal2; // Deklarerar två flyttalsvariabler.
char cTecken, cBokstav; // Deklarerar två teckenvariabler.
iTal1 = iTal2 = iTal3 = 7; // Tilldelar alla tre värdet 7.
fTal1 = fTal2 = 3.14159F; // Tilldelar bägge värdet 3,14159.
cTkn1 = cTkn2 = '$'; // Tilldelar bägge värdet '$'.
Man kan kombinera första och andra regeln:
int iTal1 = 2, iTal2 = 5; // Deklarerar två heltalsvariabler
// och tilldelar dem värden 2 och 5.
char cSiffra = '7', // Deklarerar två tecken variabler
cBokstav = 'ö'; // och tilldelar dem tecknen '7'
// respektive 'ö'.
I fortsättningen använder du dessa regler där du finner det lämpligt.
Övningsuppgift 4.12.1:
· Öppna projektet Tecken.
· Ändra så att du utnyttjar en sammansatt deklarationssats.
13. Förkortningar vid beräkning och tilldelning.
Det finns fem extra tilldelningsoperatorer som har till funktion att förkorta programsatserna. Om man har en variabel med ett långt namn, till exempel iAntalCyklisterTorsdagEftermiddagStorgatan och till exempel vill lägga till 2, eller dra ifrån värdet i Variabeln iAvdrag, så kan man skriva som vanligt:
iAntalCyklisterTorsdagEftermiddagStorgatan =
iAntalCyklisterTorsdagEftermiddagStorgatan + 2;
…respektive:
iAntalCyklisterTorsdagEftermiddagStorgatan =
iAntalCyklisterTorsdagEftermiddagStorgatan - iAvdrag;
Så kan man använda följande förkortningar (det är egentligen speciella tilldelningsoperatorer):
iAntalCyklisterTorsdagEftermiddagStorgatan += 2;
…respektive:
iAntalCyklisterTorsdagEftermiddagStorgatan -= iAvdrag;
Det finns motsvarande operatorer för de övriga tre räknesätten: *=, /= och %=.
Om man behöver lägga till eller dra ifrån talet 1, vilket är mycket vanligt i C++ programmering, så kan man använda de speciella operatorerna ++ och --. Vi kan till exempel öka värdet i iAntalCyklisterTorsdagEftermiddagStorgatan med 1 genom att skriva antingen:
iAntalCyklisterTorsdagEftermiddagStorgatan++;
…eller
++iAntalCyklisterTorsdagEftermiddagStorgatan;
I det här fallet gör det ingen skillnad huruvida ++ står före eller efter variabelnamnet, men i de fall som variabeln 'används' kommer positionen att avgöra om ökningen sker före användning eller efter. Motsvarande gäller för -- operatorn. Innan vi kan förstå vad som menas med användning behöver vi kunna mer om listor eller funktioner, så vi lämnar saken här.