Einführung in die Programmiersprache C Mikrorechentechnik 1 Wintersemester 2007/2008 Technische Universität Dresden Professur für Prozessleittechnik Grobplanung Themen Termin 8.10 Nr Thema 1 Einführung, Prozessorkonzepte, Familie i80x86 10.10 2 Assembler, Register, Flags, Speicher 15.10 3 Speicheraddressierung, Datentransfer, Operationen 17.10 4 Steuerung des Programmflusses 22.10 5 Stack, Unterprogramme, Interrupts 24.10 6 Makros, Pseudobefehle und Steueranweisungen 29.10 7 Anbindung von Prozessperipherie 31.10 5.11 Reformationstag 7 Grundelemente der Programmiersprache C 7.11 12.11 Konzilsitzung im BAR/SCHÖ 9 Datentypen, Ausdrücke und Typumwandlung 14.11 10 Steuerung des Programmflusses 19.11 11 Funktionen und Funktionssammlungen 21.11 26.11 Bußtag 12 Dynamische Datenstrukturen in C TU Dresden, 05.11.07 28.11 13 XYZ Anbindung Präsentationsname von Prozessperipherie Folie 2 von XYZ Einführung in C Teil 1 – Variablen und Ausdrücke Schlüsselwörter, Kommentare, Vereinbarung von einfachen Variablen Ausdrücke und Operatoren Felder, Zeiger Teil 2 – Programmsteuerung Bedingungen, Schleifen, Funktionen Teil 3 – Datenstrukturen Strukturen, dynamische Listen TU Dresden, 05.11.07 Präsentationsname XYZ Folie 3 von XYZ Bücher, Links Bücher Zeiner, K. (2000) Programmieren lernen mit C. München: Hanser Schellong, H. (2005) Moderne C-Programmierung. Berlin: Springer Erlenkötter, (2003) C-Bibliotheksfunktionen sicher anwenden. Reinbeck: Rowohlt Kerningham,B., & Ritchie, D. (1983/1990) Programmieren in C. München: Hanser Internet WikiBooks: C-Programmierung http://de.wikibooks.org/wiki/C-Programmierung WikiBooks: C-Sprachbeschreibung http://de.wikibooks.org/wiki/C_Sprachbeschreibung TU Dresden, 05.11.07 Präsentationsname XYZ Folie 4 von XYZ Historie ~1974 fertig entwickelt 1978 Kerningham & Ritchie: The C Programming Language - K&RStandard 1983 Deutsche Übersetzung K&R 1988 Standardisierung ANSI-C (C89) 1990 ISO/IEC 9899:1990 (C90) 1999 Überarbeitung (C99) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 5 von XYZ Warum C • Nachteile Assembler: – Prozessorabhängige Instruktionen und Adressierungsarten – Richtige Interpretation von Speicherinhalten in der Verantwortung des Programmierers • C ist die Programmiersprache für: – Eingebettete Systeme – Hardwarenahe Programmierung – Betriebssystemprogrammierung TU Dresden, 05.11.07 Präsentationsname XYZ Folie 6 von XYZ Stärken von C/1 Minimalistischer Sprachumfang (Der kleinste bekannte C-Compiler besteht aus 3742 Bytes C-Code und kann sich selbst kompilieren). Hardwarenahe Programmierung, direkter Umgang mit Bits, Bytes, direkter Speicherzugriff und Zeigerarithmetik (für die effiziente Behandlung von Feldzugriffen) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 7 von XYZ Stärken von C/2 Zeiger auf Unterprogramme (Funktionszeiger) in Datenstrukturen speicherbar Æ flexible Modularisierungskonzepte. Präprozessor zur Spracherweiterung und bedingten Übersetzung. Optimierende C-Compiler für nahezu jede Prozessorarchitektur. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 8 von XYZ Schwächen von C/1 Fehlendes Modulkonzept (wird üblicherweise durch Paare von .cund .h-Dateien notdürftig nachgebaut) Nur eingeschränkt typsicher Die Sprachdefinition besitzt Lücken (Verhalten undefiniert) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 9 von XYZ Schwächen von C/2 "Wilde" Zeiger: Man kann Zeiger auf beliebige Stellen des Speichers richten. Insbesondere zeigen nicht explizit initialisierte Stack-Variablen oft auf beliebige Stellen des Speichers Æ schwer zu diagnostizierende Fehler. Probleme mit Feldern (Kein Schutz vor Überlauf) Niedriger Abstraktionsgrad Portabilitätsprobleme beim Umstieg von 32 auf 64Bit TU Dresden, 05.11.07 Präsentationsname XYZ Folie 10 von XYZ Elemente von C Ziele der Erfinder: – Einfach, – maximale Flexibilität, – leichte Portierbarkeit Æ Komponentenkonzept: Minimaler Sprachkern + Präprozessor + Bibliotheken für Standardaufgaben TU Dresden, 05.11.07 Präsentationsname XYZ Folie 11 von XYZ Sprachkern Programmiersprache mit typisierten Variablen – Vereinbarung von komplexen Datentypen, arithmetische und logische Operationen (Bit, Datentyp) – Zeigerarithmetik – Programmflusskontrolle unabhängig von Prozessorarchitektur ! TU Dresden, 05.11.07 Präsentationsname XYZ Folie 12 von XYZ Präprozessor Direktiven für die Automatisierung von „Textbausteinen“ – Einbinden von Quelldateien #include … – Textersetzung (Konstanten, Definitionen, Makros) #define … – Bedingte Übersetzung #if defined(UNIX) || defined(CYGWIN) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 13 von XYZ Bibliotheken Standardbibliothek: Basisfunktionen für alle Systeme – Ein-/Ausgabe, – Dateihandling, – Zeichenkettenverarbeitung, – Mathematik, – Speicherreservierung, –… ( + Vielzahl von kommerziellen sowie freien Funktionssammlungen ) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 14 von XYZ Vom Quellcode zum Programm Programm erstellen Editieren, z.B. mit gedit, eclipse/cdt Ergebnis: Datei hallo.c Programmtext Compiler Übersetzen (Compiler) Kommando: gcc -g -c hallo.c Ergebnis: Objektdatei hallo.o Adressen Binden (Linker) Kommando: gcc -o hallo hallo.o Ergebnis: Ausführbare Datei hallo TU Dresden, 05.11.07 Präsentationsname XYZ OBJ-Datei Linker ausführbare Datei Folie 15 von XYZ C ist EINFACH Der Sprachkern von C besteht aus sehr wenigen Schlüsselwörtern. Das Strukturierungselement ist die Funktion Jedes ausführbare Programm wird mit der Funktion main gestartet TU Dresden, 05.11.07 Präsentationsname XYZ Folie 16 von XYZ Funktionsdefinition Jede Funktionsdefinition (auch main) folgt im wesentlichen der gleichen Syntax: Rückgabetyp FktName(Argumentliste) // Fkt.Kopf { // Fkt.Rumpf Variablenvereinbarung Anweisung return Rückgabewert; } TU Dresden, 05.11.07 Präsentationsname XYZ Folie 17 von XYZ C vs. Assembler /* Hallo in C */ #include <stdio.h> char *m = "hallo\n"; int main() { printf(m); return 0; } Achtung: Der Assembler-Code ist nicht aus dem C-Programm entstanden! TU Dresden, 05.11.07 ; Hallo in NASM segment .data m DB "Hallo",13,0 segment .text global main main: push m call printf add esp, 4 mov eax, 1 mov ebx, 0 int 80 Präsentationsname XYZ Folie 18 von XYZ Schlüsselwörter/1 9 SW für elementare 3 SW für Datenobjekte zusammengesetzte Datenobjekte char short/int/long float/double signed/unsigned enum struct union typedef 1 SW für die Größe von Datenobjekten und Typen sizeof TU Dresden, 05.11.07 Präsentationsname XYZ Folie 19 von XYZ Schlüsselwörter/2 4 SW für die Speicherklasse von Objekten 12 SW für den Ablauf von Programmen auto register static extern 2 SW für die Typqualifizierung von Objekten const volatile TU Dresden, 05.11.07 Präsentationsname XYZ if / else while for do (do … while) switch case default break continue goto return Folie 20 von XYZ Winziger Sprachumfang! 31 Schlüsselwörter ~ 50 Punktuatoren wie () , ; ~ 50 Operatoren wie + - * > < . TU Dresden, 05.11.07 Präsentationsname XYZ Folie 21 von XYZ C ist SCHWIERIG C „versteckt“ die Komplexität in den Operatoren und deren Kombinationsmöglichkeiten Je nach Kontext haben gleiche Buchstaben sehr unterschiedliche Bedeutung * 1. Multiplikation, 2. Dereferenzierung von Zeiger > 1. Relation (Größer), 2. als >> Shift Right-Operation, 3. als -> Dereferenzierung eines Elements einer Struktur, deren Adresse gegeben ist. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 22 von XYZ C ist EFFIZIENT Strukturen, Zeiger und Zeigerarithmetik erlauben effiziente Programme (die allerdings oft schwer zu verstehen sind) Die Vielfalt von Funktionssammlungen (std und andere) will beherrscht sein. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 23 von XYZ Die hohe Kunst Einstieg leicht möglich, das erste Programm ist schnell geschrieben (z.B. diese Vorlesung) Aber: Schreiben portabler (32/64 Bit), sicherer (Überlauf, Zeiger) und lesbarer (von Menschen) Programme ist nicht trivial! TU Dresden, 05.11.07 Präsentationsname XYZ Folie 24 von XYZ Grundelemente • • • • • Zeichensatz, Kommentare Identifier (Namen) Datentypen Ausdrücke Operationen Zeichensatz Buchstaben: Ziffern: Sonderzeichen: Trennzeichen: ! abc…zABC…Z 0123456789 !"#%&'() *+,-./: ;<=>?[]\^_ {|}~ Leerzeichen, Tabulator, Zeilenvorschub Achtung: Programmcode ist 1dimensionaler Strom aus Tokens. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 26 von XYZ Kommentare Fängt mit /* an, hört mit */ auf !Verschachtelung NICHT möglich Ausweg #ifdef 0 ... #endif Seit C99 Zeilenkommentare wie in C++ oder Java: Fängt mit // an, hört mit Zeilenvorschub auf TU Dresden, 05.11.07 Präsentationsname XYZ Folie 27 von XYZ Identifier = Namen von Variablen und Funktionen ! ! Fangen mit einem Buchstaben an (a-zA-Z) Danach sind auch Zahlen und Unterstriche erlaubt Unterstriche können vor dem ersten Zeichen stehen (ist aber reserviert für interne Variablen der Bibliotheken) Dürfen keine Schlüsselworte sein Variablen müssen vor Verwendung deklariert sein. Das geht nur vor der ersten Anweisung eines Blocks. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 28 von XYZ Datentypen Zeichen Ganze Zahl Gleitkommazahl mit doppelter Genauigkeit char int float double Weitere Datentypen Kleine Ganzzahl Große Ganzzahl short long Ganzzahlen und Zeichen können als signed/unsigned spezifiziert werden Ab C99: long long, long double TU Dresden, 05.11.07 Präsentationsname XYZ Folie 29 von XYZ Ausdrücke und Operatoren Zuweisungsausdruck Speicherstelle = Ausdruck Arithmetische Ausdrücke Ausdruck Arithm.Operator Ausdruck Arithmetische Operatoren +-*/ % Modula (Rest der Ganzzahldivision) ( ) Vorrang TU Dresden, 05.11.07 Präsentationsname XYZ Folie 30 von XYZ Kombinierte Zuweisungsoperatoren Kombinierte Zuweisungsausdrücke Häufig wird Ergebnis einer Operation in einer beteiligten Variable abgelegt Variable = Variable Operator Ausdruck Variable Variable Variable Variable Variable TU Dresden, 05.11.07 += Ausdruck -= Ausdruck *= Ausdruck /= Ausdruck %= Ausdruck Präsentationsname XYZ Folie 31 von XYZ Logische Ausdrücke 1 Gleichheit Ausdruck == Ausdruck Ausdruck != Ausdruck Relation Ausdruck < <= >= > Ausdruck Logische Verknüpfung (nur für Ganzzahltypen) ! Ausdruck Ausdruck || Ausdruck Ausdruck && Ausdruck TU Dresden, 05.11.07 Präsentationsname XYZ Folie 32 von XYZ Logische Ausdrücke II Bis C99 gibt es keinen Wahrheitswert (bool, booolean) Wahr: Alle Werte ungleich 0 Falsch: 0 Achtung: Ergebnis eines logischen Ausdrucks ist vom Typ int Wahr = 1 TU Dresden, 05.11.07 Präsentationsname XYZ Folie 33 von XYZ Auswertung von Ausdrücken • Vorrangregelung • Typumwandlung Vorrangregelungen (unvollständig) Auf gleicher Ebene, wenn nicht anders angegeben, Auswertung von links nach rechts: () unär ! + (rechts nach links) */% +< <= >= > == != && || = += -= *= /= %= (rechts nach links) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 35 von XYZ Beispiel a=1+4*2/(3+1); 1 4 2 3 1 + * / + TU Dresden, 05.11.07 Präsentationsname XYZ Folie 36 von XYZ Typumwandlung/1 Was passiert bei binären Ausdrücken mit unterschiedlichen Typen? Grundsätzlich int-promotion: Wenn Wertebereich von int ausreicht, Umwandlung nach int int = “Natürliche” Größe der Plattform TU Dresden, 05.11.07 Präsentationsname XYZ Folie 37 von XYZ Typumwandlung/2 2) Umwandlungen, die den Wertebereich nicht beschneiden sind wert- und vorzeichenerhaltend 3) Wandlung auf den Typ des Nachbaroperators, wenn größerer Wertebereich oder ranghöher Rangreihe: char, short, int, long, (float), double, long double TU Dresden, 05.11.07 Präsentationsname XYZ Folie 38 von XYZ Typumwandlung/3 Wandlung bei binären Operatoren (+,*,…) char und short werden in int umgewandelt, float in double A) Ist danach einer der beiden Operanden vom Typ double, so wird der andere ebenfalls nach double gewandelt und das Ergebnis ist vom Typ double B) Ist danach einer der beiden Operanden vom Typ long, so wird der andere ebenfalls nach long gewandelt und das Ergebnis ist vom Typ long TU Dresden, 05.11.07 Präsentationsname XYZ Folie 39 von XYZ Typumwandlung/4 C) Ist einer der beiden Operanden vom Typ unsigned, so wird der andere ebenfalls nach unsigned gewandelt und das Ergebnis ist vom Typ unsigned Trifft keiner der Fälle A,B,C zu, sind beide Operanden und das Ergebnis vom Typ int Wenn anderes Verhalten gewünscht, expliziter Type-Cast notwendig: (type) Ausdruck TU Dresden, 05.11.07 Präsentationsname XYZ Folie 40 von XYZ Vorrangregelungen (unvollständig) Auf gleicher Ebene, wenn nicht anders angegeben, Auswertung von links nach rechts: () unär ! + - (type) (rechts nach links) */% +< <= >= > == != && || = += -= *= /=Präsentationsname %= XYZ (rechts nach links) TU Dresden, 05.11.07 Folie 41 von XYZ Steuerung des Programmflusses •Sequenz •Wiederholung •Bedingte Ausführung Übersicht Teil 2 Programm = Sequenz von Instruktionen + Konstrukte zur Wiederholung, Auswahl, und hierarchischen Strukturierung (Funktion) In C Sequenz: Liste von Befehlen, Blöcke Wiederholung: while, do…while, for Auswahl: if … else if … else, switch … case Funktionsdefinition und -vereinbarung TU Dresden, 05.11.07 Präsentationsname XYZ Folie 43 von XYZ Sequenzen und Blöcke Sequenz = Liste von durch SEMIKOLON getrennten Anweisungen (statement) Block = Zusammenfassung einer Sequenz durch geschweifte Klammern { }. – wird von „außen“ wie ein Befehl gesehen (wichtig für Wiederholung und Auswahl). – kann lokale Variablen enthalten, die nur im Block gültig sind. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 44 von XYZ Wiederholung Kopfgesteuerte (abweisende) Schleife while ( Ausdruck) Anweisung Fußgesteuerte (annehmende) Schleife do Anweisung while ( Ausdruck) For-Schleife for ( Ausdruck1; Ausdruck2; Ausdruck 3) Anweisung TU Dresden, 05.11.07 Präsentationsname XYZ Folie 45 von XYZ For-Schleife For-Schleife for ( Ausdruck1; Ausdruck2; Ausdruck 3) Anweisung Ausdruck1: Initialisierung Kontrollvariable(n) Ausdruck2: Testen Abbruchbedingung Ausdruck3: Änderung Kontrollvariable(n) Kurzform für: Ausdruck1; While (Ausdruck2) { Anweisung Ausdruck3; TU Dresden, 05.11.07 Präsentationsname XYZ } Folie 46 von XYZ If … else Bedingte Ausführung if ( Ausdruck) Anweisung .. mit Alternative(n) if ( Ausdruck) Anweisung else if ( Ausdruck) Anweisung … else Anweisung TU Dresden, 05.11.07 Präsentationsname XYZ Folie 47 von XYZ Bedingter Ausdruck If … Else ist Anweisung, oft will man aber in Abhängigkeit von einer Bedingung das Ergebnis von zwei verschieden Ausdrücken haben (ohne Zwischenvariable) Æ Bedingter Ausdruck Ausdruck1 ? Ausdruck2 : Ausdruck3 Beispiel Erg = A1 ? A2 : A3; Entspricht (fast) if (A1) Erg=A2; else Erg=A3; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 48 von XYZ Komplexe Daten •Eindimensionale Felder (Vektoren) •Mehrdimensionale Felder (Matrizen) •Struktur •Union Felder Zusammenfassung einer definierten Anzahl GLEICHARTIGER Datensätze zu einer Einheit Operation: Auswahl eines bestimmten Datensatzes über einen Index TU Dresden, 05.11.07 Präsentationsname XYZ Folie 50 von XYZ Eindimensionale Felder Vereinbarung Typ Identifier[Positive Ganzzahl]; Elemente werden im Speicher in aufsteigender Reihenfolge angelegt Indizierung beginnt mit 0!!!! Zugriff erfolgt durch Identifier[Ausdruck] TU Dresden, 05.11.07 Präsentationsname XYZ Folie 51 von XYZ Mehrdimensionale Felder Vereinbarung Typ Identifier[Positive Ganzzahl] [Positive Ganzzahl]...; Elemente werden im Speicher in aufsteigender Reihenfolge angelegt Letzter Index „wandert“ zuerst Indizierung beginnt mit 0!!!! Zugriff erfolgt durch Identifier[Ausdruck][Ausdruck]…; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 52 von XYZ Initialisierung von Feldern Deklaration mit Initialisierung: Type Identifier[Zahl] = { Liste }; – Liste muss nicht vollständig sein, – Elemente werden mit KOMMA getrennt, – Nicht erfasste Elemente werden mit 0 initialisiert Verschachtelung von Listen für mehrdimensionale Felder: int a[2][3] = { {1, 2, 3}, {4, 5, 6} } TU Dresden, 05.11.07 Präsentationsname XYZ Folie 53 von XYZ Vorrangregelungen (vorläufig) Auswertung auf gleicher Ebene von links nach rechts, wenn nicht anders angegeben: () [] unär ! + - (type) (rechts nach links) */% +< <= >= > == != && || = += -= *= /= %= (rechts nach links) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 54 von XYZ Struktur Zusammenfassung UNTERSCHIEDLICHER Datensätze zu einer Einheit Beispiel Person Geburtstag, Geschlecht, Adresse, … Beispiel Schaltungselement Nummer, Bauteil, Eigenschaftswert, Knoten1, Knoten2, … TU Dresden, 05.11.07 Präsentationsname XYZ Folie 55 von XYZ Deklaration und Definition Deklaration Kombination von Typdeklaration und Variablendefinition möglich: struct bauteil { long number; char type; double value; //... }; struct bauteil { long number; char type; double value; //... } bt; Achtung: Nur der Typ struct bauteil wird deklariert! Definition einer Variablen: struct bauteil bt; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 56 von XYZ Initialisierung von Strukturen Initialisierung analog zu Feldern struct bauteil bt1 = { 1, 'R', 100 }; struct bauteil bt[4] = { { 1, 'R', 100 }, { 2, 'C', 90 }, { 3, 'V', 0.9 }, { 4, 'R', 1000 } }; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 57 von XYZ Bestimmung der Größe von Strukturen Tatsächlicher Speicherplatz für eine Struktur ist von Compiler und Systemabhängig – Platzbedarf von Datentypen ist systemabhängig – Manche Datentypen müssen an Adressen ausgerichtet sein, die ein Vielfaches von 2 oder 4 sind size_t sbt; sbt = sizeof(struct bauteil); TU Dresden, 05.11.07 Präsentationsname XYZ Folie 58 von XYZ Union Union: Datentyp mit Fallunterscheidung Daten unterschiedlichen Typs und Länge in einem Speicherbereich Beispiel: Unterschiedliche Sichten auf einen Sende/Empfangspuffer Anwendungsebene: Strukturorientiert Treiberebene: Byteorientiert Vereinbarung wie struct, einfach union anstelle Schlüsselwort struct TU Dresden, 05.11.07 Präsentationsname XYZ Folie 59 von XYZ Illustration des Unterschieds zwischen struct und union struct t_s { int a; char b[4]; } s; a und b bezeichnen unterschiedliche Speicherplätze union t_u { int a; char b[4]; } u; s.a 0204 0200 sizeof(u) : 4 a und b sind unterschiedliche Interpretationen des selben Speicherplatzes TU Dresden, 05.11.07 s.b s.b [0 ] s.b [1 ] s.b [2 ] s.b [3 ] sizeof(s) : 8 u.a, u.b Präsentationsname XYZ 0208 Folie 60 von XYZ Beispiel Sende/Empfangspuffer struct snd { // Befehl char code // 1 Byte Befehlscode }; struct rcv_vendor { // Identifikationsantwort int status; long version; char vendor[16]; char model[16]; }; struct rcv_error { // Fehlerantwort int status; long errno; char msg[56]; }; union buffer { struct snd send; struct rcv_vendor recv_vendor; struct rcv_error recv_error; char code[60]; }; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 61 von XYZ Bitfelder Können nur innerhalb von struct und union definiert werden Syntax: Name : bit_anzahl Bitfelder folgen in einer Speichereinheit lückenlos aufeinander Aber Achtung: Bitfelder haben keine Adresse Reihenfolge der Bits ist nicht spezifiziert Æ Implementierungsabhängig TU Dresden, 05.11.07 Präsentationsname XYZ Folie 62 von XYZ Beispiel struct bitfeld { unsigned short a:1, b:2, c:3, d:4; } bf = { 1, 2, 4, 8 }; bf.a = 0; bf.d = 11; Auf Intelarchitektur in der Regel wie folgt: 0000 0010 0010 0101 = 0x0225 0000 0010 0010 0100 = 0x0224 0000 0010 1110 0100 = 0x02E4 TU Dresden, 05.11.07 Präsentationsname XYZ Folie 63 von XYZ Einfügen von Leerfelder und springen an Wortgrenzen struct bitfeld { unsigned short a:1, b:2, :4, c:3, d:4, :0, e:5 ; } bf = { 1, 2, 4, 8, 16 }; Initialisierung auf Intelarchitektur in der Regel wie folgt: 00000000000.1000000.1000.100.0000.10.1 TU Dresden, 05.11.07 Präsentationsname XYZ Folie 64 von XYZ Zeiger Zeiger in C Variablen werden normalerweise über Namen angesprochen int summe, i = 1, j = 2; summe = i + j; Jede Variable liegt im Speicher an einer bestimmten Stelle (Adresse). Zeiger (auf Variablen) enthalten genau diese Adresse einer Variablen Zeiger sind selbst auch „nur“ Variablen TU Dresden, 05.11.07 Präsentationsname XYZ Folie 66 von XYZ Bestandteile von Zeigern Wert der Zeigervariablen (Adresse) An welcher Stelle im Speicher steht der referenzierte Wert? 4711 4711 Typ des Zeigers (char, int, double, …) Wie muss der Inhalt an der adressierten Speicherstelle interpretiert werden? 3.1415 Welchen Speicherbedarf hat das Zielobjekt? TU Dresden, 05.11.07 Präsentationsname XYZ 4 Byte Folie 67 von XYZ Zeiger Die Adressen von Zeigern zeigen auf – vereinbarte Variablen – dynamisch reservierten Speicher während der Laufzeit – auf virtuellen oder physikalischen Speicher eines Computers (z.B. Bildschirmspeicher) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 68 von XYZ Zeigergrundoperatoren Deklaration von Zeigern mit * ! int a=10; // int-variable int* b, c; // 2 zeiger auf int int *d, e; // zeiger auf int, int Adressoperator & b = &a // b zeigt auf a Dereferenzierungsoperator * *b = 11 // Inhalt von a Å 11 TU Dresden, 05.11.07 Präsentationsname XYZ Variable … c b a Adresse Inhalt Variable … c b a Adresse Inhalt Variable … c b a Adresse Inhalt 108 104 100 108 104 100 108 104 100 ? ? 10 ? 100 10 ? 100 11 Folie 69 von XYZ Zeigerarithmetik 1 Addition/Subtraktion von Zeiger und int int a[5] = {0,1,2,3,4}; // int-variable int* b = &a[0]; // b zeigt auf a[0] int* b = a; // b zeigt auf a[0] b = b + 2; // b zeigt auf a[2] Increment/Dekrement b++; b -= 2; // b zeigt auf a[3] // b zeigt auf a[1] Vorrang Incr/Decr vor Deref. *b-- = 1 TU Dresden, 05.11.07 // a[0] = 1 Präsentationsname XYZ Folie 70 von XYZ Zeiger und Felder Speichersituation int a,i; int x[4]; int *px; a px = x; px = &x[0]; i X[3] i a a a = = = = 3; x[i]; *(px+i); px[i]; px++; x++; X[2] X[1] X[0] px //!! Fehler TU Dresden, 05.11.07 Präsentationsname XYZ Folie 71 von XYZ Zeigerarithmetik 2 Vergleich von Zeigern int x,a[5] = {0,1,2,3,4};// int-variable int *b = &a[0]; // b zeigt auf a[0] int *c = &a[2]; // c zeigt auf a[2] if (b != c) { … } // < <= > >= == != Subtraktion von Zeigern x = b – c; // Anzahl Elemente zwischen b und c TU Dresden, 05.11.07 Präsentationsname XYZ Folie 72 von XYZ Zeiger auf Zeiger Zeiger können auch auf Zeigern definiert sein int x // int int *px = &x; // ptr to int int **ppx = &px; // ptr to (ptr to int) Zugriff auf den Wert an der Stelle x int y; y = x; y = *px; y = **ppx; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 73 von XYZ Zeiger auf Zeiger Einfache Zeiger int x = 0; int *px = &x; int **ppx = &px; x 0100: 00000000 px 0104: 00000100 ppx 0108: 00000104 *py,py[0] 010C: 00000100 Arrays von Zeigern int *py[4] = {&x}; int **ppy = py; py[1] 0110: 00000000 *(py+2),py[2] 0114: 00000000 py[3] 0118: 00000000 ppy 011C: 0000010C TU Dresden, 05.11.07 Präsentationsname XYZ Folie 74 von XYZ Rangordnung der Operatoren & und * bei der Auswertung Ausdruck Äquivalent mit Klammern *p++ *p + 1 *&j *p * *p -*p a / *p a /* p TU Dresden, 05.11.07 *(p++) = *(p=(p+1)) (*p)+1 *(&j) = j (*p) * (*p) -(*p) a / (*p) /* beginnt Kommentar Präsentationsname XYZ Folie 75 von XYZ Zeichenketten Zeichenketten Zeichenketten (fast immer) sind charFelder Funktionen erkennen Ende am \0-Zeichen Initialisierung char char char s3 = s4 = A B C D \0 \0 s1[7] = "ABCD"; h s2[] = "hallo"; *s3, *s4; s1; (char *) malloc(15); a l l o \0 \0 s3 = "neu"; // !! Fehler s3[3] = 'c'; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 77 von XYZ Ein/Ausgabe von Zeichenketten Funktionen zur Ein/Ausgabe von Zeichenketten sind in <stdio.h> deklariert: char *gets(char *s); int puts(const char *s); scanf(const char *format, ...); printf(const char *format, ...); char getchar(); void putchar(const char c); TU Dresden, 05.11.07 Präsentationsname XYZ Folie 78 von XYZ Bearbeiten von Zeichenketten Funktionen zur Manipulation von Zeichenketten sind in <string.h> deklariert: char *strcat(char *dest, const char *src); char *strcpy(char *dest, const char *src); char *strchr(const char *s, int c); char *strrchr(const char *s, int c); char *strstr(const char *s1, const char *s2); size_t strlen(const char *s); TU Dresden, 05.11.07 Präsentationsname XYZ Folie 79 von XYZ Felder von Zeigern auf „Zeichenketten“ Zeiger auf Zeichenketten sind Zeiger auf Zeiger auf char char *worte[4];// reserviert 4 Zeiger char **ppc; // reserviert 1 Zeiger ppc = worte; // ppc zeigt auf worte[0] Adressierung von Worten char *first, *second; first = worte[0]; second = worte[1]; first = *ppc; second = *ppc++; TU Dresden, 05.11.07 Präsentationsname XYZ Folie 80 von XYZ Zugriff auf Zeiger auf Strukturen Zuweisung und Adressoperatoren struct bauteil bt1, bt2, *pbt; bt1 = bt2; // kopiert bt2 nach bt1 pbt = &bt2; // Adresse bt2 nach pbt bt1 = *pbt; // Kopie von deref. pbt long n; n = bt1.number; // Zugriff über Var. n = pbt->number; // Zugriff über Ptr. n = (*pbt).number; // = pbt->number n = *pbt.number // Fehler! . vor * ! TU Dresden, 05.11.07 Präsentationsname XYZ Folie 81 von XYZ Beispiel: Einfache verkettete Liste null struct list_el { struct list_el *next; // nächstes Element double info; // information } struct liste { struct list_el *head; struct list_el *tail; } TU Dresden, 05.11.07 Präsentationsname XYZ // Kopf der Liste // Ende der Liste Folie 82 von XYZ Vollständige Vorrang- und Assoziativitätsregeln () [] -> . ++ -- ! ~ (type) sizeof + - * & * / % + << >> < <= >= > == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= (RL) , (Kommaoperator) TU Dresden, 05.11.07 Präsentationsname XYZ (RL) (RL) Folie 83 von XYZ Kontrollfragen/1 Welche arithmetischen Ausdrücke gibt es und was ist für arithmetische Ausdrücke zu beachten? Welche unären Operatoren kennen Sie? Nennen Sie die wichtigsten Zuweisungsoperatoren Welche Regeln gelten für das Zusammentreffen von Ausdrücken mit unterschiedlichem Datentyp? TU Dresden, 05.11.07 Präsentationsname XYZ Folie 84 von XYZ Kontrollfragen/2 Was ist ein L-Wert? Was ist bei den Operatoren ++ und -- zu beachten? Welche Vorteile ergeben sich daraus, dass die Zuweisung keine Anweisung sondern ein Ausdruck ist? Nennen Sie Relations- und Gleichheitsoperatoren Was ist ein cast-Operator Was versteht man unter impliziter Typumwandlung? TU Dresden, 05.11.07 Präsentationsname XYZ Folie 85 von XYZ Kontrollfragen/3 Was ist der Unterschied zwischen einem Zeiger und einer Adresse? Wie werden Zeigervariablen vereinbart? Was versteht man unter Dereferenzierung? Wie vereinbart man Vektoren (Felder)? Wie sind mehrdimensionale Vektoren im Speicher angeordnet? TU Dresden, 05.11.07 Präsentationsname XYZ Folie 86 von XYZ Kontrollfragen/4 In welchem Zusammenhang stehen Vektoren und Zeiger? Welchen Datentyp verwendet C zum Arbeiten mit Zeichenketten? Wie vereinbart man Variablen für eine Struktur? Welche Operatoren gibt es für den Zugriff auf Strukturelemente? TU Dresden, 05.11.07 Präsentationsname XYZ Folie 87 von XYZ Modulkonzept und Präprozessor Modularer Aufbau größerer Projekte Modulkonzept Geltungsbereich von Namen von Variablen und Funktionen Prototypen Typvereinbarungen Headerdateien Preprocessor Einbinden von anderen Dateien durch include-Direktive Verhindern mehrfachen Einbindens durch defineDirektive Erhöhen der Portabilität durch bedingte Compilation Macros TU Dresden, 05.11.07 Präsentationsname XYZ Folie 89 von XYZ Scope Rules SCOPE: Geltungsbereich von Name von Funktionen, Typdeklarationen und Variablenvereinbarungen Regel 1 - Gültigkeit Ab Bekanntgabe bis zum Ende der Datei bzw. Ende des Blocks Regel 2 - Zugriff Über Blockgrenzen hinweg von innen nach außen. Innere Symbole mit gleichem Namen verdecken äußere TU Dresden, 05.11.07 Präsentationsname XYZ Folie 90 von XYZ Speicherklassen und Gültigkeit Blockkonzept: Innerhalb von Funktionen/Blöcken definierte (lokale) Variablen sind nur in diesen Funktionen/Blöcken verfügbar. Was passiert mit den Variablen beim Verlassen des Blocks? TU Dresden, 05.11.07 Präsentationsname XYZ Folie 91 von XYZ auto vs. static Speicherklasse auto Lokale Variablen werden beim Betreten der Funktion angelegt und ggf. initialisiert und beim Verlassen wieder aufgeräumt Æ Rekursion möglich. Speicherklasse static (in Funktionen) Variablen, die als „Gedächtnis“ der Funktion dienen sollen, werden als static deklariert. Bleiben über Aufrufe hinweg erhalten! TU Dresden, 05.11.07 Präsentationsname XYZ Globale Variablen Dateikonzept: Vereinbarungen außerhalb von Funktionen sind ab dort bis zum Ende der Datei bekannt, Speicherplatz ist für die Laufzeit des Programms reserviert Speicherklasse extern (Default): – Variable kann von anderen Modulen angesprochen werden. Speicherklasse static: – Variable ist außerhalb Datei nicht bekannt. TU Dresden, 05.11.07 Präsentationsname XYZ Folie 93 von XYZ Funktionen und Prototypen Funktionen müssen vor Verwendung im Quelltext definiert werden. Rekursive Bezüge? Über Dateigrenzen hinweg? Æ PROTOTYPEN Funktion int max(int a, int b) { return (a>b) ? a : b; } Prototyp int max(int a, int b); int max(int, int); int max(); /* Alter Stil - bitte nicht! */ TU Dresden, 05.11.07 Präsentationsname XYZ Folie 94 von XYZ Programme mit mehreren Quelldateien? Quelltextübergreifende Gültigkeit – nur externe Variablen (außerhalb von Blöcken) – Bezeichner müssen überall gleich sein, ebenso Definition – Verweis durch explizite Verwendung des Schlüsselworts extern – Achtung: Initialisierung darf nur einmal sein! TU Dresden, 05.11.07 Präsentationsname XYZ Folie 95 von XYZ Externe Variablen & Funktionen Datei 1: main.c char hi[] = „hallo\n“; // implizit extern char *msg(void); // prototyp int main(void) { printf(msg()); return 0; } Datei 2: msg.c char *msg() { extern char hi[]; // externe Variable! return hi; } TU Dresden, 05.11.07 Präsentationsname XYZ Folie 96 von XYZ Header-Datei .h 15: #ifndef _STDIO_H_ 16: #define _STDIO_H_ 17: 18: /* All the headers include this file. */ 19: #include <_mingw.h> 20: Definition von 21: #ifndef RC_INVOKED Funktionsprototyp22: #define __need_size_t 23: #define __need_NULL en 24: #define __need_wchar_t Bekanntmachen von 25: #define __need_wint_t 26: #include <stddef.h> externen 27: #define __need___va_list 28: #include <stdarg.h> Variablen 29: #endif /* Not RC_INVOKED */ 30: 31: Systemkonstanten 32: /* Flags for the iobuf structure */ 33: #define _IOREAD 1 /* currently reading Funktionskonstanten*/ 34: #define _IOWRT 2 /* currently writing */ Makros 35: #define _IORW 0x0080 /* opened as TU Dresden, 05.11.07 Präsentationsname XYZ Folie 97 von XYZ "r+w" */ Preprozessor Preprozessor – bearbeitet Programmcode vor dem Übersetzen Quellcode Preprozessor reiner C-Code Compiler Trennung für Transportabilität Syntax Erstes Zeichen (außer white-space) in Zeile ist Hashmark, „Gartenzaun“: # TU Dresden, 05.11.07 Präsentationsname XYZ Folie 98 von XYZ Preprozessordirektive #include Binde Datei in den Ausgabestrom ein #include "dateiname" Suche Datei erst im aktuellen Vereichnis, danach an anderen Stellen #include <dateiname> Suche Datei in einem speziellen Systemverzeichnis TU Dresden, 05.11.07 Präsentationsname XYZ Folie 99 von XYZ Direktive #define Konstanten Definiere einen Ersatztext, der beim Auftreten von Suchtext im Ausgabestrom ersetzt wird Konstanten #define K0 -273.15 // Absoluter Nullpunkt #define kB 1.38066E-23 // BoltzmannKonstante [J/K] „Sprachverbesserungen“ #define #define #define #define #define TU Dresden, 05.11.07 TRUE 1 forever for(;;) NULL ((void *) 0) PRIVATE static PUBLIC Präsentationsname XYZ Folie 100 von XYZ Direktive #define Macros Definiere einen Ersatztext mit Parametern, die beim Auftreten von Suchtext im Ausgabestrom eingesetzt und ersetzt werden. Beispiel: #define SQR(x) x*x c*SQR(a+b) Æ c*a+b*a+b #define SQR(x) ((x)*(x)) c*SQR(a+b) Æ c*((a+b)*(a+b)) SQR(*ptr++)Æ((*ptr++)*(*ptr++)) TU Dresden, 05.11.07 Präsentationsname XYZ Folie 101 von XYZ Aufheben mit #undef Die Aufheben-Direktive hebt die Gültigkeit eines Makros auf Beispiel #define A 4 #undef A #define A 3 TU Dresden, 05.11.07 Präsentationsname XYZ Folie 102 von XYZ Vordefinierte Makros nach Standard __DATE__ Zeichenkette (ZK), Datum der Übersetzung __TIME__ ZK, Uhrzeit der Übersetzung __FILE__ ZK, Namen der Datei __LINE__ int, Nummer der aktuellen Zeile __STDC_VERSION__ 199901L, wenn Standard erfüllt TU Dresden, 05.11.07 Präsentationsname XYZ Folie 103 von XYZ Bedingte Übersetzung Bedingte Filterung des Ausgabestroms #if, #ifdef, #ifndef, #else, #elif , #endif Beispiel #define DEBUG 1 #if DEBUG printf(″DBG:funktion xyz, ptr = %p\n″, p); #endif #if 0 /* dieser Teil ist einfach weg */ #endif TU Dresden, 05.11.07 Präsentationsname XYZ Folie 104 von XYZ Bedingte Übersetzung II Konfigurationsdatei sys.h #ifndef SYSTEM #define SYSTEM LINUX ... #endif Programmcode #if SYSTEM == WINNT #include ″winnt.h″ #elif SYSTEM == LINUX && defined (I386) #include ″linux386.h″ #endif TU Dresden, 05.11.07 Präsentationsname XYZ Folie 105 von XYZ Bibliotheken stdio, stdlib, … stdio.h Typdefinitionen, Datenstrukturen, Makros, Funktionsprototypen für die Ein/Ausgabe Datentypen: FILE, fpos_t, size_t; Standard Ein/Ausgabekanäle FILE *stdin, *stdout, *stderr stdin stdout stdin Programm 1 Programm 2 pipe (Betriebssystemabhängig) stderr TU Dresden, 05.11.07 Präsentationsname XYZ Folie 107 von XYZ stdio.h – Ausgewählte Funktionen Dateioperationen int remove (const char *filename); int rename(const char *old, const char *new); FILE *tmpfile(void); char *tmpnam(char *s); Dateizugriffsfunktionen FILE *fopen(const char *name, const char *mode); int fclose(FILE *fp); int feof(FILE *fp); Ein- Ausgabe von Zeichenketten int fgetc(FILE *fp); int getc(FILE *fp); /* Makro*/ int fputc(int c, FILE *fp); int putc(int c, FILE *fp); char *fgets(char *line, int n, FILE *fp); int fputs(const char *s, FILE *fp); int getchar(void); void putchar(int c); TU Dresden, 05.11.07 Präsentationsname XYZ Folie 108 von XYZ Einschub Laufzeitargumente int main(int argc, char *argv[]); argc: Anzahl der Argumente argv: Ein Feld von Zeigern auf char #include <stdio.h> int main(int argc, char **argv) { while(NULL != *argv) printf(„%s\n“,*argv++); return 0; } TU Dresden, 05.11.07 Präsentationsname XYZ Folie 109 von XYZ printf-Familie printf(const char *format, … ); sprintf(char *dst, const char *format, … ); fprintf(FILE *fp, const char *format, … ); Format: %[modifier][breite][precision]type %d, %i – int; %hd - short, %ld – long du, hu, lu – unsigned … %x, %hx, %lx - hexadezimal %c – char; %s – char * %f – double %p - pointer / address TU Dresden, 05.11.07 Präsentationsname XYZ Folie 110 von XYZ Einschub: Variable Argumentlisten Eingeschränkt portable Version int cats(char *S0, char *S1, …) { char *s = S0, *sa, **a; if (s) { for (a=&S1; (sa=*a)!=0; a++) while (*s=*sa) ++s, ++sa; } return (int)(s-S0); } Voll portable Version #include <stdarg.h> int cats(char *S0, …) { char *s = S0, *sa; va_list a; if (s) { for (va_start(a,S0); (sa=va_arg(a,char*))!=0;) while (*s=*sa) ++s, ++sa; va_end(a); } return (int)(s-S0); } TU Dresden, 05.11.07 Präsentationsname XYZ Folie 111 von XYZ stdlib.h Mathematik abs, labs, div, ldiv, rand, srand, … Textwandlung atof, atoi, strtol, strtod, … Speicherverwaltung calloc, free, malloc, realloc, … Sortieren und suchen bsearch, qsort, … Prozess- und Umgebungssteuerung abort, atexit, exit, getenv, system, … TU Dresden, 05.11.07 Präsentationsname XYZ Folie 112 von XYZ Dynamische Speicherallokation Funktionen zur Speicherallokation sind in <stdlib.h> deklariert: typedef unsigned size_t; void void void void *malloc(size_t size); *calloc(size_t nitems, size_t size); *realloc(void *block, size_t size); free(void * block); TU Dresden, 05.11.07 Präsentationsname XYZ Folie 113 von XYZ Weitere Bibliotheken math.h – Mathematische Funktionen sqrt, sin, cos, tan, … string.h – Zeichenketten strcat, strchr, strrchr, strcmp, strcpy, strcspn, strerror, strlen, strncat, strncmp, strncpy, strspn, strstr, strtok ctype.h – Zeichen isalnum, isalpha, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, http://www2.hs-fulda.de/~klingebiel/c-stdlib/index.htm isupper, u.v.a.m … TU Dresden, 05.11.07 Präsentationsname XYZ Folie 114 von XYZ To Be Continued … • Schnittstellenprogrammierung – Einbindung von Assemblercode – C Aufruf Schnittstelle – Treiber für Schnittstellen • Dynamische Datenstrukturen – Speicherverwaltung – Listen • Ausblick Embedded Computing – ToolChains für µC in Eclipse einbinden TU Dresden, 05.11.07 Präsentationsname XYZ