Modula-2 Kurs

Aha, Sie scheinen sich für Modula-2 zu interessieren. Nach Lösung der Hausaufgaben im Kasten nun zum ersten richtigen Abschnitt in diesem Kurs: den Konventionen für Bezeichner.

Bezeichner

In einem Programm gibt es Objekte, die irgendwie angesprochen werden müssen. Es kann sich um Variablen handeln ("ch" im ersten Beispiel) oder um Modulnamen ("HelloWorld" im ersten Beispiel) und um vieles andere mehr, das Sie noch kennenlernen. Auf jeden Fall muß etwas, mit dem gearbeitet werden soll, einen Namen bekommen.

Nehmen Sie als Vergleich die Namen, die jeder von uns bei der standesamtlichen Taufe verliehen bekommt. Wir sagen "Otto" und meinen damit eine bestimmte Person. Durch den Namen "Otto" unterscheiden wir von "Peter" wenn wir mit einer dritten Person über unsere gemeinsamen Bekannten sprechen. Ein Name ist also eine Bezeichnung für jemanden, über den wir sprechen.

Die Namen werden bei Programmiersprachen Bezeichner genannt (englisch "identifiers"). Und wir "sprechen" hier mit einem Compiler, der sehr pedantisch bei den Namen ist, und der deshalb ganz exakte Vorschriften hat, wie ein Name aussehen muß.

In Modula-2 bestehen alle Namen aus Buchstaben und Ziffern. Sonderzeichen wie z.B. "_" (wie bei Pascal) sind nicht erlaubt oder besser gesagt, dem Compiler nicht geläufig. Buchstaben sind dabei A-Z (in Groß- und Kleinschreibung) und zwar ohne die Umlaute öäüÖÄÜ und ß, da sie im Computer und im Compiler eigentlich nicht als Buchstaben gelten, sondern als Sonderzeichen. Ziffern sind natürlich 0 bis 9.

Weiterhin darf ein Bezeichner keine Leerzeichen enthalten und muß mit einem Buchstaben anfangen. Alles, was mit einer Ziffer beginnt, interpretiert der Übersetzer als Zahlenkonstante. Bei einem Leerzeichen nimmt er an, daß ein neues Wort des Programms beginnt.

Als gültige Namen erkennt ein Modula Compiler also

Robert 
sdfchsf 
zahl13
x

aber sicherlich nicht

Änderung14
!achtung
zwölf^10
Modula_ist_nicht_Pascal
10ter
ein Wert

"Änderung14" enthält einen Umlaut, "!achtung" beginnt auch mit einem Sonderzeichen, ebenso ist in "zwölf^10" ein Sonderzeichen vorhanden.

"Modula_ist_nicht_Pascal" verwendet das Sonderzeichen das im Vorgänger Pascal erlaubt war, aber in Modula nicht erkannt wird. Bei "10ter" nimmt Ihr Compiler zunächst an, er hätte es mit einer Zahl zu tun, weil die "1" ja eine Ziffer ist. Beim "t" wird er heftig aufstoßen und den Namen zurückweisen, "ein Wert" enthält ein Leerzeichen, daher kann der Übersetzer nicht erkennen, wo das Ende des Bezeichners liegt - er wird "Wert" mit einer Fehlermeldung abweisen.

Modula-2 ist sehr genau, das zeigt sich schon bei den Bezeichnern. Denn ein anständiger Compiler unterscheidet auch zwischen Groß- und Kleinbuchstaben. So sind

Robert  
ROBERT
robert

drei völlig unterschiedliche Namen, die keinerlei Verbindung miteinander haben. Sie können beliebig lange Namen verwenden. In Standard-Modula ist die Länge der Bezeichner nicht begrenzt (auch wenn sie endlich sein müssen). Es gibt allerdings Compiler, die hier Beschränkungen auferlegen. z.B. maximal 32 Zeichen. Verwenden Sie möglichst "sprechende" Namen und benutzen Sie die Groß- und Kleinschreibung.

