Theorie | Beispiel | Aufgaben | Anmerkungen
Vom Quellcode bis zum ausführbaren Programm
Vorverarbeitung (preprocess)
Während der Vorverarbeitung erhalten wir vom Quellcode einen anderen
Quellcode,
in dem die Makrodefinitionen (#define) erweitert sind, und der die
"include"
Dateien (#include) enthaltet.
Übersetzung (compile)
Nach der Übersetzung erhalten wir vom Quellcode (z.B. C, C++) einen
Objektcode.
Im Fall der C oder C++ Programmen ist die Eingabe eine C oder C++ Quellcode
enthaltene
Datei, als Ausgabe erhalten wir eine Objektcode enthaltene Datei.
Der Übersetzer wird auch die Vorverarbeitung durchführen. Die C Übersetzer
unter UNIX
erstellen im allgemeinen von der Eingabe-Datei eine Objektcode enthaltene
Datei mit dem
gleichen Namen, aber mit Erweiterung „.o”
Zusammenbindung (link)
Die Aufgabe dieser Arbeitsphase ist, wenn mehrere Objektcode enthaltene
Dateien gegeben, von diesen, und eventuell vom Programm benützten
Bibliotheken
eine ausführbare Datei zu erstellen.
Das ist notwendig, weil das Programm aus mehreren Modulen bestehen kann, die
einzeln übersetzt werden. Außerdem können wir auch äußerliche Bibliotheken
benützen.
Das gcc/g++ Übersetzerprogramm
Das gcc Übersetzerprogramm ist momentan einer der kräfigsten C Übersetzers.
Seine, für die Übersetzung von C++ Quellcode geeignete Erweiterung ist g++,
dass
wir auch unter dem Namen gcc aufrufen können.
Der Übersetzer wird nach der Erweiterung der Quellcode enthaltene Datei
entscheiden
worüber es sich handelt. „.c” Erweiterung heisst C, während
„.C”, „.cc”, „.cpp”, „.c++”,
usw.
Erweiterungen stehen für C++ Quellcode.
Dieses Übersetzerprogramm führt auch die Vorverarbeitung und Zusammenbindung
durch.
Wenn wir nicht jede Phase durchgehen möchten, können wir das den Übersetzer
mit Hilfe von
Optionen oder mit der Erweiterung der Datei bekanntgeben. Wenn nicht anders
gegeben,
wird der Name der ausführbaren Datei a.out. Mehrere Informationen: man gcc.
Beispiele:
Ein einziges Modul:
gcc Bsp.C -o Bsp
Mehrere Module:
gcc Bsp.C -c
gcc Hilfe.cc -c
gcc Bsp.o Hilfe.o -o Bsp
Wenn auch eine äusserliche Bibliothek benützt wird:
gcc Bsp.C -c
gcc Hilfe.cc -c
gcc Bsp.o Hilfe.o -I/usr/lib/libncurses.a -o
Bsp
Das make Hilfsprogramm – makefile
Im Fall der komplexeren Programmen besteht ein Programm aus mehreren Modulen. Diese Modulen sind voneinander abhängig, wenn eine davon modifiziert wird, kann das als Volge haben, dass auch andere Modulen wieder übersetzt werden sollen, und das ganze Programm wieder zusammengebunden werden soll. Zwischen den verschiedenen Modulen bestehen „Abhängigkeiten”. Wir können mit der Hilfe des make Hilfsprogramms ein grosses Projekt sehr einfach übersetzen so, dass nur die Module neu übersetzt werden, für welche das –wegen der Abhängigkeiten– nötig ist, der Programmierer muss nicht jede Änderung beachten. Das make Hilfsprogramm wird nach den, in der Makefile gegebenen Regeln und Zeitstempel der Dateien entscheiden, welche Befehle ausgeführt werden sollen.
Eine makefile enthaltet Regeln, Variablendefinitionen, Direktiven und Kommentare.
Regeln
Ein Regel bestimmt von welche Dateien der Zieldatei dieser Regel abhängig
ist, bzw.
mit welchem Befehl wird sie erstellt. Wenn der Zeitstempel einer der
Abhängigkeit
verursachenden Dateien neuer las der, der Zieldatei ist, wird der Befehl
ausgeführt.
Die Struktur einer Regel:
Zieldatei: Abhängigkeit verursachende Dateien
Kommandozeile
Zieldatei: Abhängigkeit verursachende Dateien; Kommandozeile
Die Kommandozeile wird meistens in eine neue Zeile geschrieben. In diesem Fall soll die Zeile unbedingt mit einem <Tab> Charakter anfangen. Kann auch mehrere Befehle enthalten. Diese werden entweder mit „;” getrennt oder werden in eine, mit <Tab> angefangene neue Zeile geschrieben.
Variablendefinitonen
Die Variablendefiniton ist eine Zeile, die gibt eine Zeichenkette als Wert
einer Variable
an. Weiterhin wird das Programm den Variablenname mit dieser Zeichenkette
umtauschen.
Direktiven
Eine Direktive weist das make Hilfsprogramm an, dass es, während der
Makefile
eingelesen wird, soll eine spezielle Aufgabe durchführen.
Das kann z. B. das Einlesen einer anderen Makefile oder eine Bedingung, usw.
sein.
Kommentar
Das Programm betrachtet den, nach „#” folgenden Teil als
Kommentar,
wird also nicht ausgewertet.
Ebenfalls ist eine Leere Zeile auch Kommentar.
Wir können das make Hilfsprogramm einfach ohne Parameter aufrufen, in diesem Fall soll der Name der Makefile „makefile”, „Makefile”, „GNUmakefile” sein, oder können wir mit der Option -f den Namen der Makefile angeben.
Mehrere Informationen: info make
# Variablendeklarationen
CC = g++
CCFLAGS = -Wall
SRC = Hilfe.cc \
Bsp.cc
OBJ = Hilfe.o \
Bsp.o
PROGRAM = Bsp
# Regeln
$(PROGRAM) : $(OBJ)
$(CC) $(OBJ) -o $(PROGRAM)
Hilfe.o : Hilfe.cc
Daten.h
$(CC) Hilfe.cc -c $(CCFLAGS)
Bsp.o : Bsp.cc Daten.h
$(CC) Bsp.cc -c $(CCFLAGS)
# Befehle zum Löschen
.PHONY : clean
clean :
rm -f $(PROGRAM) $(OBJ) core *~
1. Schreiben Sie eine Funktion Wurzel(k,a), welche die Wurzel der Ordnung
k
von a mit Genaugkeit e=0.00000001 (k>2 ist eine
natürliche Zahl, a ist eine positive Realzahl), als Grenzwert der
Folge
xn+1 = 1/k ((k-1)
xn +a/xnk-1)
ausrechnet, wenn x0 = a/2.
Diese Funktion wird benützt um die Summe S =
Wurzel(k,x1) + ... +
Wurzel(k,xn) auszurechnen, wo
x1,
x2, ..., xn positive Realzahlen sind,
die von der Datei
„input.dat” eingelesen werden.
2. Schreiben Sie eine Funktion „ggT(k,m)”, die den größten
gemeinsamen Teiler
von k und m ausrechnet. Diese Funktion wird benützt um den
größten gemeinsamen Teiler der natürlichen Zahlen x1,
x2, ..., xn, n>1 auszurechnen. Die
Zahlen werden
von der Datei „input.dat” eingelesen.
3. Schreiben Sie eine Funktion „kgM(k,m)”, die das kleinse
gemeinsame
Mehrfache von k und m ausrechnet. Diese Funktion wird
benützt um
das kleinse gemeinsame Mehrfache der natürlichen Zahlen
x1,
x2, ..., xn, n>1, auszurechnen. Die
Zahlen werden
von der Datei „input.dat” eingelesen.
4. Schreiben Sie eine Funktion „aProg(k,m)”, die überprüft,
ob die
Zahlen a, b und c eine arithmetische Progression
bilden.
Mit der Hilfe dieser Funktion wird entschieden ob die Zahlen
x1,
x2, ..., xn, n>1, eine
arithmetische Progression
bilden. Die Zahlen werden von der Datei „input.dat”
eingelesen.
5. Schreiben Sie eine Funktion „gProg(k,m)”, die überprüft,
ob die
Zahlen a, b und c eine geometrische Progression
bilden.
Mit der Hilfe dieser Funktion wird entschieden ob die Zahlen
x1,
x2, ..., xn, n>1, eine
geometrische Progression
bilden. Die Zahlen werden von der Datei „input.dat”
eingelesen.
6. Schreiben Sie eine Funktion „Test(k)”, die überprüft ob
wir die
gleiche Zahl wie k erhalten, wenn wir die Ziffern von k in
umgekehrter
Reihenfolge aufschreiben. Mit der Hilfe dieser Funktion wird die Anzahl
der Zahlen
mit dieser Eigenschaft von den natürlichen Zahlen x1,
x2,
..., xn, n>1 ausgerechnet. Die Zahlen werden von
der Datei
„input.dat” eingelesen.
7. Schreiben Sie eine Funktion „perfekt(k)”, die überprüft
ob
die natürliche Zahl k perfekt ist, d.h. die Summe ihrer Teiler
(ausgenommen
die Zahl selbst) ergibt die Zahl. Z. B. 6=1+2+3. Mit der Hilfe dieser
Funktion wird
die Anzahl der perfekten Zahlen von den natürlichen Zahlen
x1,
x2, ..., xn, n>1 ausgerechnet.
Die Zahlen werden von der Datei „input.dat” eingelesen.
8. Schreiben Sie eine Funktion „eNorm(x,n)”, die das
euklidsche Norm
der Elementen der Vektor x = (xi),
i = 1, ..., n angibt (die Quadratwurzel der Quadrat-Summe
der Vektorelementen).
Diese Funktion wird benützt um das euklidsche Norm von k Vektoren
auszurechnen.
Die Vektoren werden von der Datei „input.dat” eingelesen, und
das Ergebnis wird
mit der Eingabedaten in die Datei „output.dat” geschrieben.
9. Schreiben Sie eine Funktion „Abstand(x,y,n)”, Welche die
euklidsche
Distanz der Vektoren x = (xi) und
y = (yi), i = 1, ..., n (Die
Quadratwurzel
der Quadrat-Summe der Differenzen zwischen den Elementen mit gleicher
Rang) angibt.
Diese Funktion wird benützt um die Distanz von zwei Vektoren zu bestimmen.
Die Vektoren werden von der Datei „input.dat” eingelesen, und
das Ergebnis wird
mit der Eingabedaten in die Datei „output.dat” geschrieben.