Inhalt:
int a=2;
bool b;
if (a < 2) befehl; // 1 Befehl
if (a == 2){ befehl1; befehl2; } // Mehrere Befehle in einem Block
if (a = 1) ... // Achtung, Zuweisung!
b = a>5; // Wahrheitswert speichern
if (b == true) befehl;
if (b) ...
if (...)
befehl;
else
andererbefehl;
if (...)
befehl;
else if (...)
befehl2;
else
befehl3;
// Achtung, dangling else:
if (...)
if (...) befehl;
else
befehl2;
//
// Besser:
if (...) {
if (...) befehl;
} else {
befehl2;
}
int i;
cin >> i;
switch (i) { // Nur fuer Ganzzahlen (int, char, ...) definiert
case 1: cout << "1" << endl;
break;
case 2: // Fall-through
case 3: cout << "2/3" << endl;
default: cout << "default" << endl;
}
int i; // Variablendeklaration
i=1; // Initialisierung
while (i < 10) { // Laufbedingung
cout << i << endl; // Eigentl. Schleifenkoerper
i++; // Inkrement/Aktualisierung
}
struct listitem *p;
p = liste;
while (p != NULL) {
cout << p->data << endl;
p = p->next;
}
// Primzahlen von 1 bis 1000 ausgeben
int j = 0;
while(++j) { // Immer wahr - Endlosschleife
if (!prime(j)) continue; // sofort naechster Durchlauf
if (j > 1000) break; // sofort abbrechen
cout << j << endl;
}
int i,j; // Variablendeklaration
for (i = 1; // Initialisierung
i < 10; // Laufbedingung
i++ ) // Inkrement
cout << i << endl; // Schleifenkörper
for (j = 10; j > 0 ; j--) {
cout << j << endl;
}
// Variablendeklaration -- nur in C++
for (int k = 0; k < 10 ; k++) {
cout << k << endl;
}
for (struct listitem *p = liste; p != NULL; p=p->next)
cout << p->data << endl;
int i;
do {
cin >> i;
cout << i + 1;
} while(i != -1);
Prototypen machen Funktionen bzgl. Rückgabewert, Name und Parameter bekannt, ohne sie näher zu beschreiben. Oft in Header-Dateien (.h) abgelegt, die sowohl zur Implementierung (=> Überprüfung) als auch beim Benutzen (=> Bekanntmachen) benutzt werden.
Beispielcode:
void funktion(int);
int a;
funktion(17);
a = 42;
Ablauf:
Beispiele:
int main(void) {
main(); // Bumm!
}
// Zaehlen ohne Schleife (Source):
void count_forward(int i) {
if (i > 0)
count_forward(i - 1);
cout << i << " ";
}
void count_backwards(int i) {
cout << i << " ";
if (i > 0)
count_backwards(i - 1);
}
int main()
{
count_forward(10); cout << endl;
count_backwards(10); cout << endl;
return 0;
}
Ausgabe:
% ./rekursiv-zaehlen 0 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1 0Stackaufbau (gross):
int zaehler(void)
{
static int meinZaehler = 1;
return meinZaehler++;
}
int max(int a, int b) { return (a > b)?a:b; }
double max(double a, double b){ return (a > b)?a:b; }
Funktionen die dieselben Parameter besitzen und sich lediglich im
Rückgabewert unterscheiden sind in C++ nicht möglich, da Rückgabewerte in
C++ genau wie in C ignoriert bzw. nicht benutzt werden müssen, und so
nicht eindeutig feststellbar wäre, welche Funktion aufgerufen werden soll:
int f(void);
double f(void);
f(); // welche Funktion aufrufen? Geht nicht!
Hintergrund:
% cat ov-C.c
int max(int a, int b) { return (a > b)?a:b; }
% cc -c ov-C.c
% nm ov-C.o
00000000 T max
% cat ov-C++.cc
int max(int a, int b) { return (a > b)?a:b; }
double max(double a, double b){ return (a > b)?a:b; }
% cc -c ov-C++.cc
% nm ov-C++.o
00000022 T _Z3maxdd
00000000 T _Z3maxii
U __gxx_personality_v0
% nm ov-C++.o | c++filt
00000022 T max(double, double)
00000000 T max(int, int)
U __gxx_personality_v0
void WetterMelder(char *grund, char *ton = NULL, int lautstaerke=100){
popupFenster(grund);
if (ton != NULL)
soundSpielen(ton, lautstaerke);
}
main() {
WetterMelder("Regen");
WetterMelder("Sonnenschein", "/mp3/beachboys - like ice in the sunshine.mp3");
WetterMelder("Wolken", "/mp3/donnergrollen.mp3", 50);
WetterMelder("Schnee", 10); // XXX Geht nicht!
}
Ziel: Vertauschen zweier Variablen a und b
void tausch (int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int main(void)
{
int x = 1, y = 2;
printf("x = %d, y = %d\n", x,y);
tausch (x,y);
printf("x = %d, y = %d\n", x,y);
return 0;
}
Problem: Funktion arbeitet auf Kopien, dadurch sinnlos
Lösung: Zeiger verwenden!
void tausch (int *za, int *zb)
{
int temp;
temp = *za;
*za = *zb;
*zb = temp;
}
int main(void)
{
int x = 1, y = 2;
printf("x = %d, y = %d\n", x,y);
tausch (&x,&y);
printf("x = %d, y = %d\n", x,y);
return 0;
}
Vorteil: Funktioniert (:-), Tatsache daß in die Funktion übergebene Werte verändert werden können ist anhand der Zeiger ersichtlich.
Nachteil: Umstaendliches hantieren mit Zeigern sowohl beim Aufruf als auch beim Schreiben der Funktion.
void tausch (int &ra, int &rb)
{
int temp;
temp = ra;
ra = rb;
rb = temp;
}
int main(void)
{
int x = 1, y = 2;
printf("x = %d, y = %d\n", x,y);
tausch (x, y);
printf("x = %d, y = %d\n", x,y);
return 0;
}
% cat src/referenz.cc #include <iostream> using namespace std; int main(void) { int i; int &ri = i; i = 42; ri = 17; cout << i << endl; return 0; } % c++ src/referenz.cc -o src/referenz % src/referenz 17
Abgesehen vom Compiler-Aufruf funktiniert dies in C++ genau wie in C.
void funktionImAnderenModul(int i);
extern int variableImAnderenModul;
static int privateVariable=0;
static int privateFunktion(void) {
return privateVariable++;
}
int oeffentlicherZaehler(void){
return privateFunktion();
}
Im Fehlerfall wird die aufrufende Funktion den Fehler zu behandeln. Kann sie mit der gefangenen Fehlerklasse nichts anfangen, so wirft sie sie weiter an die aufrufende Funktion, den Call-Stack hinauf.
#include <iostream>
using namespace std;
void func(int i)
{
try {
if (i == 1) throw 1;
if (i == 2) throw 17.42;
if (i == 3) throw 'a';
}
// Integer-Exceptions können selbst abgefangen werden
catch(int a) {
cout << "Caught integer exception: " << a << endl;
return;
}
cout << "No integer exception detected, i = " << i << endl;
return;
}
int main(void)
{
try {
func(0);
func(1);
func(2);
func(3);
func(4);
}
// Ausnahmen behandeln, die die Funktion nicht selbst behandeln konnte:
catch (double x) {
cout << "Caught double exception: " << x << endl;
}
catch (char c) {
cout << "Caught char exception: " << c << endl;
}
catch (...) {
cout << "Caught unknown exception" << endl;
}
return 0;
}
Ausgabe:
% src/exception No integer exception detected, i = 0 Caught integer exception: 1 Caught double exception: 17.42