Dabei kann man einen persönlichen Stil entwickeln. Ich werde Konstanten immer komplett groß schreiben. Variablen oder Typen, die wichtig sind, in gemischter Schreibweise und einfache Laufvariablen klein.

Wichtig ist also bei allen Bezeichnern, die für Objekte in Modula-Programmen verwendet werden:

Deklarationen

Das Beispielprogramm aus der ersten Folge habe ich in mehrere Teile aufgespalten. Der erste Teil waren die Deklarationen, und darauf werde ich heute genauer eingehen.

Ein Programm in einer Sprache wie Modula-2 ist eine Beschreibung der Aktionen, die ausgeführt, und der Objekte, die dabei benutzt werden sollen. Wenn Sie einen Pudding nach Anleitung kochen, erhalten Sie Informationen über die Zutaten und die Reihenfolge der Verarbeitung. Alles, was Sie zum Arbeiten benötigen, wird aufgeführt, damit Sie wissen, was Sie bereitstellen müssen, und womit Sie es zu tun haben.

Bei einem Modula-2 Programm sind die Dinge, mit denen der Rechner arbeiten soll, die Objekte und die Arbeitsaufgaben die Anweisungen. Diese Objekte sind meistens Variablen; es können aber auch Konstanten oder Unterprogramme sein. In dieser Folge lernen Sie Variablen und Konstanten kennen.

Alles, womit ein Programm arbeiten soll, muß vorher beschrieben werden. Dies geschieht mit Deklarationen, in denen steht, worum es sich handelt, und womit Sie es bezeichnen wollen.

Im ersten Beispielprogramm sollte der Rechner mit einer Zeichenkette arbeiten, die konstant war. nämlich dem String "Hello World". Er wurde dort direkt mit der eigentlichen Aufgabe, nämlich der Ausgabe auf dem Bildschirm mit "Write-String", notiert.

Mit einer Konstantendeklaration kann nun festgelegt werden, daß der Compiler die Zeichenkette unter dem Namen "BEGRUESSUNG" kennt. Dazu müssen Sie in Ihrem Programm notieren, daß eine Konstantendeklaration folgt. Dies geschieht mit dem Schlüsselwort "CONST'. Alles, was ab jetzt bis zu einer weiteren Deklaration oder den Anweisungen folgt, sind Deklarationen. Für das Beispiel sähe sie so aus:

CONST BEGRUESSUNG = "Hello world !";

"CONST' markiert den Beginn der Konstantendeklarationen und mit dem Gleichheitszeichen ist dem Übersetzer unter dem Bezeichner "BEGRUESSUNG" die Zeichenkette "Hello world!" bekannt.

Wenn die Konstante verwendet wird, schreiben Sie einfach den deklarierten Bezeichner in die Anweisung:

WriteString(BEGRUESSUNG);

Nachdem dem Compiler vorher in der Deklaration mitgeteilt wurde, daß BEGRUESSUNG für die Zeichenkette "Hello World!" steht, kann er den richtigen Begrüßungstext einsetzen.

Um die letzte Aufgabe der ersten Folge zu lösen, könnte jetzt die eigentliche Anweisung unverändert bleiben, lediglich bei der Deklaration der Konstanten müßte eine Änderung erfolgen. Das Programm, das die Aufgabe löst, lautet dann:

MODULE HelloWorld;

FROM	InOut	IMPORT	WriteString, WriteLn, Read ;

CONST BEGRUESSUNG = "Hallo Welt";

VAR ch:CHAR

BEGIN
    WriteString(BEGRUESSUNG);
    WriteLn;
    Read(ch);
END HelloWorld.

Durch die Konstantendeklaration abstrahieren Sie von der eigentlichen Zeichenkette. Es soll nur noch eine BEGRUESSUNG ausgegeben werden; wie sie genau aussieht, wird in der Deklaration festgelegt. Diese Erkenntnis ist wichtig. In der Anweisung ist nicht mehr von der speziellen Zeichenkette Hallo Welt!" die Rede, sondern von einem Objekt, dessen Inhalt vorher festgelegt wird.

