C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl 1 207. Techniken Algorithmische Schritte Folge von Aktionen: { ; ; } Aktion Aktion Aktion Entscheidungen: if-else, switch Bedingung ja nein Aktion Aktion Schleife, nur falls und solange Bedingung gilt: while Bedingung Aktion Schleife, wenigstens einmal und dann solange Bedingung gilt: do-while Aktion Bedingung Schleife für eine Folge von Werten, z.B. Durchlaufen eines Vektors oder einer Liste: for Variable über fixe Wert-Folge Aktion 208. Techniken Refinement Aus jeder einzelnen Aktion 2 209. C formal: Quellformat kann etwas Komplizierteres werden. Neue Beschreibung (als zweites Bild!!): Aktion Teilschritt Teilschritt Teilschritt Funktion ist eine Folge von Aktionen, die einen Wert berechnet. Prozedur ist eine Folge von Aktionen, die eine Aufgabe erledigt. In beiden Fällen handelt es sich um die Ausarbeitung einer komplexeren Aktion, um ein Refinement. Vokabeln C unterscheidet Funktionen und Prozeduren nur durch den fiktiven Resultattyp void bei der Vereinbarung von Prozeduren. typ name ( Parameter−Deklarationen ) { lokale Variablen−Definitionen Aktionen... return Resultatwert; } typ ist der Resultattyp, den der Resultatwert besitzen muß. Voreinstellung: int. Bei Prozedur: void. name ist der Name, mit dem die Funktion/Prozedur aufgerufen wird. Parameter sind Namen und Vereinbarungen für die Werte, die als Argumente übergeben werden (können). Resultatwert entfällt bei Prozedur. 209. C formal: Quellformat Zeilen, Worte und Kommentare Zwischenraum Leerzeichen, Tabulatorzeichen, Zeilentrenner. wird ignoriert (außer in Konstanten). trennt Symbole, also reservierte Worte, Namen, Konstanten. Kommentar /* ... */ äquivalent zu Zwischenraum. nicht verschachtelt. Reservierte Worte C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl auto continue enum if short switch volatile break default extern int signed typedef while case do float long sizeof union 3 char double for register static unsigned const else goto return struct void Namen Folge von Buchstaben (auch Unterstrich) und Ziffern. Muß mit Buchstaben beginnen. Sollte nicht mit Unterstrich beginnen (System-Konvention). Groß und klein wird unterschieden. Wenigstens 31 Zeichen werden unterschieden. Declare before use — mit wenigen Ausnahmen. Im Geltungsbereich eindeutig — aber extra Klasse für ‘‘Strukturen’’. Preprozessor Textersatz # define name ersatztext # define name(p1, ..., pn) ersatztext # undef name #name ersetzt String für Parameter name. ## verkettet Namen im Ersatztext. Einfügen von Dateien # include "dateiname" # include <dateiname> 210. C formal: Skalare Daten Ganzzahlige Werte typname: int short long signed unsigned Konstanten sind Ziffernfolgen: Beispiel Ziffern 123 0123 0x123 0X456 0..9 0..7 0..9abcdef ABCDEF Basis dezimal, 10 oktal, 8 hexadezimal, 16 long, falls L am Schluß oder Wert zu groß. unsigned, falls U am Schluß oder oktal/hexadezimaler Wert zu groß. Zeichen typname: char signed unsigned 4 211. C formal: Skalare Daten Konstanten sind einzelne Zeichen in einzelnen Anführungszeichen. Ersatzdarstellungen: Darstellung ASCII Name \a \b \f \n \r \t \v \0 \ddd \xhh \" \’ \? \\ \x BEL BS FF LF CR HT VT NUL " ’ ? \ x Erklärung Klingel backspace formfeed Zeilentrenner carriage return Tabulatorzeichen Vertikalvorschub Nullzeichen Bit-Muster Bit-Muster Doppel-Anführungszeichen einfaches Anführungszeichen Fragezeichen ‘‘Fluchtsymbol’’ Wert 7 8 12 10 13 9 11 0 0ddd 0xhh 34 39 63 92 211. C formal: Skalare Daten Gleitkommawerte typname: float double long double Konstanten sind double, mit F am Schluß float und mit L am Schluß sind sie long double. ganz . dezimal e vorzeichen exponent 212. C formal: Umwandlungen Übliche arithmetische Umwandlungen −> immer float −> double long char −> short −> int Integer Richtung long bleibt Wert erhalten. char Werte jenseits von 127 sind problematisch — je nach Maschine werden sie positive oder negative int. Richtung char geht signifikanter Teil verloren. Richtung double bleibt Wert, aber nicht Anzahl signifikanter Ziffern (Genauigkeit). unsigned Problematisch — je nach Größe von int wird werterhaltend auch in long umgewandelt. Gleitkomma Richtung double bleibt Wert erhalten. Richtung float gehen signifikante Ziffern (Genauigkeit) verloren. C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl 5 Richtung int bleibt (meistens) Genauigkeit, aber Wertebereich ist viel kleiner. Parameterübergabe Ohne Prototypen, oder bei ... −> immer float −> double char −> short −> int Mit Prototypen wird implizit umgewandelt. Es werden immer (kopierte) Werte übergeben. int Argumentwerte an long Parameter (ohne Prototypen) geben Ärger bei kleinen Maschinen. Von Vektoren werden Anfangsadressen übergeben — also kann man Elemente ändern. 213. C formal: Datenstrukturen Vektor Zusammenfassung von Elementen gleichen Typs. Zusammenhängend gespeichert. Konstant dimensioniert. Indexwert muß int sein. Gezählt ab 0. Vektorname ist Adresse des ersten Elements, folglich kann Vektor als Parameter geändert werden. Zeichenketten T e x t \0 Vektor mit char Elementen, nach Konvention \0 am Schluß. \0 braucht Speicherplatz, zählt aber bei Länge nicht mit. "Zeichenfolge" als Konstante, mit Ersatzdarstellungen. \0 am Schluß implizit erzeugt. Mehrere Strings nacheinander werden implizit verkettet. Konstant ist die Anfangsadresse der Zeichenkette, und ihr Inhalt: "axel was here"[0] = ’A’; /* FALSCH */ 214. C formal: Datenstrukturen Struktur und Union Zusammenfassung von Komponenten/Alternativen verschiedenen Typs. struct etikett { deklaration ... } variable ... ; union etikett { deklaration ... } variable ... ; 6 215. C formal: Ausdrücke struct ... { ... } beziehungsweise union ... { ... } insgesamt gilt als ein Typname wie int. etikett ist der (optionale) Name der Struktur oder Union. Wenn die Struktur oder Union vereinbart ist, genügt struct etikett beziehungsweise union etikett als Typname. deklaration vereinbart die Komponenten beziehungsweise Alternativen. variable vereinbart die Variablen vom Struktur- beziehungsweise Union-Typ. Es ist alles erlaubt: Strukturen mit Vektoren, Vektoren von Strukturen, ... Struktur beziehungsweise Union kann als Parameter und als Funktionsresultat verwendet werden. Dabei werden Werte übergeben. Zuweisungen sind ebenfalls erlaubt. Bit-Felder struct { unsigned wert : 10; unsigned : 3; unsigned : 0; } ... /* Platzhalter */ /* naechstes Wort */ In einer Struktur kann man ganzzahlige Komponenten mit der Anzahl Bits vorgeben — portabel nur bei unsigned. Anordnung im ‘‘Wort’’ ist unbekannt. Initialisierung ist in ANSI-C erlaubt; dabei werden unbenannte Komponenten übersprungen. Es gibt keine Vektoren von Bit-Feldern, aber es gibt Vektoren solcher Strukturen. Eine Struktur beginnt allerdings immer auf einer Adreßkante. 215. C formal: Ausdrücke Vorrangtabelle C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl Operator Klammerung Bedeutung , von links serielle Bewertung = |= ˆ= &= <<= >>= += -= *= /= %= von rechts Zuweisung Operation und Zuweisung Auswahl, bedingte Bewertung ? : || von links ODER mit Abbruch && UND mit Abbruch | Bit-ODER (Integer) ˆ Bit-exklusiv-ODER (Integer) & Bit-UND (Integer) == != gleich, nicht gleich < <= > >= kleiner, kleiner gleich größer, größer gleich << >> Bit-Verschiebung, links, rechts (Integer) + - Addition, Subtraktion * / % Multiplikation, Division, Rest ++ -- unitär, von rechts Inkrement (+= 1), Dekrement (-= 1) & * - + ! ˜ ( typ ) sizeof Adresse (scanf) Verweis Vorzeichen logische Verneinung Bit-Umkehr (Integer) Umwandlung Speicherbedarf () [] -> . Klammern Auswahl in Struktur/Union 216. C formal: Anweisungen Anweisungen ; nichts ausdruck ; z.B. Zuweisung z.B. Prozeduraufruf break ; Schleife abbrechen switch abbrechen continue ; Schleife wiederholen return ; Prozedur beenden 7 8 217. C formal: Vereinbarungen return ausdruck ; Funktionswert, Funktion beenden { lokale-Vereinbarungen anweisungen } Zusammenfassung if ( ausdruck ) anweisung if ( ausdruck ) anweisung else anweisung Auswahl zwei Fälle while ( ausdruck ) anweisung falls und so lange do anweisung while ( ausdruck ) ; einmal und falls for ( ausdruck ; ausdruck ; ausdruck ) anweisung switch — Auswahl unter vielen Fällen Fallnummer eins Anweisungen zwei Anweisungen Anweisungen switch ( ausdruck ) { case integer : anweisungen break ; ... default : anweisungen break ; } 217. C formal: Vereinbarungen Aufgabe declare before use. Vereinbarung legt für Namen fest • Art — Variable, Datentyp, Funktion. • Wertebereich — Integer, ... • Struktur — Skalar, Vektor, ... • Speicherklasse — Register, Stack, Speicher, ... • Geltungsbereich — Programm, Quelldatei, Funktion, Block. • Lebensdauer — immer, während Aufruf, ... Vereinbarung verwendet Schlüsselworte auto extern register static typedef Speicherklasse char double float int long short unsigned Typname Form, d.h. Sonderzeichen wie z.B. * name name ( ) name [ ] Zeiger Funktion Vektor C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl 9 und Position: innerhalb/außerhalb von Funktion/Block. Begriffe Programm besteht aus einigen Quelldateien. dabei die Definition einer Funktion main(), deren (impliziter) Aufruf die Programmausführung darstellt. Quelldatei besteht aus einigen äußeren Vereinbarungen. Vereinbarung ist Deklaration (vereinbart Eigenschaften eines Namens) oder Definition (vereinbart Eigenschaften und erzeugt Objekt). betrifft Variablen (also Daten) oder Funktionen (also Aktionen). äußere Vereinbarung gilt (wenigstens) bis zum Ende der Quelldatei. Funktion besitzt (optional) Parameter (also initialisierte lokale Variablen) und (optional) lokale Variablen. besteht aus Folge von Anweisungen. Zusammenfassung (Block) von Anweisungen in { } gilt wieder als Anweisung. besitzt (optional) ebenfalls lokale Variablen. 218. C formal: Vereinbarungen Geltungsbereich von Namen Programm Geltungsbereich alle Quelldateien Position der Vereinbarung globale Definition einmal extern Deklaration nicht in Funktion Funktion beliebige Quelldatei globale Definition einmal extern Deklaration in Funktion Quelldatei ab Definition bis Ende static Definition Funktion ab Definition bis Ende Definition in Funktion Zusammenfassung (Block) ab Definition bis Ende Definition in Block nicht in Funktion Geltungsbereiche sind verschachtelt: Block in Funktion in Quelldatei in Programm. Jeder Name ist in seinem Geltungsbereich eindeutig. In verschachteltem Geltungsbereich kann Name anders vereinbart werden. Faustregel So lokal wie möglich, so global wie nötig definieren! • wer muß auf ein Objekt zugreifen? • geht’s auch als Parameter? • wie lange muß es existieren (→ Lebensdauer)? 10 219. C formal: Vereinbarungen 219. C formal: Vereinbarungen Beispiele 1.c 2.c −−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−−−−− int a; ˜˜˜˜˜˜˜˜˜˜˜˜˜˜extern int a; 3.c −−−−−−−−−−−−−−−−−− static int a; f() { extern int b;˜˜˜˜˜int b; } Per Programm darf es global definierten Namen nur einmal geben. Wenigstens per Quelldatei muß er vereinbart werden, wenn Zugriff erfolgen soll. Globale Tränen vermeidet man grundsätzlich mit static. int a; global f (int a) { int a; Parameter lokal in Funktion { } { } int a; lokal in Block int a; } g (int a) { int a; } h (void) { extern int a; } global, in Funktion Parameter der gleichen Funktion sollten verschiedene Namen haben. Parameter und lokale Variablen sollten verschiedene Namen haben. 220. C formal: Vereinbarungen Lebensdauer von Objekten Lebensdauer Programmausführung statisch Geltungsbereich Programm Funktion Block Vereinbarung global static in Funktion extern in Funktion static in Block extern in Block Funktionsaufruf automatisch Funktion Parameterdeklaration lokal in Funktion Blockausführung automatisch Block lokal in Block Statische Werte bleiben über Funktionsaufrufe (rekursiv oder nicht) hinweg erhalten, automatische nicht. Statische Werte werden einmal initialisiert (falls angegeben, oder eben auf Null), automatische Werte werden bei jedem Aufruf initialisiert (nur falls angegeben). C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl 11 Statische Werte werden nur konstant initialisiert, automatische Werte auch mit Ausdrücken. Automatische Aggregate kann man initialisieren. Es gibt auch dynamisch erzeugte Objekte (→ Zeiger, Speicherverwaltung). Beispiel void f (int i) { int many = 10; ++ many; if (i) f(i/2); } many ist automatisch und erhält immer den Wert 11. void g (int i) { static int once = 10; ++ once; if (i) g(i/2); } once ist statisch und durchläuft die Werte 11, 12, ... 221. C formal: Vereinbarungen Vereinbarung speicherklasse typname deklarator = initialisierung speicherklasse typname deklarator funktionskoerper Vieles kann man weglassen, nicht alle Kombinationen sind sinnvoll (d.h., erlaubt). Fehlt der Funktionskörper, gilt die Vereinbarung für einen Parameter oder ist die Speicherklasse extern bei Daten, liegt eine Deklaration vor, sonst eine Definition. Nur bei einer Definition kann man initialisieren. Als Typname gibt es char, int, double, struct ..., usw. Eigene Namen kann man mit typedef als ‘‘Speicherklasse’’ konstruieren. Ein einfacher deklarator besteht aus einem Namen gefolgt von null oder mehr Dimensionierungen. name [ dimension ] [ dimension ] ... Bei Deklaration kann die erste Dimensionierung leer sein, bei Funktion ist keine erlaubt. Dimensionierung ist immer konstant. Interpretation Kompliziertere Deklaratoren werden aus Namen, * für Zeiger, [] für Vektor, () für Funktion und Vorrang aufgebaut. Hat ein Ausdruck die ‘‘Form’’ eines Deklarators, liefert er einen Wert vom Datentyp des Typnamens der Vereinbarung: int name; ... name ... liefert int int * ptr; ... * ptr ... ... ptr ... liefert int * anwendbar 12 222. C formal: Bindung int vec [ 10 ]; ... vec [ ausdruck ] ... ... vec ... liefert int [ ] anwendbar int fun ( ... ) ; ... fun ( ausdruck , ... ) ... ... fun ... liefert int ( ) anwendbar 222. C formal: Bindung ANSI C Externe Bindung hat ein globaler Name zwischen verschiedenen Quelldateien. Er erhält sie, wenn er zuerst ohne static auftritt. Interne Bindung hat ein globaler Name innerhalb einer Quelldatei. Er erhält sie, wenn er beim ersten Mal mit static auftritt. Keine Bindung haben lokale Namen. Eine globale Vereinbarung ist eine Definition, wenn eine Initialisierung angegeben ist. Sonst ist sie eine Deklaration. Es darf viele Deklarationen und es muß (nur) eine Definition geben. Ohne extern ist eine globale Deklaration eine vorläufige Definition. Aus allen vorläufigen Definitionen wird eine Definition erzeugt, falls keine Definition explizit vorhanden ist. Verwendung • so lokal wie möglich, so global wie nötig static Variable in Funktion nur wenn Wert über Aufrufe erhalten bleiben soll, e.g., Schalter ob Funktion zum ersten Mal aufgerufen wird, oder Puffer, dessen Adresse dem Aufrufer geliefert wird. Variable außerhalb wenn Wert mehreren Funktionen (zusammen in einer Datei) zur Verfügung stehen soll. Funktion wenn sie nur in einer Datei verwendet wird, oder wenn sie über Vektor von Funktionsnamen aufgerufen wird. nicht static lokale Variable Regelfall, wenn Wert zwischen Aufrufen zerstört werden kann. globale Variable möglichst selten; nur wenn Wert wirklich überall gebraucht wird. Funktion nur wenn sie von mehreren Dateien aus aufgerufen wird; nötig für main(). 223. C formal: Bindung Globale Namen static int g1; int g1; int g1 = 1; /* vorlaeufige Definition, interne Bindung */ /* zusaetzliche vorlaeufige Definition */ /* Definition */ extern int g2; int g2; /* Deklaration, externe Bindung */ /* vorlaeufige Definition */ C-Kurs −− © 1991, 1997 Axel T. Schreiner, © 1998 Bernd Kühl 13 int g2 = 2; /* Definition */ int g3; static int g3; extern int g3; int g3; int g3 = 3; /* /* /* /* /* vorlaeufige Definition, externe Bindung */ zu spaet... (illegal) */ zusaetzliche Deklaration */ zusaetzliche vorlaeufige Definition */ Definition */ /* /* /* /* Deklaration, Deklaration, Deklaration, Deklaration, Lokale Namen f() { extern extern extern extern { int int int int g1; g2; g3; g4; interne externe externe externe Bindung Bindung Bindung Bindung */ */ */ */ int local; /* Definition, keine Bindung */ /* auto: einmal pro Aufruf */ static int s; /* Definition, keine Bindung */ /* static: einmal fuer alle Aufrufe */ int g1 = 5; ::g1 += g1; /* Definition, keine Bindung */ /* in C++ :: greift global zu */ } } 224. Programmbeispiele Allgemeines Alle in C, C++ und Objective C codierten Programme sind auch unter Linux sowie DOS/Windows mit DJGPP benutzbar. Die in Objective C codierten Programme können unter DOS/Windows übersetzt werden. index.htm beschreibt die Beispiele UNIX: make run make all make clean produziert sie und führt sie aus produziert sie entfernt Objekte, etc. DOS/Windows: make dos_run make dos make dos_clean produziert sie und führt sie aus produziert sie entfernt Objekte, etc. Kataloge mit Hilfsmitteln Die Datei make/c.h muß für die Plattform geeignete Werte enthalten; für DOS/Windows, Linux und OPENSTEP existieren fertige Dateien. Alle Beispiele sollten von hier aus konfiguriert werden können. make include lib et paßt makefile für verschiedene Systeme an private Definitionsdateien private Bibiotheksfunktionen demonstriert Umwandlungen in C-Ausdrücken 14 images 224. Programmbeispiele Bilder für Web-Seiten