Programmiersprachen Einführung Teil 3: Prof. Dr. Jörg Schwenk Lehrstuhl für Netz- und Datensicherheit Gliederung Programmiersprachen 1. Von der Maschinensprache zu C 2. Die Struktur von C-Programmen 3. 4. Bildschirm Ein-/Ausgabe 5. Kontrollstrukturen 6. Funktionen 7. Programmierstil, Programmierrichtlinien 8. Felder u. Zeichenketten 9. Ausdrücke 10. Arbeiten mit Dateien 11. Strukturen, Aufzählungstypen 12. Zeiger 13. Enums, Strukturen und Unions 14. Speicherklassen 15. Optional: Vertiefung einiger Themen 2 1
Variablenmodell der imperativen Programmiersprachen 123245672892 822949245628 28 Zugriff auf Wert über Bezeichner u. Adresse möglich Lebenszeit und -dauer abhängig von Gültigkeitsbereich 3 Programmvariablen... müssen deklariert sein, d.h.... ihre Namen müssen vor Benutzung eingeführt werden besitzen einen Datentyp, der ebenfalls dem Compiler bekanntgemacht werden muß Variablen, die miteinander verknüpft werden, müssen verträgliche Typen besitzen Beispiel : double kathete1, kathete2, hypotenuse; <Datentyp> <Liste der Variablen des Typs> ; 4 2
Warum unterschiedliche Datentypen? Datentyp spezifische Datendarstellung (durch Bits/Bytes) Folgerung 1: interne Darstellung ganzer Zahlen (Zahl) interne Darstellung von Gleitkommazahlen (Mantisse+Exponent) Folgerung 2: Addition ganzer Zahlen ("Untereinanderschreiben + Add.") Addition von Gleitkommazahlen ("Exponentenausgleich, Untereinanderschreiben + Add.") bei Zahlentypen Verträglichkeit durch Konvertierbarkeit 5 Warum unterschiedliche Datentypen? Jeder Datentyp hat spezifische Eigenschaften, z.b. ganze Zahlen keine Rundungsfehler, sehr schnelle Bearbeitung Gleitkomma großer Wertebereich, dafür evtl. Rundungsfehler Speicherplatz vs. Wertebereich vs. Genauigkeit Vorzeichen werden benötigt oder nicht Entsprechung von HW-Registern... 6 3
Konvertierbarkeit / Verträglichkeit void main() { int zaehler, nenner; double ergebnis, faktor, erg2; zaehler = 8; nenner = 16; faktor = 1.5; // Beispiel für Anweisung mit Typanpassung: ergebnis = zaehler / nenner * faktor ; erg2 = faktor * zaehler / nenner ; // dabei Konvertierung von int-darstellung in double } 7 Wertzuweisung Zuweisungsoperator = rechte Seite z.b. (arithmetischer) Ausdruck Anweisung: <ausdruck> ; Semikolon erzeugt aus Ausdruck eine Anweisung! Beispiele: x = 2 Zuweisung + Ausdruck (C-spezifisch! Nicht in anderen Programmiersprachen!) x = 2 ; Anweisung a + 3 ; Anweisung (aber in dieser Form sinnlos!) 8 4
Basisdatentypen 8'5(23) &7539 12344256789 16739 75347539 759 7! 3"781327879 #$663! 3"78759 % ±12 % ±132 % ±4516 char short int long long int 1234356789875388753 float double long double 9 ANSI - Character-Datentypen Datentyp Mind.Anz. Bytes Wertebereich (typisch) Bemerkung signed char char 1 [-128, 127] Ganzzahl mit Vorzeichen, Zeichen unsigned char 1 [0, 255] Zeichen vorzeichenlose Ganzzahl 10 5
ANSI - Integer-Datentypen 123453678 95588 434448 4458 6348 1234567898 12345671897123457 7 767787137943787247 1897123457857 38537 1897123457 7 7677 137943787123457 554838537 1897857 7 12 767 12 7 87137943787123457 18967537 1897 7 67 13 7 137943787857 5548537 1897 397857 7 12 767 12 7 87137943787857 1897 397 397856757 1897 397857 554858 7 767 13 7 137943787 397 11 ANSI - Gleitkommadatentypen 123456789 12 6
Typumwandlungen, cast int zaehler = 8 ; int nenner = 16; double ergebnis; double faktor = 1.5 ; ergebnis = zaehler / nenner * faktor; ergebnis = 0.0 cast - erzwungene Typumwandlung (<neuer Datentyp>) <Ausdruck>, z.b. double_var = (double) int_var; ergebnis = (double) zaehler; ergebnis = 8.0 ergebnis = (double) zaehler / (double) nenner * faktor; ergebnis = 0.75 ergebnis = (double) zaehler / nenner * faktor; ergebnis = 0.75 ergebnis = (double) (zaehler / nenner) * faktor; ergebnis = 0.0 ergebnis = faktor * zaehler / nenner; ergebnis = 0.75 13 Direkte Konstanten, unmittelbar definiert Numerische Konstanten sind /C++ typbehaftet! 12345 int 1.2345 double (! nicht float!) 1.2345f float 0x1A, 0X1A int, hexadezimal (Wert: 26) 012345 int, oktal (Wert: 5349) 7926U unsigned 7926L long 'A', '\101', '\x41' char, Wert abhängig vom Zeichensatz Typinterpretation durch U(unsigned) / L(long) / f(float) Achtung: Versehentliches Vergessen des Typspezifizierers bei float kann zu undefinierten Belegungen der Variablen führen!!! 14 7
Deklarierte Konstanten Deklarierte Konstanten sind an einen Bezeichner gebunden #define name zeichenfolge textuelle Ersetzung durch den Präprozessor jedes nachfolgende Auftreten von 'name' wird durch die in #define angegebene 'zeichenfolge' ersetzt! Konstanten (ANSI C & C++) const typ name = wert; Beispiel: const double e = 2.71828182845905; "name" muß gleich mit einem Wert initialisiert sein, sonst Fehler! "name" bezeichnet nur einen typisierten Wert, es muß nicht unbedingt tatsächlich eine konstante Variable im Speicher abgelegt sein! Empfehlung "const" gegenüber #define aufgrund der hier möglichen Typ- und Syntaxprüfungen unbedingt bevorzugen 15 8