Denken Sie sich ein Programm, das an verschiedenen Stellen eine Meldung ausgeben soll. Da es sich immer um dieselbe Mitteilung handelt, geben Sie ihr einen Namen, eine Bezeichnung, und legen irgendwo anders - in der Deklaration - fest, worum es sich tatsächlich handelt. Der Inhalt an sich ist egal, ob es sich nun um eine Zeichenkette in englischer oder deutscher Sprache handelt in den Anweisungen wird immer nur von der MELDUNG gesprochen.

Eine Konstante kann eine Zeichenkette sein, eine ganze Zahl oder eine Fließkommazahl. Mit dieser offensichtlichen Unterscheidung werden Klassen von Objekten eingeführt - ein Aspekt, der bei den Variablen noch sehr wichtig wird.

Variablendeklarationen

Was ist eine Variable? Wenn Sie sich vielleicht an den Mathematikunterricht in der Grundschule erinnern, dann denken Sie an einen Platzhalter, der für einen veränderlichen Wert steht. Wenn Sie sich schon etwas mit Programmierung beschäftigt haben, werden Sie an einen Speicherbereich denken, in dem Werte abgelegt werden können. Variablen sind ein Mischung aus beiden Vorstellungen, je nachdem, ob die Sichtweise von der Verwendung einer Variablen oder von deren Deklaration ausgeht.

Denken Sie sich eine Variable als eine Schublade in einem riesigen Aktenschrank. Sie hat eine bestimmte Aufschrift und eine bestimmte Größe. In eine Schublade paßt immer ein Ding, dessen Art und Aussehen durch die Schubladen große festgelegt wird. Es gibt z.B. Schubladen, die ein DIN A5-Blatt aufnehmen, welche, die nur DIN A4-Blätter aufnehmen können, und Schubladen, in die nur ein Filzstift paßt.

Im Programm müssen Sie jede Schublade, also jede Variable, deklarieren, die Sie benutzen wollen. Dazu gehört die Aufschrift der Schublade, also der Bezeichner. unter dem die Variable angesprochen werden soll, und ihre Art. Die Beschreibung, was eine Schublade aufnehmen kann, ist der Typ der Variablen. Im ersten Beispielprogramm gab es die Variablendeklaration

VAR ch: CHAR:

Sie besagt, daß eine Schublade mit dem Namen "ch" gebraucht wird, und daß sie ein Zeichen aufnehmen soll. Die Anweisung "Read(ch)" ruft eine Funktion auf, die ein Zeichen von der Tastatur einliest und es in die Schublade "ch" packt.

Variablendeklarationen werden mit dem Schlüsselwort "VAR" eingeleitet. Jede Deklaration besteht aus einem Bezeichner, einem Doppelpunkt und dem Namen des Typs, den die Variable haben soll. Mit dem Semikolon wird die Deklaration abgeschlossen. Es können dann weitere folgen. Falls Sie mehrere Variablen des gleichen Typs brauchen, können Sie anstelle eines Bezeichners eine Liste von Namen angeben, die jeweils durch ein Komma getrennt sein müssen:

VAR ch, ab, Zeichen :CHAR; 

anstelle von

VAR ch CHAR;
ab: CHAR;
Zeichen: CHAR;

Modula-2 kennt eine Reihe vorgegebener Datentypen. Den Typ CHAR für ein Zeichen haben Sie schon kennengelernt. Er kann ein ASCII-Zeichen aufnehmen. Wahrheitswerte gehören in den Typ BOOLEAN. Variablen dieses Typs können nur zwei Werte annehmen: TRUE für "Wahr" und FALSE für "Falsch". Diese beiden Konstanten sind im Compiler vordefiniert.

