Einführung in C++ - ITAP | Universität Stuttgart

Werbung
Physik auf dem Computer
Johannes Roth
Institut für Theoretische und Angewandte Physik, Universität Stuttgart
Sommersemester 2011
Grundlagen von C++
Hauptprogramm
Notwendige Elemente:
#include <iostream>
using std::cout;
int main()
{
cout << "Hello World\n" ;
return 0;
}
// Zeichenkette auf Bildschirm
// ausdrucken
Grundlagen von C++
Präprozessoranweisungen
werden vor Programmübersetzung vorverarbeitet
#ifndef HEADER_H
#define HEADER_H
// Deklarationen
#endif
Variable extern setzen:
g++ -DHEADER_H myprog.cc
Grundlagen von C++
1. Sprachkonstrukte
Kommentare: // Kommentar
Daten: Variablen und Konstanten, Felder
(Vereinbarungen mittels Deklarationen)
Operatoren und Funktionen
I/O-Sprachelemente (Ein-, Ausgabe)
2. Kommentare
C++: Kommentare werden durch // eingeleitet.
C: /* Kommentar */
Kommentare lassen sich nicht schachteln!
Grundlagen von C++
Datentypen
3. Datentypen, Variablen, Konstanten
Grundlegende Datentypen in C++: int, float, double, bool, char
(i) Datentyp int: ganzzahlige (integer) Variablen
Deklaration von Variablen:
int i, j=5;
Im weiteren Verlauf des Programms werden die Variablen über den in der
Deklaration vereinbarten Variablennamen angesprochen.
Interne Darstellung von int-Variablen im Speicher: Folge von {0, 1}-bits,
8bit =
ˆ 1 byte (=
ˆ 1 character)
int i // 32-bit Variable
(Zahlenbereich von −231 bis 231 − 1 = 2 147 483 647)
Größere oder kleinere Zahlen führen zu overflow.
Beispiel: i = 1 000 000 ∗ 1 000 000: overflow
Grundlagen von C++
Datentypen
Weitere Datentypen für ganzzahlige Variablen:
short s; // 16-bit Variable
long l; // 64-bit Variable
Datentyp beeinflußt Speicherbedarf und Rechenzeit!
(ii) Datentyp float und double: Typen für Gleitkommazahlen
float f = 1./3.; // f=0.3333333 (einfache Genauigkeit)
float f; // 32-bit Variable (ca. 7 Dezimalstellen + Exponent)
double d; // 64-bit Variable (ca. 15 Dezimalstellen + Exponent)
Empfehlung: Verwende double!
Ein- und Ausgabe als Gleitkommazahlen oder in Exponentialdarstellung:
Mantisse, Exponent
1.2345e+6 = 1.2345 × 106
Interne Zahlendarstellung: Compiler- und Maschinenabhängig!
Datentypen int, float, double: wichtig zum Rechnen
Grundlagen von C++
Datentypen
(iii) Datentyp char: Variablen für einzelne Textzeichen
char c=’x’; // ein Zeichen: x (1 byte ^= 8 bit)
Aneinanderreihung von characters liefert string (Text).
(iv) Datentyp bool: Boolsche Variable, kann nur den Wert true oder false
annehmen.
bool test; // Deklaration einer Boolschen Variable
test = (0 < 5) // test hat den Wert true
if test {Anweisung 1} else {Anweisung 2} // Anweisung 1 wird
// ausgefuehrt
(Logische Verknüpfungen: && (and), || (or), ! (not))
(Vergleichsoperatoren: ==, !=, <, <=, >, >=)
Grundlagen von C++
Datentypen
Bemerkungen zu den Datentypen:
Deklarationen können an fast beliebiger Stelle im Programm stehen.
Soll der Wert nach einer Initialisierung nicht mehr geändert werden,
so empfiehlt sich die Deklaration von Konstanten. Beispiel:
const double pi = 3.14159265;
Die Variablen existieren innerhalb des Blocks {. . . } in welchem sie
deklariert sind.
sizeof(variable) liefert die aktuelle Größe der Variablen variable (in
bytes).
Grundlagen von C++
Datentypen
Felder:
Zusammenfassung mehrerer Variablen gleichen Typs in einem
zusammenhängenden Speicherbereich. Beispiele:
const int size = 20;
int a[size]; // array von 20 int Variablen
Zugriff auf einzelne Elemente erfolgt durch Indizes:
a[0] = 3;
a[1] = 5;
a[19] = a[0] + a[1]; // a[19] = 8
Wichtig: Index läuft von 0 bis size−1 !!!
double matrix [20] [30]; //
//
char text[] = "hello";
//
//
Deklaration einer Matrix
mit 20*30=600 Elementen
Text array mit 5 Zeichen
(Achtung: sizeof(string) = 6)
Grundlagen von C++
Datentypen
Beispiel: Matrix-Vektor-Multiplikation ~v2 = M · ~v1
double matrix [20] [30];
double vector1[30];
double vector2[20];
... Initialisierung von matrix und vector1 ...
for (int i=0; i<20; i++){
double tmp = 0;
for (int j=0; j<30; j++)
tmp = tmp + matrix[i][j] * vector1[j];
vector2[i] = tmp;
}
Grundlagen von C++
Kontrollstrukturen
4. Kontrollstrukturen
Bedingte und wiederholte Ausführung von Programmteilen:
if, switch-Anweisung und do, while, for-Schleifen
If-Anweisung:
if (Boolscher Ausdruck/Variable)
{Anweisungsblock 1}
else if (...)
// optional
{Anweisungsblock 2}
else
// optional
{Anweisungsblock 3};
Grundlagen von C++
Kontrollstrukturen
Switch-Anweisung:
switch( c) {
// Anfang des case blocks
case ’a’: cout << "hello world!";
break;
case ’b’: cout << "HELLO "; // Weitergehen beabsichtigt,
// break fehlt
case ’c’: cout << "WORLD!";
break;
default: cout << "unknown input";
break;
// Nicht noetig, aber guter Stil
}
// Ende des case blocks
Grundlagen von C++
Kontrollstrukturen
While-Schleifen:
while (Boolscher Ausdruck/Variable)
{Anweisungsblock};
Do-Schleifen:
do {Anweisungsblock}
while (Boolscher Ausdruck/Variable);
For-Schleifen:
for (int i=0; i<20; i++)
{Anweisungsblock}; // Zaehlschleife fuer i=0,...,19
Grundlagen von C++
Kontrollstrukturen
Goto-Anweisung, Labels
Vorzeitiges Verlassen tiefer verschachtelter Schleifen
Beispiel: Durchsuchen einer Liste
int a[20][30],i,j;
for (i=0; i<20; i++)
for (j=0; j<20; j++)
if (a[i][j] == 42)
goto element_gefunden;
..
.
element_gefunden:
// label
... // Ausgabe von i,j ...
Grundlagen von C++
Funktionen und Operatoren
5. Funktionen und Operatoren
Sinn und Zweck von Funktionen:
Einmaliges Schreiben von Programmteilen, die sich im Programm
mehrfach wiederholen
Bessere Strukturierung und Lesbarkeit von Programmen
Beispiel: Berechnung von Potenzen
y = xn = power(x, n)
mit x reell, n ganze Zahl.
Vereinbarung (Deklaration) der Funktion (vor dem Hauptprogramm):
double power (double base, int exponent)
Aufruf der Funktion im Programm:
..
.
y = power(x,n);
..
.
Grundlagen von C++
Funktionen und Operatoren
Definition der Funktion in separatem Programmtext:
double power (double base, int exponent);
{
double result;
// weitere Deklarationen, Rechenoperationen
return result // Datentyp double
}
Grundlagen von C++
Funktionen und Operatoren
Viele Standardfunktionen brauchen nicht selbst geschrieben zu werden,
sondern sind in Bibliotheken vorhanden.
Beispiel:
Benutzung von Funktionen aus der Mathematik-Bibliothek
#include <cmath>
double x, y;
...
y = sqrt(x);
Übersetzen des Programms und “Linken” der Programmbibliothek
(“library”) libm.a:
g++ programm.cc power.cc -lm
Programmteile in anderen Dateien müssen angegeben werden!
Grundlagen von C++
Funktionen und Operatoren
Häufig einfacher zu lesen als Funktionen sind:
Operatoren
Beispiel:
Statt z = plus(x,y) (Funktion mit 2 Argumenten) schreibt man
einfacher
z = x + y
Arithmetische binäre Operatoren: + - * / %
(Beachte: Division ist abhängig vom Datentyp!)
Kurzschreibweisen durch Kombination mit Gleichheitszeichen:
i
i
i
i
+=
-=
*=
/=
j;
j;
j;
j;
//
//
//
//
i
i
i
i
=
=
=
=
i
i
i
i
+
*
/
j;
j;
j;
j;
Grundlagen von C++
Funktionen und Operatoren
Unäre Operatoren:
x = feld[i++];
x = feld[++i];
//
//
//
//
x = feld[i]; i = i + 1;
(postfix-Form)
i = i + 1; x = feld[i];
(prefix-Form)
Analog: i-- und --i
Vergleichsoperatoren:
==
!=
>
>=
<
<=
//
//
//
//
//
//
gleich
ungleich
groesser
groesser oder gleich
kleiner
kleiner oder gleich
Grundlagen von C++
Funktionen und Operatoren
Logische Operatoren
(zwischen Boolschen Variablen oder Ausdrücken):
&&
||
!
// and
// or
// not
Der Wert eines logischen Ausdrucks und das Resultat eines
Vergleichsoperators sind vom Typ bool, also entweder true oder false.
Beispiel:
(1 < 2) && (2 < 3) k (3 < 4) && (5 < 5)
| {z } | {z }
| {z }
| {z }
true
true
true
false
|
{z
} |
{z
}
true
false
|
{z
}
true
Grundlagen von C++
Funktionen und Operatoren
Bindungsstärke (Priorität) von Operatoren:
*
+
<
==
&&
||
=
/
<=
!=
%
>
>=
*=
/=
%=
+=
-=
Grundlagen von C++
Funktionen und Operatoren
Ternärer Operator:
(Boolscher Ausdruck/Variable) ? (Ausdruck 1) : (Ausdruck 2)
Beispiel:
int i;
cout << (i>0) ? i : 0;
ist Alternative zu
int i;
if (i>0)
cout << i
else
cout << 0;
Grundlagen von C++
Funktionen und Operatoren
Übergabe von Argumenten an eine Funktion: by value
Vor dem Aufruf der Funktion erfolgt eine Kopie der Argumente (auf dem
Stack). Die Funktion arbeitet mit den Kopien. (Ausnahme: Felder.) Dies
eröffnet die Möglichkeit, Funktionen rekursiv aufzurufen.
1,
n=0
Rekursive Funktionen, Beispiel Fakultät: n! ≡
n · (n − 1)!, n > 0
int fak(int n){
if (n==0)
return 1;
else
return n*fak(n-1);
}
ist Alternative zu
int fak(int n){
int result=1;
for (int i=2; i<=n; i++)
result *= i;
return result;
}
Grundlagen von C++
Funktionen und Operatoren
Beispiel quicksort:
void quicksort(int left, int right){
int i;
if (left < right){
i = partition(left,right);
quicksort(left,i-1);
quicksort(i+1,right)
}
}
Parameterübergabe per Referenz (Adresse):
Voranstellen von & vor den Variablennamen
Beispiel:
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp
}
#include <iostream>
#include <fstream>
using namespace std;
void quicksort(int l, int r, double x[]);
int main(){
int n = 0;
double x[1000];
ifstream ins("data", ios::in);
while (ins >> x[n]) n++;
quicksort(0,n-1,x);
ofstream outs("sort", ios::out);
for (int i=0; i<n; i++)
outs << x[i] << ’\n’;
return 0;
}
// Oeffnen der Eingabedatei
// Lesen der Daten
// Oeffnen der Ausgabedatei
// Schreiben der Daten
void quicksort(int l, int r, double x[]){
if (r > l){
int i = l;
double xpivot = x[l];
for (int j=l+1; j<=r; j++)
if (x[j] < xpivot){
x[i++] = x[j]; // Kurzform fuer: x[i] = x[j]; i = i+1;
x[j] = x[i];
}
x[i] = xpivot;
quicksort(l, i-1, x);
quicksort(i+1, r, x);
}
}
Grundlagen von C++
Zeiger
6. Zeiger
Zu jeder Variablen gehört eine Adresse im Speicher.
Zeiger = Speicheradresse
C++ bietet (fortgeschrittenen Programmierern) die Möglichkeit, diese
Adressen der Speicherstellen für Programmierzwecke nutzbar zu machen.
& vor Variable: liefert Adresse (“pointer”) einer Variable
* vor pointer: “value of” Operator liefer den Wert der Variable
Beispiel:
int i = 5;
int *p_i = &i;
cout << *p_i;
//
//
//
//
//
Variable i hat den Wert i=5
p_i ist Zeiger (pointer)
auf die Variable i
liefert 5 (den Wert von i)
als Ausgabe
Grundlagen von C++
Ein- und Ausgabe
7. Ein- und Ausgabe (i/o)
Kanaltypen: istream und ostream
Dekalaration im header durch
#include <iostream>
Zugriff auf z.B.
cin >> ... >> ...;
cout << ... << ...;
// Standardeingabe
// Standardausgabe
Die Auswertung erfolgt von links nach rechts.
Alternative Schreibweise mit Funktionsaufrufen (put, get):
char c1=’x’;
cout << c1 << ’\n’;
cout.put(c1); cout.put(’\n’);
Entsprechend für die Eingabe mit cin.get.
Grundlagen von C++
Ein- und Ausgabe
Formatierung der Datenausgabe
Ausgabe von Text gemäß ASCII-Tabelle (’\n’ = “newline”).
Ausgabe von int, float, double erfordert Konversion, d.h. Umwandlung
der internen (binären) Zahlendarstellung in Text.
Die Konversion läßt sich durch Formatierungsanweisungen steuern, z.B.
zur Rundung von Daten oder für die gleichmäßige Ausgabe von Tabellen.
Beispiel:
#include <iomanip>
double x=1234.5;
cout << setfill(’*’)
<< setw(10) << setprecision(5);
cout << x << ’\n’;
// Ausgabe: ****1234.5
setfill(’*’): Angabe eines Füllzeichens
setw(10): Minimale Größe der direkt folgenden Ausgabe
setprecision(5): Zahl der Stellen für Festkomma, bzw. Zahl der
Stellen hinter dem Komma bei Gleitkommadarstellung
Grundlagen von C++
Ein- und Ausgabe
Dateien (Files)
Beim Arbeiten mit Dateien gibt es viele Parallelen zur Standard Ein- und
Ausgabe, aber einige spezifische Besonderheiten:
Bekanntmachung bereits existierender Dateien im Programm (zum
Lesen)
Einrichten neuer Dateien über das Betriebssystem (zum Schreiben)
Erkennen von z.B. Größe und Ende von Dateien beim Lesen
Kanaltypen ifstream und ofstream.
Beispiel:
#include <fstream>
int variable;
ifstream ins("Eingabedatei", ios::in);
// Oeffnen zum Lesen
ins >> variable; // Einlesen von Daten aus der Eingabedatei
ofstream outs("Ausgabedatei", ios::out); // Oeffnen zum Schreiben
outs << variable; // Ausgabe von variable in die Ausgabedatei
Grundlagen von C++
Ein- und Ausgabe
Schließen der Dateien:
ins.close();
outs.close();
Statusinformationen (beim Lesen): Typ bool
ins.good();
ins.eof();
ins.bad();
ins.fail();
ins.clear();
//
//
//
//
//
true, falls kein Fehler
true bei "end of file"
true bei hardware error
true bei logical error
setzt ins.good auf ’true’
Lesen einer Datei bis Dateiende (eof):
int n;
while (ins >> n){
...
}
Grundlagen von C++
Verschiedenes
Macros vs. inline
Macros in C und C++ (keine Typprüfung!):
#define SQR(a) ((a)*(a))
int b=2,c;
c = SQR(b++); // c = ((a++) * (a++));
// c ist nun 2*3 = 6, b ist 4 nach 2(!)-maligem
// Inkrement
besser in C++: inline-Funktionen verwenden:
inline int sqr (int a){ return a*a; }
int b=2, c;
c = sqr(b++); // b++ wird einmal ausgewertet, deshalb ist c
// nun 4, b ist 3
Grundlagen von C++
Verschiedenes
Definition neuer Datentypen
typedef int
Int32; // neuer Name für alte Typen
typedef struct { int lower, upper } TwoInt; // komplexer
// neuer Type
TwoInt interval;
// Variable definieren
interval.lower=-1;
interval.upper=2;
// Teile initialisieren
Grundlagen von C++
Verschiedenes
Dynamischer Speicher
Belegen
int
int
int
*p_i = new int;
n = 40;
*pa_i = new int[n];
Freigeben
delete
p_p;
delete[] pa_i;
// eine Variable
// ein Feld
Grundlagen von C++
Verschiedenes
Namespaces
enthalten Klassen von Befehlen, bspw. für Ein-/Ausgabe:
#include <iostream>
using namespace std;
cout << " Gehalt: "
<< Personal.mGehalt;
kollektiv statt einzeln:
#include <iostream>
using std::cout;
using std::cin;
cin >> Personal.mGehalt;
cout << " Gehalt: " << Personal.mGehalt;
Grundlagen von C++
Verschiedenes
Makefile
enthält Anweisungen zum Kompilieren
Übersetzen der einzelnen Dateien
Zusammenbau der .o-Dateien und Bibliotheken
Verwendung: make oder make programm
Grundlagen von C++
Verschiedenes
Objektorientierte Programmierung
Klassen: Unterprogramme mit Datenstrukturen
Templates: selber Name für verschiedene Fälle, bspw.
power(int(base),int(exponent)) und
power(double(base),double(exponent))
Bibliotheken: enthalten fertige Programmpakete, benutzen mit
#include <math>
C++-Standardbibliothek enthält bspw.
vector
list
set
Herunterladen