Propädeutikum 2015
Vorbereitungskurs Informatikstudium Erfolgreich Studieren Programmieren (C-Kurs) guettler@informatik.uni-leipzig.de Universität Leipzig Institut für Informatik Technische Informatik 2
Weiterführende Literatur C Die Programmiersprache C. Ein Nachschlagewerk RRZN Bücher, 18. Auflage 3,60 (2013) http://www.unileipzig.de/~boesze/softwarehandbuecher.php The C Programming Language Standardwerk Kernigham & Ritchie ISBN 978-0131103627 3
Überblick Kapitel 10 (Fortsetzung) Funktionen Kapitel 11 Bibliotheken (Funktionssammlungen) Kapitel 12 Module und Kompilierung 4
Kapitel 10 (Fortsetzung) Funktionen 5
Kapitel 10 - Funktionen Funktionen - Verwendung // kreisumfang.c Berechnung des Kreisumfangs mittels Radius #include <stdio.h> #define M_PI 3.14159 float umfang(float radius); int main() { float radius, ergebnis; printf("kreisradius? "); scanf("%f", &radius); ergebnis = umfang(radius); printf("kreisumfang: %f\n", ergebnis); } return 0; float umfang(float radius) { return 2 * radius * M_PI; } 6
Kapitel 10 - Funktionen Funktionsaufruf ergebnis = umfang(radius); Semantik 1. Werte aus Argumenten berechnen, ggf. Typ konvertieren 2. Werte als Kopie (call-by-value) übergeben Andere Moeglichkeit: call-by-reference (später) 3. Funktion ausführen 4. Aufrufstelle wird mit Rückgabewert ersetzen 5. Programmausführung fortsetzen 7
Kapitel 10 - Funktionen Hauptfunktion int main() Muss existieren Darf nicht manuell aufgerufen werden Deklaration und Definition fallen zusammen Typ int return Wert; muss angegeben werden Vereinbarung: Rückgabewert 0 = korrekter Programmablauf Beispiel int main() { return 0; } 8
Kapitel 10 - Funktionen Funktionsrücksprung Rücksprung Implizit: Nach Abarbeitung der letzten Anweisung Kein Rückgabewert Explizit (return) An beliebiger Stelle in Funktion Meist Rückgabewert Syntax return [ Ausdruck ]; Semantik 1. Ausdruckswert in Rückgabetyp konvertieren 2. Wert zurückgeben 3. Programm an Aufrufstelle fortsetzen 4. I.d.R Auswertung des Rückgabewerts 9
Funktionsrücksprung Beispiel int highfive(void) { return 5; } int highfive2() { return 2+3; } void { ; } donothing() void donothing2(void) { return; } 10
Kapitel 11 Bibliotheken (Funktionssammlungen) 11
Kapitel 11 - Bibliotheken (Funktionssammlungen) Bibliotheken - Übersicht I. Editieren Quelldatei modul.c II. Übersetzen - Präprozessor - Compiler - Assembler Objektdatei modul.o Bibliothek Bibliothek Bibliothek lib1.so lib1.so lib1.so III. Binden Programm a.out IV. Ausführen Komandozeile $./a.out 19
Bibliotheken - Deklarationen Kapitel 11 - Bibliotheken (Funktionssammlungen) Header (.h) Zusammenfassung der Funktionsdeklarationen einer Bibliothek Einbindung mit #include <stdio.h> (Compiler-/Systemverzeichnis) #include name.h (Aktuelles Verzeichnis)
Kapitel 11 - Bibliotheken (Funktionssammlungen) Bibliotheken - Deklarationen
Kapitel 11 - Bibliotheken (Funktionssammlungen) Bibliotheken - Übersicht math.c wurzel.c math.h Kompilieren Kompilieren Linken wurzel.o wurzel math.o 15
Bibliotheken - Definitionen Kapitel 11 - Bibliotheken (Funktionssammlungen) Bibliotheksarchive (.a,.so,.dll) Bereits übersetzte Definitionen Bibliothek kann unterschiedliche Header haben Namensgebung Statische Bibliothek: libname.a Dynamische Bibliothek: libname.so, libname.dll Beispiel: C-Bibliothek Header: stdio.h, stdlib.h, string.h,... Archiv: libc.a 16
Kapitel 11 - Bibliotheken (Funktionssammlungen) Bibliotheken - Linker Linker Erzeugt ausführbares Programm Laden von Objektcode aus Objektdateien u. Archiven Automatisch bei libc.a Manuell über Compileroption Linkerhinweis l Name Suchverzeichnis L Pfad Beispiel: Bibliothek libm (für <math.h>) gcc wurzel.c lm o wurzel Beispiel: Bibliothek libbool in /home/prop01/lib gcc logik.c L/home/prop001/lib lbool o logik 17
Kapitel 12 Module und Kompilierung 18
Beispiel // main.c #include <stdio.h> #include kreis.h int main(void) { float radius, erg; printf("kreisradius? "); scanf("%f", &radius); erg = umfang(radius); printf("kreisumfang: %f\n", erg); // kreis.h #define M_PI 3.14159 float umfang(float radius); // kreis.c #include kreis.h float umfang(float radius) { return 2 * radius * M_PI; } } return 0; 19
Überblick Kompilierung mit Modulen Durchläuft mehrere Schritte Verteilung des Quellcode auf unterschiedliche Dateien Wiederverwendung von Code Compileraufruf ein Modul gcc kreisumfang.c -o kreisumfang mehrere Module gcc main.c kreis.c -o main Abarbeitung von rechts nach links 20
Kompilierung - Einführung I. Editieren Quelldatei main.c Quelldatei kreis.c II. Kompilieren Präprozessor Compiler Assember Objektdatei main.o Objektdatei kreis.o Bibliothek Bibliothek Bibliothek lib1.so lib1.so libc.a III. Linken Programm main 21
Programmerstellung I. Editieren Erstellung von Quellcode II. Kompilierung (Übersetzung) Generierung von Zwischencode Unterscheidung in Dateiendung Dateien werden wegen kürzerer Kompilierzeit oft beibehalten 3 Phasen: 1. Präprozessor 2. Compiler 3. Assembler III. Linken (Binden) Zusammenfügen zu ausführbarem Programm 22
I. Editieren // main.c #define ZERO 0 #nclude <stdio.h> int main(void); { printf(hallo\n); return ZERO; } 23
II. Kompilierung Präprozessor Präprozessordirektiven ausführen, z.b.: Einfügen von include -Dateien Ersetzen von define -Konstanten // main.c #define ZERO 0 #nclude <stdio.h> int main(void); { printf(hallo\n); return ZERO; } Präprozessor- Syntaxanalyse main.c (Quellcode) Fehler Fehlerliste: error: invalid preprocessing directive #nclude 24
II. Kompilierung Präprozessor Präprozessordirektiven ausführen, z.b.: Einfügen von include -Dateien Ersetzen von define -Konstanten // main.c #define ZERO 0 #include <stdio.h> int main(void); { printf(hallo\n); return ZERO; } Präprozessor- Syntaxanalyse main.c (Quellcode) Fehler Fehlerliste: error: invalid preprocessing directive #nclude main.i (präzisierter Quellcode) 25
II. Kompilierung Präprozessor Präprozessordirektiven ausführen, z.b.: Einfügen von include -Dateien Ersetzen von define -Konstanten main.i int printf(...); int scanf(...);... int main(void); { printf(hallo\n); return 0; } Präprozessor- Syntaxanalyse main.c (Quellcode) main.i (präzisierter Quellcode) 26
II. Kompilierung Compiler Präzisierten Quellcode in Assemblercode übersetzen Syntaxanalyse evtl. Optimierungen Code-Generierung main.i int printf(...); int scanf(...);... int main(void); { printf(hallo\n); return 0; } C-Syntaxanalyse main.i (präzisierter Quellcode) Fehler Fehlerliste: error: expected... before { token error: stray \ in program 27
II. Kompilierung Compiler Präzisierten Quellcode in Assemblercode übersetzen Syntaxanalyse evtl. Optimierungen Code-Generierung main.i int printf(...); int scanf(...);... int main(void) { printf( Hallo\n ); return 0; } C-Syntaxanalyse main.i (präzisierter Quellcode) Fehler Keine Fehler Fehlerliste: error: expected... before { token error: stray \ in program 28
II. Kompilierung Compiler Präzisierten Quellcode in Assemblercode übersetzen Syntaxanalyse evtl. Optimierungen Code-Generierung main.i int printf(...); int scanf(...);... int main(void) { printf( Hallo\n ); return 0; } C-Syntaxanalyse Optimierung und Code-Generierung main.i (präzisierter Quellcode) Keine Fehler main.s (Assemblercode) 29
II. Kompilierung Compiler Präzisierten Quellcode in Assemblercode übersetzen Syntaxanalyse evtl. Optimierungen Code-Generierung main.s section.data msg db Hallo\n" section.text global _start _start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 6 syscall mov rax, 60 mov rdi, 0 syscall C-Syntaxanalyse Optimierung und Code-Generierung main.i (präzisierter Quellcode) Keine Fehler main.s (Assemblercode) 30
II. Kompilierung Assembler Assemblercode in Objekt-/Maschinencode übersetzen main.s section.data msg db Hallo\n" section.text global _start _start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 6 syscall mov rax, 60 mov rdi, 0 syscall Syntaxanalyse main.s (Assemblercode) Fehler Fehlerliste:...... Ungewöhnlich, da Assemblercode von Compiler erzeugt 31
II. Kompilierung Assembler Assemblercode in Objekt-/Maschinencode übersetzen main.s section.data msg db Hallo\n" section.text global _start _start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 6 syscall mov rax, 60 mov rdi, 0 syscall Syntaxanalyse main.s (Assemblercode) Globale Objekte (wie die Funktion printf) erhalten eine Scheinadresse, da ihre tatsächliche Adresse noch nicht bekannt ist. main.o (Objekt-/Maschinencode) 32
II. Kompilierung Assembler Assemblercode in Objekt-/Maschinencode übersetzen main.o 001110100101110111010 101101101100101010111 101100101010101111001 010010010010111010100 100010010010010100100 111101010101001111111 011001010111001000010 101010101001010100101 010101010101001011100 001010000110001001001 001111111011101001010 010100101001010101010 010110110101010100100 011011111001011010011 Syntaxanalyse main.s (Assemblercode) Globale Objekte (wie die Funktion printf) erhalten eine Scheinadresse, da ihre tatsächliche Adresse noch nicht bekannt ist. main.o (Objekt-/Maschinencode) 33
III. Linken Ausführbares Programm erstellen Objektdateien des Programm gegen Objektdateien der benötigten Bibliotheken linken Dabei werden die Scheinadressen aufgelöst main.o 001110100101110111010 101101101100101010111 101100101010101111001 010010010010111010100 100010010010010100100 111101010101001111111 011001010111001000010 101010101001010100101 010101010101001011100 001010000110001001001 001111111011101001010 010100101001010101010 010110110101010100100 011011111001011010011 main.o (Objekt-/Maschinencode) Bibliotheken 34
III. Linken Ausführbares Programm erstellen Objektdateien des Programm gegen Objektdateien der benötigten Bibliotheken linken Dabei werden die Scheinadressen aufgelöst main.o 001110100101110111010 101101101100101010111 101100101010101111001 010011110001111010100 100010010010010100100 111101010101001111111 011001010111001000010 101010101001010100101 010101010101001011100 001010000110001001001 001111111011101001010 010100101001010101010 010110110101010100100 011011111001011010011 main.o (Objekt-/Maschinencode) Bibliotheken 35
III. Linken Ausführbares Programm erstellen Objektdateien des Programm gegen Objektdateien der benötigten Bibliotheken linken Dabei werden die Scheinadressen aufgelöst main.o 001110100101110111010 101101101100101010111 101100101010101111001 010011110001111010100 100010010010010100100 111101010101001111111 011001010111001000010 101010101001010100101 010101010101001011100 001010000110001001001 001111111011101001010 010100101001010101010 010110110101010100100 011011111001011010011 main.o (Objekt-/Maschinencode) Bibliotheken Fehler Fehlerliste: undefined reference to printf error: ld returned 1 exit status 36
III. Linken Ausführbares Programm erstellen Objektdateien des Programm gegen Objektdateien der benötigten Bibliotheken linken Dabei werden die Scheinadressen aufgelöst main.o 001110100101110111010 101101101100101010111 101100101010101111001 010011110001111010100 100010010010010100100 111101010101001111111 011001010111001000010 101010101001010100101 010101010001101111100 001010000110001001001 001111111011101001010 010100101001010101010 010110110101010100100 011011111001011010011 main.o (Objekt-/Maschinencode) Bibliotheken main (ausführbares Programm) 37
Für Interessierte Präprozessor-Ausgabe ansehen gcc E P main.c > main.i Code befindet sich in main.i Assembler-Code ansehen gcc S main.c Code befindet sich in main.s 38
Viel Erfolg! Propädeutikum Bis morgen! 2015