Für Ganzzahlen gibt es zwei Typen, nämlich INTEGER für Zahlen mit Vorzeichen und CARDINAL für vorzeichenlose Werte. Der Wertebereich dieser Typen ist Compiler- und rechnerabhängig. Wird INTEGER mit 16 Bit implementiert, kann eine INTEGER-Variable einen Wert von -32 768 bis 32 767 haben: CARDINAL hätte dabei einen Wertebereich von 0 bis 65 535. Es gibt keinen Standard für die Größe dieser Datentypen: Compiler auf dem ATARI ST verwenden entweder 16 oder 32 Bit.

Einen kleinen Ausweg aus dieser Unbestimmtheit bieten die Typen SHORTINT. LONGINT. SHORTCARD und LONGCARD Sie sind jeweils "kleinere" oder "größere" Verwandte der Grundtypen INTEGER und CARDINAL. Wenn Ihr Compiler INTEGER mit 16 Bit verwendet, dann wird LONGINT 32 Bit groß sein und einen Wertebereich von - 2 147 483 648 bis 2 147 483 647 haben. Leider sind die meisten Compiler nicht sehr konsequent; man kann daraus nicht schließen, daß SHORTINT dann mit 8 Bit implementiert sei. Die beiden Standardfunktionen MIN und MAX liefern den Wertebereich eines Typs; Sie werden Sie aber erst später in der Anwendung kennenlernen. Beschränken Sie sich zunächst auf INTEGER und CARDINAL, die kurzen und langen Abarten brauchen Sie noch lange nicht.

Falls Sie eine Variable deklarieren wollen, die nur einen ganz bestimmten, ganzzahligen Wertebereich haben soll, sollten Sie ihn als Unterbereichstyp deklarieren. Eine Variable, die Werte von 50 bis 100 annehmen soll, ließe sich so deklarieren:

VAR FuenfzigBisHundert: [50..100];

Damit geben Sie dem Compiler eine Chance zur Optimierung; schließlich braucht ein solcher Wert weniger Speicher. Die Bezeichnung "Unterbereichstyp" deutet schon an, daß der Compiler die Variable aus einem Unterbereich eines der Basistypen nimmt. Im Beispiel könnte "FuenfzigBisHundert" aus einem Unterbereich von CARDINAL stammen. Wenn Sie den Grundtyp selber festlegen wollen, können Sie dies durch Voranstellen des Typbezeichners tun:

VAR FuenfzigBisHundert: 
INTEGER[50..100];

Daß eine solche Festlegung in Anweisungen und Ausdrücken wichtig sein kann, werden Sie später im Zusammenhang mit der Typenstrenge in Modula-2 sehen.

Fließkommazahlen werden in Variablen des Typs REAL gehalten. Auch hier gibt es einen "größeren" Typ, LONGREAL. Ob er wirklich doppelte Genauigkeit und einen größeren Wertebereich bietet, hängt wiederum vom verwendeten Compiler ab.

Damit haben Sie die Basistypen CHAR, BOOLEAN, INTEGER, CARDINAL und REAL kennengelernt. Es gibt noch eine Fülle weiterer Typen, und Sie können sogar selber welche definieren. Die damit verbundenen Konzepte sollen aber erst in späteren Folgen eingeführt werden, so daß wir uns jetzt den Ausdrücken und dem Zuweisungsstatement zuwenden. Damit können Sie auch erste Programme schreiben, das bringt Ihnen einen besseren Übungseffekt als eine eher tabellarische Aufführung aller Typen.

Anweisungen

Bis jetzt haben Sie ein Programm kennengelernt und einiges über Konstanten- und Variablendeklarationen gelesen. Ein Programm in Modula-2 besteht aber hauptsächlich aus Anweisungen (engl.: Statements), in denen beschrieben wird, was der Rechner machen soll.

