DEF

Aus C64-Wiki
Wechseln zu: Navigation, Suche
DEF
Format: DEF FN <Funktionsname>(<Parameter>)=<Ausdruck>
Parameter
<Funktionsname>: Name der benutzerdefinierten Funktion
<Parameter>: Parametervariable, der der Funktion übergeben wird
<Ausdruck>: beliebiger Ausdruck mit numerischem Ergebnis
Einordnung
Typ: Anweisung
Kontext:
Aufgabe: Definition eigener Funktionen
Abkürzung: dE
Verwandte Befehle
FN

Anmerkung: Dieser Artikel beschreibt den BASIC-Befehl DEF unter BASIC V2 des Commodore 64.


Der BASIC-Befehl DEF dient dazu, eigene Funktionen innerhalb von BASIC-Programmen zu definieren, die später mit (FN) aufgerufen werden kann. Die zu definierende Funktion kann aus einem beliebigen BASIC-Ausdruck bestehen, sofern dieser ein numerisches Ergebnis liefert. Der Ausdruck darf neben dem Parameter (das ist lediglich ein Platzhalter), Zahlenwerten, Variablen und den mathematischen und logischen Operatoren auch mathematische, sowie auch Zeichenketten-Funktionen oder Ausleseanweisungen enthalten. Zulässige Funktionen, deren Ergebnis direkt verwendet werden können, sind z.B. ABS(), AND, ATN(), ASC(), COS(), EXP(), FN<Funktionsname>(), FRE(), INT(), LEN() LOG(), NOT, PEEK(), POS(), OR, RND(), SGN(), SIN(), SQR(), STATUS bzw. ST, TAN(), TIME bzw. TI oder VAL().

In der DEF-Zeile wird die Funktion einmal komplett als Prototyp vorgegeben, wobei der Parameter als numerische Eingangsgröße in den Ausdruck einfließen kann (aber nicht muss). Der Parametername kollidiert dabei aber nicht mit einer bereits gleichnamigen, eventuell existierenden Variablen. Später kann die Funktion mit dem BASIC-Befehl FN <Funktionsname>(<Ausdruck>) aufgerufen werden. Ein CLR-Befehl löscht auch alle bisher so definierten Funktionen. In einem solchen Fall muss die DEF-Definition erneut durchlaufen werden, falls wieder ein FN-Aufruf erfolgen soll.
Der Funktionsname muss (analog zu den Variablennamen) mindestens aus einem Zeichen bestehen, davon ist das erste Zeichen stets ein Buchstabe (A-Z) und die nachfolgenden Zeichen dürfen entweder aus Buchstaben (A-Z) oder aus Ziffern (0-9) bestehen. Es kann auch eine Funktion überschrieben werden, wenn diese den gleichen Funktionsnamen besitzt wie eine schon definierte! Ist der Funktionsname länger als zwei Zeichen, werden die restlichen Zeichen ignoriert. D.h. FN TEST0 wird durch die Definition von FN TEST1 überschrieben, da der eigentliche Funktionsname in beiden Fällen FN TE ist. Hier sollte ebenso die Verwendung von BASIC-Schlüsselwörtern vermieden werden, was üblicherweise zur Fehlermeldung ?SYNTAX ERROR führt.

Wenn der BASIC-Befehl nicht im Programmmodus ausgeführt wird, so erscheint die BASIC-Fehlermeldung ?ILLEGAL DIRECT ERROR. Wird die falsche Typenbezeichnung beim Parameter benutzt, so tritt entweder die BASIC-Fehlermeldung ?SYNTAX ERROR (bei Integer- bzw. Ganzzahl Variablenbezeichner) oder ?TYPE MISMATCH ERROR (bei dem Versuch Variablenbezeichner von Zeichenketten anzugeben) auf.
Andere Fehler in der Definition des Funktionsausdrucks treten erst auf, wenn die Funktion erstmalig aufgerufen wird: Liefert der Ausdruck kein numerisches Ergebnis, bricht das Programm mit ?TYPE MISMATCH ERROR ab oder ?ILLEGAL QUANTITY ERROR beendet den Programmlauf, wenn ein Eingabeparameter einer Funktionen keinen gültigen Wert aufweist).

Beispiele[Bearbeiten]

Zum Start eine einfache Definition einer Funktion, die den übergebenen Parameterwert verdreifacht:

10 DEF FN FTEST1(X) = X*3
20 INPUT "Geben Sie ein Zahl ein:"; A
30 PRINT FN FTEST1(A): PRINT
40 IF A<>64 THEN 20

Im folgenden Fall muss zwar ein Parameter übergeben werden, dieser wird aber nicht berücksichtigt, da ausschließlich die Variablen A und B für die Berechnung herangezogen werden:

10 A=10: B=11
20 DEF FN C(X) = 3+(A*B)/2
30 D = FN C(0): PRINT D

Mit folgendem Beispiel wird die sonst fehlende logische Funktion Exklusiv-Oder "XR" definiert. Das Problem dabei ist, dass nur Funktionen mit genau einem Parameter (hier werden zwei gebraucht) angelegt werden können. Der 2. Parameter wird über die Variable B beigesteuert. Das Beispiel stellt die Logikmatrix dar (-1 für "wahr" und 0 für "falsch"):

10 DEF FN XR(A) = (A OR B) AND NOT(A AND B)
20 PRINT "X","Y","X XOR Y"
30 FOR X= -1 TO 0
40 FOR Y= -1 TO 0
50 B=Y: R=FN XR(X)
60 PRINT X,Y,R
70 NEXT Y
80 NEXT X

Auch diese Funktion ist bei anderen BASIC-Dialekten zu finden und kann so nachgebildet werden, die Funktion DEEK(Adresse):

10 DEF FN D(A) = PEEK(A)+256*PEEK(A+1)
20 PRINT "PROGRAMMLAENGE:" FN D(45) - FN D(43) - 2

Die Programmlänge wird auch den beiden Zeigern für den BASIC-Variablenstart und den BASIC-Textanfang ermittelt (siehe Zeropage-Stellen 43/44 und 45/46).

Die Funktion FRE des BASIC 2.0 ist ja bekannt für die fehlerhafte Werte (negative bei Werten > 32767) und kann durch folgende Funktion ersetzt werden:

10 DEF FN F(X)=FRE(0)-65536*(FRE(0)<0)
20 PRINT "FREIER SPEICHER" FN F(0)

Nebenwirkung: FRE() wird dabei 2× aufgerufen, was auch gleichzeitig implizit die Garbage Collection entsprechend oft aufruft. Sollten viel belegte Strings vorhanden sein, kommt es dadurch zur doppelten Verzögerung.
Der Parameter wird hier ignoriert.

In folgenden Beispiel wird in Zeile 10 die Berechnung des 10er Logarithmus definiert und in Zeile 30 wird die neue Logarithmusfunktion LO10 aufgerufen:

10 DEF FN LO10(X) = LOG(X)/LOG(10)
20 Y = 10
30 Y = Y * 10 : PRINT FN LO10(Y); " ";
40 IF Y<1E38 THEN 20

Dieses Beispiel zeigt, was u.a. möglich ist. Es sind hier mehrere Funktionen und Ausleseanweisungen zusammengefasst und Funktionen geschachtelt.

10 A$="12.12.1964 SAMSTAGABEND"
20 DEF FN F1(X) = ( LEN(A$)/VAL(A$) ) * PEEK(53280)
30 PRINT FN F1(0)
40 DEF FN F2(X) = INT( ABS( FN F1(X)* 1E+8) / ASC(A$) )
50 PRINT FN F2(1)