Höllische Programmiersprachen Seminar im Wintersemester 2015 Multistage Programming via Präprozessor

Größe: px
Ab Seite anzeigen:

Download "Höllische Programmiersprachen Seminar im Wintersemester 2015 Multistage Programming via Präprozessor"

Transkript

1 Höllische Programmiersprachen Seminar im Wintersemester 2015 Multistage Programming via Präprozessor Dániel Somogyi Technische Universität München 18. Dezember 2014 I

2 Inhaltsverzeichnis 1 Einführung 1 2 Multi-Stage Programming Basiskonstrukte ein Beispiel zur veranschaulichung Präprozessor Funktionsweise Möglichkeiten die #define und #undef Direktiven Die #include Direktive Bedingte Compelierung Die Operatoren Weitere Direktiven Einsatzgebiete Vor- und Nachteile eines Präprozessors Vorteile Nachteile Evaluation 11 II

3 Zusammenfassung Viele der verbreiteten Programmiersprachen wie etwa Java erlauben es dem Nutzer mit einer Folge von Befehlen ein Programm zu schreiben und so bestimmte Aufgaben zu erledigen. Jedoch ist diese Befehlsfolge, oder Code, fest vorgegeben. Es wird an den Compiler zum übersetzen gegeben und heraus kommt eine ausführbare Datei. Durch Metaprogrammierung lässt sich dieser geschriebene Code durch das Programm selbst manipulieren. Eine Art der Metaprogrammierung nennt sich Multi-Stage Programming. Hierbei besteht die Compelierung des Programmes aus mehreren stufen, bei denen jeweils nur bestimmte Befehle betrachtet und umgesetzt werden. Der Präprozessor, unter Anderem in C genutzt, zeigt eine Form des Multi-Stage Programming. Dieser prüft den Code nach bestimmten Befehlen, manipuliert es entsprechend und übergibt diese geänderte Fassung der Datei an den Compiler. Der wiederum erstellt daraus eine ausführbare Datei. Diese Ausarbeitung zeigt die Vorteile von Multi-Stage Programming mit dem C-Präprozessor, wie bessere Übersichtlichkeit und Effizienz, weist aber auch auf die Gefahren hin, welche das Programm schnell ins negative ziehen. III

4 1 Einführung Neben vielen Programmiersprachen, wie zum Beispiel C, Haskell oder Java, gibt es auch eine Reihe von Programmieransätzen oder -techniken. Diese sind unter Anderem die Funktionale Programmierung und die Objektorientierte Programmierung. Eine weitere, besondere Form ist die Metaprogrammierung. Das Besondere an diesen Programmiersprachen ist, dass sie selbst Programme oder Programmteile analysieren, Erzeugen und bearbeiten können. Eine unterklasse der Metaprogrammierung ist die Multi-Stage Programmierung. Zusätzlich zum normalen übersetzen in eine ausführbare Datei durch den Compiler wird multi-staged Code ein-, oder auch mehrfach, durchlaufen. Hierbei werden bestimmte Befehle bereits ausgewertet und der Code wird teilweise sogar abgeändert. Erst dieser neue, veränderte Code wird tatsächlich vom Compiler in ein tatsächliches, lauffähiges Programm übersetzt. Oft braucht man für diese Besondere Programmierung zusätzliche Erweiterungen (zum Beispiel Mint für Java). Einige Programmiersprachen besitzen jedoch von Haus aus Möglichkeiten, um den Code sich selbst manipulieren zu lassen. Diese Sprachen besitzen hierfür einen sogenannten Präprozessor, welcher vor dem Compiler den Code nach bestimmten Befehlen durchsucht und ihn dementsprechend abändert. Richtig gehandhabt kann man damit große Vorteile, besonders in der Performance gewinnen, jedoch birgen multi-stage Programme und Präprozessoren viele Gefahren und Probleme, weshalb man sie nur mit Vorsicht genießen sollte. 2 Multi-Stage Programming Multi-Stage Programmierung basiert auf eine einfache Idee: Wir schreiben ein Programm in einer beliebigen Programmiersprachen, fügen jedoch einige Befehle hinzu, mit denen wir bestimmte Teile des Programmes bereits zur Compelierzeit auswerten lassen können. Somit muss zur Laufzeit selbst dieser Teil nicht mehr berechnet werden und wir gewinnen Ressourcen, sowohl Zeit, als auch Speicher. Hierfür brauchen wir eine Möglichkeit um vor der eigentlichen Compelierung neuen Code zu generieren. Wichtig ist hierbei, dass schon während der Compelierung sowohl auf die korrekte Syntax, als auch auf Codesicherheit geachtet wird um nicht erst zur Laufzeit entsprechende Fehler zu bekommen. 2.1 Basiskonstrukte Für die MSP gibt es Prinzipiell nur drei Basiskonstrukte, Brackets (oder Klammern), Escape und Run. Mit den Klammern.<>. kann man Ausdrücke umgeben und sie damit verzögern. Dies bedeutet, dass sie als Code-abschnitt betrachtet werden. Dadurch wird nicht mehr zur Laufzeit der Ausdruck ausgewertet und weitergegeben, sondern noch durch die erste Stage des Compelierens der Code an die passende Stelle eingesetzt. Dadurch hat man auch nicht mehr den vorherigen 1

5 Datentyp (z.b. Integer), sondern Code vom Datentyp (also z.b. Code vom Typ Integer). Das Escape. Dient zur konkatenation von mehreren Verzögerten Ausdrücken. Dadurch kann man aus mehreren kleinen Code Abschnitten in Klammern ein größeres bilden, was besonders bei Funktionsaufrufen genutzt wird. Die Code-abschnitte werden letzendlich mit einem Run.! tatsächlich compeliert und ausgeführt. 2.2 ein Beispiel zur veranschaulichung Um das Prinzip und die Funktionsweise eines multi-stage Programmes zu erklären folgt ein einfaches Beispiel. Wir nehmen an, wir haben in einer singlestaged Programmiersprache die Funktion power (n,x) = (n == 0)? 1 : x * power ((n-1), x); welche uns die Potenz mit der Basis x für den (nicht negativen) Exponenten n berechnen soll. Da wir häufig die Quadratische Funktion brauchen schreiben wir eine zusätzliche Funktion square(x) = power (2,x); Man erkennt schnell, dass wir so einen großen Overhead erhalten, da durch die Rekursion die erste Funktion power(n,x) drei mal aufgerufen wird. Schneller wäre es, wenn wir die Quadratfunktion einfach als square(x) = x*x schreiben würden, jedoch ist dann power(n,x) aus dieser Sicht nutzlos. Wollten wir außerdem noch andere Exponenten standartisieren wäre es ein zu hoher Aufwand jede Funktion per Hand schreiben zu müssen. Mithilfe von Multi-stage Programmierung können wir unsere Ausgangsfunktion erweitern. Wir schreiben power(n,x) = (n == 0)?.<1>. :.<.~ x *.~ power((n-1),x) >.; und square(x) =.!.<power(2,.<x>.)>.; Wichtig ist in diesem Fall, dass wir nicht mehr mit Integern, sondern (durch die Klammerung) mit Code vom Typ Integer Arbeiten. Deshalb musste auch die 1 in power(n,x) und das x in square(x) geklammert werden. Außerdem ist die Konkatenation von x und dem Aufruf power((n-1), x) mithilfe eines Escape-Zeichens zu beachten. In der Funktion square(x) wird schließlich alles wieder Ausgewertet, indem wir den Run-Befehl davor setzen. 2