Die Informatik unterscheidet zwischen imperativen, funktionalen, logischen und andern Programmiersprachen und -kalkülen. Funktional sind LISP, FP und andere; PROLOG ist der klassische Vertreter einer logischen Programmierung, und weiterhin gibt es z.B. die Datenflußprogrammierung. Aber bevor dieser Kurs in wissenschaftliche oder zu universitäre Gefilde abschweift: Modula-2 ist eine imperative Sprache.

"Imperativ" steht im DUDEN-Fremdwörterbuch verzeichnet unter "1. Befehlsform. 2. Pflichtgebot; vgl. kategorischer Imperativ". Auch wenn wir diesen Kurs nicht ganz so philosophisch betreiben wollen, trifft es die erste Definition doch recht genau. Jeder Programmschritt muß genau beschrieben werden - es erfolgt eine Anweisung an den Computer, genau dieses und jenes zu tun. Ein Modula-2-Programm besteht also hauptsächlich aus Anweisungen (Statements) an den Rechner (ein PROLOG-Programm besteht aus einer Beschreibung dessen, was zu lösen ist und den Regeln, die dabei verwendet werden können).

In einem Modula-Programm werden die Anweisungen nacheinander notiert und nacheinander vom Rechner ausgeführt. Getrennt werden sie durch das Semikolon. Eine Anweisungsfolge besteht aus einer Reihe von Anweisungen, die durch getrennt sind.

Die erste Art der Anweisungen, die Sie kennenlernen sollen, sind die Zuweisungen. In ihnen wird dem Rechner gesagt: "rechne das Ergebnis des folgenden (mathematischen) Ausdrucks aus, und schreibe es in die Variable". Sie haben schon gelernt, daß Variablen im Gegensatz zu den Konstanten veränderlich sind - durch die Zuweisungen führt der Rechner die Veränderungen aus.

Ausdrücke

Eine Zuweisungsoperation besteht aus linker und rechter Seite. Auf der linken Seite steht der Bezeichner der Variablen, deren Inhalt verändert werden soll; auf der rechten ein Ausdruck, den der Computer berechnen soll. Getrennt werden sie durch den Zuweisungsoperator Ein Bei spiel:

a:=100+b*30-c;

Der erste Eindruck ist der richtige: Die Variable "a" soll so verändert werden, daß ihr Inhalt dem Ergebnis der Berechnung von "100+b*30-c" entspricht, "fr" und "c" sind andere Variablen oder Konstanten, deren Inhalt in die Berechnung eingeht.

Ein Ausdruck ist eine Art Formel, er besteht aus Operanden, deren Wert benutzt wird, und aus Operationen, die die Berechnungsart festlegen. In dem Beispiel sind die Operanden 100, "b", 30 und "c" vorhanden; die Operationen sind +, *, -. Ein Ausdruck hat ein Ergebnis eines bestimmten Typs. Obiger Ausdruck ergäbe ein Ergebnis, das vom Typ INTEGER oderCARDIN AL sein könnte. Modula-2 ist in Sachen Typ sehr streng. Der Ergebnistyp eines Ausdrucks muß mit dem Typ der Variablen übereinstimmen, die auf der linken Seite der Zuweisung steht.

Der Typ eines Ausdrucks ergibt sich aus dem Typ der Operanden. Oben sind 100 und 30 sicherlich ganze Zahlen. Wenn nun "b" und "c" vom Typ INTEGER sind, hat der Ausdruck den Typ INTEGER. Wenn beide CARDINAL wären, ergäbe sich ein CARDINAL-Ergebnis. "a" muß nun auch von diesem Typ sein, ansonsten meldet der Modula-Compiler einen Typ-Fehler. Die gleiche Folge ergäbe sich, wenn "b" z.B. ein CARDINAL und "c" ein REAL wäre. Daß man kein BOOLEAN mit einem CHAR multiplizieren kann, sollte offensichtlich sein.

