' $ embedded C und C++ S. Arlt/K. Pahnke 2006 Fakultät EI Fachbereich Elektronische Schaltungen und Systeme emsys GmbH & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 1 ' $ abgeleitete Datentypen & % ' $ entstehen durch Anwendung von Strukturierungsmethoden auf Basistypen • Felder • Strukturen struct (PASCAL: Records) • Überlagerungen union (PASCAL: variante Records) • Bitfelder 1. Felder • Zusammenfassung von Objekten gleichen Typs • wahlfreier Zugriff auf ein Element durch Indizierung • Indexzählung beginnt immer bei 0 • es wird keine Indexüberprüfung durchgeführt formale Definition: speicherklasse typ bezeichner[ konst ausdruck ]; Beispiel: #define SIZE int 10 vektor[SIZE]; /* besitzt 10 Elemente, Index 0..9 */ & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 2 ' $ mehrdimensionale Felder & % ' $ Eigenschaften mehrdimensionaler Felder: • Sie werden im Speicher linearisiert abgelegt. • Der am weitesten rechts stehende Index läuft am schnellsten. • Für jeden Zugriff ist mindestens eine Multiplikation notwendig. Beispiel: #define ZEILEN 2 #define SPALTEN 3 int matrix[ZEILEN][SPALTEN];/* besitzt 2*3 Elemente */ Initialisierung von Feldern: (gilt nur für static und globale Felder) int a[ ] = {0, 1, 2, 3}; /* a besitzt 4 Elemente */ int b[7] = {0, 1, 2, 3}; /* b besitzt 7 Elemente */ & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 3 ' $ Strukturen & % ' $ 2. Struktur := Zusammenfassung von Objekten verschiedenen Typs • Die Namen der Strukturkomponenten müssen untereinander verschieden sein. • Sie können jedoch mit dem Namen anderer Variablen und mit dem Typnamen identisch sein. • Eine Struktur darf sich nicht selbst enthalten. • Strukturen können geschachtelt werden. • Ein Zuweisen von Strukturen ist möglich. & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 4 ' $ Union und Bitfelder & % ' $ 3. Union := Objekte verschiedenen Typs auf gleicher Adresse • Es wird soviel Platz benötigt, wie für die größte Komponente. • Es ist immer nur eine Komponente enthalten. • Die Interpretation der Komponenten liegt voll beim Nutzer. 4. Bitfeld := gepackter Datentyp • spezielle Form einer Struktur • symbolischer Zugriff auf Teile eines Maschinenwortes möglich • Alternative zur Bitmanipulation • Compilerabhängig ! & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 5 ' $ Zeiger auf Felder & % ' $ Der Name eines Feldes ist eine Zeigerkonstante, also auch ein Zeiger. Beispiel: int v[10], *vptr; ... vptr = v; /* ist identisch mit vptr = &v[0] */ (vptr + 1); /* ist identisch mit v[1]; */ vptr++; /* ergibt Zeiger auf Nachfolger */ vptr--; /* ergibt Zeiger auf Vorgaenger */ & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 6 ' $ Zeiger auf Strukturen & % ' $ ermöglichen indirekten Zugriff auf Strukturkomponenten. Zugriff: (*ptr).Strukturkomponente oder spezieller Operator: −> Zeiger auf Strukturkomponente Beispiel: struct datum { short tag; char monat[4]; short jahr; } heute; struct datum *datumptr = &heute; (*datumptr).tag = 5; /* oder besser */ datumptr -> tag = 5; & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 7 ' $ Einführendes Beispiel & % ' $ Aufgabe: Kürzen eines gegebenen Bruches auf seine reduzierte Form. Lösungsansatz: • Bestimmung des größten gemeinsamen Teilers (Euklidischer Algorithmus) • Kürzen mit diesem Wert Algorithmus: • Wenn u > v, dann ist ggT (u, v) == ggT (v, u − v) (ggT ... größter gemeinsamer Teiler) • iterative Substitution von u durch u − v, solange u > 0 • v enthält dann ggT & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 8 ' $ Datenstrukturen & % ' $ • Wahl der geigneten Datenstruktur ist die wesentliche Designentscheidung im Softwareentwurf • Vielfach höhere Priorität als Algorithmen • Größere Lebensdauer • Änderungen in der Datenstruktur verursachen meisst Änderungen in mehreren Algorithmen • Unterscheidung in der Effizienz – Speicherplatzverbrauch – Komplexität der Operationen Abstrakter Datentyp (ADT) := Datenstruktur + darauf definierte Operationen und Funktionen • Zugriff erfolgt über Funktionen • Implementation wird versteckt“ ” & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 9 ' $ Zeitkomplexität & % ' $ • Beurteilung des Laufzeitverhaltens von SW • Exakte Quantifizierung nicht möglich, da abhängig vom Prozessor und der konkreten Konstellation • Qualitative Aussage über das zeitliche Verhalten einer Software mittels BigO-Funktion“ → T = O(f (n)) ” • f (n) ≡ Typ der Funktion, die das zetliche Verhalten bestimmt • selten verwendet BigΩ-Funktion“→ T = Ω(f (n)) ” Beispiel: x(n) = n P i=1 = 1 + 2 + 3 + 4 + . . . + (n − 1) + n & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 10 ' $ statisch versus dynamisch & % ' $ statisch: Vorteile: • (fast) kein Zeitaufwand für Speicherverwaltung • geringer Speicherplatzverbrauch für max. Elemente Nachteile: • Anzahl der (max.) erwarteten Elemente muß bekannt sein • Anzahl der erwarteten Elemente kann nicht überschritten werden dynamisch: Vorteile: • Speicherplatzverbrauch entsprechend Anzahl Elemente • (fast) beliebige Anzahl von Elementen möglich Nachteile: • größerer Zeitaufwand für Speicherverwaltung • Speicherplatz-Mehrverbrauch für Verkettungen (bei max. Elementen) break even ? & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 11 ' $ Listen & % ' $ Listen sind Bestandteil der Programmiersprache LISP. einfach verkettete Listen: Eigenschaften: Platzbedarf: dynamisch, Anzahl der enthaltenen Elemente Zugriff: O(n) auf Element i Einfügen: O(1) (wenn Position bekannt) Streichen: O(1) (wenn Position bekannt) Umordnen: O(1) (wenn Position bekannt) • max. Anzahl von Elementen wird durch den (Haupt-)Speicher bestimmt • Mehrverbrauch für Verkettungsinformation & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 12 ' $ Doppelt verkettete Listen & % ' $ • zusätzlicher previous - Zeiger -¿ Verkettung in beiden Richtungen • Durchlaufen der Liste in beiden Richtungen • Vereinfachtes Lschen & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 13 ' $ Operationen auf einfach verketteter Liste & % ' $ Einfügen am Anfang: addAtHead() Reihenfolge invers zum Eintrag, O(1) Löschen am Anfang: detachFromHead() Anfügen am Ende: addAtTail() richtige Reihenfolge, aber O(n) Löschen am Ende: detachFromTail() & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 14 ' $ Durchlaufen einer Liste & % ' $ Prinzip: p = Listenanfang; while ( p ist nicht Listenende ) { führe Operation auf p aus; gehe zu Nachfolger von p; } p wird nacheinander auf alle Listenelemente gesetzt. Realisierung: Benutzung eines Iterators als Cursor. Der Iterator kennt: • die zu durchlaufende Liste • die aktuelle Position • das aktuelle Element & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 15 ' $ Operationen mit Iterator & % ' $ Einfügen nach Position: insertAfter() Löschen nach Position: detachAfter() Einfügen vor Position: insertBefore() Löschen auf Position: detachAt() Alle dargestellten Operationen haben die Komplexität O(1). & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 16 ' $ Stack (Stapel) & % ' $ Eigenschaften: • LIFO Struktur • Zugriff nur mit Einschränkungen auf Daten möglich. (Nur das oberste Element ist sichtbar) Platzbedarf: max. Anzahl erwarteter Elemente / dynamisch Zugriff: O(1) auf Element top Einfügen: O(1) (Operation push) Streichen: O(1) (Operation pop) Umordnen: nicht zulässig Realisierung: • statisch auf Array-Basis (BoundedStack) • dynamisch auf Listen-Basis & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 17 ' $ Queues (Schlangen) & % ' $ Eigenschaften: • FIFO Struktur • Zugriff nur mit Einschränkungen auf Daten möglich. (Nur das jeweils zuerst eingefügte Element ist sichtbar) Platzbedarf: max. Anzahl erwarteter Elemente / dynamisch Einfügen: O(1) (Operation put) Streichen: O(1) (Operation get) Umordnen: nicht zulässig • statisch auf Array-Basis (BoundedQueue) • dynamisch auf Listen-Basis & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 18 ' $ statisches Feld & % ' $ Felder sind Bestandteil von Programmiersprachen. Eigenschaften: Platzbedarf: max. Anzahl erwarteter Elemente Zugriff: O(1) auf Element i Einfügen: O(n) (n Elemente verschieben) Streichen: O(n) (n Elemente verschieben) Umordnen: O(n) • falls max. Größe überschritten wird, muß die Berabeitung abgebrochen werden. & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 19 ' $ Initialisierung von Feldern & % ' $ Variante CISC (386/25) RISC (Sparc ELC) 1 70 ms 8.9 ms 2 30 ms 8.6 ms 3 10 ms 8.2 ms & Arlt/Pahnke TUI/EI/ESS emsys % eC CPP-II 20 $ ' dynamische Arrays & % ' $ Ziel: Vereinigung der Vorteile des statischen Array mit der Fähigkeit der dynamischen Anpassung der Größe an die aktuellen Erfordernisse. Eigenschaften: Platzbedarf: dynamisch (Anzahl Elemente + delta) Vergrößern: O(n) (n Elemente kopieren) Realisierung: • Benutzung des Freispeichers als Array mittels void *calloc(int anz elem, int sizeof elem); • Berücksichtigung eines Pufferbereiches delta anz elem = minanz elem + delta; • Modifikation der Größe über Funktion void *realloc(void *oldbuf, int anz bytes); Achtung: Es dürfen keine Zeiger auf den Standort der Elemente aufgehoben werden. & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-2 $ ' geordnete Datenstrukturen & % ' $ Prinzip: Definition einer Ordnungsrelation zwischen zwei Elementen. Eine Vergleichsfunktion int cmp(elem1, elem2) liefert: < 0, wenn elem1 < elem2 0, wenn elem1 == elem2 > 0, wenn elem1 > elem2 • Plazierung der Elemente innerhalb der Datenstruktur nach ihrer Relation zu benachbarten Elementen. • Anordnung ist Aufgabe der Datenstruktur, nicht des Anwenders Universalität: Benutzung von Zeigern auf Funktionen für Vergleichsfunktion. & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-3 $ ' sortiertes Array & % ' $ Eigenschaften: wird zurückgeführt auf normales Array. Suchen: O(log n) (binäre Suche im Array) Realisierung der binären Suche: lower = 0, upper = nb elem - 1 while ( lower < upper ) { middle = (lower + upper) / 2; if ( gesuchtes Element == array[middle] ) gefunden else if ( gesuchtes Element < array[middle] ) suche in unterer Hälfte weiter upper = middle - 1 else suche in oberer Hälfte weiter lower = middle + 1 } Element war nicht enthalten & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-4 $ ' sortierte Liste & % ' $ wird zurückgeführt auf einfache Liste. Eigenschaften: Mischen: O(m+n) (Vereinigung zweier Listen mit m und n Elementen) Realisierung des Mischens: Einsatz von zwei Iteratoren vergleiche Listenanfänge und lege aktive Liste fest Anfang Zielliste = Anfang aktive Liste while ( noch Elemente da ) { if ( aktives Element > erstes ruhendes Element ) Kettung von Vorgänger aktiver Liste zu ruhendem Element Wechsel der Listen ruhend und aktiv else Kettung bleibt unverändert bestehen } füge die verbliebenen Elemente an die Zielliste an & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-5 $ ' Rekursion & % ' $ • Ein rekursives Objekt enthält sich selbst als Teil oder wird mit Hilfe seiner selbst beschrieben. direkt rekursiv: Programm enthält Aufruf von sich selbst indirekt rekursiv: erneuter Aufruf in Unterprogramm verborgen • unendliche Menge von Objekten wird durch endliche Aussage spezifiziert Eigenschaften: • lokale Variablen (auch Funktionsparameter) werden für jeden Aufruf neu angelegt • sie haben i.a. in jedem Aufruf andere Werte • Konflikte durch Gültigkeitsbereiche ausgeschlossen Achtung: • Abbruchbedingung definieren: if (bedingung) return; • möglichst geringe Stacktiefe garantieren • für rekursive Datenstrukturen anwenden • Entscheidung: Iterative Lösung besser ?“ (Lesbarkeit etc.) ” & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-6 $ ' Bäume & % ' $ Definition: Baum := spezieller (gerichteter) Graph, kann zur Liste entarten Darstellungen: • ,,oberster” Knoten ist root (auf Ebene 0) • der Knoten ,,unterhalb” eines Knoten ’x’ (auf Ebene i) ist direkter Nachfolger von ’x’ (auf Ebene i+1) • ,,Höhe” des Baumes wird durch Anzahl der Ebenen bestimmt • Knoten ohne Nachfolger sind leaf nodes (Endknoten) • Anzahl der Nachfolger eines Knoten bestimmen seinen ,,Grad” • Anzahl der Kanten von Wurzel bis Knoten ’x’ heißt ,,Weglänge” von ’x’ & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-7 $ ' binärer Baum & % ' $ 2-dimensional verkettete Strukturen Häufige Anwendung als binärer Suchbaum. Eigenschaften: Platzbedarf: dynamisch Höhe: (logn) + 1, wenn ausgeglichen Blattanzahl: ca. n / 2, wenn ausgeglichen Einfügen: O(log n) falls nicht entartet Löschen: O(log n) falls nicht entartet Realisierung: typedef int NODEDATA; NODEDATA data; struct node *left; struct node *right; struct node { }; & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-8 $ ' Beispiel Syntaxbaum & % ' $ Darstellung von: (a + b / c) * (d - e * f) & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-9 $ ' Operationen auf Binär - Bäumen (1) & % ' $ Durchmustern 1.Tiefe Preorder: (Wurzel, Links, Rechts) *+a/bc–d*ef Inorder: (Links, Wurzel, Rechts) a+b/c*d–e*f Postorder: (Links, Rechts, Wurzel) abc/+def*–* 2. Breite Levelorder: (vgl. Wellenfront) *+–a/d*bcef & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-10 $ ' Operationen auf Binär - Bäumen (2) & % ' $ Konstruktion ausgeglichener Bäume • linker Teilbaum: nl = n / 2 Knoten • rechter Teilbaum: nr = n - nl - 1 Knoten Einfügen • Richtungswahl von Schlüssel und aktuellem Knoten abhängig Löschen • trivial für Endknoten und Knoten mit einem Nachfolger • sonst Reparatur“ des Baumes notwendig ” & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-11 $ ' ausgeglichene Bäume & % ' $ Ziel: • Erhaltung der hervorragenden Eigenschaften des Baumes unabhängig von den ausgeführten Operationen. • Vermeidung des Entartens. Definition: Ausgeglichen := Höhe der Teilbäume zu jedem Knoten höchstens um 1 verschieden Achtung: Implementierung oft schwierig, da viele Sonderfälle zu behandeln sind. & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-12 $ ' balancierter binärer Baum (AVL - Tree) & % ' $ Eigenschaften: Höhe: (log n) + 1 Blattanzahl: ca. n / 2 Einfügen: O(log n)+1 Löschen: O(log n)+1 Realisierung: typedef int NODEDATA; NODEDATA data; int balance; struct node *left; struct node *right; struct node { }; Anwendung: • häufige Suche, wenig Erweiterungen • Ausgleich erfolgt – nach etwa 2 Einfügeoperationen – nach etwa 5 Löschoperationen & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-13 $ ' Operationen auf AVL - Trees & % ' $ Beispiel Einfügen (linker Teilbaum): h(left) == h(right) Höhe wird verschieden (zulässig) h(left) < h(right) Höhe wird ausgeglichen h(left) > h(right) Ausgeglichenheit wird zerstört Umstrukturieren ! Auf dem Rückweg vom Abstieg zur Wurzel wird Reparatur durchgeführt. (wird als Rotation bezeichnet) & Pahnke/Schröder/Arlt TUI/EI/ESS % eC CPP Kap10-12-14 $ ' 2-3-4 - Bäume & % ' $ & % Pahnke/Schröder/Arlt TUI/EI/ESS eC CPP Kap10-12-15