int (*fp) (char, char*) //pekare till funktion som tar //argumenten (char, char*) och //returnerar int

Relevanta dokument
Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

Minnestilldelning (allokering) och frigörande (avallokering) av minne

Det finns många flaggor till g++,

TDIU01 - Programmering i C++, grundkurs

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

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

Kapitel 6 - Undantag

TDDC76 - Programmering och Datastrukturer

TDIU01 - Programmering i C++, grundkurs

Innehåll. Pekare Exempel

TDIU01 - Programmering i C++, grundkurs

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

grundläggande C++, funktioner m.m.

Innehåll. Pekare Syntax

Innehåll. Pekare Exempel

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Funktionens deklaration

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Klassdeklaration. Metoddeklaration. Parameteröverföring

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

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << "Hello World\n"; return 0; } C++, Övning 1

Första exemplet. Kompilator & länkare. Projekt. Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, Ronnie Johansson,

Föreläsning 2, vecka 8: Repetition

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

TENTAMEN CD5250. Objektorienterad programutveckling med C++, 5p. Datum: , Tid: 14:00-19:00

Övning från förra gången: readword

Föreläsning 6: Metoder och fält (arrays)

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

C++-programmets beståndsdelar

Tommy Färnqvist, IDA, Linköpings universitet

TDDC76 - Programmering och Datastrukturer

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper

Ulf Assarsson. Grundläggande C-programmering del 2 Pekare och Arrayer. Läromoment:

C++ Objektorientering - Klasser. Eric Elfving

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

Programmeringsteknik med C och Matlab

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

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Classes och Interfaces, Objects och References, Initialization

Att använda pekare i. C-kod

Pekare och arrayer. Indexering och avreferering

Dynamiskt minne. Vad är dynamiskt minne Motivering Hur gör man i C Övningar

Enkla datatyper minne

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

TDIU01 Programmering i C++

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

Tillämpad programmering

TDDC76 - Programmering och Datastrukturer

Programsystemkonstruktion med C++: Övning 1. Karl Palmskog september 2010

Kapitel 1. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Kapitel 1 grunderna i C++

Föreläsning 8 Programmeringsteknik och Matlab 2D1312/2D1305. Klass Object, instans av klass public/private Klassvariabler och klassmetoder

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Programmering A. Johan Eliasson

Programsystemkonstruktion med C++

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

TDDC76 - Programmering och Datastrukturer

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

Hantering av textsträngar och talsträngar. William Sandqvist

Synlighet. Namespace Scope-operatorn Klasser Vänner

Föreläsning 11. Arrayer. Arrayer. Arrayer. Lagrar flera värden av samma typ Kan vara primitiva typer eller objekt. Kan ha en array av t.

Programmering i C++ EDA623 Typer. EDA623 (Föreläsning 4) HT / 33

Kapitel 3. Synlighet. Kapitel 3 - Klassanvändning, operatorer och pekare. Synlighet

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

Objekt och klasser - Introduktion

Tentamen EDAF30 Programmering i C++

Objektorienterad programmering i Java

*Pekarvärden *Pekarvariabler & *

KLASSER. Inkapsling Abstrakt datatyp Public och private. Klassmedlemmar Datamedlemmar Exempel Funktionsmedlemmar

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt:

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

En klass behöver både deklaration och definition. Daniel Aarno Globala funktioner och variabler är OK.

Klasser. Kapitel 2. Kapitel 2 - Klasser, medlemmar och arv. Klasser. Klasser Medlemmar Arv

1 Funktioner och procedurell abstraktion

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT / 33

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Tentamen OOP

Föreläsning 3-4 Innehåll

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv

Kapitel 6. Hakparenteser fšr att ange index MŒnga všrden av samma typ

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

Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( )

TDDC77 Objektorienterad Programmering

Pekare. Pekare. Varför använder vi pekare? Vad är en pekare? Pekare. Deklaration/initiering av pekare

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

1 Namnkontroll (NameControl)

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

C++ Objektorientering - Klasser. Eric Elfving Institutionen för datavetenskap

Typkonvertering. Java versus C

Föreläsning 5-6 Innehåll

Transkript:

