Einführung in die Programmiersprache Csb/data/EinfuehrungC.pdf · d = 23 / ((int) c); Bei der...

Post on 12-Aug-2019

218 views 0 download

Transcript of Einführung in die Programmiersprache Csb/data/EinfuehrungC.pdf · d = 23 / ((int) c); Bei der...

Einfuhrung in die Programmiersprache C

Steffen Borm

Christian-Albrechts-Universitat zu Kiel

Sommersemester 2014

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 1 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 2 / 68

Wieso C?

Flexibel: Volles Potential des Computers steht zur Verfugung.Effizient: Maschinennah, viele Operationen konnen durch denCompiler unmittelbar in Maschinenbefehle verwandelt werden.Beherrschbar: Es passiert nur, was wir explizit programmieren.Verbreitet: Eine der am haufigsten genutztenProgrammiersprachen, verwandt mit C++, Objective C und Java.

Vorsicht: C verzeiht Fehler nicht so leicht wie andere Sprachen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 3 / 68

Termine

Fur die C-Einfuhrung werden die Termine der Vorlesungen

”Algorithmen und Datenstrukturen“ und ”Organisation und Architekturvon Rechnersystemen“ der ersten Semesterwoche verwendet:

Montag, 14. April 2014, CAP3 Horsaal 2, 10 c.t. (Borm)Montag, 14. April 2014, CAP3 Horsaal 2, 16 c.t. (von Hanxleden)Dienstag, 15. April 2014, CAP3 Horsaal 2, 9 s.t. (von Hanxleden)Freitag, 25. April 2014, CAP3 Horsaal 2, 8 c.t. (Borm)

Hinzu kommen praktische Aufgaben und Erganzungen in denjeweiligen Ubungen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 4 / 68

Literatur

Wir konnen im Rahmen der Vorlesung nur einen kurzen Einblick in diewichtigsten Aspekte der Sprache C geben, deshalb empfehlen wir fureine eingehendere Beschaftigung die folgenden Quellen:

D. Ritchie und B. W. Kernighan:Programmieren in CP. Baumle-Courth, T. Schmidt:Praktische Einfuhrung in CRRZN Hannover:Die Programmiersprache C. Ein Nachschlagewerk.Wikibook C-ProgrammierungC-Howto.de

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 5 / 68

Entwicklungsumgebung

Ein C-Programm durchlauft mehrere Stufen, bevor es ausgefuhrtwerden kann:

Editor: Wir schreiben das Programm als gewohnliche Textdatei.Praprozessor: Einzelne Zeichenketten konnen ersetzt werden,beispielsweise um Abkurzungen zu verwenden.Compiler: Der resultierende Text wird in die Maschinenspracheeines Computers ubersetzt.Linker: Es entsteht eine fur das Betriebssystem ausfuhrbare Datei.Loader: Die ausfuhrbare Datei wird in den Speicher geladen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 6 / 68

Software

Fur die Bearbeitung der Ubungsaufgaben ist ein Computer mitC-Entwicklungsumgebung erforderlich.

Windows: Visual Studio ExpressWindows: MinGW / MSys (Unix-ahnlich)MacOS: XcodeLinux: GNU Compiler Collection

Alternative: Virtuelles Linux-System unter VirtualBox

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 7 / 68

Beispiel: GNU Compiler Collection

Praprozessor und Compiler: Uberfuhren den Quelltext example.c ineine Objektdatei example.o, die Maschinenbefehle undLinker-Informationen, beispielsweise uber Funktionsnamen, enthalt.

gcc -c example.c

Linker: Fugt Objektdateien und Bibliotheken zu einer ausfuhrbarenDatei example zusammen.

gcc example.o -o example

Programmstart: Unmittelbar per Befehlszeile.

./example

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 8 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 9 / 68

Variablen

Eine Variable ist in C ein Speicherbereich, der eine gewisse Große hatund an einer gewissen Adresse beginnt.

Variablen werden im Rahmen einer Variablendefinition mit einemNamen versehen, um dem Programmierer die Arbeit zu erleichtern.Variablennamen durfen aus

Buchstaben (a, . . . , z, A, . . . ,Z),Ziffern (1, . . . ,9, 0) undUnterstrichen ( ) bestehen,

