DAP2-ProgrammierpraktikumEinführung in C++ (Teil 1)
Carsten Gutwenger11. April 200811. April 2008
Lehrstuhl 11 – Algorithm EngineeringFakultät für Informatik, TU Dortmund
Überblick
• Mein erstes C++-Programm
– Namensräume
– Ausgabe mit C++-Streams
• Compilieren und Linken
• Primitive Datentypen, Kontrollstrukturen
Carsten Gutwenger: Einführung in C++ (Teil 1) 2
• Primitive Datentypen, Kontrollstrukturen
• Zeiger und Referenzen
• Die main-Funktion und ihre Parameter
• Deklarationen und Definitionen
– Der Präprozessor
– Makefiles
Mein erstes C++-Programm
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
Carsten Gutwenger: Einführung in C++ (Teil 1) 3
return 0;
}
g++ hello.cpp –o hello
Mein erstes C++-Programm
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
Programm-Einstiegspunkt
Deklaration von Ausgabeoperationen
Carsten Gutwenger: Einführung in C++ (Teil 1) 4
return 0;
}
Namensraum std
Ausgabeoperator für StreamsStandardausgabe cout
g++ hello.cpp –o hello
Ausgabe mit Streams
• Standardausgabe (Konsole): std::cout
• Ausgabeoperator <<
– Definiert für alle Standardtypen (int, …) und C++-Strings
– Überladen für eigene Datentypen (Klassen, …) möglich
– „Verkettung“ von Ausgabeoperationen möglich
Carsten Gutwenger: Einführung in C++ (Teil 1) 5
– „Verkettung“ von Ausgabeoperationen möglich
• Beispiel:const char *str = "Wert";double x = 5/3;
std::cout << "Der " << str << " von x ist "<< x << endl;
Namensräume
• Gruppieren verwandte Symbole und verhindern Namenskonflikte
• Definition eines Namensraumes:namespace meineBib { … }
Carsten Gutwenger: Einführung in C++ (Teil 1) 6
namespace meineBib { … }
• Benutzen von Namen aus meineBib:– meineBib:: voranstellen
– alle Symbole global benutzen:using namespace meineBib;
– bestimmte Symbole selektiv benutzen:using meineBib::f;
Namensräume
namespace A {
int f(int x) { return x+1; }
float g(float y) {
return 2*y;
}
}
using A::g;
using namespace B;
using namespace std;
cout << f(10) << endl;
Carsten Gutwenger: Einführung in C++ (Teil 1) 7
namespace B {
int f(int x) { return x-1; }
float g(float a, float b) {
return a+b;
}
}
cout << A::f(10) << endl;
cout << g(2.0f) << endl;
cout << g(2.0f,3.0f) <<
endl;
Compilieren und Linken
Präprozessor LinkerCompiler
.h-File
.cpp-File
Compilier-einheit
Objektcode
Carsten Gutwenger: Einführung in C++ (Teil 1) 8
.h-File
.h-File
Programm
einheitObjektcode
Bibliothek
……
……
g++ -c main.cpp –o main.o g++ main.o –lmyLib –o main
Compilieren und Linken
Der Präprozessor:• Verarbeitet Direktiven wie #include
• Erzeugt Compiliereinheit aus .cpp-Datei und allen davon inkludierten Headerdateien
• Wird automatisch vom Compiler aufgerufen
Carsten Gutwenger: Einführung in C++ (Teil 1) 9
Der Compiler:
• Erzeugt Objektdatei (Maschinencode) aus Compiliereinheit
Der Linker:
• Überprüft, ob alle Symbole (Funktionen etc.) vorhanden sind
• Fügt alle Objektdateien und Bibliotheken zum Programm zusammen
• (In der Regel) unabhängig vom Compiler
Compiler- und Linkeroptionen
-c nur compilieren und Objektcode erzeugen
-Wall alle Compilerwarnungen ausgeben
-g Debug-Informationen generieren
-O Code-Optimierung (-O0, -O1, -O2, -O3)
Carsten Gutwenger: Einführung in C++ (Teil 1) 10
-O -O0 -O1 -O2 -O3
-o output Name der Ausgabedatei festlegen
-llibrary Bibliothek library hinzulinken
-Idir zusätzliches Verzeichnis dir für Headerdateien
-Ldir zusätzliches Verzeichnis dir für Bibliotheken
Primitive Datentypen
• Ähnlich wie in Java:– char, short, int, long long: gewöhnlich 1, 2, 4, 8 Byte
– wchar_t: 16-bit Zeichen
– bool: boolescher Wert true oder false
– float, double: Fließkommazahlen (einfache und doppelte Genauigkeit), g++ auch long double
Carsten Gutwenger: Einführung in C++ (Teil 1) 11
Genauigkeit), g++ auch long double
• Zusätzlich nicht-negative Wertebereiche:– unsigned char
– unsigned short, unsigned int, unsigned long long
• Vorsicht: Wertebereiche sind i.A. plattformabhängig!
Kontrollstrukturen
• Wie in Java:
– if(…) { … } else { … }
– while(…) { … }
– do { … } while;
Carsten Gutwenger: Einführung in C++ (Teil 1) 12
– for(…;…;…) { … }
– switch(…) {
case: …
break;
…
default: …
}
Zeiger (Pointer)
• Der Adressoperator &
– gibt die Adresse einer Variablen im Speicher zurück
• Ein Zeiger vom Type type
– verweist auf eine Stelle im Speicher
– interpretiert den Speicher ab dieser Stelle als Variable vom Typ type
Carsten Gutwenger: Einführung in C++ (Teil 1) 13
– interpretiert den Speicher ab dieser Stelle als Variable vom Typ type
• Beispiel:int a[4];
int *p = &a[2];
a pSpeicher
Zeiger (Pointer)
• Dereferenzierungsoperator *
– „verwandelt“ den Zeiger in die Variable, auf die er verweist
• *p = 17;
cout << a[2] << endl; // gibt 17 aus!
Carsten Gutwenger: Einführung in C++ (Teil 1) 14
• Kurzform -> für Dereferenzierung und Member-Selektion:
– struct A { int x; int y; }
– A *q = …
– q->x = 25;
Zeigerarithmetik
• q = p + i
– Schiebt den Zeiger um i Elemente von Typ type weiter (i ist ein ganzzahliger Wert!)
– Auch Subtraktion einer ganzen Zahl möglich
• Subtraktion zweier Zeiger: q – p
Carsten Gutwenger: Einführung in C++ (Teil 1) 15
• Subtraktion zweier Zeiger: q – p
– ergibt Anzahl Elemente von p bis q (hier: i)
a pSpeicher
q hier: q = p+1
Referenzen
• Eine Referenz ist ein Stellvertreter für eine Variable– int x = 17;
int &refX = x;
– Eine Referenz muss immer initialisiert werden
– Jede Verwendung von refX ist äquivalent dazu, dass x benutzt wird
Carsten Gutwenger: Einführung in C++ (Teil 1) 16
– Das gilt auch für eine Zuweisung:refX = 20; // x ist jetzt 20
• Eine const-Referenz ist eine Referenz, deren Wert nicht verändert werden darf:– const int &crX = x;
crX = 20; // Fehler!
• Häufige Anwendung: Parameter von Funktionen
Parameter von main
• int main(int argc, char *argv[])
– argc: Anzahl der übergebenen Argumente
– argv: Feld der übergebenen Argumente
• Ausgabe der Parameter:– for(int i = 0; i < argc; ++i) {
Carsten Gutwenger: Einführung in C++ (Teil 1) 17
– for(int i = 0; i < argc; ++i) {
cout << "Parameter " << i << ": " <<
argv[i] << endl;
}
• Vorsicht: erster Parameter ist der Programmname!
Deklarationen und Definitionen
• Betrachte folgendes Beispiel:
– class Vector {
private:
double m_x, m_y;
public:
Carsten Gutwenger: Einführung in C++ (Teil 1) 18
public:
Vector(double x, double y) : m_x(x), m_y(y) { }
Vector add(const Vector &v) {
return Vector(m_x+v.m_x, m_y+v.m_y);
}
};
Deklaration
• Die Deklaration einer Klasse gibt an, welche Signatur (Rückgabetyp, Typen der Parameter) die Methoden der Klasse haben.– class Vector {
private:
double m_x, m_y;
Carsten Gutwenger: Einführung in C++ (Teil 1) 19
double m_x, m_y;
public:
Vector(double x, double y);
Vector add(const Vector &v);
};
• Header-Datei Vector.h
Definition
• Die Definition einer Methode gibt den Code der Implementierung an:– Vector::Vector(double x, double y)
: m_x(x), m_y(y) { }
– Vector Vector::add(const Vector &v)
Carsten Gutwenger: Einführung in C++ (Teil 1) 20
– Vector Vector::add(const Vector &v)
{
return Vector(m_x+v.m_x, m_y+v.m_y);
}
• Implementierungsdatei Vector.cpp
• Inkludiert Vector.h:
– #include "Vector.h"
Der Präprozessor
• Verhindern von Mehrfachdeklarationen:– #ifndef VECTOR_H
#define VECTOR_H
class Vector {
private:
Carsten Gutwenger: Einführung in C++ (Teil 1) 21
private:
double m_x, m_y;
public:
Vector(double x, double y);
Vector add(const Vector &v);
};
#endif
Präprozessor-Direktiven
• #include "Dateiname"– Fügt die Datei Dateiname an dieser Stelle ein
– (in der Regel) Datei in aktuellem Verzeichnis
• #include <Dateiname>
– Fügt die (System-)Datei Dateiname an dieser Stelle ein
– Datei im Include-Pfad des Compilers
Carsten Gutwenger: Einführung in C++ (Teil 1) 22
– Datei im Include-Pfad des Compilers
• #ifdef, #ifndef, #if, #else, #endif– Bedingte Compilierung
• #define Makro
– Definiert Makro (ohne Wert)
• #define Makro Wert
– Definiert Makro mit Wert
Makefiles
• Erleichtern das Compilieren und Linken gößerer Projekte
• Minimales Neuerstellen nach Veränderungen
• Regeln definieren Abhängigkeiten und Neuerstellung:
– Ziel: Abhängigkeiten
<TAB>Befehl
Carsten Gutwenger: Einführung in C++ (Teil 1) 23
<TAB>Befehl
– Vorsicht: <TAB> bezeichnet das Tabulatorzeichen!
• Variablendefinitionen:
– CC = g++
– $(CC)
• Aufruf des Makefiles: make
Makefiles
• Beispiel:
– CC = g++
CFLAGS = -Wall -g
prog: prog.o Vector.o
$(CC) prog.o Vector.o -o prog
Carsten Gutwenger: Einführung in C++ (Teil 1) 24
$(CC) prog.o Vector.o -o prog
prog.o: prog.cpp Vector.h
$(CC) -c $(CFLAGS) prog.cpp -o prog.o
Vector.o: Vector.cpp Vector.h
$(CC) -c $(CFLAGS) Vector.cpp –o Vector.o