• No results found

C++-programmets beståndsdelar

N/A
N/A
Protected

Academic year: 2021

Share "C++-programmets beståndsdelar"

Copied!
39
0
0

Loading.... (view fulltext now)

Full text

(1)

C++-programmets beståndsdelar

• Ett C++-program är uppdelat i headerfiler (fil.h) och implementationsfiler (fil.cpp)

• Programmet måste innehålla åtminstone funktionen int main()

main() startar programmet

(2)

C++-programmets beståndsdelar

Ett första litet C++-program

#include <iostream> // behövs för utskrifter

int main() // main är obligatorisk i C++

{

// utskrift av "Hello world!" och radbrytning std::cout << "Hello world!" << std::endl;

return 0; // avsluta programmet med värde 0 }

(3)

Byggstenar

Inbyggda datatyper Funktionsanrop,

argument och returvärden Styrstrukturer

(4)

Grundläggande datatyper

I C++ finns många inbyggda datatyper.

De flesta av dem representerar heltal:

bool – sanningsvärde, true eller false

char – oftast 8 bitar (ettor och nollor). Används ofta för att lagra bokstäver

short – oftast 16 bitar

int – oftast 32 bitar, datorns ordstorlek

long int – större eller lika med int

(5)

Övriga datatyper representerar flyttal...

float – flyttal, 16 bitar

double – flyttal med dubbel precision, dvs 32 bitar

long double – 64 bitars flyttal

...och minnesplatser:

Pekare – Håller adressen till valfri datatyp, oftast 32 bitar (för att adressera datorns hela minne), även funktioner

Grundläggande datatyper

(6)

Exempel på datatyper

bool b = true; // sanningsvariabel

int i = 85; // i tilldelas värdet 85 int j = i; // j blir 85

char a = 'x'; // a blir 120 = asciivärdet för 'x' float f = 3.1; // flyttal

double d = 3.141593; // dubbel precision

signed int k = 17; // heltal med tecken (default) unsigned char c = 4; // positivt heltal

int *q = &i; // pekare till ett heltal int *p = 0; // pekare till null

(7)

Funktioner och funktionsanrop

För att dela upp sitt program i logiska delar använder man funktioner

All kod i C++ ligger i funktioner

Vid anrop till funktionen skickar man med argument

Anrop i C++ är antingen värdeanrop (call by value) där argumentens värden kopieras eller referensanrop (mer om det senare)

Tillbaka får man ett returvärde

(8)

double maximum(double, double); // deklaration

int main() {

double d = maximum(1.7, 3.2); // anrop std::cout << "d = " << d << std::endl; // d = 3.2 return 0;

}

double maximum(double d1, double d2) // definition {

if(d1 > d2)

return d1; // returvärde else

return d2; // returvärde }

En funktion bör ha en deklaration

En funktion som används har precis en definition

Funktioner och funktionsanrop

(9)

• Funktioner kan ta ett förvalt argument (eng. default argument)

• Funktioner med samma namn och olika argument kallas överlagringar

Funktioner kan deklareras inline, vilket är ett förslag till kompilatorn att ersätta

funktionsanropet med programkod

Funktioners egenskaper

(10)

Funktioners egenskaper

int f(char c, int i = 7); // ett förvalt argument

f('a'); // anrop med förvalt arg = 7 f('a', 3); // anrop med annat arg = 3

int g(int); // g tar int int g(double); // överlagring int g(A); // överlagring

int h(double d); // deklaration

inline int h(double d) // inlinedefinition { return d; }

double x = h(3.14); // anrop till inlinefunktion double y = 3.14; // anrop ersatt mha inline

(11)

Styrstrukturer

Översikt:

i n t i = 7 ;

i f ( i ) { } e l s e { } / / i f - e l s e

i = a > b ? a : b ; / / v i l l k o r s o p e r a t o r n f o r ( i = 0 ; i < 1 7 ; i + + ) { } / / l o o p m e d f o r

w h i l e ( i ) { } / / l o o p m e d w h i l e d o { } w h i l e ( i ) ; / / l o o p m e d d o - w h i l e

s w i t c h ( i ) { / / s w i t c h - c a s e c a s e 1 : f ( ) ; b r e a k ;

c a s e 2 : g ( ) ; b r e a k ; d e f a u l t : h ( ) ; b r e a k ; }

(12)

Styrstrukturer – for

for(int i = 0; i < 10; i++) // 10 varv {

// i är synlig här }

// i är inte synlig här

const int size = 100;

int j;

for(j = 0; j < size; j++) // 100 varv std::cout << "varv " << j << std::endl;

(13)

Styrstrukturer – while

int i = 0;

while(i < 100) // 100 varv {

std::cout << "varv " << i << std::endl;

i++;

}

