2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten Operatoren, Ausdrücke und Anweisungen Kontrollstrukturen (Steuerfluss) Funktionen Felder (Arrays) Zeiger, Zeigerarithmetik, Zeiger-Dereferenzierung Zeichenketten (Strings) Benutzerdefinierte Datentypen Speicherverwaltung und Datenstrukturen Dateiarbeit Bitlevel-Verarbeitung Peter Sobe 1 Variablen und Datentypen Die Verarbeitung erfolgt durch Anweisungen, die die Werte der Variablen verändern. Ausdrücke enthalten Variablen. Der Wert eines Ausdrucks wird u.a. durch den Wert der enthaltenen Variablen bestimmt. Variablen können Zahlenwerte, logische Werte (wahr, falsch), Zeichen, Zeichenketten, Zeiger, Felder aufnehmen Variablen müssen vor ihrer ersten Benutzung auf jeden Fall deklariert worden sein. Bezeichner (Namen für Variable, Funktionen, ...) • Namen beginnen mit einem Buchstaben oder einem Unterstrich. • Die weiteren Zeichen sind Buchstaben, Zahlen oder Unterstriche. • Schlüsselworte der Sprache dürfen nicht als Name verwendet werden Peter Sobe 2 Variablen und Datentypen Zulässige Variablennamen: • a; i; j; k; • _pointer; • ganz_langer_name_24_undNochLaenger; • name; Name; // Groß- und Kleinschreibung wird unterschieden Nicht als Variablenname zulässig: • 34Name; // Fehler Zahl am Anfang nicht erlaubt • Strassen Name; // Leerzeichen nicht erlaubt, besser: Strassen_Name • Ölinhalt // Fehler, Umlaute verboten • C&A; // Fehler; Sonderzeichen verboten • while; // da es ein Schlüsselwort while bereits gibt Variablenname sollten kurz sein, aber inhaltlich ihre Bedeutung wiedergeben Peter Sobe 3 Variablendeklaration Alle benutzen Variablen müssen am Anfang des Programms deklariert werden. Deklaration bedeutet Variablennamen erwähnen Typ angeben Wahlweise eine Initialisierung mit einen Wert Genereller Aufbau typ variablenname; typ variablenname-1, variablenname-1; typ variablenname = init-ausdruck; Peter Sobe 4 Variablendeklaration Beispiele: int anzahl_patienten; float gewicht; float x,y,z; char eingabe, auswahl=‘h‘; int anzahl=25; int start = anzahl-1; Peter Sobe 5 Basisdatentypen Grundatentypen char für einzelne Zeichen im ASCII-Code int für ganzzahlige Zahlen float für Gleitkommazahlen (Darstellung reeller Zahlen), double für Gleitkommazahlen doppelter Genauigkeit enum für programmspezifische Aufzählungen Die einige Grundatentypen können noch mit Modifikatoren versehen werden: signed, unsigned, short, long Peter Sobe 6 Basisdatentypen Typ Länge Wertebereich Genauigkeit char = signed char unsigned char 1 Byte 1 Byte -2^7 ... +2^7-1 0 ... 2^8-1 2 Dezimalstellen, z.B. ‚88‘ ist genau int = signed int unsigned int 4 Byte 4 Byte -2^31 ... +2^31-1 0 ... 2^32-1 9 Dezimalstellen short int = signed short int 2 Byte unsigned short int 2 Byte -2^15 ... +2^15-1 0 ... 2^16-1 4 Dezimalstellen long int = signed long int unsigned long int 8 Byte 8 Byte -2^63 ... +2^63-1 0 ... 2^64-1 19 Dezimalstellen (ab C99, 64 Bit) float double long double 4 Byte 8 Byte 10 Byte ca. -10^38 ... +10^38 ca. –10^308 ... +10^308 ca. -10^4932 ... +10^4932 6 Dez.-Stellen 15 Dez.-Stellen 19 Dez.-Stellen Die angegebenen Werte stellen Beispiele für 32-Bit Umgebungen dar, sie sind implementierungsabhängig Peter Sobe 7 Basisdatentypen (Fortsetzung) Wertebereich enum { list } enum id { list } enum id 4 Byte 4 Byte 4 Byte 2^32 verschiedene Werte bool (nur C++) 1 Byte true, false type* void* 4 Byte 4 Byte 0...2^32-1 0...2^32-1 type& (nur C++) 4 Byte 0...2^32-1 Peter Sobe Genauigkeit einzelne Bytes im Speicher adressierbar 8 Verwendung der Datentypen Datentypen für ganze Zahlen in C: int, signed int, unsigned int, long, signed long, unsigned long, short, signed short, unsigned short Beispiel: int i = -64; long li = 3; Integer-Variablen werden für beispielsweise für zählbare Dinge benutzt, oder für Index-Berechnungen. Peter Sobe 9 Verwendung der Datentypen Gleitkommazahlen: float, double, long double Beispiele: double d = 64.3345; double d1 = 1.234e-22; // ohne Leerzeichen zu schreiben float f = 67.31f; float f1 = 2.9744e-22f; double x = 5.; // 5. entspricht 5.0 Gleitkommazahlen werden für Eigenschaften, Größen verwendet, die als rationale oder reelle Zahlen angegeben werden, z.B. Wachstumsrate = 2.12 %. Peter Sobe 10 Verwendung der Datentypen Einzelne Zeichen (char) - die Werte entsprechen in der Regel dem ASCII-Zeichensatz Beispiele: char c = 64; char c1 = ‘h’; char c2 = ‘\n’; Peter Sobe 11 ASCII-Code Peter Sobe 12 Verwendung der Datentypen Einzelne Zeichen (char) können auch zur Aufnahme von ganzzahligen Werten benutzt werden: unsigned char … kann 0 bis 255 repräsentieren (vorzeichenlos) char … kann Werte von -128 bis +127 repräsentieren Ob eine char-Variable als Zeichen, oder als Zahl benutzt wird, hängt immer vom Kontext ab. Benutzung als Zeichen: Benutzung als Zahlenwert: char z; int i=0; do { z= getchar(); // Eingabe Zeichen if (z!=‘x‘) i = i+1; else break; } while (true); Peter Sobe char z=0; do { if (z<12) printf(“ %d Uhr morgens\n“,z); else if (z==12) printf(“ %d Uhr mittags\n“,z); else printf(“ %d Uhr nachmittags\n“,z-12); z = z + 1; } while (z<24); 13 Konstantenausdrücke Konstantenausdrücke sind • ganze Zahlen, z.B. 123, -465, 033, 0xab, 0XFF, 123L, 123UL, • Gleitkommazahlen, z.B. 12.34, 12.45e-3, 0123, 1e20, • Zeichenkonstanten, z.B. ‘a‘, ‘X‘, ‘\07‘, ‘\xb‘ und • Aufzählungswerte, z.B. rot, Montag, ... (wenn vorher entsprechend definiert) • Konstante Zeichenfolgen wie z.B. "Guten Morgen" Konstantenausdrücke werden in Zuweisungen benutzt, z.B. für Anfangswerte int startwert=5; auch für ‘feste‘ Werte in Berechnungen float umfang = 2*a+2*b; float flaeche= 0.433f*a*a; Peter Sobe 14 Konstante Variablen Variablen können als „const“ markiert werden. Dann darf der Wert einer Variable später nicht mehr geändert werden. Die Verwendung von Konstanten erhöht die Lesbarkeit des Programms und macht es änderungsfreundlicher Anstatt: umfang = 2 * radius * 3.14159; Besser: const double PI = 3.14159; umfang = 2 * radius * PI; const heißt nur, dass die Variable nicht mehr verändert werden darf, der Wert muss nicht schon zur Übersetzungs-Zeit bestimmt werden können. Beispiel: const double UmfangMeinKreis = 2.0 * radius * PI; // radius muss keine Konstante sein Peter Sobe 15 Konstante Variablen Guter Programmierstil ist es, außer den Konstanten –1, 0 und 1 keine numerischen Konstantenausdrücke in einem Programm zu verwenden, sondern diese immer einer konstanten Variable zuzuweisen. Anstatt: for (int i=0;i<10;i++) spieler[i].anzahl_huetchen= … Besser: const int ANZAHL_MITSPIELER = 10; … for (int i=0; i < ANZAHL_MITSPIELER; i++) spieler[i].anzahl_huetchen=… Peter Sobe 16 Aufzählungstypen Manchmal ist es sinnvoll, eine Vielzahl gleichartiger Konstanten zu einer Menge zusammenzufassen. Jedes Element dieser Menge wird intern durch eine Zahl repräsentiert. Der Programmierer benutzt aber nur die Konstanten. Beispiel: enum Wochentag { Mon, Die, Mit, Don, Fri, Sam, Son }; Wochentag Tag; Tag = Mon; Syntax von Aufzählungen: enum AufzTyp { Bezeichnerl, Bezeichner2, ... } Variable; enum { Bezeichnerl, Bezeichner2, ... } Variable; enum AufzTyp { Bezeichnerl = 2, Bezeichner2, ... }; Peter Sobe 17 Interne Informationsdarstellung Interne Darstellung ganzzahliger Datentypen Fließkomma-Datentypen Was passiert: Dezimalkonstantenausdrücke werden vom Übersetzer in eine interne Binärdarstellung umgewandelt Eingegebene Werte (z.B. mit der scanf()-Funktion) werden durch die Eingabefunktion in ihr Binärformat umgewandelt Rechenoperationen werden immer im Binärformat ausgeführt Ausgabefunktionen (z.B. printf()) wandeln die binären Repräsentation der Variablen wieder in dezimale Werte zurück. Peter Sobe 18 Operatoren und Ausdrücke Ausdrücke werden aus Variablen, Operatoren und Konstanten gebildet. Beispiele: a*2.1 a<c Ausdrücke enthalten oftmals Teilausdrücke Beispiele: a+(b+c) (a+1) < (b-c) Ausdrücke ergeben zur Ausführungszeit des Programms einen Wert Bei der Übersetzung wird einem Ausdruck ein Typ zugeordnet, die berechneten Werte werden wie der zugeordnete Typ interpretiert Peter Sobe 19 Operatoren und Ausdrücke Regeln für Ausdrücke: Konstanten entsprechen einem Typ, z.B. 1 entspricht Typ int, 1.1 entspricht Typ double 1.1f entspricht Typ float, ‘1‘ entspricht Typ char Einzelne Variable entsprechen ihren deklarierten Typ int a; // a ergibt immer den Typ int Durch Operatoren zusammengesetzte Ausdrücke ergeben int für die Operatoren ==,!=, <,> usw. (Relationen) ergeben int für Rechenoperationen zwischen zwei int-Ausdrücken ergeben float für Rechenoperationen mit zwei float-Ausdrücken ergeben double für Rechenoperationen mit zwei double-Ausdrücken und auch den Wert der jeweiligen Operation. Peter Sobe 20 Operatoren und Ausdrücke Operatoren zwischen Ausdrücken verschiedener Typen (int, float, double) bewirken eine implizite Typumwandlung hin zu dem jeweils „höheren“ Typ. aus int op float wird float op float aus double op int wird double op double Merke: Sobald ein Ausdruck einem float-Typ entspricht, wird die Operation im Fließkomma-Rechenwerk mit zwei float-Operanden ausgeführt. Sobald ein Ausdruck einem double-Typ entspricht, wird die Operation im Fließkomma-Rechenwerk mit zwei double-Operanden ausgeführt. Nur solche Operationen, die zwischen zwei int-Ausdrücken platziert sind, werden durch das int-Rechenwerk ausgeführt, bzw. vom Compiler vorab ausgerechnet. Peter Sobe 21 Operatoren (1) Binäre Operatoren + * / % Addition Subtraktion Multiplikation Division Divisionsrest < <= == != >= > Vergl. auf kleiner Vergl. auf kleiner oder gleich Vergl. auf gleich Vergl. auf ungleich Vergl. auf größer oder gleich Vergl. auf größer Vergleich Alle Typen & | ^ << >> bitw. UND-Verknüpfung bitw. ODER-Verknüpfung bitw. Exkl.-Oder-Verknüpfung bitw. Linksverschieben bitw. Rechtsverschieben Bitoperationen Ganzzahlige Typen && || log. UND-Verknüpfung log. ODER-Verknüpfung Logische Verknüpfungen Boolesche Werte Peter Sobe Arithmetik Zahlen, mit Einschränkung Adressen nur ganze Zahlen 22 Operatoren (2) Unäre Operatoren, Postfix- und Präfix-Operatoren & * Adresse von Inhalt von Refernzierung Dereferenzierung alle Typen Zeiger + - pos. Vorzeichen neg. Vorzeichen Arithmetik Zahlen ~ bitw. Invertierung Bitoperationen ganzz. Typen ! logische Invertierung Log. Verknüpfung boolesche Werte Typecast C-Allzweck-Cast viele Typen (type) sizeof sizeof ++ -- Peter Sobe sizeof expr.: Speicherbedarf sizeof (type):Speicherbedarf Inkrementierung Dekrementierung Ausdrücke Typen Postfix und Präfix ganzz. Typen und Zeiger 23 Operatoren (3) Zuweisungs-Operatoren und sonstige Operatoren = Wertzuweisung Zuweisung Alle Typen += -= *= /= %= Addition Subtraktion Multiplikation Division Divisionsrest Arithmetik und Zuweisung Zahlen, mit Einschränkungen, Adressen nur ganze Zahlen &= |= ^= <<= >>= bitw. UND-Verknüpfung bitw. ODER-Verknüpfung bitw. Eckl.-Oder-Verkn. bitw. Linksverschieben bitw. Rechtsverschieben Bitoperationen und Zuweisung ?: , Formulierung bed. Ausdrücke Aufzählung in Klammerausdr. Peter Sobe ganzz. Typen Ausdrücke Ausdrücke 24 Prioritäten von Operatoren 1 ! ~ ++ -- + - * & sizeof (type) unär, postfix, präfix 2 3 • /% +- binäre arithmetische Operatoren 4 << >> Shift-Operationen 5 6 < <= > >= == != Vergleichsoperatoren 7 8 9 & ^ | Bitoperationen 10 11 && || logische Verknüpfungen 12 = += -= *= /= %= &= = |= <<= >>= Zuweisungsoperatoren 13 , Komma-Operator 1 ist die höchste Priorität, 13 die niedrigste Peter Sobe 25