Table of Contents
Namenskonventionen
- *.h - Header File
- *.cc - Source File
- lib*.a - Library. When including the library, the “lib” prefix is not mentioned.
- *.o - Object File. Precompiled, not executable code (no main function)
Basics
3 == pow ( pow(3,0.5) , 2 ) //bei den Berechnungen kann der linke Teil um eine winzige Zahl kleiner als 3 werden, somit wird er abgerundet und wird zu 2
=== Speicherverwaltung === C kann Speicherbereiche gezielt adressieren. Dazu wird der folgende Mechanismus benutzt: == Wichtige unäre operatoren == * ist der dereferenzeoperator. Er löst einen Pointer auf einen Objekt auf. & ist der address-of operator. Er liefert die Adresse, an welcher der Objekt in der übergebenen Variable gespeichert ist.
*Pointer = <Pointer-Ziel> //in Java ist der Punkt-Operator der äquivalent zum Stern operator. Objektname.var löst "Objektname" zu einem Objekt auf. &Variable = <Adresse des Objektes in der Variablen>
Vorweg:
Referenzen sind statische Ersatznamen für eine Objekt.
Pointer sind Objekte, die auf Speicherbereiche zeigen und mithilfe des dereferenzoperators (*) die Objekte in diesem Speicherbereich liefern koennen.
Pointer können umgehangen werden
Ein tolle Erklärung zum Thema Pointer und Referenzen:
http://www.cplusplus.com/doc/tutorial/pointers/
== Referenz==
Eine Referenz sollte man als einen Ersatznamen eines Objektes sehen.
JEDES Auftreten einer Referenz wird vor dem Anfang JEDER Operation darauf zu deren Zielobjekt aufgelöst. Deswegen sind Referenz-Objekte selbst (nicht die Objekte für die sie als Ersatznamen dienen) - nach deren Erzeugung nicht mehr greifbar.
In C sind Referenzen typisiert, genau wie variablen. (In C gibt es Referenzen nicht als Typ, nur Pointer).
Referenztypen werden aus VariablenTypeNamen mit angehängeten & erzeugt.
Eine Referenz als Ersatznamen fuer A erstellt man wie folgt:
int A int& referenzName = A;
Eine Referenz muss sofort bei der Definition und für immer initialisiert werden. Die Referenz kann nicht auf ein anderes Ziel “umgehangen” werden. Pointer können “umgehangen” werden.
int& meineReferenz ; // compiler will complain: error: `meineReferenz' declared as reference but not initialized
Trotz des Vorkommens von '&' Zeichen und obwohl die Referenzen als Pointer implementiert sind - hat das Konzept der Referenz nichts mit dem Speicher zu tun. Deswegen wird der Referenz bei der Initialisierung - das Objekt selbst zugewiesen und nicht etwa dessen Adress im Speicher.
int var = 2; int& meineReferenz = var;
Der Typ der Referenz in der Objekorientierten Welt wird durch das anfügen des & zeichen RECHTS an dem Variablentyp gebildet.
typeof ( meineReferenz ) // int&
Pointer
Einen Pointer sollte man wie ein Objekt betrachten, welches auf eine Adresse zeigt, genau wie Referenzen. Ein Pointer ist nur eine Möglichkeit die im Speicher abgelegte Variable anders zu benennen. Im gegensatz zu den Referenzen können Pointer:
- Können Pointer auf ein anderes Ziel “umgehangen werden” - Referenzen werden bei deren erstellung ein für alle mal initialisiert. Somit sind referenzen - statische Pointer
- Ein Pointer kann NULL sein. Referenzen sind sicherer, sie können nur ungültig werden, wenn der Speicherbereich auf den sie zeigen - ausserhalb der Reichweite oder fotmariert ist.
- Man kann die Adresse des Pointer-objektes rausfinden. Der-Referenz Objekt ist als Objekt nicht greifbar, er gibt bei jeder Erwähnung sein Ziel-Objekt aus.
- There's no “reference arithmetics” (but you can take the address of an object pointed by a reference and do pointer arithmetics on it as in &obj + 5).
Ein Pointer auf eine Variable sieht wie folgt aus:
*pointerName
Initialisierung des Pointers sieht so aus:
int * number; char * character; float * greatnumber;
Pointer werden zusammen mit dem “adress-of” Operator benutzt. Vor der Pointerdefinition muss der TypName der Variablen stehen, auf dessen Speicher der Pointer später zeigen soll. zB bei Integer siehts so aus:
double varA = 2; double varB = 3; double* pointerName; //neuer Pointer auf int Variablen namens "pointerName" definiert pointername = &varA; //der Pointer "ponterName" zeigt nun auf die Adresse der Variablen. Er kann, zusammen mit dem Dereferenzoperator den Inhalt von varA liefern echo (*pointername); //liefert 2 echo (pointername); //liefert die MEMORY-ADRESSE der Variablen varA. Die Adresse ist ein int Wert.
Der Typ des Pointers in der Objekorientierten Welt wird durch das anfügen des Sterns RECHTS an dem Variablentyp gebildet:
typeof ( *pointerName ) // double* typeof ( pointerName ) // int
Es ist möglich einen Pointer mit einem unbestimmten Typ zu erstellen, indem man void* als typ nimmt. bei solchen Zeigern hat der Kompiler aber keine Ahnung, was fuer eine Information im Speicher liegt. Sie muss gecastet werden.
int a = 22222222; void* test = &a; // compiler doesn't know, that test points to int int* b = reinterpret_cast<int*>(test); // reinterpret the pointer test as pointer to int std::cout << *b << endl; // gives 22222222
Entsorgung des Pointers
Weil mehrere Pointer auf eine Adresse zeigen können wird nach dem “Umhängen des Pointers” auf andere Adresse der Speicher nicht freigegeben. Es muss explizit gemacht werden durch
delete pointerName
Struct
Ein struct ist eine möglichkeit mehrere Variablen in einem Objekt zu kapseln.
Gekapselte Variablen dürfen nicht initiiert worden sein.
struct Computer{ int ram; int mhz; int terrabyte; }
Typedef can be used, to define a struct as a new encapsulation object.
typedef struct{ int x; int y; } Point; //after that you can use a Point construct. Point a; a.x = x; a.y = y; return a;
Union
Wie struct, nur teilen sich die, im union definierten variablen, den Speicherplatz.
Arrays
Operatoren können überladen werden. Das heisst den Operatoren kann man beibringen, wie man mit neuen Objekttypen umgeht.
Es können keine neuen Operatoren definiert werden wie z.B. ein Exponential-Operator “\*\*” oder ähnliches.
//so wird ein operator X überladen an dem k Zahlen beteiligt sind RückgabeTyp operatorX(Def1, Def2, ..., Defk){} //so wird ein operator + überladen fuer den eigens definierten Typ namens "complex" complex operator+(complex& lhs, complex& rhs) { complex Tmp; ... return Tmp; }
Makefile
Makefiles ermöglichen die Automatisierung des Kompillier-Prozesses von mehreren Dateien inkl. der Auflösung von Abhängigkeiten.
In Makefiles definiert man Blockweise Dateien und Abhängigkeit ( Bibliotheken, Header Dateien ).
Zusätzlich werden die Befehle aufgeführt, die ausgeführt werden sollen, um die Abhängigkeiten aufzulösen.
Syntax:
//Makros makro1 = . makro2 = $(makro1)/code makro3 = $(makro1)/sources makro4 = $(makro1)/include makro5 = $(makro1)/routines makro6 = $(makro1)/lib MAKRO_BINFILES = $(makro3)/ObjectFile.o MAKRO_LIBFILES = $(makro3)/Y1.o $(makro3)/Y2.o $(makro3)/Y3.o C++ = /usr/local/bin/gcc MAKRO_BIND = $(C++) $(LIBDIRS) //block1 $(makro1)/BinaryZiel : $(MAKRO_BINFILES) $makro2/dependecy1.a $(MAKRO_BIND) -o $@ $(MAKRO_BINFILES) $(MAKRO_LIBFILES) //block2 $(makro2)/dependecy1: $(MAKRO_LIBFILES) ....
Das Makro $@ gibt das aktuelle Ziel aus.
Das Makro $? gibt alle Abhängigkeiten des aktuellen Blockes aus, dessen Zeitstempel aelter als das Zeitstempel des Zeils ist.
Casting
Summary
Eine Liste der wichtigen Momente, um Referenzen und Pointer zu verstehen:
- Referenzen haben einen festen Typ, abhängig davon was sie referenzieren. Der Referenztyp wird gebildet als
'ZielObjektTyp'+'&' int& float& double&
- Trotz des Vorkommens vom '&' Zeichen im Typ der Referenzen sind Referenzen - Ersatznamen für Objekte. Deswegen werden Objekte den Referenzen zugewiesen und nicht etwa die Adressen der Objekte. Der unäre “adress-of” Operator hat nichts mit den Referenzen zu tun.
- Pointer haben einen festen Typ, abhängig davon was sie referenzieren. Der Referenztyp wird gebildet als
'ZielObjektTyp'+'*' int* float* double*
- Pointer selbst speichern Adressen, die mit dem “adress-of” Operator (&) vor der Objekt-Variablen abgefragt werden kann
int* p; p = &var
- Pointer können mit dem unären Dereferenzoperator '*' aufgelöst werden. Mit einem '*' vor der Pointer-Variablen wird der Inhalt an der Adresse, die im Pointer gespeichert ist, abgefragt.
int var = 2 int* p; p = &var echo (*p) \\2
- Referenzen sind für immer, können nicht auf andere Objekte “umgehangen” werden
- Pointer können “umgehangen” werden
- Pointer müssen manuell entsorgt werden durch “delete PointerName”
Konzept | Bezeichnung | Erklärung | Initiierung |
---|---|---|---|
TYPE& refName = varName | Referenz | Ist ein alias für eine Variable. Wird einmal und fuer immer initiiert. | Wird mit Variablennamen initiiert, weil Referenz immer genau dasselbe bedeutet, wie dessen Ziel. Zusaetzlich ist eine explizite Referenz als Methodenparameter - die einzige Möglichkeit etwas “by reference” zu übergeben |
&varName | Adress-off Operator | wenn man & vor einem variablennamen setzt - dann gibt der Ausdruck die Adresse der Variablen im Speicher zurück | |
TYPE* pointerName | Pointer | Ist ein pointer auf die Adresse der Variablen | Wird mit der Adresse der Variablen initiiert. |
*pointerName | Dereferenz Operator | wenn man * vor einem Pointernamen setzt - dann gibt der Ausdruck den Wert der Variablen zurueck, die im Speicher an der Stelle liegt, auf welche der Pointer zeigt. |
- Everything is passed by value, even the objects (Except when passing by reference is explicitely used)
//objects are passed by value on default (not like in java) void swapObj(MyNamespace::MyClass a, MyNamespace::MyClass b); //explicitely passing by reference void swapRefObj(MyNamespace::MyClass& a, MyNamespace::MyClass& b);
- The functions can not be overloaded by references. References are allways replaced by their aim, so such an overload is ambigous
- The function, which needs a reference can be started with a normal value instead of the reference, because there is no diffrerence between reference and their aim.
- The operator new is not used, like in java. Using new returns a pointer to a new object.
MyType var = MyType(); //no new used. Instance of the object returned. MyType* pvar = new MyType(); //A pointer to a new instance returned, because new was used.