6 Noch vor der Compelierung wird die Funktion auf einer höheren Stufe ausgewertet, was schließlich zu square(x) =.!.<.~x*.~.<.~x*.~.<1>.>.>.; führt. Zusammengefasst ist dass nur noch square(x) =.!.<x*x*1>.; und nach dem ausführen von run ergibt es square(x) = 1*x*x; An den Compiler selbst wird nur dieser letzte Ausdruck weitergegeben. Staging hat dafür gesorgt, dass der Laufzeit-Overhead der Quadratfunktion nicht mehr vorhanden ist, sondern zur Compile-zeit eliminiert wurde[9]. Hier möchte ich Anmerken, dies ist nur ein einfaches Beispiel, formuliert in Pseudocode, ledeglich um das Grundprinzip zu verdeutlichen. In Multi-Staged Programmiersprachen gibt es viel mehr zu Beachten, unter Anderem muss der Zugriff von innerhalb der Klammern auf Variablen außerhalb verhindert werden. Noch mehr auf die Multi-staged Programmiersprachen einzugehen würde den Rahmen sprengen. Wen die multi-stage Programming besonders interessiert sollte sich die Arbeit A Gentle Introduction to Multi-stage Programming ([9]) durchlesen, wir fahren mit einer genaueren Form fort, nämlich den Präprozessoren. 3 Präprozessor Eine besondere Form von Multistage Programming bieten die sogenannten Präprozessoren (PP). Diese sind standardmäßig in den Compiler einer Sprache integriert und bieten eine reihe von Befehlen, um den Code selbst zu bearbeiten und bestimmte Befehle schon während der Compelierung auszuführen. Einen Präprozessor bietet unter Anderem die Sprache C 1, sowie deren fortführungen, wie C++ oder C#. Dieser wird hier auch genauer beschrieben, konkret im Bezug auf den GNU C preprocessor, welcher im GNU C-Compiler enthalten ist. 3.1 Funktionsweise Der CPP wird beim Compelieren automatisch aufgerufen. Hierbei wird der Code über mehrere Schritte verändert, bevor der Compiler sich ans Werk macht. Vor allem anderen wird der Zeichensatz angepasst. Der Code darf in einem Beliebigen Zeichensatz geschrieben werden (meißt ASCII), die C-Quelldaten 1 seit [8] 3