sie durfen allerdings nicht mit einer Ziffer beginnen.

Um die Zuordnung eines geeigneten Speicherbereichs zu einemVariablennamen kummern sich Compiler, Linker und Loader.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 10 / 68

TypenDamit der Compiler weiß, wie eine Variable zu interpretieren ist, wirdjeder Variablen ein Typ zugeordnet.

Typen konnen mit Namen versehen sein, fur die dieselben Regeln wiefur Variablennamen gelten.

Einige Typen sind vordefiniert, beispielsweiseint fur ganze Zahlen,float und double fur Gleitkommazahlen oderchar fur Buchstaben.

Manche Typen konnen mit den Schlusselworten short, long undunsigned modifiziert werden.

Mathematik: Ein Typ kann als eine Menge von Werten interpretiertwerden, eine Variable dieses Typs entspricht dann einem Elementdieser Menge.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 11 / 68

Variablendefinitionen

Eine Variable wird definiert, indem ihr Typ und ihr Name durchLeerraum getrennt angegeben werden, den Abschluss bildet einSemikolon:int x; 4 ganze Zahl, Variablenname xint 2y; 8 Variablenname beginnt mit Zifferlong int y4; 4 lange ganze Zahl namens y4short int w_3; 4 kurze ganze Zahl namens w_3float x+y; 8 Variablenname enthalt Zeichen ”+“float x_plus_y; 4 Gleitkommazahl namens x_plus_ychar _Next; 4 Buchstabe namens _Nextunsigned char a; 4 Buchstabe ohne Vorzeichen namens a

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 12 / 68

Verbunde

Mit dem Schlusselwort struct konnen wir neue Typen aus bereitsdefinierten Typen zusammensetzen.

struct {int a;float x;

} z;

Die beiden Komponenten konnen wir dann mit z.a und z.x erreichen,sie sind Variablen des Typs int beziehungsweise float.

Mathematik: Ein Typ entspricht einer Menge T , ein Verbundtypentspricht dem kartesischen Produkt mehrere Mengen T = X × Y .

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 13 / 68

Typdefinitionen

Spatestens bei Verbunden empfiehlt es sich, neu definierten Typeneinen eigenen Namen zu geben. Diesem Zweck dient dasSchlusselwort typedef:

typedef unsigned int uint;typedef struct { float re; float im; } complex;typedef struct { int r; int g; int b; } color;

Die neuen Typen konnen in Variablendefinitionen verwendet werden:

uint i;complex z;color background;

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 14 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 15 / 68

Operatoren fur arithmetische BerechnungenDie Inhalte von Variablen werden durch Operatoren verwendet undverandert.

Arithmetische Operatoren fuhren Berechnungen durch.

x + y y - z3 * a b / 17 c % 5

Zuweisungsoperatoren verandern Werte von Variablen.

a = bx += y y -= za *= 3 b /= 17 c %= 5i ++ j --++ i -- j

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 16 / 68

Operatoren fur die Bitmanipulationint- und char-Variablen konnen auch als Folge von Bits interpretiertund entsprechend manipuliert werden.

Bitweise Verknupfungen fuhren Oder-, Exklusiv-Oder-, Und- sowieKomplement-Operationen fur alle Bits des Ergebnisses durch.

x | y p ˆ q a & bx |= y p ˆ= q a &= b˜f

Bitweises Schieben nach ”links“ und ”rechts“, wobei das niedrigste Bit

”rechts“ steht.

x << 5 y >> 3a <<= 2 b >>= 4

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 17 / 68

Ausdrucke

Mehrere Operatoren konnen zu komplexeren Termenzusammengesetzt werden.

Dabei gelten die ublichen Regeln fur arithmetische Ausdrucke,beispielsweise ”Punkt- vor Strichrechnung“. Mit Klammern lasst sichdie Reihenfolge der Anwendung der Operatoren steuern.

Fur konstante Großen konnen Literale verwendet werden,beispielsweise 3 fur die Zahl drei oder 3.141 als Naherung der Zahl π.

x = (a + 7) * 3a += 3 * b + 17p = q = r

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 18 / 68

Typkonvertierung