(14)

Styrstrukturer – do while

bool done = false;

do {

done = do_something();

/* ... */

} while(!done);

(15)

Styrstrukturer – switch case

/ / s k r i v u t m e n y

s t d : : c o u t < < " 1 . Ö p p n a " < < s t d : : e n d l ; s t d : : c o u t < < " 2 . S p a r a " < < s t d : : e n d l ; s t d : : c o u t < < " 3 . A v s l u t a " < < s t d : : e n d l ;

/ / h ä m t a t a l f r å n t a n g e n t b o r d e t i n t v a l u e ;

s t d : : c i n > > v a l u e ;

s w i t c h ( v a l u e ) {

c a s e 1 : o p e n ( ) ; b r e a k ; c a s e 2 : s a v e ( ) ; b r e a k ; c a s e 3 : q u i t ( ) ; b r e a k ;

d e f a u l t : s t d : : c o u t < < " o g i l t i g i n m a t n i n g " < < s t d : : e n d l ; }

(16)

Sammansatta datatyper

Vektorer Strukturer

Klasser Unioner

(17)

Sammansatta datatyper

Man kan skapa vektorer av en given datatyp

int a[7]; // alla element oinitierade int b[] = {1, 2, 3}; // b har 3 element

int c[2] = {7, 8};

char r[] = {'b', 'a', 'r', '\0'}; // '\0' har värdet 0 char t[4] = "bar"; // "bar" är en sträng

char s[] = "bar"; // s har 4 element pga '\0'

Förklaring av strängar

(18)

Sammansatta datatyper

Det finns inga inbyggda strängar i C/C++

(C++:s standardbibliotek innehåller dock en strängklass, std::string)

• Strängar i C/C++ representeras av en

vektor av char, avslutad med bokstaven

’\0’ (nolla) som har värdet noll och kallas NUL.

• Vill man använda en sträng läser man

vektorn tills man stöter på bokstaven ’\0’.

(19)

Indexoperatorn

Åtkomst i vektorer sker genom att använda []-operatorn.

Elementen i en vektor är indexerade från noll.

i n t c [ 2 ] = { 7 , 8 } ;

s t d : : c o u t < < " c [ 0 ] = " < < c [ 0 ] < < s t d : : e n d l ; / / c [ 0 ] ä r 7 s t d : : c o u t < < " c [ 1 ] = " < < c [ 1 ] < < s t d : : e n d l ; / / c [ 1 ] ä r 8 c [ 0 ] = 5 ; / / c [ 0 ] ä r 5

/ / e x e m p e l p å l ä s n i n g a v e n s t r ä n g c h a r s t r [ 4 ] = " f o o " ;

i n t i = 0 ;

w h i l e ( s t r [ i ] ! = ' \ 0 ' ) / / l o o p a t i l l s s t r ä r s l u t {

s t d : : c o u t < < s t r [ i ] ; / / s k r i v u t v ä r d e t i + + ; / / ö k a v ä r d e t p å i }

(20)

class - en kort introduktion