Als Operanden können Variablen oder Konstanten verwendet werden. Eine Variable wird durch Angabe ihres Namens, also durch einen Bezeichner, im Ausdruck aufgeführt. Für Konstanten gibt es einige Vorschriften bezüglich ihres Aussehens.

Ganzzahlige Konstanten werden einfach als Ziffernfolge notiert. Bei INTEGER-Konstanten kann das Vorzeichen hinzukommen: positive INTEGER- und CARDINAL-Konstanten unterscheiden sich nicht. REAL-Konstanten müssen immer mit einem Kommazeichen, und das ist im anglo-amerikanischen Sprachraum eben der Punkt, notiert werden.

"0.0" ist eine REAL-Konstante; "0" eine INTEGER- oder CARDINAL-Konstante.

Die zwei möglichen Belegungen für BOOLEAN-Variablen kennen Sie schon; es sind FALSE und TRUE. Zeichenkonstanten werden mit einfachem oder doppeltem Hochkomma eingeschlossen.

Zu jedem Typ gibt es eine Reihe von Operationen, mit denen ein Ausdruck gebildet werden kann. Die grundlegenden arithmetischen Operationen +, - und * sind für die Typen INTEGER, CARDINAL und REAL vorhanden. Die Division muß bei ganzzahligen Ausdrücken als DIV notiert werden, für REAL gibt es die "/"-Operation.

Wahrheitswerte werden durch Vergleiche erzeugt. Zwei Variablen können gleich oder verschieden sein. Dafür gibt es die Operationen = und #. Bei Zahlen kann man auch auf eine Größenrelation testen. Die Operatoren sind hier ">" für größer und "<" für kleiner. Modula-2 kennt auch die Kombinationen ">=" und "<=".

Vergleiche ergeben einen Wahrheitswert, sie müssen nicht unbedingt zwischen BOOLEANs angestellt werden. Sie sind definiert auf den Zahlentypen und auf CHARs: ferner gilt FALSE<TRUE. Die Aufzählungstypen, denen Sie in der nächsten Folge begegnen, werden wie Zahlenwerte behandelt: auf zusammengesetzten Typen sind die Gleichheit und die Ungleichheit definiert.

Zwischen BOOLEAN-Werten können die logischen Operationen AND (Und. Konjunktion) und OR (Oder, Disjunktion) verwendet werden. Negiert wird ein Wahrheitswert mit NOT. Bei allen Ausdrücken gelten zwischen den Operatoren bestimmte Hierarchien. * gilt als höher als +, somit wird zunächst der Unterausdruck, der sich um das * gruppiert, ausgewertet. "10-5*2" ergibt also 0. Um diese Regeln zu umgehen, können Sie wie in der Mathematik Klammern verwenden. "(10-5)*2" ergibt dann 10, da zunächst der Unterausdruck in den Klammem berechnet wird.

Einige Beispiele für Ausdrücke und Zuweisungen finden Sie unten.

.
.
.
VAR	i,j : INTEGER ;
    r,s : REAL ; 
    b   : BOOLEAN;

BEGIN
    i:=-10;
    j:=1+i*3*i-1; 
    j:=1+i*3*(i-1); 
    i:=i DIV 2; 
    r:=0.0;
    s:=100.123;
    s:=100.0;
    s:=s/2;
    b:=TRUE; 
    b:=(i>j);
    b:=(i>j) OR (r-0.0); 
    b:=NOT (s>r);

END
.
.
.
# Auflösung von Teil I

Aha, Sie scheinen sich für die Hausaufgaben zu interessieren. Dann werden Sie sicherlich auch die Aufgaben gelöst haben, und ich muß natürlich die Auflösung bieten.

Die erste Aufgabe dürften Sie verdaut haben. Basic ist keine Hochsprache, und ich werde mich hüten, Vergleiche zwischen Modula-2 und BASIC zu ziehen; das will ich weder Ihnen noch mir antun. Als zweites sollten Sie die Anleitung zu Ihrem Modula-System lesen. Nun, wenn Sie es immer noch nicht getan haben sollten - ohne Handbuch werden Sie die Beispiele nicht eintippen können, und ohne die Beispiel Programme wiederum bekommen Sie niemals die Übung, die Sie brauchen, um in Modula zu programmieren.

