Ein Zeiger ist eine Variable, die die Speicheradresse (des RAMs) einer anderen Variablen enthält.
int i = 100; int* pi = &i; cout << pi; //Speicheradresse: z.B. 0x000026
Dereferenzieren von Zeigern: *Operator
- auf den Wert zugreifen, auf den ein Zeiger(Pointer) zeigt
int i = 100; int* pi = &i; cout << *pi; //100 cout << pi; //Speicheradresse: z.B. 0x000026
void Zeiger
- Zeiger auf unbekannten Typ -> dynamisch
- muss gecastet werden bei Zugriff
int i=10; void* pi; pi=&i; cout << *(int*) pi;
NULL-Zeiger
- Speicher freigeben des Pointers, z.B. um Zombie Zeiger zu vermeiden, die auf nicht mehr existierende Objekte zeigen
int i = 100; int* pi = &i; pi = NULL;
Zeiger auf Konstanten
- müssen auch const sein, damit nicht änderbar
const int i = 100; const int* pi = &i;
Zeiger auf Funktionen
int f(float a){return 1;}; int (*pf)(float) = &f; int x = (*pf)(1,5);
Zeiger bei Funktionen
Call by Value
- Funktionswerte werden kopiert, Übergabeparameter werden nicht dauerhaft geändert nur innerhalb der Funktion
- um Werte ändern zu können müssen Referenzen übergeben werden (Call by Reference)
Bsp. char* strcpy(char* dest, const char* src));
Call By Reference
- Parameter wird in der Funktion verändert dauerhaft
- kein Kopieren der Parameter auf Stack
- wenn Referenzen nicht verändert werden sollen, const setzen
Bsp. void f(int& a, const int& b);
Dynamische Speicher Allokation
- Speicherreservierung zur Laufzeit, wenn der Speicherbedarf vorher unbekannt ist, z.B. bei Erzeugung von dynamischen Arrays mit unbekannter Länge
malloc()
- liefert Zeiger auf void zurück, muss gecastet werden
- Anzahl der Bytes übergeben
- ohne Initialisierung vorher
char* s = (char*)malloc(5*sizof(char)); //char mit Platz für 5 Zeichen
free()
- dynamischer Speicher sollte wieder freigegeben werden
- oder automatisch am Ende des Programms
free(s); //Speicher freigeben s = NULL; //Referent auf leeren Speicher entfernen (Zombie)
Calloc()
- initialisiert den Speicher vorher
char* s = (char*)calloc(5*sizof(char)); //char mit Platz für 5 Zeichen
Realloc()
- vergrößert/verkleinert dynamischen Speicher
char* sNew = (char*)realloc(s, 10*sizof(char)); //char mit Platz für 10 Zeichen von vorher 5
new-Operator
- komfortabel, keine Größenberechnung in Bytes
- Freigabe des Speichers mit delete[]
char* s = new char(5); delete[] s;
Wo werden die Programmbestandteile im RAM gespeichert?
- Stack: Funktionsvariablen, vergrößert/verkleinert sich automatisch bei Aufruf nächster Funktion
- Stack Pointer: nächste frei Adresse
- Heap: globale Variablen und Code, dynamisch erstellter Speicher, um diesen Speicher sollte man sich selber kümmern
Die Reihenfolge der Speicheradressen ist verschieden, abhängig von der CPU Hardware. Intel CPU Small Endian, andere Big Endian.
int i = 100; //int werden als 2 Byte dargestellt, hexadezimal: 4*1 + 6*16 = 100
Big Endian Speicherabbild:
Speicheradresse / Wert 0x2000004 / 0x64 0x2000008 / 0x00
Small Endian Speicherabbild:
Speicheradresse / Wert 0x2000004 / 0x00 0x2000008 / 0x64
Inhaltsverzeichnis:
Einführung in C++ – Vorteile, Compiler, Namespaces – Teil1
Einführung in C++ – Zeiger, Pointer,Referenzen – Teil2
Einführung in C++ – Datentypen, Casting, Klassen – Teil3
Einführung in C++ – Funktionen und Operatoren überladen (Overloading) – Teil4
Einführung in C++ – Klassen: Vererbung, Adjustment, Friends, abstrakt – Teil5