För att kapsla in data tillsammans med funktioner använder man datatypen class

Åtkomsttypen avgör vem som kan se in i instanser av klassen.

class Foo {

int i; // åtkomst private är default

public:

int j; // alla kommer åt j

int fnc(double d) // funktion fnc som tar double och

{ // lägger till ett

return d + 1;

}

private:

int k; // endast medlemsfunktioner når k

};

(21)

Struct - en variant av class

struct Bar { int i; long j; };

Bar a = {7, 4711}; // lista av initierare

Bar b; // medlemmarna oinitierade b.i = 7; // tilldelning

b.j = 4711;

Den enda skillnaden mellan class och

struct är att åtkomsttypen är private i class och public i struct.

(22)

Uppräkningar

Typen enum gör uppräkninar mer läsbara

enum weekday {Mon, Tue, Wed, Thu, Fri, Sat, Sun, count};

enum wingdings {foo = 11, bar = 3, baz};

weekday today = Mon;

std::cout << "Today is day number "

<< today + 1 << std::endl;

std::cout << "There are " << count

<< " days of the week" << std::endl;

std::cout << "bar = " << bar << ", "

<< "baz = " << baz << std::endl;

(23)

Utdata blir

Today is day number 1

There are 7 days of the week bar = 3, baz = 4

Uppräkningar

(24)

Pekare, minne och referenser

Pekararitmetik Vektorer

Referenser Ekvivalens

Statiskt och globalt minne Dynamiskt minne

(25)

Pekare

En pekare är en adress till en plats i minnet

Alla variabler och funktioner i ett program har en adress och kan pekas på

Pekare ger upphov till många fel, och dessa kan vara svåra att finna

int i = 7; // i är 7

int *ip = 0; // pekare till en int

ip = &i; // ip innehåller adressen till i *ip = 8; // avreferera pekaren och tilldela // i är nu 8

(26)

Pekare

char c;

char *s = "foobar";

char *t;

c = s[3]; // c är nu 'b' t = s; // t pekar på 'f' t = &s[0]; // t pekar på 'f' t = &s[4]; // t pekar på 'a'

Ytterligare exempel på pekare

(27)

Exempel på när det kan gå fel med pekare

char *s = name();

std::cout << "my name is " << s // skriver ut skräp << std::endl;