Pekare char v[10]; //array med 10 characters char* p; //pekare till characters //p pekar på v's fjärde element p = &v[3] p & är "adressen-av" operatorn. För de flesta typer T gäller att T* är typpekare. En variabel av typen T* kan alltså hålla adressen till ett objekt av typen T. int* pi; char** cpp; //pekare till pekare av char int (*vp)[10] //pekare till en array av 10 heltal int (*fp) (char, char*) //pekare till funktion som tar //argumenten (char, char*) och //returnerar int Fundamental operation på en pekare - avreferering (dereferencing), innebär att man refererar till objektet som pekaren pekar på. char c1 = 'a'; char* p = &c1; char c2 = *p; //avreferering int* k; *k = 4; //ej tillåtet, //inget minnesutrymme int j = 4; //skapa minne int* k = &j; //adressen av j *k = 2; //OK, ändrat på j int* k, j = 5; k = &j; cout << k << " " << *k;//ok //ok void* ptr; //pekare till okänd typ //kräver kastning

Funktionspekare När väl en funktion är kompilerad och laddad i minnet för att exekveras har den en minnes plats. Minnet och även funktionen, har en adress. Precis som man kan använda pekare till variabler kan man använda dem till funktioner. Man definierar ex. en funktionspekare enligt följande: void (*funcptr)(); Variabeln funcptr är en pekare (*), som kan peka på funktioner (), som tar noll argument, och som returnerar void. void *funcptr(); //Ingen funktionspekare, //funktion som returnerar void* //bör skrivas void* funcptr(); // Komplicerade definitions.cpp /* 1. */ int * (*(*fp1)(int))[10]; /* 2. */ float (*(*fp2)(int,int,float))(int); /* 3. */ typedef double (*(*(*fp3)())[10])(); fp3 a; /* 4. */ int (*(*f4())[10])(); #1: fp1 är en pekare till en funktion som tar ett heltalsargument och returnerar en pekare till en array av 10 intpekare. #2: fp2 är en pekare till en funktion som tar tre argument (int, int, and float) och returnerar en pekare till en funktion som tar ett heltalsargument och som i sin tur returnerar ett flyttal. #3: Om man skapar komplicerade definitioner, så kan man använda typedef. Fp3 är en pekare till en funktion tar noll argument och returnerar en pekare till en array med 10 pekare till funktioner som tar noll argument och returnerar double. A är en fp3 typ. #4: Detta är en funktionsdeklaration, inte en funktionspekare. F4 är en funktion som returnerar en pekare till en array med 10 stycken pekare till funktioner som returnerar heltal.

