Die ersten zwei Teile des Workshops zu Linux-Programmierung mit Kylix demonstrierten Installation und Einrichtung des Programm sowie den Umgang mit der IDE und Projekten. Im dritten Teil soll die Sprachbasis von Kylix im Mittelpunkt stehen. Lernen Sie Object Pascal kennen.
Object Pascal
Kylix erlaubt es, schnell und einfach Applikationen mit der Maus und wenigen Code-Zeilen zu erstellen. Aber so schön die visuelle Erstellung von Applikationen ist – ohne Kenntnis der Kylix zugrunde liegenden Programmiersprache kann man nur sehr einfache Anwendungen erstellen. Ob Sie visuell oder auf Ebene eines Texteditors arbeiten – Sie generieren Quelltext, der irgendwann in ein Programm übersetzt (kompiliert) wird. Die leichte Arbeit mit der Kylix-IDE darf nicht den Blick darauf verstellen, dass auch hinter dem visuellen Erstellen von Programmen Quelltext in einer Programmiersprache steht. Diese müssen Sie in Grundzügen verstehen, wenn Sie den visuell generierten Quelltext erweitern wollen. Gab es in Kylix 1 und 2 nur die Sprachbasis Object Pascal, hat im August 2002 die Version 3 zwei potentielle Grundlagen eingeführt: C/C++ und “Delphi Language” (kurz “Delphi”, was aber nicht mit dem Windows-Entwicklungspaket verwechselt werden darf). Dabei ist Delphi Language nur ein neuer Name für das Object Pascal der Vorgängerversionen. Diese Sprache wollen wir hier behandeln.
Hauptprogramm und Units
Im Grunde kann jedes Programm unter Object Pascal (und theoretisch Kylix) als eine einzelne Quelltextdatei erstellt werden. Eine solche Datei sieht in der einfachsten Form schematisch so aus:
program …;
uses ….;
{$….}
begin
…
end.
Als Dateierweiterung verwendet man .pas (historisch: Pascal) oder die Kylix-Projekterweiterung .dpr (siehe dazu auch Teil 2 des Workshops). Zwingend ist dabei im einfachsten Fall nur die Zeile mit program sowie begin und end.. Hinter program wird der Name des Programms, gefolgt von einem Semikolon angegeben. Danach folgen eventuell verwendete Units (siehe unten) sowie Compiler-Schalter. Beides ist optional, wobei Kylix sehr viel automatisch generiert, wenn Sie über die IDE ein Programm erstellen. Das eigentliche Programm wird in den mit begin und end. eingeschlossenen Block geschrieben.
Obwohl natürlich die Kylix-IDE einen geeigneten Editor bereit stellt, können Sie ein Programm auch mit einem anderen Editor erstellen – etwa so:
program Project1;
begin
Writeln('Hallo Welt');
end.
Wenn Sie diese Datei als Project1.pas speichern, können Sie sie mit dem Kylix-Compilerdcc auf Befehlszeilenebene kompilieren:
/opt/kylix3/bin/dcc Project1.pas