Mit dem Cast-Operator konnen wir Ausdrucke eines Typs in andereTypen umwandeln:

int a; int b; float c; int d;a = 17;b = a / 3;c = ((float) a) / 3;d = 23 / ((int) c);

Bei der Berechnung von b wird die ganzzahlige Division verwendet,bei der von c die konventionelle, bei der von d wiederum dieganzzahlige, da in diesem Fall c abgerundet wird.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 19 / 68

FunktionenEine Funktion beschreibt eine Folge von Anweisungen, die der Reihenach ausgefuhrt werden.

Sie werden nach demselben Schema wie Variablen und Typen mitNamen bezeichnet.

Die einfachste Anweisung ist ein mit einem Semikolonabgeschlossener Ausdruck, der ausgefuhrt wird.

voidcompute(){x = 4 * y + 3;

}

Das Schlusselwort void gibt in diesem Beispiel an, dass die Funktionkeinen Wert zuruckgibt.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 20 / 68

Parameter und Ruckgabewert

Eine Funktion kann eine Anzahl von Parametern erhalten. Parametersind Variablen, denen Werte zugewiesen werden, wenn wir dieFunktion aufrufen.

Eine Funktion kann mit der Anweisung return ein Ergebniszuruckgeben.

doublearea_triangle(double height, double base){return height * base / 2.0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 21 / 68

Funktionen ohne Ruckgabewert

Falls eine Funktion keinen Wert zuruckgeben soll, beispielsweise weilihre Ergebnis anders ubermittelt werden konnen, konnen wir denvordefinierten Typ void verwenden:

voidstop_program(){exit();

}

Der Typ void weist die Besonderheit auf, dass wir keine Variablenoder Parameter dieses Typs definieren durfen.

Allerdings durfen wir (dazu spater mehr) Zeiger auf diesen Typverwenden.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 22 / 68

FunktionsaufrufeDer Aufruf einer Funktion ist ein weiterer Operator, der die Parameterubergibt und das Ergebnis der Funktion als Wert zuruckgibt.

a = area_triangle(3.0, 1.5)b = area_triangle(4.0, 2.0)

- 3.0 * area_triangle(1.0, 0.5)

Die Ausfuhrung unseres Programms beginnt mit dem Aufruf derFunktion main durch das System. Einfachstes Beispiel:

intmain(){return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 23 / 68

Lokale Variablen

Zu Beginn einer Funktion konnen eine Reihe von Variablen definiertwerden, die nur innerhalb der Funktion existieren und sichtbar sind:

intmain(){int i;int j;

i = 3 + 5 * 7;j = i * i - 2;

return j;}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 24 / 68

Beispiel: Flache eines DreiecksAufgabe: Berechne die Flache des Dreiecks ABC.

Mathematik: Flache ist halbe Determinante der Kantenvektoren:

12

det(

Bx − Ax Cx − AxBy − Ay Cy − Ay

)floatarea_triangle3(float ax, float ay,

float bx, float by,float cx, float cy)

{float bax; float bay; float cax; float cay;bax = bx - ax; bay = by - ay;cax = cx - ax; cay = cy - ay;return 0.5 * (bax * cay - bay * cax);

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 25 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 26 / 68

Fallunterscheidungen

Haufig mussen wir in Abhangigkeit von Variablen unterschiedlicheRechenoperationen ausfuhren.

if(x)y = 2.0 * a + b;

elsez = 1.5 * b - a;

Falls x ungleich null ist, werden die Befehle in der zweiten Zeileausgefuhrt, sonst die in der vierten.Die dritte und vierte Zeile konnen wir wegfallen lassen, falls wir sienicht benotigen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 27 / 68

Operatoren fur Wahrheitswerte

In C steht der Wert 0 fur ”falsch“ und jeder andere Wert fur ”wahr“.

Vergleichsoperatoren ergeben 1, falls eine Relation gilt, und 0 sonst.

x < y a > b p != qx <= y a >= b p == q

Vorsicht: x = y ist eine Zuweisung, x == y ist ein Vergleich.

Logische Operatoren fuhren Oder-, Und- und Nicht-Operationen durch.

x || y a && b !f

Vorsicht: In x || y wird y nur ausgewertet, falls x gleich null ist, undin x && y wird es nur auswertet, falls x ungleich null ist.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 28 / 68

Beispiel: Fakultat per Rekursion

Induktive Definition: Die Fakultat der Zahl 0 ist 1.Die Fakultat der Zahl n ist dasselbe wie das Produkt aus n und derFakultat der Zahl n-1.

unsigned intfactorial(unsigned int n){if(n == 0)return 1;

elsereturn n * factorial(n-1);

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 29 / 68

Beispiel: Fallunterscheidung in AusdruckenWir konnen in C eine Fallunterscheidung auch direkt in einen Ausdruckhineinschreiben, beispielsweise lasst sich das Maximum der Zahlen aund b wir folgt berechnen:

maximum = (a < b ? b : a)

Falls das erste Argument ungleich null ist, wird das zweite Argumentausgewertet, sonst das dritte.

Die Berechnung der Fakultat lasst sich so kurzer schreiben:

unsigned intfactorial(unsigned int n){return (n == 0 ? 1 : n * factorial(n-1));

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 30 / 68

BlockanweisungenFormal unterscheidet die if-Anweisung nur zwischen zweiAnweisungen, die ausgefuhrt werden sollen.

Wir konnen allerdings mehrere Anweisungen und sogar lokaleVariablen mit geschweiften Klammern {, } zu einer Blockanweisungzusammenfassen:

int i; int j;if(i == 3) {int j;j = i * 7 + 5;i = j / 2;

}elsei = 2 * i + 3;

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 31 / 68

Mehrfache Fallunterscheidung

Wir konnen mit einer einzigen Fallunterscheidung auch mehreremogliche Werte eines Ausdrucks behandeln:

switch(x) {case 0:a = b;break;

case 1:a = c;break;

default:a = b + c;

}

Vorsicht: Ohne break werden auch die folgenden Befehle ausgefuhrt.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 32 / 68

while-Schleife

Wir konnen dafur sorgen, dass eine Folge von Anweisungenwiederholt wird, solange eine Bedingung erfullt ist:

i = 1;j = 0;while(i < 1000) {i *= 2;j ++;

}

Der Schleifenrumpf, der Anweisungsblock in geschweiften Klammern,wird ausgefuhrt, solange die Auswertung der Schleifenbedingung, desAusdrucks in den runden Klammern, einen von null verschiedenenWert ergibt.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 33 / 68

Beispiel: Euklidischer Algorithmus

Aufgabe: Berechnung des großten gemeinsamen Teilers.

if(a == 0)return b;

while(b != 0) {if(a > b)a -= b;

elseb -= a;

}return a;

Idee: Der ggT beider Zahlen bleibt in jedem Schritt unverandert.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 34 / 68

Beispiel: Agyptisches Potenzieren

Aufgabe: Berechne y = xp fur eine naturliche Zahl p.

y = 1; z = x;while(p > 0) {if(p % 2 == 1)y *= z;

p /= 2;z *= z;

}return y;

Idee: Binardarstellung p = pk2k + pk−12k−1 + . . .+ p121 + p0 fuhrt zuxp = (x2k

)pk (x2k−1)pk−1 . . . (x2)p1xp0 .

Vorsicht: Division ganzer Zahlen ergibt eine ganze Zahl.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 35 / 68

for-Schleife

Haufig sind vor dem Eintritt in eine Schleife Variablen zu setzen und injedem Durchlauf zu aktualisieren.

j = 0;for(i=1; i<=100; i++)j += i;

Der erste Ausdruck der for-Anweisung wird vor Eintritt in dieeigentliche Schleife ausgefuhrt.Die Schleife wird wiederholt, solange der zweite Ausdruckungleich null ist.Am Ende jedes Schleifendurchlaufs wird der dritte Ausdruckausgewertet.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 36 / 68

for-Schleife als while-Schleife

Jede for-Schleife kann auch als while-Schleife geschrieben werden:

for(i=7; i>0; i/=2)j++;

ist aquivalent zu

i = 7;while(i > 0) {j++;i /= 2;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 37 / 68

Beispiel: Fibonacci-Folge

Aufgabe: Berechne die durch f0 = 0, f1 = 1, fk = fk−1 + fk−2 gegebeneFibonacci-Folge.

if(k == 0)return 0;

g = 0;f = 1;for(i=1; i<k; i++) {h = g;g = f;f = g + h;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 38 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 39 / 68

ZeigerEine Besonderheit der Sprache C ist die Moglichkeit, unmittelbar aufdie Adressen von Variablen zuzugreifen.

Wenn wir den Adressoperator & auf eine Variablen anwenden,erhalten wir einen Zeiger auf den zu ihr gehorenden Speicherbereich.

voidpointer(){int k;int *k_ptr;k_ptr = &k;

}

Zeiger konnen genauso in Variablen gespeichert werden wie Zahlen,der Typ T * beschreibt dabei Zeiger auf Variablen des Typs T.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 40 / 68

DereferenzierenIndem wir den Inhaltsoperator * auf einen Zeiger anwenden, konnenwir den Speicherbereich, auf den er zeigt, wie eine Variableverwenden:

intdereference(){int k;int *k_ptr;k_ptr = &k;

*k_ptr = 7;return k;

}

Die Zuweisung an *k_ptr hat hier denselben Effekt wie eineZuweisung an k, die Funktion gibt immer 7 zuruck.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 41 / 68

Zeiger als FunktionsparameterMit Zeigern kann eine Funktion mehrere Ergebnisse zuruckgeben:

voidsum_and_product(float x, float y,

float *sum, float *product){

*sum = x + y;

*product = x * y;}

int main(){float a; float b;sum_and_product(7, 5, &a, &b);return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 42 / 68

Arrays

Wir konnen Variablen definieren, die mehrere Elemente einesbestimmten Typs aufnehmen, indem wir Arrays verwenden:

voidarray(){int x[4];x[0] = 3; x[2] = 8;x[1] = 5; x[3] = x[1] + x[2];

}

Vorsicht: Die Elemente eines Arrays der Lange n sind mit 0 bis n-1durchnumeriert, im Beispiel darf etwa x[4] nicht verwendet werden.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 43 / 68

Arrays und Zeiger

In fast allen Fallen unterscheidet C nicht zwischen einem Array undeinem Zeiger auf das erste Element des Arrays:

voidarray_pointer(){int x[4];int *x_ptr;x_ptr = x;x_ptr[2] = 7;x[3] = x_ptr[2];

}

Vorsicht: Dadurch wird es dem Compiler unmoglich, die Korrektheitvon Arrayzugriffen zu prufen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 44 / 68

Zeigerarithmetik

Wenn wir zu einem Zeiger eine ganze Zahl hinzuaddieren, erhalten wireinen Zeiger auf einen anderen Eintrag des Arrays:

voidpointer_add(){float x[5];float *x0_ptr, *x3_ptr, *x2_ptr;x0_ptr = x;x3_ptr = x0_ptr + 3;x2_ptr = x3_ptr - 1;

}

Vorsicht: Wir konnen in dieser Weise Werte anderer Variablen undwomoglich sogar das Programm selbst verandern.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 45 / 68

Strings

Zeichenketten werden in C als Arrays des Typs char dargestellt.

Um Zeichenketten unterschiedlicher Lange handhaben zu konnen,wird das Ende der Zeichenkette durch eine Null markiert.

Wie Zahlen konnen auch konstante Strings durch Literale definiertwerden, namlich durch in doppelte Anfuhrungszeicheneingeschlossene Buchstabenfolgen.

char *a;a = "Algorithmen und Datenstrukturen\n";

Mit einem Backslash \ konnen Sonderzeichen eingefugt werden, hieretwa durch \n der Wechsel in eine neue Zeile.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 46 / 68

Beispiel: Lange eines Strings

intlength_string(char *a){int len;len = 0;while(*a != 0) {len++; a++;

}return len;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 47 / 68

Beispiel: Suchen eines Teilstrings

char *findsub_string(char *a, char *b){char *asub, *bsub;while(*a != 0) {asub = a; bsub = b;while(*bsub != 0 && *asub == *bsub) {asub++; bsub++;

}if(*bsub == 0)return a;

a++;}return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 48 / 68

Beispiel: Befehlszeilenparameter

Der Funktion main werden in einer Unix-Umgebung auch die in derBefehlszeile angegebenen Parameter als Funktionsparameterubergeben.Das erfolgt uber ein Array aus Strings:

intmain(int argc, char **argv){int i;for(i=1; i<argc; i++)if(strcmp(argv[i], "--help") == 0)print_help_message();

return 0;}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 49 / 68

Verbunde und ZeigerEin Verbundtyp kann Zeiger auf sich selbst enthalten, wenn wir bei derDefinition dem Verbundtyp einen Namen geben:

typedef struct list_element_s {int entry;struct list_element_s *next;

} list_element;

Fur den Zugriff auf die Komponenten eines Verbundtyps, auf die einZeiger verweist, gibt es als Abkurzung den Operator ->:

list_element *this;this->entry = 42;this->next = 0;

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 50 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 51 / 68

Funktionsdeklaration

Wir konnen eine Funktion dem Compiler bekannt machen, ohne sievollstandig zu definieren. Statt einer Funktionsdefinition ist es danneine Funktionsdeklaration:

extern float area_circle(float radius);

Eine deklarierte Funktion kann wie jede andere aufgerufen werden,allerdings muss spatestens zur Laufzeit des Programms auch einevollstandige Definition vorliegen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 52 / 68

Header-DateienUber Funktionsdeklarationen lasst sich einfach der Zugriff auf externeProgrammbibliotheken und das Betriebssystem umsetzen.

Die Deklarationen werden in einer separaten Datei zusammengefasst,die wir mit einer Praprozessor-Anweisung einbinden konnen:

#include <math.h>intmain(){double x;double y;x = sin(3.0) / cos(3.0) - tan(3.0);y = log(3.5) + exp(-2.5);return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 53 / 68

Standardbibliothek

Die Kommunikation mit dem Betriebssystem, also insbesondere auchmit dem Anwender, erfolgt uber eine Standardbibliothek, die eineReihe von Funktionen enthalt, unter anderem fur

die Ein- und Ausgabe von Zeichen,die Anforderung und Freigabe von Speicher,die Manipulation von Zeichenketten odermathematische Operationen.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 54 / 68

Ausgabe von Daten

#include <stdio.h>intmain(){int i;printf("Hallo\n");i = 3 * 4 + 7;printf("3 * 4 + 7 = %d\n", i);return 0;

}

Der erste Parameter definiert das Format der Ausgabe, mit %markierte Platzhalter werden durch die weiteren Parameter ersetzt.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 55 / 68

Eingabe von Daten

#include <stdio.h>intmain(){int i;int j;scanf("%d", &i);scanf("%d", &j);printf("%d mod %d = %d\n", i, j, i % j);return 0;

}

Auch hier definiert der erste Parameter, welche Daten die Funktionerwarten soll. Vorsicht: Die weiteren Parameter mussen Zeiger sein.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 56 / 68

Speicherverwaltung

#include <stdlib.h>intmain(){int *a;a = (int *) malloc(sizeof(int));

*a = 17;free(a);return 0;

}

Der Großenoperator sizeof ermittelt die Speichergroße eines Typsoder einer Variablen,Der Cast-Operator (T) interpretiert sein Argument als Typ T.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 57 / 68

Beispiel: Einfach verkettete Liste, Teil 1

typedef struct list_s {int entry;struct list_s *next;

} list;

list *addto_list(int entry, list *s){list *new;new = malloc(sizeof(list));new->entry = entry; new->next = s;return new;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 58 / 68

Beispiel: Einfach verkettete Liste, Teil 2

list *s, *x;

s = addto_list(17, 0);s = addto_list(36, s);s = addto_list(5, s);

for(x=s; x; x=x->next)printf("%d\n", x->entry);

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 59 / 68

Arrays variabler Große

#include <stdlib.h>intmain(){int *fib; int n; int i;n = 17;fib = (int *) malloc(sizeof(int) * n);fib[0] = 0; fib[1] = 1;for(i=2; i<n; i++) {fib[i] = fib[i-1] + fib[i-2];

}free(fib);return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 60 / 68

Beispiel: StringoperationenDa Strings nur Arrays sind, wurde der Zuweisungsoperator = lediglichden Zeiger auf ihr erstes Element kopieren. Deshalb brauchen wirHilfsfunktionen, die Speicher anfordern und die Arrays kopieren.

#include <string.h>intmain(){char *a; char *b; char *ca = "Algorithmen"; b = " und Datenstrukturen";c = (char *) malloc(sizeof(char)

* (strlen(a) + strlen(b) + 1));strcpy(c, a);strcat(c, b);return 0;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 61 / 68

Ubersicht

1 Einleitung

2 Daten

3 Ausdrucke und Funktionen

4 Fallunterscheidungen und Schleifen

5 Zeiger und Arrays

6 Programmbibliotheken

7 Praxis

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 62 / 68

Compiler-WarnungenGute Compiler konnen eine Reihe typischer Programmierfehlererkennen, die in formal korrekten C-Programmen auftreten.

Das folgende Programmfragment ist korrektes C, bewirkt abervermutlich nicht das vom Programmierer Erwartete:

if(x=y)x += 3;

Wenn wir den GNU-Compiler mit zusatzlichen Parametern aufrufen,erhalten wir eine Warnung:

gcc -c -Wall -Wextra ifdemo.cwarning: suggest parentheses around assignmentused as truth value

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 63 / 68

Defensives ProgrammierenZusicherungen: C bietet eine einfache Moglichkeit, die Gultigkeitlogischer Bedingungen zu uberprufen:

#include <assert.h>

assert(p != 0);p->entry = 5;

Falls die in assert angegebene Bedingung nicht wahr ist, wird dasProgramm mit einer Fehlermeldung beendet.

Initialisierung: Es ist haufig sinnvoll, Variablen rechtzeitig in einendefinierten Zustand zu bringen. Das gilt insbesondere bei der Freigabedynamischen Speichers:

free(p); p = 0;

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 64 / 68

Verstandlichkeit des ProgrammtextsUm ein Programm verstandlich zu halten, empfiehlt es sich,Kommentare einzufugen, die zwischen /* und */ eingeschlossenwerden:

int i; /* Schleifenvariable *//* Zahlen von 1 bis 10 aufsummieren */j = 0;for(i=1; i<=10; i++)j += i;

Kommentare werden durch den Praprozessor durch Leerraum ersetzt.

Die Lesbarkeit eines Programms lasst sich weiter verbessern, indemkonsequent Leerzeilen zwischen zusammengehorenden Anweisungeneingefugt und Rumpfe von Schleifen und Fallunterscheidungen durchEinruckungen kenntlich gemacht werden.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 65 / 68

Konstante Parameter

Insbesondere bei Funktionen, die mit Zeigern arbeiten, ist es sinnvoll,das Schlusselwort const einzusetzen, um sicher zu stellen, dass uberbestimmte Zeiger nur lesend auf Variablen zugegriffen werden kann.

intstring_compare(const char *a, const char *b){while(*a != 0 && *a == *b) {

a++; b++;}if(*a == *b) return 0;else if(*a < *b) return -1;else return 1;

}

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 66 / 68

Debugger

Mit einem Debugger konnen ubersetzte Programme Schritt fur Schrittausgefuhrt und Variablen untersucht werden.Zu der GNU Compiler Collection gehort beispielsweise der GNUDebugger gdb.

gdb debugtestbreak debugtest.c:10runprint istepcont

Fur die Analyse von Speicherzugriffen ist valgrind ein hilfreichesWerkzeug, das das Programm auf einem simulierten Rechner ausfuhrtund sein Verhalten protokolliert.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 67 / 68

Make

Fur umfangreichere Projekte bietet es sich an, den Aufruf der Compilerund Linker zu automatisieren. Das Programm make berucksichtigtdabei die Abhangigkeiten zwischen den einzelnen Dateien, die wir ihmin Form der Datei Makefile zur Verfugung stellen mussen:

modul1.o: modul1.c modul1.hmodul2.o: modul2.c modul2.hprog.o: prog.c modul1.h modul2.hprog: prog.o modul1.o modul2.o

Fur jede Abhangigkeit konnen wir (mit −−→−−→ eingeruckt) Befehleangeben, mit denen das Ziel aus den Quellen erzeugt werden kann.

S. Borm (CAU Kiel) Einfuhrung C Sommersemester 2014 68 / 68