7 müssen jedoch dem Unicode-Standard 2 entsprechen. Nachdem der PP seine Arbeit beendet hat werden char-konstanten und Strings in den Zeichensatz der Ausführung zurückkonvertiert, um eine korrekte Ausgabe zu garantieren. Als nächstes wird der Code aufbearbeitet. Nachdem die Datei in den Speicher geladen wurde, wird es in einzelne Zeilen getrennt. Welche Zeichen tatsächlich als Zeilenumbruch akzeptiert werden ist Compilerabhängig, die gängigen jedoch machen keinen Unterschied zwischen den dafür typischen ASCII Kontrollzeichen 3. Hierbei werden auch Zeilen, welche in der Datei über mehrere Zeilen geschrieben wurden (mit \ ), in eine vereinigt. Kommentare (/*.. */ bzw. //..) werden durch einzelne Leerzeichen ersetzt, da sie der Compiler nicht beachten soll. Auch die sogenannten Trigraphen werden ersetzt. Trigraphen sind dreistellige Zeichenkombinationen, die andere Sonderzeichen ersetzen sollten, falls die gewünschten Zeichen auf der Maschine oder dem Zeichensatz nicht verfügbar sind. Heutzutage sind diese jedoch kaum bis gar nicht mehr in Gebrauch [2]. Sind die Textformatierungen fertig, wird der Code in preprocessing tokens unterteilt (Tokenisiert). Der C-Compiler erledigt diese Arbeit danach nicht mehr, jeder Token aus dem Präprozessor wird zu einem Token im Compiler. Der Tokenizer ist allerdings nicht sehr intelligent. So sind identifier (Variablennamen) zwar (wie in C selbst) definiert als beliebige Zeichenfolge aus Zahlen, Buchstaben und Unterstrichen, beginnend mit Unterstrich oder Buchstabe, jedoch sind die C-Schlüsselwörter nicht ausgeschlossen. Dies und andere vergleichbare Unterschiede können leicht zu Fehlern im Code führen. Solche Probleme werden unter genauer erklärt. Erst danach werden Anpassungen getroffen, welche durch den Programmierer selbst beeinflussbar sind. Mit der sogenannten preprocessing language (Präprozessorsprache) kann man dem PP Befehle erteilen bestimmte Codeabschnitte zu ersetzen und zu Manipulieren. Bis auf wenige vordefinierte Makros werden diese in preprocessing directives (Präprozessor-Direktiven) definiert. Das sind Codezeilen, welche (bis auf whitespace-charaktere vor und nach dem # ) mit einem #name beginnen, wobei name die Direktive bestimmt, gefolgt von eventuellen Parametern und dem Befehlssatz. Wie diese direktiven auszusehen haben, und welche Möglichkeiten es gibt steht im folgenden Kapitel [3, 6]. 3.2 Möglichkeiten Mit bestimmten Befehlen, den Präprozessor-Direktiven, kann man den Quelltext aktiv verändern. Die Anzahl der Präprozessor-Direktiven hält sich in Grenzen. Die wichtigsten sind #define, #undef, #include, #if, #ifdef #elif, #else und #endif. Alle Befehle haben strikte Vorgaben, wie sie genutzt werden können und wie sie den Code beeinflussen. Neben den Direktiven gibt es drei Operatoren, die in allen Befehlen genutzt werden können. Dies sind das Backslash ( \ ), das Doppelkreuz( # ) und das 2 ISO LF - Zeichenvorschub, CR - Wagenrücklauf, sowie deren Kombination [1] 4

8 Doppelte Doppelkreuz ( ## ). Alle anderen Operatoren (wie +, oder - ) werden vom Präprozessor selbst nicht ausgwertet, sondern nur eingesetzt. Im folgenden sind alle Direktiven sowie die Operatoren und deren Funktionen kurz erklärt die #define und #undef Direktiven Bei der Direktive #define kann man zwischen zwei arten Unterscheiden. Einerseits kann man symbolische Konstanten, als auch komplexere Makros erzeugen. Die Syntax ist mit #define NAME(p1,p2,..) MAKRO_BODY denkbar einfach. Hierbei steht NAME für den Bezeichner und p1,p2,.. für beliebig viele Parameter des Makros. Auch die Funktion lässt sich in einem Satz erklären: Im folgenden Code wird NAME(a1,a2,..) (a1,a2,.. stehen für Argumente) durch MACRO BODY ersetzt und die Argumente werden entsprechend eingesetzt. Wichtig ist, dass zwischen dem Namen und den Parametern kein Leerzeichen oder andere Whitespace-Zeichen stehen dürfen. Die Definition ist erst ab dem Punkt gültig, wo sie gesetzt wird, nicht rückläufig. Makros dürfen zwar andere Makros nutzen, jedoch ist Rekursion direkt nicht möglich. Der Präprozessor ersetzt nur Textinhalte und führt diese nicht aus. Rekursion würde so zu einem endlosen Einsetzen Führen. Damit dies nicht passiert wird nur einmal ersetzt. Stand der Makroname selbst im Makro steht dieser nun auch im Code. Um einen Compiler-Fehler zu vermeiden muss eine Funktion mit dem gleichen Namen exestieren. Ohne Parameter hat man einfache Konstanten. So kann man mit #define PI 3.14 die Konstante PI erzeugen und ab da überall im Programm (beziehungsweise im Dokument) nutzen. Für den Compiler erscheint es so, als wäre die Zahl 3.14 überall fest im Code geschrieben und nicht als Variable. Mit Parametern definiert man kleine Funktionen. Die Anweisung #define POW(x) (x) * (x) erzeugt ein kleines Makro für die Berechnung des Quadrates von x. Der Präprozessor ersetzt dann die Codezeile y = POW(3) durch y = (3) * (3) 5

9 und gibt dann diesen Code dem Compiler weiter. Es ist bei Makros besonders auf die Klammerung zu achten, denn der Präprozessor achtet nicht auf etwaige mathematischen Regeln wie Punkt vor Strich, sondern ersetzt die Textpassagen einfach, was leicht Fehlern führt. #undef ist das Gegenstück zu #define. Um ein Makro neu zu definieren muss die definition erst entfernt werden. Mit dem Befehl #undef NAME wird der mit #define NAME Definierte Makro oder Konstante wieder gelöscht. Versucht man danach diese zu nutzen erhält man einen Compilerfehler. Ähnlich wie Bibliotheksklassen mit vordefinierten Funktionen exestieren auch vordefinierte Makros. Viele Compiler bieten eigene an, nach ANSI sind jedcoh nur sechs Makros vordefiniert. Diese dienen eher der Überwachung des Programmes [4, 5, 6]. DATE wird durch einen String ersetzt, welcher dem Compelierungsdatum entspricht. TIME zeigt die letzte Compelierungszeit an. FILE wird ebenfalls zu einem String, dem aktuellen Dateinamen (sie Zeigt jedoch nicht das Verzeichnis). LINE setzt die aktuelle Zeile ein. STDC wird genutzt, um zu prüfen ob der Compiler dem ANSI-Standard entspricht. Wenn ja ist das eine Konstante 1, ansonsten ist sie nicht definiert. TIMESTAMP gibt einen String zurück, welcher den Letzten änderungszeitpunkt der Quelldatei anzeigt (Datum und Uhrzeit) Die #include Direktive Ein sehr häufig genutzter Befehl des Präprozessors ist #include. Damit lassen sich andere Quelldateien in das Programm einbinden, so dass man deren Funktionen ebenfalls nutzen kann. Genau genommen werden nur die sogenannten Header-Dateien eingebunden, was der konkrete Unterschied ist wird hier nicht weiter erklärt. Die #include Direktive hat als Parameter den Dateinamen des jeweiligen Headers, es gibt aber zwei verschiedene Formen. Entweder, der Name steht in 6

10 spitzen Klammern (#include <file.h>), das bedeutet, die Datei ist in einem Standardverzeichnis (meißt für die Standardbibliotheken). Oder der Dateiname steht in Anführungszeichen (#include "file.h"), wodurch die Datei im aktuellen Verzeichnis gesucht wird. Beide Ordner lassen sich für gewöhnlich mit dem Compileraufruf spezifizieren Bedingte Compelierung Die restlichen Direktiven gehören zusammen und dienen der bedingten Compelierung (Conditional Compilation). Ähnlich, wie im normalen C-Code kann man mit #if Bedingungen abfragen und dementsprechend Codeabschnitte entfernen lassen. Die Struktur ist Vergleichbar mit der normalen if-anweisung von C: #if BED_1 anweisung1; #elif BED_2 anweisung2;... #else anweisung_else; #endif Das ganze wird mit einem #if, gefolgt von einer Bedingung BED 1, eingeleitet. Ab der nächsten Zeile folgt ein Anweisungsblock anweisung1;, in dem sowohl normaler C-Code, als auch weitere Makro-definitionen stehen können. Ist das Ergebnis der Bedingung BED 1 == true, also nicht-null, wird der entsprechende Anweisungsblock anweisung1; einfach im Code gelassen, die anderen Anweisungsblöcke verschwinden. Gilt BED 1 == false, verschwindet der Block aus dem Code und die nächste wird geprüft Bedingung. Diese muss nach einem #elif stehen. Das Ganze kann beliebig oft wiederholt werden. Als letztes kann man mit einem #else ein Standardanweisungsblock definieren. Dieser bleibt bestehen, wenn alle anderen Bedingungen 0 ergeben haben. Anschließend muss mit #endif der Befehl abgeschlossen werden. Die #elif und #else-anweisungen sind Optional, das #endif muss bei jeder Bedingten Compelierung dabei stehen. Für die Bedingungen in der #if-direktive gibt es noch besondere Voraussetzungen. Die Bedingung muss eine Konstante ergeben, jedoch sind hier die normalen Arithmetischen Operatoren, sowie weitere Makro-Anweisungen erlaubt. Diese Makros werden noch vor der Auswertung ersetzt, damit ist auch Verschachtelung möglich. Nach ANSI-Standard werden diese Bedingungen als long int variablen gehandhabt. Sollte ein Makroname auftreten, welcher (noch) nicht definiert wurde wird einfach eine 0 eingesetzt. Möchte man prüfen, ob ein Makro definiert ist, kann man zwar #if benutzen, jedoch ist es nicht möglich zu unterscheiden, ob das Makro 0 als Ergebnis liefert oder einfach nicht exestiert. #ifdef ist die Direktive dieses Problem zu umgehen. Sie nimmt als Bedingung einen Makronamen und wertet sie zu einer 1 aus, falls 7

11 das Makro definiert wurde, und zu einer 0, falls nicht [5, 6] Die Operatoren Das erste Zeichen ist das Backslash ( \ ) und dient der Verknüpfung von Zeilen. Präprozessor-Direktiven enden nicht mit einem Semikolon, sondern mit einem Zeilenumbruch. Dadurch dürfen sie prinzipiell nur über eine Zeile gehen, mit einem Backslash am Zeilenende wird dem Präprozessor befohlen die aktuelle und die folgende Zeilen zu einer längeren zu verbinden. Dies kann beliebig oft wiederholt werden, ist jedoch keine sehr übersichtliche Art. Das zweite Zeichen ist das Doppelkreuz ( # ). Dieses zeichen umschließt einen darauf Folgenden Ausdruck mit Anführungszeichen. Schreibt man folgenden Code: #define str(s) #s... printf( str(hello World!) ); so übersetzt es der Präprozessor in printf( "Hello World!" ); Schließlich gibt es noch das Doppelte Doppelkreuz ( ## ), auch Verkettungsoperator genannt. Dieser Operator verkettet zwei Token. Damit kann man zum Beispiel beim Funktionsaufruf zwischen mehreren Funktionen mithilfe von Variablen frei wählen. Veranschaulichen kann man das folgendem dem Codeausschnitt #define callfunc(x) funk ## x... t = callfunc(3)(); Hierbei bekommt der Compiler die Zeile t = funk3(); übergeben. Anstelle der 3 könnte man nun auch andere Zeichenfolgen einsetzen und damit zwischen mehreren Funktionen variieren [5, 6] Weitere Direktiven Es gibt noch weitere, weniger genutzte Direktiven. Zur aktiven Fehlerausgabe während des preprocessing kann man #error benutzen. Dieser Befehl, gefolgt von einem String-Parameter gibt die Meldung auf der Standardausgabe (meistens die Konsole) aus und unterbricht die Compelierung. Da man jedoch nur 8

12 mit der #if und der #ifdef direktive Bedingungen abfragen kann geschieht das selten. Um sich die Zeilenausgaben von LINE und FILE angenehmer zu machen kann man mit #line die aktuelle Codezeile und Datei definieren. Die Direktive nimmt eine oder zwei Parameter, entweder eine Zahl als Zeile, oder eine Zahl und einen String als Zeile und Dateinamen. Einige Compiler bieten sogenannte pragma-direktiven an. Mit dem Aufruf #pragma kann man den Compiler selbst manipulieren. Diese Aufrufe sind jedoch meist Compilerspezifisch und werden daher hier nicht behandelt [3]. 3.3 Einsatzgebiete Der C-Präprozessor bietet viele möglichkeiten, den Code zu beeinflussen, da stellt sich schnell die Frage: Was macht man damit? Eine der Offensichtlicheren Einsatzgebiete ist die einfache und übersichtliche Nutzung von Konstanten und k urzen Funktionen. Diese lassen sich als Makro definieren und mit einem aussagekräftigen Namen überall verwenden. Hält man sich an die Konvention der Großbuchstaben in Makronamen kann man auch gut im Code sehen, was nur Makros und was wirklich Funktionen sind. Ebenfalls leicht zu erraten ist der Einsatz des Befehls #include. Jeder, der schon einmal in C Programmiert hat nutzt dieses Makro, wenigstens für die Einbindung von Standardbibliotheken. Bei Größeren Projekten wird es jedoch unerlässlich den Code in mehrere Teile und damit Dateien zu unterteilen, allein schon für die Mehrfachnutzung von Funktionen. Bei Dateien mit zu vielen LOC hat man keine Übersicht mehr und keiner versteht, was wie gemacht wurde. Am häufigsten wird der Präprozessor, besonders die bedingte Compelierung, für das Debugging eingesetzt. Mithilfe von Makros kann man sehr gute Fehlerausgaben erstellen, die mit beinhaltender Datei und Zeile leicht zum Fehler führen. Dazu definiert man sich oft ein konstantes Makro, zum Beispiel DEBUG, sodass man mit Bedingter Compelierung zusätzliche Ausgaben erhält und das Programm während der Laufzeit prüfen kann. Ist das Debuggen fertig negiert man die Konstante mit #undef DEBUG und man hat keine zusätzlichen Texte mehr auf der Konsole. Besonders praktisch an dieser Form von Debugging ist, dass man es sehr einfach wieder herstellen kann. Möchte man später am Code weiterarbeiten, und beim Testen und Debuggen die ursprünglichen Ausgaben wieder haben, muss man ledeglich den #undef Befehl wieder löschen[5, 6]. 3.4 Vor- und Nachteile eines Präprozessors Nachdem man gelernt hat, was der Präprozessor alles kann, fragt man sich natürlich, wann man ihn einsetzen sollte? Die meißten Makros lassen sich auch 9

13 als Funktion schreiben und umgekehrt, was ist besser? Wieso nutzt man Bedingte Compelierung zum Debuggen? Die meißten dieser Fragen lassen sich durch das Aufzeigen von Vor- und Nachteilen leicht beantworten Vorteile Einige der Vorteile des Präprozessors erschließen sich aus den Einsatzgebieten. So kann man dank symbolische Konstanten, definiert durch Makros sauberen und leicht leserlichen Code schreiben, und mithilfe von bedingter Compelierung sehr angenehmen Debuggen. Für andere Vorteile muss man jedoch genauer beobachten. Oft wird, wenn man Makros kennenlernt, die Frage gestellt: Warum Makros? Oder warum Funktionen? Was ist der Unterschied? Am wichtigsten ist wohl die Geschwindigkeit. Makros sind grundsätzlich schneller als Funktionen. Das liegt daran, dass ein Funktionsaufruf zusätzlichen Overhead benötigt, unter Anderem um die Programmausführung an den Funktionscode, und am ende wieder zum Hauptprogramm zu übergeben. Bei einem Makro gibt es diesen Overhead nicht, da der Makro-Körper ja direkt an die entsprechende Stelle kopiert wurde. Dieser unterschied ist zwar sehr gering, aber besonders bei kurzen Funktionen kann das Verhältnis zwischen dem zusätzlichen Overhead und der eigentlichen Funktionsausführung relativ groß werden. Auch kann als Vorteil gesehen werden, dass Makros nicht Datentypspezifisch sind. Dadurch kann man das Selbe Makro für mehrere Datentypen benutzen, ohne die Eingabewerte vorher zu casten oder mehrere Funktionen schreiben zu müssen. Mit #define MIN(a,b) ((a) < (b)? (a) : (b)) kann man sich ein Makro definieren, welches das kleinere von zwei Zahlen zurückgibt, wobei egal ist, ob a und b ganze Zahlen, oder Dezimalzahlen sind[5, 6] Nachteile Zwar hat der Präprozessor schöne seiten, jedoch raten die meißten C-Lehrbücher zu großer Vorsicht, wenn man Makros oder andere Präprozessor-Direktiven einsetzt. Neben offensichtlichen Problemen, wie dem leichten Verlust von Übersichtlichkeit, zum Beispiel durch mehrzeilige Makros, oder zu viel bedingter Compelierung, kann es auch unscheinbare Probleme mit sich führen den Präprozessor zu nutzen. Es ist sehr leicht kleine Fehler in den Code zu bekommen, welche in C alleine gar nicht möglich sind. Wie schon in erwähnt achten Makros nicht auf die Klammerung, und ersetzen den aktuellen Code einfach. Wenn man ein Makro mit einem Arithmetischen Ausdruck aufruft, so wird nicht, wie bei Funktionen, erst der Parameter berechnet, sondern der ganze Arithmetische Ausdruck eingesetzt. Das verursacht leicht Rechenfehler, falls die Makros nicht genügend ausgeklammert sind. 10

14 Makors erlauben zudem kein Leerzeichen zwischen dem namen und den Klammern für die Argumente. Steht dennoch eins da, so wird die Klammer, und damit auch die Parameterliste, als Teil des Makro-Körpers angeshen und mit in den Code eingesetzt. Definiert man sich also das Makro #define addfive (a) (a) + 5 und benutzt es mit y = addfive(x); so expandiert das zu y = (a) (a) + 5 (x); was offensichtlich nicht gewünscht war. Hat man Glück, erkennt der Compiler den Fehler durch die falsche Notation. Hat man jedoch Pech können so auch vollkommen legale Ausdrücke entstehen, die einfach während der Laufzeit Probleme machen. Auch kommen oft Fehler zustande, wenn aus Macht der Gewohnheit Makros mit einem Semikolon abschließt. Das Semikolon wird in diesem fall ebenfalls zum Makrokörper gezählt und einfach mit eingesetzt. Letzendlich ist auch darauf hinzuweisen, dass Fehler, welche durch den Präprozessor zustande kommen, meist nur sehr schwer gefunden werden, was die Fehlersuche zu einer Qual werden lässt[5]. Auch die Performance kann unter Makros leiden. Zwar sind Funktionsaufrufe langsamer als Makros, aber Funktionen stehen dafür nur einmal im Code. Makros werden an jeder einzelnen stelle, wo sie aufgerufen werden, expandiert. Nutzt man ein Mehrzeiliges Makro nun in hunderten von Zeilen, so wird der Code beim Compelieren erstmal um ein paar Hundert zeilen länger. Bei kleinen Programmen ist das kein Problem, ähnlich wie es keinen wirklichen Geschwindigkeitsvorteil bringt Makros zu nutzen, aber bei großen Projekten, besonders bei zeitkritischen Aufgaben, muss fein abgewogen werden, ob nun Makros oder Funktionen die bessere Wahl sind [6]. 4 Evaluation Zwar mag multi-stage Programmierung am Anfang einfach aussehen Da es eine Erweiterung für bestehende Sprachen ist, muss man jedoch Permanent mit zwei Konzepten gleichzeitig arbeiten: Man muss die eigentliche Sprache effektiv nutzen und trotzdem erkennen, wann es Vorteile bringt schon vor der Compelierung bestimmte teile des Codes zu berechnen. Die Tatsache dass es nur bedingt Aktivität (zum Beispiel in Foren) um die Multi-Stage Programmierung gibt, und in vielen Arbeiten und Vorträgen (siehe [9, 7]) die selben Beispiele gezeigt werden, weist auch auf wenig Beliebtheit des Konzeptes hin. 11

15 Der Präprozessor mag zwar unerlässliche, auch gute Konzepte bieten (besonders die #include-direktive), jedoch sind einige auch nicht wirklich nötig. Der Effizienzunterschied zwischen Makros und Funktionen ist minimal und besonders auf heutigen Systemen meist vernachlässigbar. Zum Debuggen gibt es eigene Programme, die viel mehr bieten, als einfach nur bedingte Zeilenausgaben, wie zum Beispiel schrittweises abarbeiten eines Programmes oder Echtzeitauswertung von Variablen. Dagegen gibt es jedoch viele Nachteile. Der Präprozessor ist sehr penibel, wodurch sich sehr schnell Fehler einschleichen welche man danach nur schwer findet. Diese und andere Gründe führen dazu, dass sowohl Lehrbücher [6, 5], als auch Foren dazu raten, tatsächlich in C zu Programmieren und den Präprozessor nur mit bedacht zu genießen. Schlussendlich muss ich sagen, dass mich die Multi-Stage Programmierung und der Präprozessor nicht überzeugen konnten, da es einfach zu viele Nachteile und Probleme durch Kleinigkeiten geben kann. Das, und das Konzept von zwei Sprachen paralell sind zu viele Nachteile für den kleinen Gewinn. 12

16 Literatur [1] Ascii codes. [2] Trigraphen. [3] Free Software Foundation. The c preprocessor, [4] Microsoft. Predefined macros. [5] Philip E. Margolis Peter A. Darnell. C - A Software Engeneering Approach. Springer-Verlag, [6] Bradley L. Jones Peter Aitken. C in 21 Tagen. Markt+Technik Verlag, [7] Mathias Ricken. Mint: A multi-stage extension of java. video by RICE University, Houston, Texas. [8] Dennis M. Ritchie. The development of the c language, [9] Walid Taha. A gentle introduction to multi-stage programming. taha/publications/journal/dspg04a.pdf. 13

FACHHOCHSCHULE MANNHEIM

FACHHOCHSCHULE MANNHEIM für Java-Programmierer Der Präprozessor Prof. Dr. Wolfgang Schramm FACHHOCHSCHULE MANNHEIM Hochschule für Technik und Gestaltung Präprozessor Ist dem Compiler vorgeschaltet ( Prä -). Spezielle Anweisungen

Mehr

C - PRÄPROZESSOR. Seminar effiziente C Programmierung WS 2012/13. Von Christian Peter

C - PRÄPROZESSOR. Seminar effiziente C Programmierung WS 2012/13. Von Christian Peter C - PRÄPROZESSOR Seminar effiziente C Programmierung WS 2012/13 Von Christian Peter Themen Was sind Präprozessoren? Beispiele für Präprozessoren Funktionsweisen Der C - Präprozessor Der # Präfix #include

Mehr

Proseminar. C-Programmierung Grundlagen und Konzepte. Der Präprozessor. von: Svenja Neef

Proseminar. C-Programmierung Grundlagen und Konzepte. Der Präprozessor. von: Svenja Neef Proseminar C-Programmierung Grundlagen und Konzepte Der Präprozessor von: Svenja Neef Inhaltsverzeichnis 1Der C-Präprozessor...2 1.1Was ist der C-Präprozessor...2 1.2Präprozessor-Befehle...2 1.2.1Zusammenführen

Mehr

C/C++ Programmierung

C/C++ Programmierung 1 C/C++ Programmierung Grundlagen: Der Präprozessor Sebastian Hack Christoph Mallon (hack mallon)@cs.uni-sb.de Fachbereich Informatik Universität des Saarlandes Wintersemester 2009/2010 2 Der Präprozessor

Mehr

Programmierung mit C Modularisierung von Programmen. Präprozessor-Anweisungen nutzen.

Programmierung mit C Modularisierung von Programmen. Präprozessor-Anweisungen nutzen. Programmierung mit C Modularisierung von Programmen. Präprozessor-Anweisungen nutzen. Modularisierung Zerlegung eines Programms in überschaubare Einheiten Die einzelnen Einheiten werden als Modul bezeichnet.

Mehr

C++ - Einführung in die Programmiersprache Header-Dateien und Funktionen. Leibniz Universität IT Services Anja Aue

C++ - Einführung in die Programmiersprache Header-Dateien und Funktionen. Leibniz Universität IT Services Anja Aue C++ - Einführung in die Programmiersprache Header-Dateien und Funktionen Leibniz Universität IT Services Anja Aue Modularisierung Logische Gliederung von Programmteilen mit Hilfe von Namensräumen. Aufteilung

Mehr

Der C-Präprozessor. Lukas Stabe

Der C-Präprozessor. Lukas Stabe Der C-Präprozessor Lukas Stabe Inhaltsverzeichnis 1 Einleitung 1 2 Makros 1 2.1 Parameterlose............................ 1 2.2 Parameterbehaftete......................... 3 2.3 Verbreitete Fehler..........................

Mehr

Tag 2 Repetitorium Informatik (Java)

Tag 2 Repetitorium Informatik (Java) Tag 2 Repetitorium Informatik (Java) Dozent: Daniela Novac Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018 Übersicht Zeichen und

Mehr

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 29

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf  Seite 1 von 29 Kapitel 2 Einführung in C++ Seite 1 von 29 C++ Zeichensatz - Buchstaben: a bis z und A bis Z. - Ziffern: 0 bis 9 - Sonderzeichen: ; :,. # + - * / % _ \! < > & ^ ~ ( ) { } [ ]? Seite 2 von 29 Höhere Elemente

Mehr

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML. JavaScript JavaScript wird direkt in HTML-Dokumente eingebunden. Gib folgende Zeilen mit einem Texteditor (Notepad) ein: (Falls der Editor nicht gefunden wird, öffne im Browser eine Datei mit der Endung

Mehr

Übungspaket 17 Der gcc Compiler

Übungspaket 17 Der gcc Compiler Übungspaket 17 Der gcc Compiler Übungsziele: Skript: 1. Sicherer Umgang mit gemischten Ausdrücken 2. Herleiten der unterschiedlichen Datentypen in gemischten Ausdrücken 3. Kenntnis über die implizite Durchführung

Mehr

Einführung Makros Includes Errors und Warnings Pragmas Diverses. Der C-Präprozessor. Lukas Stabe. Universität Hamburg

Einführung Makros Includes Errors und Warnings Pragmas Diverses. Der C-Präprozessor. Lukas Stabe. Universität Hamburg Der C-Präprozessor Lukas Stabe Universität Hamburg Proseminar C - Grundlagen und Konzepte, 2013 Lukas Stabe C-Präprozessor 1 / 19 Inhalt 1. Einführung 2. Makros 3. Includes 4. Errors und Warnings 5. Pragmas

Mehr

Intensivübung zu Algorithmen und Datenstrukturen

Intensivübung zu Algorithmen und Datenstrukturen Intensivübung zu Algorithmen und Datenstrukturen Silvia Schreier Informatik 2 Programmiersysteme Martensstraße 3 91058 Erlangen Übersicht Programmierung Fallunterscheidung Flussdiagramm Bedingungen Boolesche

Mehr

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen 16OH21005 gefördert. Die Verantwortung für den Inhalt dieser

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff Programmieren in C Eine Einführung in die Programmiersprache C Prof. Dr. Nikolaus Wulff Agenda Elementare Einführung C Programm Syntax Datentypen, Variablen und Konstanten Operatoren und Ausdrücke Kontrollstrukturen

Mehr

Allgemeines. Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C. #include <stdio.h>

Allgemeines. Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C. #include <stdio.h> Allgemeines Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C #include int main() { printf( hello world\n ); return 0; } Peter Sobe 1 Verschiedene Sprachkonzepte

Mehr

Übungsblatt 1. Java Vorkurs (WS 2017)

Übungsblatt 1. Java Vorkurs (WS 2017) Übungsblatt 1 Java Vorkurs (WS 2017) Aufgabe 1 Hallo-Welt Erstelle ein neues Projekt mit dem Namen HelloJava. Erzeuge in diesem Projekt eine neue Klasse HelloJava. (a) Schreibe die main-methode in die

Mehr

Inhaltsverzeichnis. Kapitel i: Schnelleinstieg 13. Kapitel 2: Was sind Programme? 17. Kapitel 3: Wie erstellt man eigene Programme?

Inhaltsverzeichnis. Kapitel i: Schnelleinstieg 13. Kapitel 2: Was sind Programme? 17. Kapitel 3: Wie erstellt man eigene Programme? Liebe Leserin, lieber Leser 10 Kapitel i: Schnelleinstieg 13 Kapitel 2: Was sind Programme? 17 Was ist ein Programm? 18 Sprechen Sie Computer? 18 Von der Idee zum Programm 19 Von Windows, Fenstern und

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

Funktionen in JavaScript

Funktionen in JavaScript Funktionen in JavaScript Eine Funktion enthält gebündelten Code, der sich in dieser Form wiederverwenden lässt. Mithilfe von Funktionen kann man denselben Code von mehreren Stellen des Programms aus aufrufen.

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

2 Eine einfache Programmiersprache. Variablen. Operationen Zuweisung. Variablen

2 Eine einfache Programmiersprache. Variablen. Operationen Zuweisung. Variablen Variablen Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Variablen dienen zur Speicherung von Daten. Um Variablen

Mehr

Funktionen in JavaScript

Funktionen in JavaScript Funktionen in JavaScript Eine Funktion enthält gebündelten Code, der sich in dieser Form wiederverwenden lässt. Es können ganze Programmteile aufgenommen werden. Mithilfe von Funktionen kann man denselben

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

Abschnitt 11: Korrektheit von imperativen Programmen

Abschnitt 11: Korrektheit von imperativen Programmen Abschnitt 11: Korrektheit von imperativen Programmen 11. Korrektheit von imperativen Programmen 11.1 11.2Testen der Korrektheit in Java Peer Kröger (LMU München) in die Programmierung WS 16/17 931 / 961

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

Elementare Konzepte von

Elementare Konzepte von Elementare Konzepte von Programmiersprachen Teil 1: Bezeichner, Elementare Datentypen, Variablen, Referenzen, Zuweisungen, Ausdrücke Kapitel 6.3 bis 6.7 in Küchlin/Weber: Einführung in die Informatik Bezeichner

Mehr

Institut für Computational Science Prof. Dr. H. Hinterberger. Praxismodul 1. Einführung in die Programmierung Erste Programme

Institut für Computational Science Prof. Dr. H. Hinterberger. Praxismodul 1. Einführung in die Programmierung Erste Programme Institut für Computational Science Prof. Dr. H. Hinterberger Praxismodul 1 Einführung in die Programmierung Erste Programme Einführung in die Programmierung 2 Institut für Computational Science, ETH Zürich,

Mehr

Funktionen in Matlab. Nutzerdefinierte Funktionen können in.m-datei gespeichert werden

Funktionen in Matlab. Nutzerdefinierte Funktionen können in.m-datei gespeichert werden Funktionen in Matlab Zusammenfassung von Befehlssequenzen als aufrufbare/wiederverwendbare Funktionen in einem Programmblock mit festgelegter Schnittstelle (Signatur) Derartige prozedurale Programmierung

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten Operatoren, Ausdrücke und Anweisungen Kontrollstrukturen (Steuerfluss)

Mehr

Übungspaket 17 Der gcc Compiler

Übungspaket 17 Der gcc Compiler Übungspaket 17 Der gcc Compiler Übungsziele: Skript: 1. Sicherer Umgang mit gemischten Ausdrücken 2. Herleiten der unterschiedlichen Datentypen in gemischten Ausdrücken 3. Kenntnis über die implizite Durchführung

Mehr

Methoden. Gerd Bohlender. Einstieg in die Informatik mit Java, Vorlesung vom

Methoden. Gerd Bohlender. Einstieg in die Informatik mit Java, Vorlesung vom Einstieg in die Informatik mit Java, Vorlesung vom 2.5.07 Übersicht 1 2 definition 3 Parameterübergabe, aufruf 4 Referenztypen bei 5 Überladen von 6 Hauptprogrammparameter 7 Rekursion bilden das Analogon

Mehr

Kapitel 2. Einfache Beispielprogramme

Kapitel 2. Einfache Beispielprogramme Kapitel 2 Einfache Beispielprogramme 2.1 Ausgabe auf dem Bildschirm 2.2 Lokale Variablen, Ausdrücke und Schleifen 2.3 Zahlen von der Tastatur einlesen 2.4 Formatierung bei der Ausgabe 2.5 Zusammenfassung

Mehr

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung C Sprachelemente für Übung 2 Typumwandlungen (type casts) Bei Ausdrücken, in denen Operanden mit unterschiedlichem Typ vorkommen, werden diese vom Compiler vor der Ausführung automatisch in einen gemeinsamen

Mehr

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 12/13. Kapitel 3. Grunddatentypen, Ausdrücke und Variable

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 12/13. Kapitel 3. Grunddatentypen, Ausdrücke und Variable 1 Kapitel 3 Grunddatentypen, Ausdrücke und Variable 2 Eine Datenstruktur besteht aus Grunddatentypen in Java einer Menge von Daten (Werten) charakteristischen Operationen Datenstrukturen werden mit einem

Mehr

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 1

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 1 Fakultät Verkehrswissenschaften Friedrich List, Professur für Verkehrsbetriebslehre und Logistik Modul Entscheidungsunterstützung in der Logistik Einführung in die Programmierung mit C++ Übung 1 SS 2016

Mehr

Übungen zur Vorlesung Wissenschaftliches Rechnen I

Übungen zur Vorlesung Wissenschaftliches Rechnen I Übungen zur Vorlesung Wissenschaftliches Rechnen I Nicolas Gauger, René Lamour, Hella Rabus Wintersemester 2007/2008 Programmierung - Einführung Programmierung - Einführung Berechnung einer Formel y =

Mehr

Angewandte Mathematik und Programmierung

Angewandte Mathematik und Programmierung Angewandte Mathematik und Programmierung Einführung in das Konzept der objektorientierten Anwendungen zu mathematischen Rechnens WS 2013/14 Operatoren Operatoren führen Aktionen mit Operanden aus. Der

Mehr

C++ Programmieren mit einfachen Beispielen DIRK LOUIS

C++ Programmieren mit einfachen Beispielen DIRK LOUIS C++ Programmieren mit einfachen Beispielen DIRK LOUIS C++ - PDF Inhaltsverzeichnis C++ Programmieren mit einfachen Beispielen Impressum Inhaltsverzeichnis Liebe Leserin, lieber Leser Schnelleinstieg Was

Mehr

Übungspaket 12 Der Datentyp char

Übungspaket 12 Der Datentyp char Übungspaket 1 Der Datentyp char Übungsziele: Skript: 1. Umgang mit dem Datentyp char,. Deklarationen von char-variablen, 3. char-konstanten 4. und char-rechenoperationen. Kapitel: 9 bis 31 sowie 4, 5 und

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

Einführung in die Programmierung II. 5. Zeiger

Einführung in die Programmierung II. 5. Zeiger Einführung in die Programmierung II 5. Zeiger Thomas Huckle, Stefan Zimmer 16. 5. 2007-1- Bezüge als Objekte Bisher kennen wir als Bezüge (Lvalues) nur Variablennamen Jetzt kommt eine neue Sorte dazu,

Mehr

Einführung in die Programmierung 1

Einführung in die Programmierung 1 Einführung in die Programmierung 1 Einführung (S.2) Einrichten von Eclipse (S.4) Mein Erstes Programm (S.5) Hallo Welt!? Programm Der Mensch (S.11) Klassen (S.12) Einführung Wie Funktioniert Code? Geschriebener

Mehr

Übungs- und Praktikumsaufgaben zur Systemprogrammierung Dipl.-Ing. H. Büchter (Lehrbeauftragter) FH-Dortmund WS 2001/2002 / SS 2002

Übungs- und Praktikumsaufgaben zur Systemprogrammierung Dipl.-Ing. H. Büchter (Lehrbeauftragter) FH-Dortmund WS 2001/2002 / SS 2002 1. Stellen Sie die schrittweise Verbesserung eines Compilers durch das Bootstrap- Verfahren mit Hilfe von T-Diagrammen dar. Gegeben ist ein auf der Maschine M lauffähiger Compiler C 1, der in S geschrieben

Mehr

JAVA-Datentypen und deren Wertebereich

JAVA-Datentypen und deren Wertebereich Folge 8 Variablen & Operatoren JAVA 8.1 Variablen JAVA nutzt zum Ablegen (Zwischenspeichern) von Daten Variablen. (Dies funktioniert wie beim Taschenrechner. Dort können Sie mit der Taste eine Zahl zwischenspeichern).

Mehr

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff Programmieren in C Eine Einführung in die Programmiersprache C Prof. Dr. Nikolaus Wulff Textausgabe per printf Die Funktion printf ist kein Bestandteil der C Sprache sondern gehört zur C Bibliothek. printf

Mehr

Teil II. Literatur zur C-Programmierung:

Teil II. Literatur zur C-Programmierung: Teil II 2Kurzeinführung in die Programmiersprache C Literatur zur C-Programmierung: Darnell, Margolis. C: A Software Engineering Approach. Springer 1991 Kernighan, Ritchie. The C Programming Language.

Mehr

Inhalt. 1 Einstieg in die Welt von C Erste Schritte in C 31. Vorwort... 15

Inhalt. 1 Einstieg in die Welt von C Erste Schritte in C 31. Vorwort... 15 Vorwort... 15 1 Einstieg in die Welt von C 17 1.1 Die Sprache C... 17 1.2 Die C-Standardbibliothek... 18 1.3 Die nötigen Werkzeuge für C... 21 1.4 Übersetzen mit der Entwicklungsumgebung... 23 1.5 Übersetzen

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

1 Bedingte Anweisungen. 2 Vergleiche und logische Operatoren. 3 Fallunterscheidungen. 4 Zeichen und Zeichenketten. 5 Schleifen.

1 Bedingte Anweisungen. 2 Vergleiche und logische Operatoren. 3 Fallunterscheidungen. 4 Zeichen und Zeichenketten. 5 Schleifen. Themen der Übung Kontrollstrukturen, Pseudocode und Modulo-Rechnung CoMa-Übung III TU Berlin 9.10.01 1 Bedingte Anweisungen Vergleiche und logische Operatoren 3 Fallunterscheidungen 4 Zeichen und Zeichenketten

Mehr

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny 7. Funktionen Einleitung Nach dem Prinzip Divide and Conquer bietet es sich an, größere Aufgaben in kleinere Teile zu unterteilen. Anweisungsblöcke,

Mehr

Hello World! Eine Einführung in das Programmieren Das erste Programm

Hello World! Eine Einführung in das Programmieren Das erste Programm Hello World! Eine Einführung in das Programmieren Das erste Programm Görschwin Fey Institute of Embedded Systems Hamburg University of Technology Slide 2 Betriebssystem Funktion Anwendung Gerätesteuerung

Mehr

Grundlagen der Informatik Vorlesungsskript

Grundlagen der Informatik Vorlesungsskript Grundlagen der Informatik Vorlesungsskript Prof. Dr. T. Gervens, Prof. Dr.-Ing. B. Lang, Prof. Dr. F.M. Thiesing, Prof. Dr.-Ing. C. Westerkamp 16 AUTOMATISCHES ÜBERSETZEN VON PROGRAMMEN MIT MAKE... 2 16.1

Mehr

Bash-Skripting Linux-Kurs der Unix-AG

Bash-Skripting Linux-Kurs der Unix-AG Bash-Skripting Linux-Kurs der Unix-AG Sebastian Weber 07.01.2013 Was ist ein Bash-Skript? Skript muss mit chmod +x ausführbar gemacht sein Aneinanderreihung von Befehlen normale Befehle nutzbar Sebastian

Mehr

Organisatorisches. Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online

Organisatorisches. Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online Organisatorisches Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online Nächste Woche VO und UE am Dienstag, den 30.10.! UE im CR IL/IT Wissensüberprüfung am Zettel 25.10.2018 IT I - VO 3 1 Organisatorisches

Mehr

Java Anweisungen und Ablaufsteuerung

Java Anweisungen und Ablaufsteuerung Informatik 1 für Nebenfachstudierende Grundmodul Java Anweisungen und Ablaufsteuerung Kai-Steffen Hielscher Folienversion: 24. Januar 2017 Informatik 7 Rechnernetze und Kommunikationssysteme Inhaltsübersicht

Mehr

Beispiel. Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio)

Beispiel. Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio) Beispiel Beispiel: Namensliste konvertieren (Karl Egon Meier Meier, Karl Egon). s/(.*) (.*)/$2, $1/; Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio) s/(.*) (.*)/$2, $1/; s/(.*) ([a-z]+

Mehr

Shell-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG Shell-Scripting Linux-Kurs der Unix-AG Benjamin Eberle 6. Juli 2016 Was ist ein Shell-Script? Aneinanderreihung von Befehlen, die ausgeführt werden Bedingte und wiederholende Ausführung möglich Nützlich

Mehr

Übersicht Shell-Scripten

Übersicht Shell-Scripten !!!! Wichtig: Bei Shell-Scripten enden die Zeilen nicht mit einem Strichpunkt!!!! Erste Zeile eines Shell-Scripts: #! /bin/bash Variablen in Shell-Scripts: Variablennamen müssen mit einem Buchstaben beginnen,

Mehr

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8 Java 8 Elmar Fuchs Grundlagen Programmierung 1. Ausgabe, Oktober 2014 JAV8 5 Java 8 - Grundlagen Programmierung 5 Kontrollstrukturen In diesem Kapitel erfahren Sie wie Sie die Ausführung von von Bedingungen

Mehr

Informatik I. Übung 2 : Programmieren in Eclipse. 5. März Daniel Hentzen

Informatik I. Übung 2 : Programmieren in Eclipse. 5. März Daniel Hentzen Informatik I Übung 2 : Programmieren in Eclipse 5. März 2014 Daniel Hentzen dhentzen@student.ethz.ch Downloads : http://n.ethz.ch/~dhentzen/download/ Heute 1. Nachbesprechung Übung 1 2. Theorie 3. Vorbesprechung

Mehr

Die Programmiersprache C

Die Programmiersprache C Die Programmiersprache C höhere Programmiersprache (mit einigen assemblerähnlichen Konstrukten) gut verständliche Kommandos muss von Compiler in maschinenlesbaren Code (Binärdatei) übersetzt werden universell,

Mehr

lex - Eine Einführung

lex - Eine Einführung lex - Eine Einführung Axel Kohnert 9th May 2005 Abstract lex ist ein Unixprogramm, welches die Erstellung eines C-programms für die lexikalische Analyse unterstützt. Dazu kann man Aktionen definieren,

Mehr

Unterlagen. CPP-Uebungen-08/

Unterlagen.  CPP-Uebungen-08/ Unterlagen http://projects.eml.org/bcb/people/ralph/ CPP-Uebungen-08/ http://www.katjawegner.de/lectures.html Kommentare in C++ #include /* Dies ist ein langer Kommentar, der über zwei Zeilen

Mehr

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

C++ Notnagel. Ziel, Inhalt. Programmieren in C++ C++ Notnagel Ziel, Inhalt Ich versuche in diesem Dokument noch einmal die Dinge zu erwähnen, die mir als absolut notwendig für den C++ Unterricht und die Prüfungen erscheinen. C++ Notnagel 1 Ziel, Inhalt

Mehr

Funktionen. mehrfach benötigte Programmteile nur einmal zu schreiben und mehrfach aufzurufen

Funktionen. mehrfach benötigte Programmteile nur einmal zu schreiben und mehrfach aufzurufen Funktionen Funktionen erlauben, dem Programmcode hierarchisch zu strukturieren ein Hauptprogramm steuert dabei die Abfolge von Schritten, die einzelnen Schritte können durch Funktionen realisiert werden

Mehr

Shell-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG Shell-Scripting Linux-Kurs der Unix-AG Benjamin Eberle 1. Februar 2016 Was ist ein Shell-Script? Aneinanderreihung von Befehlen, die ausgeführt werden Bedingte und wiederholende Ausführung möglich Nützlich

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 06: Einführung in Kontrollstrukturen Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Einführung in Kontrollstrukturen 3 Grundstrukturen von

Mehr

Shell-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG Shell-Scripting Linux-Kurs der Unix-AG Andreas Teuchert 8. Juli 2014 Was ist ein Shell-Script? Aneinanderreihung von Befehlen, die ausgeführt werden Bedingte und wiederholende Ausführung möglich Nützlich

Mehr

Einleitung Entwicklung in C Hello-World! Konstrukte in C Zusammenfassung Literatur. Grundlagen von C. Jonas Gresens

Einleitung Entwicklung in C Hello-World! Konstrukte in C Zusammenfassung Literatur. Grundlagen von C. Jonas Gresens Grundlagen von C Jonas Gresens Proseminar C Grundlagen und Konzepte Arbeitsbereich Wissenschaftliches Rechnen Fachbereich Informatik Fakultät für Mathematik, Informatik und Naturwissenschaften Universität

Mehr

Tag 4 Repetitorium Informatik (Java)

Tag 4 Repetitorium Informatik (Java) Tag 4 Repetitorium Informatik (Java) Dozent: Michael Baer Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018 Übersicht Arrays (Reihungen)

Mehr

8.1 Vom Quellcode zur ausführbaren Programm

8.1 Vom Quellcode zur ausführbaren Programm 8. Die Umgebung von C- 8.1 Vom Quellcode zur Programmausführung 8.2 Präprozessor-Anweisungen 8.3 Compiler, Assembler, Binder 8.4 Das Make-Utility 8.5 Datenübergabe vom und zum Betriebssystem 8-1 8.1 Vom

Mehr

Wo sind wir? Übersicht lexikale Struktur von Java

Wo sind wir? Übersicht lexikale Struktur von Java Wo sind wir? Java-Umgebung Lexikale Konventionen Datentypen Kontrollstrukturen Ausdrücke Klassen, Pakete, Schnittstellen JVM Exceptions Java Klassenbibliotheken Ein-/Ausgabe Collections Threads Applets,

Mehr

Algorithmus: Kochrezept

Algorithmus: Kochrezept Algorithmus: Kochrezept Ziel: Menü mit drei Gängen für 4 Personen Grundlegende Spezifikation: 1. Vorspeise: Badische Flädlesuppe 2. Hauptgericht: Überbackene Schinkenröllchen mit Spargel 3. Dessert: Vanilleeis

Mehr

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass: OOP (Java), 22. Aufzählungstypen 1/20 Objektorientierte Programmierung Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester

Mehr

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download Organisatorisches Folien (u.a.) gibt's auf der Lva-Homepage zum Download Diesen Mi erstes Tutorium (15-17) Ab nächster Woche montags 10-12 (jeweils im Computerraum) 17.10.2017 IT I - VO 3 1 Organisatorisches

Mehr

Gedächtnis. Während der Abarbeitung eines Algorithmus müssen sich Dinge gemerkt werden bzw. auf Dingen wird gerechnet. Zugriff.

Gedächtnis. Während der Abarbeitung eines Algorithmus müssen sich Dinge gemerkt werden bzw. auf Dingen wird gerechnet. Zugriff. Gedächtnis Während der Abarbeitung eines Algorithmus müssen sich Dinge gemerkt werden bzw. auf Dingen wird gerechnet Hauptspeicher 38265 Telefon CPU Gedächtnis Vorlesender Zugriff Verarbeitungseinheit

Mehr

4 PROGRAMMSTRUKTUR - WERKZEUGE

4 PROGRAMMSTRUKTUR - WERKZEUGE 4 PROGRAMMSTRUKTUR - WERKZEUGE Leitideen: Getrenntes Übersetzen und nachfolgendes Linken wird meistens mit Hilfe von Werkzeugen (z.b. make) durchgeführt. Bei Änderungen werden nicht alle Dateien neu übersetzt

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java 1 / 26 Einstieg in die Informatik mit Java Methoden Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 26 1 Methoden 2 Methodendefinition 3 Parameterübergabe, Methodenaufruf

Mehr

Übungen zu Kognitive Systeme I

Übungen zu Kognitive Systeme I Übungen zu Kognitive Systeme I Stephan Weller (Stephan.Weller@wiai.uni-bamberg.de) Kognitive Systeme / WIAI / Uni Bamberg 19. Oktober 2005 Inhalt Intro Was ist Prolog? Wie funktioniert Prolog? Rekursion

Mehr

Hallo Haskell. (Funktionale Programmierung) Prof. Dr. Oliver Braun. Letzte Änderung: :08. Hallo Haskell 1/23

Hallo Haskell. (Funktionale Programmierung) Prof. Dr. Oliver Braun. Letzte Änderung: :08. Hallo Haskell 1/23 Hallo Haskell (Funktionale Programmierung) Prof. Dr. Oliver Braun Letzte Änderung: 18.03.2018 21:08 Hallo Haskell 1/23 Glasgow Haskell Compiler (GHC) der Haskell-Compiler ist der GHC Sie installieren ihn

Mehr

Kapitel 3. Grunddatentypen, Ausdrücke und Variable

Kapitel 3. Grunddatentypen, Ausdrücke und Variable Kapitel 3 Grunddatentypen, Ausdrücke und Variable Grunddatentypen, Ausdrücke und Variable 1 Eine Datenstruktur besteht aus Grunddatentypen in Java einer Menge von Daten (Werten) charakteristischen Operationen

Mehr

Beuth Hochschule Einführende Gentle-Programme WS12/13, S. 1

Beuth Hochschule Einführende Gentle-Programme WS12/13, S. 1 Beuth Hochschule Einführende Gentle-Programme WS12/13, S. 1 Einführende Gentle-Programme Dieses Papier soll die Syntax und Semantik (die Schreibweise und Bedeutung) von einfachen Gentle Programmen anhand

Mehr

Übungen zu Kognitive Systeme I

Übungen zu Kognitive Systeme I Übungen zu Kognitive Systeme I Kognitive Systeme / WIAI / Uni Bamberg 14. Oktober 2005 Inhalt 1 2 3 4 5 6 Ablauf der Übungen Ablauf SWI-Prolog Ab nächster Woche wird es Übungszettel geben Ablauf der Übungen

Mehr

Programmiersprachen Einführung in C

Programmiersprachen Einführung in C Programmiersprachen Einführung in C 14 Vertiefung einiger Themen Prof. Dr. Gliederung Programmiersprachen 1. Von der Maschinensprache zu C 2. Die Struktur von C-Programmen 3. Variable und Datentypen in

Mehr

6. Zeiger Allgemeines Definition eines Zeigers

6. Zeiger Allgemeines Definition eines Zeigers 6. Zeiger www.c-programme.de Stefan Thiemert Kapitel 6 - Seite 1 von 6 6. 1. Allgemeines Zeiger spielen in der Programmierung eine wichtige Rolle. Sie sind wichtig, bei der Arbeit mit Arrays und Funktionen.

Mehr

01 Einführung in PHP. Einführung in PHP 1/13 PHP in Aktion

01 Einführung in PHP. Einführung in PHP 1/13 PHP in Aktion 01 Einführung in PHP Einführung in PHP 1/13 PHP in Aktion PHP ist eine Programmiersprache, die ganz verschiedene Dinge tun kann: von einem Browser gesendete Formularinhalte auswerten, angepasste Webinhalte

Mehr

Java Übung. Übung 2. Werner Gaulke. 19. April Universität Duisburg-Essen Kommedia, Übung EinPro SS06, Einführung in Java - Übung.

Java Übung. Übung 2. Werner Gaulke. 19. April Universität Duisburg-Essen Kommedia, Übung EinPro SS06, Einführung in Java - Übung. Java Übung Übung 2 Universität Duisburg-Essen Kommedia, Übung EinPro SS06, 19. April 2006 (UniDUE) 19. April 2006 1 / 13 Java Programme Java Programme bestehen aus (meist mehreren) Klassen. In den Klassen

Mehr

Informatik I: Einführung in die Programmierung

Informatik I: Einführung in die Programmierung Informatik I: Einführung in die Programmierung 5., bedingte Ausführung und Albert-Ludwigs-Universität Freiburg Bernhard Nebel 27. Oktober 2017 1 und der Typ bool Typ bool Typ bool Vergleichsoperationen

Mehr