Abbildung 2: Der Compiler befindet sich als eigenständiges Programm unter /bin im Kylix-Installationsverzeichnis (hier Kylix 2)
Der Compiler generiert eine ausführbare Datei Project1, die Sie zum Beispiel in ein Startskript einbauen können. Ein passendes Startskript (das Sie auch für andere Kylix-Programme verwenden können – beachten Sie aber den Pfad zu Kylix) sieht so aus:
#!/bin/bash export LD_LIBRARY_PATH=/opt/kylix3/bin:$LD_LIBRARY_PATH ./Project1
Wenn Sie das Programm laufen lassen, wird in der Shell der angegebene Text ausgegeben. Allerdings werden unter Umständen die voranstehenden Systemmeldungen stören, was aber bei Programmen mit grafischer Oberfläche keine Rolle spielt.
Natürlich kann man so ein Programm auch mit der Kylix-IDE erstellen. Dazu wählen Sie im Menü Datei unter Neu den Punkt Konsolen-Anwendung.
Sie erhalten dann automatisch ein Grundgerüst wie im ersten Listing, in dem nur der zusätzliche Compiler-Schalter {$APPTYPE CONSOLE} explizit anzeigt, dass es sich um eine Konsolen-Anwendung handelt und die eigentliche Funktionalität fehlt. Kylix ist im Grunde für Konsolen-Anwendungen nicht ausgelegt; testen müssen Sie eine solche Anwendung in der Shell.
Units
Die Ansammlung von Programm-Code in nur einer Datei ist aus verschiedenen Gründen bei etwas umfangreicheren Programmen ungünstig. Programm-Code wird daher in einzelne Quelltext-Dateien aufgeteilt, die von einer zentralen Steuerdatei (dem Hauptprogramm) zusammengeführt werden. Das Hauptprogramm einer typischen Kylix-Applikation ist sogar normalerweise auf den reinen Start der Applikation reduziert (siehe Teil 2 des Workshops).
In Pascal werden diese Quelltextmodule Units genannt. Sie sind Klartextdateien mit der Dateierweiterung .pas. Jede Unit wird in einer eigenen Datei gespeichert und separat kompiliert. Die kompilierten Module werden dann zu einer Anwendung gelinkt (zusammengebunden). Mit Units bilden Sie Bibliotheken und unterteilen Programme in logisch zusammen gehörende Einheiten. Object Pascal bzw. Kylix stellen Ihnen bereits diverse Standard-Units zur Verfügung, die zum Teil auch automatisch verwendet werden, wenn Sie über die IDE ein Programm erzeugen. Sowohl diese vorgefertigten als auch selbst definierte Module lassen sich in andere Programme und Module einbinden. Eine Unit setzt sich aus folgenden, teilweise optionalen, Komponenten zusammen:
- dem Kopf, der mit dem Schlüsselwortunit beginnt. Der Bezeichner dahinter legt den Namen der Unit fest. Innerhalb eines Programms muss der Name jeder verwendeten Unit eindeutig sein. Kylix kümmert sich automatisch darum, dass eine Unit beim Speichern den Dateinamen bekommt, der als Bezeichner angegeben ist. Am besten greifen Sie in diesen Automatismus nicht manuell ein.
- dem Interface-Teil, der durch das Schlüsselwort interface eingeleitet wird und unmittelbar hinter dem Bezeichner des Unit-Namens beginnt. Er reicht bis zum Beginn des nachfolgenden Implementationsteil und bildet eine Schnittstelle zu anderen Modulen, über die Quelltextelemente als öffentlich zugänglich deklariert werden. Mit anderen Worten: Hier steht all das, was bei einer Verwendung der Unit durch ein anderes Modul dort verfügbar sein soll. Zentraler Bestandteil des Interface-Teils ist die uses-Klausel, die Sie in der Regel auch im Hauptprogramm finden. Darin werden (bei Verwendung mehrerer Units durch Kommata getrennt) die Namen aller Units angegeben, die in der aktuellen Datei verwendet werden sollen.
- der Implementierung, die durch das Schlüsselwort implementation eingeleitet wird. Der Implementationsteil definiert die Funktionalität aller Bestandteile einer Unit. Mit anderen Worten: Hier wird die konkrete Funktionalität der einzelnen Unit-Elemente umgesetzt. Ein Bestandteil des Implementationsabschnitts sind Compiler-Schalter, die in der Regel auch im Hauptprogramm stehen. (Kylix generiert diese weitgehend automatisch.)
- den Initialisierungs- und Finalisierungsteilen. Meist wird darauf aber verzichtet.
Wir verfolgen den Aufbau von Units nicht weiter, sondern verlassen uns auf die Kylix-IDE, die den Anwender in der Regel sehr komfortabel führt.
Variablen und Wertzuweisungen
Fast jedes Programm verwendet Variablen, deren Deklaration bzw. Wertzuweisungen und Datentypen. Um diesen doch recht komplexen Bereich nicht ausarten zu lassen, können Sie sich Variablen einfach als Stellen im Hauptspeicher des Rechners vorstellen, wo zur Programmlaufzeit Informationen temporär gespeichert werden. Um diese später wieder verwenden zu können, werden diese Stellen mit einem Namen bzw. Bezeichner versehen, und es wird festgelegt, welche Art von Daten dort abgelegt werden kann. Das nennt man das Deklarieren einer Variablen.
Der Name einer Variablen beginnt mit einem Buchstaben oder Unterstrich und darf nicht zu lang (unter 255 Zeichen) sein sowie keine Leerzeichen enthalten. Auf das erste Zeichen können Buchstaben, Ziffern und Unterstriche folgen. In Object Pascal bereits reservierte Worte (so genannte Schlüsselworte) dürfen nicht als Namen verwendet werden. Object Pascal unterscheidet nicht zwischen Groß- und Kleinschreibung, was insbesondere unter Linux zu erwähnen ist.
Eine Variable wird deklariert, indem das Schlüsselwort var einen Abschnitt einleitet, der einen Variablennamen, einen Doppelpunkt, den Datentyp und ein Semikolon enthält. Das sieht schematisch so aus:
var Bez:Datentyp;
Zum Beispiel wird eine Integer-Variable (ganzzahlig) mit var i:Integer; deklariert.
Auf den Datentyp gehen wir an dieser Stelle nur so weit ein, dass dieser die Art der Daten, die Größe des benötigten Hauptspeichers und den Umgang mit den Werten bei bestimmten Operationen festlegt. Hier folgt eine Tabelle mit einigen wichtigen Datentypen von Object Pascal.
Tabelle 1: Wichtige Datentypen von Object Pascal
| Datentyp | Beschreibung | Wertebereich | Größe/Format |
|---|---|---|---|
| Boolean | Wahrheitswert | True, False | 8 Bit |
| Byte | Ganze Zahl | 0 .. 255 | 8 Bit, ohne Vorzeichen |
| Char | Zeichen | 0 .. 255 | 8 Bit |
| Double | Kommazahl | 5.0 x 10^-324 .. 1.7 x 10^308 | 8 Byte |
| Integer | Ganze Zahl | -2147483648 .. 2147483647 | 32 Bit mit Vorzeichen |
| string | Text | abhängig vom genauen Typ |
Bei der Deklaration kann statt eines einzelnen Variablenbezeichners eine Liste mit gültigen Bezeichnern (durch Kommata getrennt) angegeben werden, wenn die Variablen den gleichen Datentyp haben. Das Schlüsselwort var leitet – wie oben erwähnt – einen Deklarationsblock ein und muss bei aufeinander folgenden Deklarationen nicht wiederholt werden. Ein Beispiel ist:
var a, b: Double;
i: Integer;
test: Boolean;
Die Zuweisung eines Wertes zu einer Variablen erfolgt mit dem Zuweisungsoperator :=. Dabei steht der zugewiesene Wert (bzw. eine andere Variable passenden Typs, das Ergebnis einer Operation oder der Rückgabewert einer Funktion) auf der rechten Seite des Operators, der Variablenbezeichner auf der linken. Beispiele sind:
i:=42; i:=j; k:=4*6;
Variablen, die innerhalb von Prozeduren und Funktionen (siehe unten) deklariert werden, heißen lokale Variablen. Alle nichtlokalen Variablen sind global. Grundsätzlich gilt, dass Variablen zwar an verschiedenen Stellen innerhalb eines Moduls, aber immer außerhalb von Anweisungsblöcken, deklariert werden. Das bedeutet: Eine Deklaration darf niemals zwischen einem begin und end erfolgen. Mit var wird ein separater Block eingeleitet, der ohne explizites Endezeichen unmittelbar endet, wenn ein anderes Schlüsselwort wie etwa begin einen neuen Block öffnet. Jede global deklarierte Variable, der noch kein Wert zugewiesen wurde, besitzt einen Vorgabewert, der je nach Typ einem Null-, Leer- oder False-Wert entspricht. Lokale Variablen können erst nach einer Wertzuweisung verwendet werden.
Kommentare
Ein Kommentar ist eine Passage innerhalb des Quelltextes, die beim Übersetzen vom Compiler ignoriert wird. Ein Kommentar kann überall im Quelltext stehen. Object Pascal kennt sowohl mehrzeilige Kommentare, die mit einer geschweiften Klammer { beginnen und mit der umgedrehten Klammer } enden als auch einzeilige Kommentare, die mit einem Doppel-Slash // beginnen und mit dem Zeilenende enden.
Prozeduren und Funktionen
Wenn ein Programm eine gewisse Komplexität erreicht hat, fasst man Programmschritte in Routinen zusammen, die als abgeschlossene Anweisungsblöcke an unterschiedlichen Positionen in einem Programm aufgerufen werden können. Dabei unterscheidet man drei Konstruktionen:
- Prozeduren
- Funktionen
- Methoden
Funktionen und Prozeduren sind verwandt. Sie unterscheiden sich darin, dass eine Funktion nach Ausführung enthaltener Anweisungen einen Wert (ein Ergebnis) zurückgibt, während eine Prozedur ihre Aufgabe ohne Rückgabe eines Werts erledigt. Eine Methode ist eine Variante von beiden, die im Rahmen der objektorientierten Programmierung (in Teil 4 des Workshops) besprochen werden soll.
Bevor Funktionen oder Prozeduren verwendet werden können, müssen sie eingeführt (deklariert) werden. Die Deklaration von Prozeduren sieht leicht anders als die von Funktionen aus, viele Aspekte sind aber gleich. Bei beiden Deklarationen geben Sie den Bezeichner der Routine sowie die Datentypen der Parameter an. Da eine Funktion ein Ergebnis liefert, muss dort noch der Typ des Rückgabewertes genannt werden. Danach folgt innerhalb eines begin-end-Blocks der Code, der beim Aufruf der Prozedur oder Funktion ausgeführt werden soll – dieser Teil wird als Rumpf bezeichnet; im Interface-Teil einer Unit wird er weg gelassen.
Eine Prozedurdeklaration hat folgende Form:
procedure <Bezeichner> (<Parameterliste>); <Direktiven>; <lokale Deklarationen>; begin <Anweisungen> end;
Das Schlüsselwort procedure leitet immer die Deklaration ein, der anschließende Bezeichner ist auch immer vorhanden. Die Parameterliste (mehrere Parameter werden mit Semikolon getrennt), die “Direktiven” und lokalen Deklarationen sind optional.
Ein Beispiel mit zwei Parametern ohne Direktiven und lokale Deklarationen:
procedure Multi (a: Integer; b: Integer); var erg: Integer; begin erg:=a*b; ShowMessage(erg); end;
Eine Funktionsdeklaration hat folgende Form:
function <Bezeichner> (<Parameterliste>): <Rückgabetyp>; <Direktiven>; <lokale Deklarationen>; begin <Anweisungen> end;
Der Aufbau ähnelt einer Prozedurdeklaration. Abweichend gibt es hier aber einen Rückgabewert. Innerhalb der Funktion verwendet man den Funktionsnamen, um diesen Rückgabewert festzulegen. Alternativ gibt es die vordefinierte Variable Result, welche man auch verwenden kann. Ein Beispiel:
function meineFkt(): Integer; begin meineFkt:=7*6; end;
Aufruf von Funktionen und Prozeduren
Um eine Routine nach ihrer Deklaration zu nutzen, rufen Sie sie über ihren Bezeichner mit eventuellen Parametern auf. Die Parameterliste bei der Deklaration gibt Anzahl, Reihenfolge und Typ der Parameter an, die beim Aufruf an die Routine übergeben werden müssen (mehrere Parameter werden beim Aufruf mit Kommata getrennt). Diese Syntax muss auf jeden Fall eingehalten werden: Anzahl und Datentypen der Parameter müssen zur Deklaration passen. Beim Aufruf der Routine wird der Programmablauf unmittelbar vom Punkt des Aufrufs an den Rumpf der Routine übergeben. Ist die Routine beendet, geht es mit der nächsten Anweisung weiter. Listing 1 zeigt ein vollständiges Programmbeispiel:
Listing 1
Ein Object-Pascal-Programm
program Project3;
function antwort():Integer;
begin
Result:=42;
end;
function multi(a:Integer;b:Integer):Integer;
begin
multi:=a*b;
end;
procedure add(a:Integer;b:Integer);
begin
Writeln(a+b);
end;
begin
Writeln('Die Antwort ist:');
Writeln(antwort()); // Aufruf von antwort.
Writeln(multi(5,4)); // Aufruf von multi.
add(30,12); // Aufruf von add.
end.
Anweisungen
Ein Programm ist die Umsetzung eines Algorithmus’ in eine Folge von Befehlen bzw. Anweisungen, die in einer festgelegten Reihenfolge auszuführen sind. Grundsätzlich wird eine Anweisung immer vollständig durchgeführt, bevor die nächste Anweisung folgt. Anweisungen enden in Pascal meist mit einem Semikolon, etwa wie im folgenden Beispiel:
Application.Terminate;
Explizit kennen gelernt haben Sie schon die Zuweisung, die Deklarationsanweisung und Funktions- bzw. Prozeduraufrufe. Ohne es zu erwähnen, haben wir auch schon Blockanweisungen verwendet: Das sind Zusammenfassungen von mehreren Anweisungen zu einem Block, die überall da stehen können, wo auch einzelne Anweisungen stehen dürfen. In Object Pascal werden Blöcke über die immer zusammen gehörenden Schlüsselworte begin und end gebildet. Im Inneren eines solchen Blocks steht einfach eine Reihe anderer Anweisungen. Blöcke können beliebig geschachtelt werden.
Auswahlanweisung
Auswahlanweisungen (auch bedingte Anweisungen genannt) sind Strukturen, über die auf Grund einer bestimmten Bedingung einer von mehreren möglichen Kontrollflüssen eines Programms ausgesucht werden kann. Object Pascal kennte folgende Auswahlanweisungen:
- if bzw. if-else
- case
Wir behandeln hier die if-else-Anweisung. Eine if-Anweisung testet einen Wahrheitswert oder einen Ausdruck. Wenn der Test den Wert True (wahr) ergibt, wird die nachstehende Anweisung ausgeführt. Liefert der Test False, wird die folgende Anweisung ignoriert. Die Syntax ist wie folgt:
if (<Bedingung>) then …
Beispiel:
if (a < 5) then ShowMessage('Linux');
Die if-else-Anweisung ist eine Erweiterung der if-Anweisung um einen zusätzlichen else-Teil. Die hinter else stehende Anweisung wird ausgeführt, wenn der Test im if-Teil der Anweisung den Wert False ergibt. Die schematische Syntax sieht so aus:
if (<Bedingung>) then Anweisung(en) else Anweisung(en)
Beispiel:
if (a < 5) then
ShowMessage('Kleiner 5')
else
ShowMessage('Größer oder gleich 5');
Die Anweisung ShowMessage(‘Kleiner 5’) wird ausgeführt, wenn die Variable a kleiner als 5 ist, ansonsten wird die andere Anweisung gewählt. Beachten Sie, dass die letzte Anweisung vor einem else in Object Pascal nicht mit einem Semikolon abgeschlossen wird. Wenn Sie innerhalb des else-Zweigs als erste Anweisung eine neue if-Anweisung notieren, haben Sie mit der resultierenden if-else-if-Anweisung einen Spezialfall der if-else-Anweisung: Damit kann man ein Konstrukt mit einer über zwei Alternativen hinausgehenden Auswahl von Möglichkeiten aufbauen.
Iterationsanweisungen
Iterationsanweisungen heißen auch Schleifen oder Wiederholungsanweisungen. Sie dienen der programmgesteuerten, kontrollierten Wiederholung von Anweisungen. Es gibt in Object Pascal drei Arten von Iterationsanweisungen:
- while
- repeat
- for
Eine schauen wir uns an.
Die for-Anweisung
Die for-Anweisung (auch Zählschleife genannt) wiederholt Anweisungen so oft wie vorgegeben. Die Syntax einer for-Anweisung sieht so aus:
for Zähler := Anfangswert to Endwert do Anweisungen
oder
for Zähler := Anfangswert downto Endwert do Anweisungen
Im ersten Fall wird eine Zählvariable initialisiert und solange bei jedem Durchlauf hochgezählt, bis der Endwert exakt erreicht ist. Im zweiten Fall wird rückwärts gezählt. Die Zählvariable ist ganzzahlig und muss im gleichen Block deklariert werden, in dem auch die for-Schleife steht.
for i:=1 to 100 do WriteLn(i);
Operatoren und Operanden
Operatoren sind Zeichen oder Zeichenkombinationen, die eine auszuführende Operation mit einem oder mehreren Operanden (Werte, Ausdrücke, Variablen, Rückgabewerte) durchführen. Einer der wichtigsten Operatoren ist der Zuweisungsoperator :=, den wir schon kennengelernt haben. Daneben gibt es beispielsweise Operatoren, die für Berechnungen verwendet werden (etwa * oder +) und Operatoren, die dem Vergleich zweier Operanden dienen (etwa = zum Testen der Gleichheit, <> für Ungleichheit, < für Kleiner als oder > für Größer als in Schleifenbedingungen).
Damit soll unsere kurze Einführung in Object Pascal enden.
Über den Autor
Ralph Steyer ist Diplom-Mathematiker und hat sich sowohl als Anwender als auch Programmierer von DOS über Windows zu Linux durchgeschlagen. Obwohl nicht dogmatisch auf Linux festgelegt und auch unter Windows zu Hause, überzeugen ihn seit einiger Zeit die Vorteile von Linux immer mehr. Zu erreichen ist er über http://www.rjs.de.
Glossar
-
Compiler
-
Ein Übersetzungsprogramm, das Quelltext einer höheren Programmiersprache in vom Prozessor ausführbare Maschinensprachebefehle umwandelt.
-
Compiler-Schalter
-
Einstellungen für den Compiler zum genaueren Spezifizieren der Art der Übersetzung des Quelltextes.
-
Schlüsselwort
-
Die reservierten Wörter einer Programmiersprache, die ein essentieller Teil einer Sprachdefinition sind und eine besondere Bedeutung haben. Sie können nicht für andere Zwecke (zum Beispiel als Bezeichner für Variablen) verwendet werden.