Die dritte Aufgabe müßte eigentlich leicht zu lösen gewesen sein. Die Zeichenkette "Hello World !" war durch "Hallo Welt!" zu ersetzen. Dazu muß das kleine Programm wie folgt lauten:

Sie haben damit eine Zeichenkonstante geändert. In Modula-2 sind alle Zeichenketten, die unveränderlich ausgegeben oder sonstwie verwendet werden, mit dem Zeichen 4 eingeschlossen. Wie bekommt man nun ein Zeichen 4 in den Ausgabetext? Anstelle des Begrenzers # für Zeichenketten können Sie auch " verwenden. Ein konstanter Text, in dem das Zeichen ' vorkommt, wird mit " begrenzt, andersherum verwenden Sie " als Begrenzung.

Sinn der Aufgabe war, daß Sie ein Programm mit Ihrem Modula-System eingeben, verändern und übersetzen. Bei Megamax und SPC gibt es das Load-Time-Linking; bei Softwave. Jefferson und TDI mußten Sie auch noch den Linker benutzen.

MODULE HelloMorld

FROM	InOut	IMPORT	WriteString, WriteLn, Read ;

VAR ch: CHAR;

BEGIN
    WriteString('Hallo Welt!');
    WriteLn;
    Read(ch);
END HelloWorld

Casts und Umwandlungen

Die genannte Typenstrenge in Modula kann bei einigen Ausdrücken hinderlich sein. Um Werte zwischen Variablen verschiedenen Typs auszutauschen, müssen Wandlungsfunktionen vorhanden sein.

Es gibt zwei Arten von Wandlungsfunktionen, einmal die "Casts", die lediglich den Compiler anweisen, einen anderen Typ für eine Variable oder einen Ausdruck anzunehmen und keine Veränderung an der Darstellung des Wertes vorzunehmen, und die Umwandlungen, die einen Wert tatsächlich verändern.

Casts können zwischen sehr vielen Typen angewandt werden. Sie werden immer mit der Angabe des Typs notiert. Der Ausdruck oder die Variable, deren Typ verändert werden soll, folgt in Klammem. Eine Variable "b" vom Typ CARDINAL kann mit

a:=INTEGER(b);

der INTEGER-Variable "a" zugewiesen werden. Der Modula-Compiler stellt zunächst für "h" den Typ CARDINAL fest, durch den Cast erhält die rechte Seite des Ausdrucks den Typ INTEGER, womit die Zuweisung die Typgleichheit erfüllt.

Casts sind lediglich eine Anweisung an den Compiler, sie verändern nicht das eigentliche Datenobjekt. Daher sind sie nur eingeschränkt verwendbar. Die maschineninterne Darstellung eines REALs ist immer anders als die Darstellung eines INTEGERs. Wenn Sie einen Cast "REAL(b)" versuchen, erhalten Sie eine Fehlermeldung wie "Type conversion not implemented". In diesen Fällen stehen Umwandlungsfunktionen zur Verfügung.

Zwischen Ganz- und Fließkommazahlen wandeln die Funktionen FLOAT und TRUNC. FLOAT macht aus einem ganzzahligen Datenobjekt einen Fließkommawert. TRUNC bewirkt das Gegenteil: Die Nachkommastellen werden abgeschnitten und ein INTEGER oder CARDINAL-Wert erzeugt. Der obige Versuch müßte also korrekt

f:=FLOAT(b)

lauten. Entsprechend könnte später ein

a:=TRUNC(f)

folgen. Wollen Sie die Nachkommastellen einer REAL Zahl nicht einfach abschneiden, sondern korrekt auf- oder abrunden. gibt es die Umwandlungsfunktion ROUND, die analog angewendet wird.