char *name() {

char *str = "alice"; // fel: lokalt minne är return s; // ogiltig då funktionen returnerat }

Pekare

(28)

Pekare, vektorer och minne

En vektor konverteras till en pekare vid användning

Man kan addera en pekare med ett heltal, s.k.

pekararitmetik

Man kan subtrahera pekare (avstånd) men inte addera

(29)

Pekare, vektorer och minne

int a[] = {0, 1, 2, 3, 4};

int *p;

int j;

p = a + 1; // p pekar på 1 j = a[2]; // j är 2

j = p[2]; // j är 3

*(a+1) = 5; // a är {0,5,2,3,4}

Exempel på hur pekare och vektorer opererar på datorns minne

(30)

Objekt tar upp olika storlek i minnet.

Pekararitmetik använder storleken för att bestämma avstånd mellan pekare

Pekare, vektorer och minne

int a[] = {0, 1, 2, 3, 4};

int j;

j = sizeof a[2]; // j är 4 j = sizeof(int); // j är 4 j = sizeof a; // j är 20

int *p = a + 1; // stegar 1 vektorposition = 4 bytes

(31)

Minneshantering

Lokala objekt allokeras på stacken och har kort livslängd

• Objekt med längre livslängd måste

allokeras dynamiskt på heapen (free store)

Dynamisk allokering görs med new och delete

• Statiska och globala objekt finns under programmets hela körtid

(32)

Minneshantering

void foo() {

A a; // a allokerad på stacken A *ap = new A; // dynamiskt allokerad A *aa = new A[5]; // vektor med 5 A-objekt delete ap; // frigör allokerat minne

delete aa; // fel: odefinierat beteende!

delete [] aa; // ok: destruktor för 5 element } /* vid funktionens slut frigörs a automatiskt */

Minne (objekt) som allokerats med new ska deallokeras med delete

Minne (vektorer av objekt) som allokerats med new[] ska deallokeras med delete[]

(33)

Minneshantering

• C++ har ingen automatrisk

minneshantering (garbage collection)

• Alla dynamiska objekt som inte lämnas tillbaka läcker minne

• Speciellt viktigt är det att hålla ordning på minnet i objekt som skapas och destrueras ofta som t.ex. strängar.

(34)

Undvik vanliga problem

• Undvik pekare!

– Det är lätt att referera otillåtet minne (t.ex.

genom att avreferera NULL)

– Det är lätt att referera ogiltigt minne (redan frigjort med delete)

• Skapa istället objekt på stacken

• Använd referenser! Dessa är garanterade att alltid referera ett giltigt objekt

(35)

Byggstenar

Typdefinitioner Styrstrukturer

Operatorer Preprocessorn

(36)

Operatorer

Operatorerna i C++ har olika prioritetsordning (precedence) och associativitet:

Logiska operatorer

&& ||

Villkorsoperatorn

?:

Tilldelning

+= -= &= ~= <<= etc.

Kommaoperatorn ,

Funktionsanrop m.m.

() [] :: -> . ->* .*

Unära operatorer

! ~ ++ -- + - * &

Aritmetiska operatorer + - * / %

Jämförelseoperatorer

< <= >= > == !=

Bitvisa operatorer

& ^ | ~ << >>

(37)

Preprocessorn

• Körs innan programmet ses av kompilatorn

• Används för att inkludera/exkludera källkod

• Kan användas för att definiera konstanter och makron

• C++ har många tekniker för att undvika

preprocessorn, såsom inline, template och const

(38)

Preprocessorn

#include <iostream> // inkluderar filen iostream #include "myfile.h" // letar i lokal katalog först

#ifdef MSDOS // inkludera endast om MSDOS-miljö #include <conio.h>

#endif

(39)

Preprocessorn

Exempel på konstanter och makron:

#ifndef MYFILE_H // kontrollera så att filen #define MYFILE_H // inte inkluderas 2 ggr

#define PI 3.14159265 // konstant

#define max(x, y) ((x) > (y) ? (x) : (y)) // makro #if 0 // kompileras inte

std::cout << "You won't see this one" << std::endl;

#endif

#endif // matchar #ifndef MYFILE_H

References

Related documents

En konsument som fått ett beslut om avslag (eller uppsägning, se 9 §) ska således enligt vad som framkommit kunna vända sig till följande instanser för att klaga eller

Om ett program, till exempel Internet Explorer, redan körs håller du Skift-tangenten nedtryckt när du klickar på programikonen.. Då öppnas näm- ligen ett nytt fönster, så att

Att se publiken och inte bara artisterna som utövare av rapbattles och roastbattles kommer vara genomgående och viktigt för uppsatsen.. Bakgrunden för artisterna Anton Magnusson

Här fi nns hjälp om det är problem med hem- gruppen, till exempel om del- ningen mellan olika datorer i gruppen inte fungerar. Nätverkskort

Om det av ditt registreringsbevis för firman som du fått från Skatteverket framgår att du ska använda den s k faktureringsmetoden vid din bokföring, måste du byta

• Konstruktor som är private ger möjlighet att förhindra användandet av t.ex. med delete eller då det hamnar utom räckvidd) anropas

Vi är egentligen bara intresserade av att skicka information (ett eller flera värden) till en funktion som gör vissa beräkningar med hjälp av dessa värden och sen returnerar ett

Det innebär alltså att fältet själv inte kommer kopieras över till ett nytt fält som hör till funktionen (det som kallas värdeanrop, se tidigare), utan bara minnesadressen till