Carsten Gutwenger - Algorithm Engineeringls11- · Primitive Datentypen • Ähnlich wie in Java:...

24
DAP2-Programmierpraktikum Einführung in C++ (Teil 1) Carsten Gutwenger 11. April 2008 11. April 2008 Lehrstuhl 11 – Algorithm Engineering Fakultät für Informatik, TU Dortmund

Transcript of Carsten Gutwenger - Algorithm Engineeringls11- · Primitive Datentypen • Ähnlich wie in Java:...

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