Använda en funktionspekare När man väl har definierat en funktionspekare ska man tilldela den en funktionsadress innan man kan använda den. Precis som adressen till en array arr[10] är namnet utan hårdparenteserna arr, så är adressen till en funktion func() funktionsnamnet utan argumenten, (func). void func() { cout << "func() called..." << endl; void main() { void (*fp)(); // Define a function pointer fp = func; // Initialize it (*fp)(); // Dereferencing calls the function void (*fp2)() = func; // Define and initialize (*fp2)(); Array av pekare till funtioner Möjligt att skapa arrayer av funktionspekare. Anrop till en funktion i arrayen - indexera arrayen och avreferera pekaren. Koncept stödjer 'tabelldriven kod'; istället för att använda sig av villkor och case statements, väljer man funktionen som ska exekvera utifrån indexvariabeln. Designen är användbar då man ofta tar bort och lägger till funktioner från tabellen. Ex: Körschema Varje funktion utför specifika operationer Funktionspekare lagras i en array Ändras körschemat => ändra funktionspekarna Följande exempel skapar en 'dummy' funktion genom ett preprocessor macro.

#include <iostream> // A macro to define dummy functions: #define DF(N) void N(int i) { \ cout << "function " #N " called...with argument " << i << endl; DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); // { a, b, c, d, e, f, g = function address void (*func_table[])(int) = { a, b, c, d, e, f, g ; int main() { int num = 0; while(1) { num++; cout << "press a key from 'a' to 'g' " "or q to quit" << endl; char c, cr; cin.get(c); cin.get(cr); // second one for return if ( c == 'q' ) break; //... out of while(1) if ( c < 'a' c > 'g' ) continue; (*func_table[c - 'a'])(num); a(1); b(2); New och delete New new operatorn används för att skapa nya objekt dynamiskt. Anropar aktuell konstruktor i objektet. New operatorn returnerar en pekare till det nyskapade objektet. Typ* a = new Typ; Typ* a = new Typ[5]; Livstiden av ett objekt skapat med new är inte bundet till det scope { det skapas i. När objektet är en array kommer en pekare till första elementet att returneras. Ex: Både new int och new int[10] returnerar en int*.

New operatorn kommer att anropa funktionen ::operator new() för att allokera minne. Ett första argument sizeof(t) kommer skickas med när man allokerar minne för ett objekt av typen T. Om operator new() misslyckas kommer den att returnera 0 och ett undantag kastas (bad_alloc). Ex: new T resulterar i ett anrop till ::operator new(sizeof(t)) Ett objekt kan skapas med new endast om klassen har en konstruktor. Inga initialiserare kan specificeras för en array. Implicerar att en array av objekt endast kan skapas om det finns en defaultkonstruktor. Då kommer defaultkonstruktorn att anropas för varje element i arrayen. Initialisering sker endast om new returnerar icke noll. Ett exempel av allokering av en array new (int (*[10]) () ); Allokerar en array av 10 stycken pekare till funktioner som inte tar några argument och returnerar int Delete Delete operatorn frigör ett objekt skapat av new operatorn. delete objektpekarvariabel; Resultatet är av typen void. Operanden (objekt-variabel) måste vara en pekare returnerad av new. Resultatet av att applicera delete på en pekare som inte härstammar från new är odefinierat (programmet kan krascha). Att ta delete på en pekare med värdet null är däremot OK. Att accessa ett borttaget objekt är odefinierat. Ett anrop till delete kommer anropa destruktorn för objektet som pekaren avser. Ett delete-anrop leder till att funktionen ::operator delete() anropas. För ett objekt av klassen T kommer T::operator delete() anropas i första hand, annars kommer den globala ::operator delete() anropas. Att använda ::delete försäkrar att den globala versionen av ::operator delete() anropas även om T::operator delete() existerar. Ex: delete [] objekt-varibel;

Används för att ta bort arrayer. Uttrycket pekar på en array och destruktorn för objekten i arrayen anropas. Att ta bort en array med enkelt delete utan [] är odefinierat så även att ta bort ett objekt med delete []. class A{ A(); ~A(); void function(){ A* a = new A; delete a; A* b = new A[10]; delete [] b; void main(){ function(); Det är möjligt att omdefiniera operatorerna new och delete för att möjliggöra en fri minneshantering. En användardefinierad operator new måste returnera en void* och måste även ha en size_t som första argument (typedef unsigned int size_t). En användardefinierad operator delete måste ha void som retur typ och void* som första argument. Ett andra argument av typen size_t är möjligt. Anger storleken på objektet som ska tas bort. Endast en operator delete() kan definieras för en klass vilket implicerar att den inte kan överlagras med olika antal argument. Size_t är definierad i stddef.h som unsigned int. Ex: #include <iostream.h> #include <new.h> class myclass{ public: void* myclass::operator new(size_t size) {cout << "new " << size << endl; return new char[size]; void myclass::operator delete(void* p, size_t size) { if(p) delete[] p; cout << "delete " << size << endl;

void* myclass::operator new[](size_t size) {cout << "new[] " << size << endl; return new char[size]; void myclass::operator delete[](void* p, size_t size) {if(p) delete[] p; cout << "delete[] " << size << endl; ; void f(){ myclass* m = new myclass; delete m; myclass* n = new myclass[4]; delete[] n; int main(){ f(); return 0; Const Const - "minnesplats som inte kan ändras". Const kan tillsynes vara en efterföljare till preprocessor direktivet #define. Men det har fått en rad fler användningsområden för pekare, funktioner, klassfunktioner. Const - värden Const kan användas på alla inbyggda typer och deras invarianter. Det rekommenderas att använda const före #define. #define BUFFERSIZE 100 const int BUFFERSIZE = 100; Initierar man en variabel en gång i sitt program och den inte ändras bör man ändra den till en const, vilket också innebär att man inte av misstag ändrar värdet på den => säkerhet. /*#define NUMBER 32 not used in C++*/ const int MyNumber = 32; void main(){ const int a = MyNumber; a = 3; //error: cannot modify constant object int *b = &MyNumber

//error: different types const int *c = &MyNumber; //fine! Const - pekare Två sätt att använda const tillsammans med pekare: Ex: appliceras på det pekaren pekar på eller adressen i pekaren. void main(){ const char *str_1 = "AAAA!!!!!!!!"; //ERROR: cannot modify string str_1[1] = 'a'; //fine str_1 = "OOOOOOOOOOOO"; char* const str_2 = "BBBBB!!!!!!"; //fine str_2[1] = 'a'; //ERROR: cannot modify pointer str_2 = "OOOOOOOOOOOO"; //everything protected: string & pointer const char* const str = "Hello"; char const* const str = "Hello"; int x = 5; int* const d = &x; int* const e = &x; //ERROR: cannot modify constant object d = e; //fine, pointer const, not value *d = 8; Const - funktioner (argument / returtyper) Det är möjligt att specificera konstanta argument till en funktion och även konstanta returtyper från funktionen. Om man skickar en parameter by-value kommer specifikationen med const, ur ett perspektiv, vara överflödig (Lokala variabler).

Om man returnerar en användardefinierad typ by-value som en const, innebär det att returvärdet inte kan ändras. Om man skickar och returnerar som alias kommer const förebygga att innehållet i aliaset inte förändras. void func(const int& i){ i++; //ERROR Konstanta returtyper från en funktion. const int func(); Här sker en försäkran om att returvärdet inte kan ändras. // Returning consts by value // has no meaning for built-in types int f3() { return 1; const int f4() { return 1; int main() { const int j = f3(); // Works fine int k = f4(); // But this works fine too! När man skickar och returnerar referenser och pekare spelar const en större roll. // Constant pointer arg/return void t(int*) { void u(const int* cip) { //! *cip = 2; // Illegal -- modifies value int i = *cip; // OK -- copies value //! int* ip2 = cip; // Illegal: non-const const char* v() { // Returns address of static character array: return "result of function v()"; const int* const w() {

static int i; return &i; //valid after the function returns only because it is static. int main() { int x = 0; int* ip = &x; const int* cip = &x; t(ip); // OK //! t(cip); // Not OK u(ip); // OK u(cip); // Also OK //! char* cp = v(); // Not OK const char* ccp = v(); // OK //! int* ip2 = w(); // Not OK const int* const ccip = w(); // OK const int* cip2 = w(); // OK //! *w() = 1; // Not OK Const - klasser Skydda förändring av medlemmar i en klassfunktion: #include <iostream> #include <conio> class A{ private: int aa, bb, cc; public: A(int a, int b,int c); A(int a = 2){A::aa = a; cout << A::aa;; int a() const; ; int A::a() const { //aa = 1;//error cannot modify const object ((A*)(this))->aa = 1; //works, but it s not a good way to do it return aa; void main(){ A* abba = new A(); cout << abba->a() << endl; A* baab = new A(4); cout << baab->a() << endl; delete abba;

delete baab; getch(); Extern Extern talar om för kompilatorn att en variabel eller funktion existerar även om inte den har upptäckt variabeln tidigare i filen. Variabeln eller funktionen kan definieras i en annan fil (.cpp) eller längre ned i samma fil. Ex: // This is not actually external, but the // compiler must be told it exists somewhere: extern int i; extern void func(); int main() { i = 0; func(); // The data definition int i; // The function definition void func() { i++; cout << i; När kompilatorn påträffar deklarationen av extern int i - definition av i existerar någonstans som en global variabel. När kompilatorn når definitionen av i mappas i mot deklarationen med extern. Volatile Data som kan ändras utanför processens vetskap, genom trådar, interupt etc. - ska deklareras som volatile. En volatile variabel avläses varje gång den används även om den användes raden innan. Om man har deklarerat en volatile variabel som modifieras av en tråd eller annan process, förhindrar man kompilatorn att av effektivitetsskäl ta bort multipla läsningar av variabeln. En vanlig variabel som avläses behöver nödvändigtvis inte läsas från minnet varje gång den används. Samma syntax som för const objekt.

Att skapa ett const volatile objekt - kan inte ändras av programmet utan istället förändras av utomstående processer. #include <iostream> #include <conio> //Class to represent a piece of communication hardware class Comm { const volatile unsigned char byte; volatile unsigned char flag; enum { bufsize = 100 ; unsigned char buf[bufsize]; int index; public: Comm(); void isr() volatile; char read(int index) const; ; Comm::Comm() : byte(0), flag(0), index(0) { //interrupt service routine: void Comm::isr() volatile { cout << "isr()\n"; flag = 0; buf[index++] = byte; // Wrap to beginning of buffer: if(index >= bufsize) index = 0; char Comm::read(int index) const { cout << "read(" << index << ")\n"; if(index < 0 index >= bufsize) return 0; return buf[index]; int main() { volatile Comm port; port.isr(); // OK port.read(0); // Error, read() not volatile getch(); Likt const - kan använda volatile på objekts data medlemmar, funktioner och objekten själva. Kan endast anropa volatile-medlemsfunktioner från ett volatile-objekt.