Programmieren in C "Was ist wichtig?" Hochschule Fulda – FB AI Wintersemester 2014/15 http://c-ai.rz.hs-fulda.de Peter Klingebiel, HS Fulda, DVZ Der Alles-Markierer von Pia Valentin (AI - Digitale Medien – Danke an Pia für das Foto) 1. Platz im Fotowettbewerb „Zeig mir wie Du lernst“, HS Fulda 2014 Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 2 Grafik von Prof. Dr. U. Werner, ET Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 3 C-Preprozessor 1 • C-Preprozessor bearbeitet C-Quelltexte vor dem eigentlichen Compilerlauf • rein textueller Eingriff in den Quelltext • CPP hat eigene Syntax • # leitet CPP-Anweisungen ein • CPP-Anweisungen nicht mit ; terminiert! • Wichtige Direktiven von CPP: – #include – Dateien einfügen – #define – Makros definieren – #if / #ifdef – Bedingte Compilierung Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 4 C-Preprozessor 2 • #include – fügt den Inhalt anderer Dateien (sog. Headerfiles) in den Quelltext ein • Includedateien enthalten i.w. – – – – – – – Deklarationen von Funktionen (prototypes) Deklarationen von Datentypen Deklarationen von externen/globalen Variablen Definitionen von Konstanten (const) Definitionen von Konstanten als CPP-Makro Definitionen von CPP-Makros Bedingte Compilierung Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 5 C-Preprozessor 3 • #define – definiert ein Makro Textersatz #define makroname #define makroname ersatztext #undef makroname • Beispiele: – #define UNIX - Makro UNIX definiert, z.B. zur Verwendung bei bedingter Compilierung – #define EOF (-1) - Makro EOF wird durch Ersatztext (-1) ersetzt wie Konstante – #undef TEST - Makro TEST nicht definiert Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 6 C-Preprozessor 4 Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 7 C-Preprozessor 5 • Bedingte Compilierung Verändern des Quelltextes abhängig von CPP-Makros • Syntax #if (expr1) #elif (expr2) #else #endif • und #ifdef (symbol) #ifndef (symbol) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 8 Anweisung / Ausdruck 1 • C kennt keine Anweisungen (statements), sondern nur Ausdrücke (expressions) • Ausdruck hat einen Wert (wie in Assembler!) • Beispiel: Zuweisung in C int i; i = 4711; • Zuweisung kann auch ausgewertet werden: int a, b, c, i, j; a = b = c = 3; if(i = 4711) ... while(j = 1) ... Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 9 Anweisung / Ausdruck 2 • Ausdruck Gültige Kombination von Konstanten, Variablen, Operatoren, Funktionen • Reihenfolge der Auswertung – Vorrangregeln der Operatoren legen Reihenfolge der Auswertung implizit fest – Klammern ( ) legen Vorrangregeln explizit fest – Sind Vorrangregeln nicht eindeutig Reihenfolge der Auswertung nicht definiert – Compiler kann Ausdrücke / Teilausdrücke in effizient auswerten / optimieren Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 10 Typumwandlung in Ausdrücken • Implizite (automatische) Typumwandlung • Explizite Typumwandlung durch Type Casting: double x; int i = 3, j = 10; x = (double) i / (double) j; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 11 Datentypen 1 • Vordefinierte Grunddatentypen char int Zeichen (ASCII-Kode, 8 Bit) Ganzzahl (maschinenabhängig, meist 16 oder 32 Bit) float Gleitkommazahl (32 Bit, IEEE, etwa auf 6 Stellen genau) double doppelt genaue Gleitkommazahl (64 Bit, IEEE, etwa auf 12 Stellen genau) void ohne Wert (z.B. Zeiger) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 12 Datentypen 2 • Type-Modifier spezifizieren Grunddatentypen • short int, long int, long long – legen Länge der Ganzzahl – maschinenabhängig, 16 Bit, 32 Bit – int kann auch fehlen • long double – Gleitkommazahl, erw. Genauigkeit – oft 96 oder 128 Bit, IEEE • signed, unsigned – char/int mit/ohne Vorzeichen Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 13 Konstanten • Konstanten haben einen festgelegten und damit unveränderbaren Wert • explizite Definition, z.B. const float pi = 3.141; • implizite Definition, z.B. u = 2 * r * 3.141; • mittels CPP textuelle implizite Ersetzung #define PI 3.141 ... u = 2 * PI * r; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 14 Variablen 1 • Variable sind Platzhalter für Daten • haben einen festgelegten Speicherort, an dem der aktuelle Wert gespeichert wird • der aktuelle Wert (an seinem Speicherort) ist veränderbar • Eigenschaften von Variablen: – – – – – Datentyp Namen (Bezeichner, Identifier) Lebensdauer / Speicherklasse evtl. initialer Wert Sichtbarkeit (Scope) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 15 Variablen 2 • Variablen-Definitionen typ name und evtl. Initialisierung , z.B. double u; short int i, tab = 5; char *hallo = "Hallo, Welt!"; • Position im Programm: – außerhalb von Funktionen – in einem Block, also zwischen { } • Wert ist veränderbar (Zuweisung, Operation) • Programmstruktur Lebensdauer / Scope Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 16 Wie speichert C? • Programmstart und Aufruf von main() Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 17 Zeiger 1 • Jede Variable hat einen Speicherort, d.h. eine Adresse im Hauptspeicher • Zeiger (Pointer) sind Variable, die auf eine andere Variable verweisen, oder exakter: den Speicherort bzw. die Adresse dieser Variablen als Wert haben • Pointerdefinition: int *ip; int i = 5; • Adresszuweisung: ip = &i; • Zugriff auf Wert: *ip = *ip + *ip; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 18 Zeiger 2 • Zuweisung ip = &i; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 19 Funktionsaufruf und Parameter • Parameterübergabe als Werte (call by value), z.B. bei printf() • Variable werden als Werte in den Adressraum der Funktion kopiert • Parameterübergabe als Adresse (call by reference), z.B. bei scanf() • Adressen der Variablen werden in den Adressraum der Funktion kopiert • In Funktion sind die Parameter Zeiger Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 20 Call by value • Kopie des Parameters an Funktion Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 21 Call by reference • Kopie der Adresse an Funktion Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 22 Felder 1 • ein Feld (array) ist die Zusammenfassung von Daten gleichen Typs in einer Variablen • Felder haben eine oder auch mehrere Dimensionen (Vektoren, Matrizen, …) • Definition von Feldern: char sbuf[128]; int arr[] = { 1, 8, 7, -1, 2 }; short mat[2][2] = { 11, 12, 21, 22}; • mit der Felddefinition wird der benötigte Speicherplatz für die Variable reserviert Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 23 Felder 2 • Zugriff auf Feldelemente mit Index in []: char c; c = sbuf[32]; sbuf[0] = 'A'; • die Feldindizierung beginnt immer mit 0! short s, mat[3][3]; s = mat[0][0]; • Felder werden elementweise und Zeile für Zeile hintereinander gespeichert • es gibt beim Zugriff keinerlei Überprüfungen auf Bereichsgrenzen von Feldern! Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 24 Felder 3 • Feldvariable sind eigentlich Pointer, sie zeigen auf das erste Element im Feld int i, *ip, ia[4] = {11, 22, 33, 44}; ip = ia; i = *++ip; • Felder werden mit Adresse an Funktionen übergeben (wie Pointer) • Feldindizes sind eigentlich Offsets und geben den Abstand zum Feldanfang an Bsp: ia[3] *(&ia[0] + 3 * sizeof(int)) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 25 Felder und Zeiger • Felder reservieren bei der Definition den benötigten Speicherplatz • Zeiger erhalten den Speicherplatz erst bei der Zuweisung des Objekts, auf das sie zeigen, oder bei dynamischer Speicherallokation • Ähnlichkeit von Feldern und Zeigern mächtige Pointerarithmetik möglich • Manchmal ein wenig unverständlich! • Pointer essentiell bei Zeichenketten (strings) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 26 Zeichenketten 1 • Zeichenketten (strings) sind eine Folge von Einzelzeichen char • String ist terminiert mit '\0' • Speicherbedarf: Länge + 1 Byte • Beispiel: char *s; char *hallo = "Hallo, Welt!"; • String Pointer auf Feld von Elementen vom Typ char • Nullstring NULL (definiert in stdio.h) • Leerstring char *leerstr = ""; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 27 Zeichenketten 2 • Beispiel: char buffer[128]; char *bp = buffer; • Stringpointer bp erstes Zeichen im Feld buffer • Ähnlichkeit von Feldern und Pointern! • Beispiel: String kopieren und ausgeben char buffer[64], *bp; strcpy(buffer, "Hallo, Welt"); bp = buffer; while(*bp) putchar(*bp++); Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 28 Kommandozeilenparameter • Jedes C-Programm startet mit einer mainFunktion • main-Funktion ist vom Typ int und hat drei Parameter: • int argc Anzahl von Kommandozeilenparametern • char *argv[] Feld von Strings Kommandozeilenparameter • char *envv[] Feld von Strings Umgebungsparameter Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 29 Aufzählungsdatentyp • Aufzählungsdatentyp enum • Für Datentypen mit diskreten konstanten Werten • Beispiel: enum color { rot, gruen, blau } c; enum boolean { FALSE, TRUE } b; b = FALSE; c = blau; • Darstellung als int beginnend mit 0, wenn nicht explizit angegeben: enum boolean { TRUE=1, FALSE=0 } b; b = TRUE; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 30 Zusammengesetzte Datentypen 1 • Zusammenfassung von zusammengehörigen Daten in eigenen Datentyp struct • Beispiel: einfaches EA-Gerät mit 8-Bit Steuerregister cr und 16-Bit Datenregister dr: struct { char cr; int dr; } ea1; struct _ea { char cr; int dr; } ea2; • Zugriff durch Selektor . if(ea1.cr & 0x01) ea2.dr = 4711; • bei Pointern durch Selektor -> if(ea1->cr & 0x01) ea2->dr = 4711; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 31 Zusammengesetzte Datentypen 2 • Beispiel: Datentyp struct circle für Objekt Kreis in einem Zeichenprogramm notwendig Mittelpunkt (x,y) und Radius r /* Kreis: Typ */ struct circle { int x; /* Mittelpunktkoordinate x */ int y; /* Mittelpunktkoordinate y */ int r; /* Radius */ }; struct circle c; c.x = 100; c.y = 100; c.r = 50; Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 32 Zusammengesetzte Datentypen 3 • union - spezielle Art von struct • anderer Name: varianter Rekord • Speichern der Elemente in union nicht nacheinander, sondern übereinander • union-Elemente teilen sich Speicherplatz • sinnvoll bei gleichartigen Objekten, die aber verschiedenen Typs sein können union { char c; short s; int i; } u; /* Union: /* char /* short /* int /* teilen sich Platz Programmieren in C - Peter Klingebiel - HS Fulda - DVZ */ */ */ */ */ 33 Zusammengesetzte Datentypen 4 • union meist Element in einem struct • Typ des Elements in union muss definiert sein eigenes Typelement im struct • Beispiel struct number { byte typ; union { byte b; short s; int i; } u; }; /* Struct Zahl /* Typ union-Element /* Union: /* byte /* short /* int Programmieren in C - Peter Klingebiel - HS Fulda - DVZ */ */ */ */ */ */ 34 Typdefinitionen • Oft sinnvoll, eigene Typen oder Untertypen zu definieren typedef • Beispiel: typedef unsigned char byte; • Beispiel: typedef struct _ea { byte cr; int dr; } ea; ea ea1, ea2; • eigentlich nur ein neuer Name für den Typ besser lesbar, bessere Dokumentation! Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 35 Ausdrücke • Ausdrücke – Definitionen, Zuweisungen, … – arithmetische, logische, … Operationen, … • bei Zuweisungen zu beachten: gültiger l-value und r-value – l-value (left, location) Variable mit Speicherplatz – r-value (right, read) auswertbarer Ausdruck – Beispiel: int i, j; i = 9 / 3; 45 = j; /* gültiger l-value */ /* ungültiger l-value */ Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 36 Blöcke 1 • • • • Zusammenfassung mehrerer Anweisungen Geklammert mit { } v.a. bei Funktionen, Kontrollstrukturen aber auch lokale Blöcke (Unterblöcke) z.B. zur Definition von lokalen Variablen, insbesondere Hilfsvariablen • legt Lebensdauer von Variablen fest • legt Sichtbarkeit (Scope) von Variablen fest • bei Namensgleichheit ist Variable des innersten Blocks sichtbar Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 37 Blöcke 2 Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 38 Kontrollstrukturen • Kontrolle des Programmablaufs abhängig von Ergebnis von Ausdrücken • Selektionen / bedingte Anweisungen – Einfache Alternative if … else – Mehrfache Alternative if … else if … else – Fallunterscheidung switch • Iterationen / Schleifen – Abweisende Schleife while – Laufanweisung for – Annehmende Schleife do … while Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 39 Selektionen 1 • Bedingte Anweisung if • Syntax: if (ausdruck) anweisung • Bedingte Anweisung if … else • Syntax: if (ausdruck) anweisung else anweisung Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 40 Selektionen 2 • Mehrfache Alternative if…else if…else if (ausdruck_1) anweisung_1 else if(ausdruck_2) anweisung_2 else if(ausdruck_3) anweisung_3 else if (ausdruck_n) anweisung_n ... ... else /* kann auch fehlen */ anweisung_else Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 41 Selektionen 3 • Mehrfachauswahl oder Fallunterscheidung bei konstanten Alternativen switch switch(ausdruck){ case k1: // k1 Konstante anweisung_1; break; case k2: // k2 Konstante anweisung_2; break; . . . default: anweisung_default; } Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 42 Iterationen 1 • Abweisende Schleife while, manchmal auch kopfgesteuerte Schleife genannt • Syntax while (ausdruck) anweisung • Bedingung ausdruck wird vor Ausführung vom Schleifenkörper anweisung geprüft • Schleifenkörper wird nur ausgeführt, wenn Bedingung ausdruck wahr ist Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 43 Iterationen 2 • Laufanweisung oder abweisende Schleife mit for • Syntax for(ausdruck1; ausdruck2; ausdruck3) anweisung • Kann durch while-Schleife ersetzt werden: ausdruck1; while(ausdruck2) { anweisung; ausdruck3; } Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 44 Iterationen 3 • Nicht-annehmende Schleife do while, machmal auch: fußgesteuerte Schleife • Syntax do anweisung while (ausdruck) • Bedingung ausdruck wird erst am Ende des Schleifenkörperts geprüft • Schleife wird mindestens einmal durchlaufen Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 45 Iterationen 4 • Schleifensteuerung • break – bricht die Ausführung der aktuellen Schleife bzw. switch-Anweisung ab und verlässt diese • continue – bricht den aktuellen Schleifendurchlauf ab – setzt mit Ausführung des Schleifenkopfes fort • Endlosschleife while(1) ... for(;;) ... Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 46 Funktionen 1 • Funktionen sind Programmteile (Blöcke) mit Namen, ggfs. Parametern und ggfs. einem Rückgabewert • elementare Bausteine für Programme – gliedern umfangreiche Aufgaben in kleinere Komponenten – reduzieren Komplexität – Wiederverwendung von Komponenten – verbergen Details der Implementierung vor anderen Programmteilen (black box) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 47 Funktionen 2 • Funktionsdefinition typ name(parameter) • Typ – Datentyp, der von Funktion zurückgeliefert wird – void kein Rückgabewert (Prozedur) • Name – Bezeichner kann beliebig gewählt sein – Regeln für Identifier, keine Schlüsselworte • Parameter – Liste von typ name der Parameter in Klammern – keine Parameter: () oder (void) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 48 Funktionen 3 • Body Block mit {} geklammert • zusätzliche Anweisung return(ausdruck) Rückkehr aus der Funktion • Bei void-Funktion: nur return • nach Rückkehr aus Funktion Programm wird nach Funktionsaufruf fortgesetzt • Typ von Ausdruck und Funktion müssen übereinstimmen • Klammern bei return können entfallen Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 49 Funktionen 4 • Die Ausdrücke in der Parameterliste werden vor dem Sprung in die Funktion ausgewertet aktuelle Parameter • Anzahl und Typen der Ausdrücke der aktuellen Parameter müssen mit denen der formalen Parameter in der Definition der Funktion übereinstimmen • Die Auswertungsreihenfolge der Parameterausdrücke ist nicht festgelegt Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 50 Funktionen 5 • Funktionen werden global definiert keine lokalen Funktionen möglich • static beschränkt Funktion auf Modul • main() ist normale Funktion, die aber beim Programmstart automatisch aufgerufen wird • Rekursion ist möglich: int fak(int n) { if(n == 1) return(1); else return(n * fak(n-1)); } Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 51 Funktionen 6 • Funktionen müssen deklariert sein, bevor sie aufgerufen werden können • Name, Rückgabetyp und Parametertypen müssen dem Compiler bekannt sein • Funktionsdefinition Funktion ist automatisch deklariert und bekannt • sonst Prototype, z.B. in Headerdatei typ name ( liste der parametertypen ); • Beispiele: double sin(double); double cos(double x); Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 52 Funktionen 7 • Parameterübergabe an Funktionen • call by value – aktuelle Parameter werden in Speicherbereich der Funktion kopiert – in Funktion: Änderungen nur lokal in Funktion • call by reference – In C nur über Zeiger realisierbar – Adresse der Parameter werden in Funktion kopiert – Änderungen an Parametern Änderungen an den originalen Variablen Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 53 Speicherklassen 1 • Funktionen können nur global, d.h. ausserhalb von Blöcken definiert werden – Sichtbarkeit global – static Sichtbarkeit im Quelldateikontext • Variablen können ausserhalb von Blöcken, d.h. global definiert werden – Sichtbarkeit global – static Sichtbarkeit im Quelldateikontext • Variablen können innerhalb von Blöcken, d.h. lokal oder automatisch definiert werden Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 54 Speicherklassen 2 • auto – nur innerhalb eines Blocks, Standardklasse – Variable existiert / ist sichtbar nur im Block • static – in Block: Variable erhält ihren Wert – sonst: Variable/Funktion nur in C-Quelle sichtbar • extern – Variable ist in anderer C-Quelle definiert • register – Variable CPU-Register, hat keine Adresse! Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 55 Lebensdauer • Lebensdauer einer Variablen ist die Zeit, in der diese Variable Speicherplatz belegt • lokale / automatische Variable – „lebt“, d.h. hat einen Speicherort vom Anfang bis zum Ende des Blocks, in dem sie definiert ist – Speicherplatz wird bei Verlassen des Blocks wieder freigegeben Variable ist ungültig! – Zugriff darauf ist dann undefiniert • globale oder statische Variable – „lebt“ vom Anfang bis zum Ende des Programms Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 56 Sichtbarkeit 1 • der Sichtbarkeitsbereich (Scope) einer Variablen Programmabschnitt, in dem die Variable sichtbar / nutzbar / gültig ist • der Scope wird durch den Ort der Definition bzw. Deklaration der Variablen festgelegt – innerhalb eines Blocks sichtbar von der Stelle der Definition bis zum Blockende – ausserhalb sichtbar von Stelle der Definition bzw. Deklaration bis zum Ende der Quelldatei – mit static definierte Variablen sind nur im Modul (= C-Quelldatei) sichtbar Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 57 Sichtbarkeit 2 • globale Variable müssen ausserhalb von Blöcken definiert sein • Variablen aus anderen Modulen (globale Variable) müssen explizit als extern deklariert werden • Scope einer Funktion: Bereich auf Ebene des Programms, in der die Funktion nutzbar ist – global – sollte dann vor Nutzung bekannt sein (Prototype) – lokal nur im Modul bei Definition als static Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 58 Module • um größere Programmprojekte überschaubar und sicherer zu machen, wird die Aufgabe in kleinere Teilaufgaben (= Module) zerlegt – – – – Reduktion der Komplexität separates Entwickeln und Testen Wiederverwendbarkeit von Programmteilen Erstellen von Programmbibliotheken • Abstraktion von Daten und Funktionen • Kapselung von Daten Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 59 Bibliotheken • in der Programmiersprache C sind nur die notwendigsten Grundfunktionalitäten definiert – es fehlen z.B. Funktionen für Ein-/Ausgabe, Funktionen für Dateihandling, Funktionen für Stringhandling, höhere mathematische Funktionen und vieles andere mehr – erleichtert die Entwicklung eines C-Compilers – leichtere Anpassung / Übertragung auf andere Hardware oder Betriebssystem • Viele der o.g. Funktionen sind in der sog. Standardbibliothek definiert! Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 60 Bibliotheken und Module • Projekt: Module und Bibliotheken Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 61 Dynamischer Speicher • Oft: Größe von Objekten erst zur Laufzeit bekannt Bereitstellen des benötigten Speicherplatzes dynamisch (Heapsegment) • #include <stdlib.h> • Anforderung von Speicher: – void *malloc(size_t s) – s Bytes allozieren – void *calloc(size_t n, size_t s) – s * n Bytes allozieren und mit 0 initialisieren – return NULL bei Fehler, sonst Pointer auf Speicherbereich • Freigabe von alloziertem Speicher – void free(void *ptr) Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 62 Dynamische Datenstrukturen • häufig ist die Anzahl der zu speichernden und zu bearbeitenden Daten erst zur Laufzeit des Programms bekannt • Felder ungeeignet: müssen zur Compilezeit oder in Blöcken dimensioniert werden • dynamische Datenstrukturen – – – – einfach verkettete Listen doppelt verkettete Listen Bäume usw. Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 63 Dynamische Listen 1 • Beispiel: einfach verkettete Liste /* Datentyp f. einfach verkettete Liste */ typedef struct _slist { int value; /* Daten */ struct slist *next; /* Nachfolger */ } slist; • Beispiel: doppelt verkette Liste /* Datentyp f. typedef struct int value; struct dlist struct dlist } dlist; doppelt verkettete Liste _dlist { /* Daten *prev; /* Vorgaenger *next; /* Nachfolger Programmieren in C - Peter Klingebiel - HS Fulda - DVZ */ */ */ */ 64 Dynamische Listen 2 • Objekte der Listentypen werden zur Laufzeit – alloziert slist *insert(slist *llp, int value){ slist *nlp; nlp = (slist *) malloc(sizeof(slist)); – besetzt bzw. initialisiert nlp-> value = value; nlp->next = NULL; – und in die Liste eingehängt if(llp) llp->next = nlp; return(nlp); } Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 65 Dynamische Listen 3 • Einfache Liste: Erzeugung 1. Element Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 66 Dynamische Listen 4 • Einfache Liste: n. Element und Verkettung Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 67 Dynamische Listen 5 • erstes Element wird oft Wurzel, Anker oder Kopf der Liste genannt • Durchlaufen der Liste i.d.R. von der Wurzel der Liste aus slist *root, *slp; for(slp = root; slp; slp = slp->next) printf("%d\n", slp->value); • wird das letzte Listenobjekt mit der Wurzel verlinkt Ringpuffer • Sortieren bei Erzeugen der Liste möglich Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 68 Felder, Zeiger, Listen 1 • bekannt: Felder und Zeiger werden in C ganz ähnlich behandelt • Wesentlichster Unterschied: – Felder sind dimensioniert ihnen ist ein fester Speicherort zugeordnet für die zu speichernden Objekte / Feldelemente ist Platz vorhanden – Zeiger weisen erst nach Zuweisung oder dyn. Allozierung auf den Speicherort ihrer Objekte • Feldvariable Adresse des 1. Elements • Feldindizes Offset im Feld Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 69 Felder, Zeiger, Listen 2 • Konstante Dimensionierung von Feldern double df[100]; /* Feld mit 100 Elementen */ • Variable Dimensionierung von Feldern nur für automatische Feldvariable zulässig void fun(int n) { double df[n]; /* Feld mit n Elementen */ ... } • Grund: Feldgröße muss beim Anlegen / bei Speicherzuweisung des Felds bekannt sein – statisch / global Compilezeit – automatisch / lokal Eintritt in Funktion / Block Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 70 Felder, Zeiger, Listen 3 • variable Dimensionierung von statischen und globalen Feldern häufig benötigt • Lösung dynamische Feldallozierung • Beispiel: double-Feld dynamisch duplizieren double *dbldup(double d[], int n) { double *df; int i; df = calloc(n, sizeof(double)); for(i = 0; i < n; i++) df[i] = d[i]; return(df); } Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 71 … und nun: viel Erfolg in der Klausur … Programmieren in C - Peter Klingebiel - HS Fulda - DVZ 72