2 1 0 / ) - & 9 > ; 7 * ( ) ) En klass behöver både deklaration och definition Deklaration i h (hh) och definition i cc (cpp) Private är förvalt Student::learn() Student::Student() Student::~Student() Globala funktioner och variabler är OK main() är en global funktion Macro (inleds med #) körs av preprocessorn Daniel Aarno bishop@kthse $ # 4: 5687 34 4 E CD 4 B <?A@ : 7<= studenth #ifndef _STUDENT_ #define _STUDENT_ #include <iostream> #include <string> using std::string; class Student private: string knowledge_; public: Student(); ~Student(); void learn (string info); string speak(); ; #endif studentcc #include studenth Student::Student() knowledge_=; void Student::learn (string info) knowledge_=info; string Student::speak() return knowledge_; Kompilering och länkning Makefile Preprocessordirektiv Funktioner Funktionen main() Datatyper Minneshantering Pekare och arrayer Vanliga slarvfel Referenser Statiska variabler Kommentarer
4 ( & = 9< 7 56 1 $ 3-2 * 1 ) 0 / -$ $ )* #$ Filer kan kompileras var för sig till objektfiler (o) > g -c filecc > g -c maincc > ls fileo maino Flera objektfiler kan länkas samman till ett program (endast om main() är definerad) > g -o ex1 maino fileo > g -o ex1_debug -g -O1 maino fileo debug optimeringsnivå 1 maincc #include studenth int main() Student s; slearn(bla bla bla); cout << sspeak() << endl; return 0; För att köra programmet: > g -o ex1 maincc studentcc > /ex1 > bla bla bla D C B 9 =A > 9 = @9 > 9? = > 9 8:9; Om vi ändrar maincc räcker det att kompilera om den Men om vi ändrar i studentcc/h måste vi eventuellt kompilera om både studentcc och maincc (maincc beror på studenth) Jobbigt hålla reda på beroenden Långsamt att alltid kompilera om allt Intressanta fel om om allt som behöver kompileras inte kompileras om startkod bibliotekskod (lib*so lib*a) Källkod (cpp c h ) kompilator objektkod (o) Länkare exekverbar kod
# #include slår ihop filer innan kompilering #ifndef #define #endif garanterar att en fil bara inkluderas en gång //may be usefull #define MAX 10000 //dangerous #define SQR1(A) A*A //less dangerous #define SQR2(A) (A)*(A) #variables CC = g FLAGS = -g -I~/ckurs/student OBJ = maino studento #rules ex1: $(OBJ) $(CC) $(FLAGS) -o ex1 $(OBJ) #dont forget tab maino: maincc studenth $(CC) $(FLAGS) -c maincc studento: studenth $(CC) $(FLAGS) -c studentcc clean: rm *o ex1 - * ( ) $& En funktion Behöver inte defineras där den deklareras Behöver deklareras innan den används int foo(int x); // declaration of foo int bar(int x) 12 return foo(x); //call to foo int foo(int x) return x; //definition of foo Kan överlagras int foo(int x) //code here int foo(float x) //code here #variables CC = g FLAGS = -g -I~/ckurs/student OBJ = maino studento SRC = maincc studentcc #rules ex1: $(OBJ) $(CC) $(FLAGS) -o ex1 $(OBJ) o: cc $(CC) $(FLAGS) -c $*cc depend: makedepend $(FLAGS) $(SRC) clean: rm *o ex1 http://wwwgnuorg/manual/make3791/html_chapter/make_tochtml
* # & : 9 8 1 / /4 / 5 () $ # En funktion inline är användbart för korta funktioner som används ofta Over-head vid funktionsanrop är störst för små funktioner Inline gör att funktionsanropet ersätts med koden det innehåller vid kompileringstilfället För mycket inlining kan ge långsammare program och större filer För mycket inlining ger långsammare kompilering Kan ha argument med förvalt värde int foo(float f int x = 0); //< OK int foo(float f = 0 int x int y = 0); //< NOT OK Kan vara inline inline int sqr(int x) return x*x; 67 3 23 0 1 - Funktionen main() är speciell Kan inte heta något annat argc är antalet argument inkl programmets namn argv är en array av C-strängar med argumenten som gavs till programmet argv[0] är programmets namn (tex /usr/bin/zip eller zip) main() är en global funktion och således inte del av någon klass main() behöver inte deklareras Fördelar med funktionen sqr() Mer läsbar kod (samma anledning som macrot SQR) Ett ställe att ändra på Alla anrop till sqr funkar likadant Löser problemet med macrot SQR Det går slött att använda funktioner Argument måste kopieras och programmets exekvering måste styras om
1 0 2 & $ # Egna datatyper typedef char* charptr; enum Fruit apple banana orange ; struct int x; int y; double d; ; class int x; public: void foo(); ; union int x bool ok double d ; Testa sizeof(t); för olika typer T (int double charptr osv) maincc #include <iostream> int main(int argc char* argv[]) for(int i = 0; i < argc; i) std::cout << argv[i] << std::endl; > g maincc -o main > /main hej 12 hej 12 > (*) -/ ) (*) ) Automatiska objekt Städas automatiskt upp när scopet är slut Snabb allokering på stacken Mindre risk för slarvfel void foo(student s) //< begin scope int x; for(int i = 0; i < 5; i) //< begin scope int y = 2*i; x = 3 y; //< end scope (iy) //< end scope (xs) Inbyggda datatyper bool (true/false (1 byte)) char (1 byte) int (platformsberoende storlek = undvik) short long float (4 byte) double (8 byte) long double void (ingenting)
* & ) $ # & void foo(student *studptr) int *ptr i; //< ptr is ptr to int i is int int* x y; //< x is ptr to int y is int ptr = &i; //< ptr now holds address //< of i (eg 0xbfffff24) *ptr = 5; //< assign 5 to i x = ptr; //< x now also points to i; cout << *x << endl; //< would print 5 (*studptr)learn(``something); studptr->learn(``more); ptr = new int; //< ptr now holds adr //< of an int on the heap ptr = &y; //< error no way to access //< memory on heap anymore Dynamiska objekt Heap större än stack Arrayers längd kan bestämmas i run-time Objekt kan leva utanför scope där de skapas void foo(int nmemb) int *xptr; // Allocate array of nmemb ints xptr = new int[nmemb]; // do stuff then // delete memory allocated by new[] delete[] xptr; $ ( $# - $ # void foo(float f) char array[4711]; //< array of 4711 uninitialized chars int ary[] = 125; //< array of 3 initialized ints // same as const char str[] = jej0; char str[] = ``hej; char* ptr=0; //< char pointer to nothing const float *fptr; //< The memory pointed to by f is //< read-only float * const fcptr=f; //< The pointer f is read-only ptr = array; //< same as ptr = &array[0]; ptr[4] = x; //< set fifth element of array to x; *(ptr 4) = y; //< same thing but to y ptr = new char[512]; //< dynamicly allocated array CODE/TEXT Själva programkoden och konstanta variabler DATA Statiska (static) initialiserade variabler BSS Statiska icke initialiserade variabler STACK Automatiskt allokerade variabler vid körning Returvärden och returadresser 4kB på Linux kan växa till 2MB (default)
#$ # ( $( staticcc void foo() static int i = 5; cout << i << endl; int main() foo(); foo(); foo(); > /static 5 6 7 > void foo(int* p) delete p; int* bar() int x=1; return &x; //oops void fun() int* p1 p2; //p2 is normal int not pointer int *p3 = new int[2]; int *p4 = new int[2]; p3 = p4; //MEMORY LEAK foo(p3); //destruction of p3 (and p4) int x = p4[1]; //error (segfault if LUCKY) & Funktionskommentarer förklarar användning (h) /** * Send a signal to the task * * @param signal The signal to send (ie SIGINT) * @return true on success false on failiure */ bool sigsend(int signal); Procedurkommentarer förklarar implementationen (cc) /* getline reads one line from stdin and stores it in * the given buffer The newline is stored * The given buffer must be big enough to store the * trailing \0 (ie it must be at least one bigger * than nmax) */ void getline (char buf[] int nmax int *nread) //function implementation Som i Java Alias för ett objekt Som en pekare vars adress inte får ändras Måste referera till ett objekt (inte NULL) Snabbare skicka referens än objekt void iswap(int &i1 int &i2) int tmp = i1; i1 = i2; i2 = tmp; void main() int i = 5; int &iref = i; int *iptr = &i; iref; // i iref and // *iptr is now 6