Einem Zeichen ist je nach Zeichensatz ein ganzzahliger Wert zugeordnet. Sie können ihn mit ORD als Ganzzahl verwenden. Umgekehrt verwandelt CHR eine Zahl in ein Zeichen. Sie könnten z.B. schreiben

a:=ORD('A');

oder

ch:=CHR(65):

Der Cast "ch:=CHAR(65)" arbeitet in der Regel auch, aber denken Sie daran, daß eine solche Wandlung rechnerabhängig ist, denn trotz der weiten Verbreitung von Mikros gibt es Rechner, die andere Zeichensätze verwenden. Wer einmal an einem IBM-Großrechner gearbeitet hat, wird sich sicherlich erstmal wundern, daß beim dort verwendeten EBCDIC-Code das "A" eben nicht wie bei ASCII mit 65, sondern mit 193 codiert wird.

Beim nächsten Mal stelle ich Ihnen einige neue Variablentypen vor und Sie werden die Kontrollstrukuren für Schleifen kennenlernen. Angehende Modula-Experten, die die Aufgaben im Vorbeigehen erledigen müssen leider noch etwas warten, um einen "Brain-Teaser" in Sachen Rekursion präsentiert zu bekommen. In diesem Sinne ... bis in vier Wochen.

RT

Der Appell an das gute Gewissen

Bitte beachten Sie die Aufgaben nicht als Übel oder notwendiges - sie sind wirklich dazu da, die vorgestellten Konzepte zu vertiefen. Es wird Ihnen nichts nutzen, lediglich den Text zu lesen und dann das Heft zuzuschlagen - erst wenn Sie in der Lage sind, die Fragen richtig zu beantworten, haben Sie etwas dazugelernt.

Ich hoffe, daß meine Auflösungen in der jeweils nächsten Folge ausreichen. Wenn nicht: Schreiben Sie sofort, was unklar geblieben ist! Momentan bewegen wir uns noch in den Grundlagen, ohne die Sie nicht weiterkommen werden. Und wenn Sie den Kurs ernst nehmen (ich tue das jedenfalls), dann sollten Sie in Ihrem Interesse auch Fragen stellen. Seien Sie sicher, daß ich jede Anfrage beantworte (natürlich nur, wenn Sie Rückporto beilegen) und die wichtigsten auch im Modula-Forum veröffentliche.

# Hausaufgaben

Ich werde Sie nicht so einfach davonkommen lassen! Deshalb gibt es natürlich auch heute ein paar Hausaufgaben, für die Sie ja immerhin vier Wochen Zeit haben.

  1. Welche Namen erkennt ein Modula-Compiler?

a) "Null problemo"
b) "Nullproblemo"
c) "NullProblemo"
d) "Nullproblemo"

  1. Welche Namen sind für den Modula-Compiler identisch?

a) "ThanksForAllTheFish"
b) "thanksforallthefish"
c) "Thanks_Por_All_The_Fish"
d) "ThanxForAllTheFish"
e) "ThanksForAllTheFish"

  1. Welche der folgenden Variablendeklarationen sind erlaubt?

a) VAR a:INTEGER:
b) VAR a,b;c:CARDINAL;
c) VAR a: CARDINAL[-100..10];
d) var d:REALO;
e) VAR a:CARDINAL: b:INTEGER;

  1. Schreiben Sie das erste Beispielprogramm so um. daß anstelle eines Zeichens ein positiver ganzzahliger Wert nach der Begrüßung eingelesen wird. Verwenden Sie dazu anstelle von "Read" die Prozedur "ReadCard".

  2. Fügen Sie in das Programm eine Zuweisung an die BOOLEAN-Variable "GleichNull" ein. Der Ausdruck soll TRUE ergeben, wenn die eingelesene Zahl gleich Null ist.



Aus: ST-Computer 02 / 1989, Seite 126

Links

Copyright-Bestimmungen: siehe Über diese Seite