Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Berechnen von arithmetischen Ausdrücken in der Kommandozeile Sitz!Platz!Fass!
Das Verschachteln von Ausdrücken Alte Schachtel!
Das Speichern von Werten in Variablen Gebunkert
Verhindern der Evaluation mit Quote Bergbäche
Erzeugen von einfachen Listen in AutoLisp Brot,Eier,Käse
Einfache Funktionen zur Listenbearbeitung ...um die Wurst
Funktionen für den Zugriff auf Listenelemente Was ein Salat!
Über Haupt- und Nebeneffekte von Funktionen Schwer schuften
Das Definieren von eigenen Funktionen in AutoLisp Ostfriesischer...
Lokale Variablen und Funktionsargumente in AutoLisp Kondome!
Das Laden von Programmdateien in AutoLisp Banküberfall
Verzweigung in Funktionen aufgrund von Entscheidungen Wenn das Wort...
Zusammenfassen von Entscheidungen mit den Logik-Funktionen Ins Schweinderl
Mehrfach-Verzweigungen in AutoLisp mit Cond 3. Strasse links
Schleifen zum Steuern des Ablaufs in AutoLisp-Funktionen Wie im Fernsehen
Testfunktionen zum Steuern von Schleifen in AutoLisp Schwanger?
Gleichheitstests als Schleifenkriterium in AutoLisp Noch gleicher?
Zeichneketten-Bearbeitung in AutoLisp Rauchzeichen
Funktionen zur Konvertierung von Datentypen in AutoLisp Wasser zu Wein
Komplexere Funktionen für die Bearbeitung von Listen in AutoLisp Nicht arbeiten...
Das Erzeugen von anonymen Funktionen mit lambda Schwarze Kutte
Das Bearbeiten von Listenelementen mit foreach Jedem das Seine
Erzeugen und Verwenden von Assoziationslisten in AutoLisp Beim Psychiater
Zugriff auf Geometriedaten und Erzeugen von Geometrieelementen Ententanz
Der Umgang mit Auswahlsätzen in AutoLisp Jung gefreit, ...
Auswahl von AutoCAD-Zeichnungsgeometrie mit ssget Raffgierig!
Verändern von Zeichnungs-Geometrie mit entmod Flickschusterei
Das Erzeugen von Geometrie mit entmake Houdini
Über Programmierstile in AutoLisp, Teil 1 Emma
Über Programmierstile in AutoLisp, Teil 2 Sti(e)lblüten
Über Programmierstile in AutoLisp, Teil 3 Eingewickelt
Über Programmierstile in AutoLisp, Teil 4 Doofe Frisur?


Zum den Seiten für Fortgeschrittene

Zu den ActiveX-Seiten

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










Eines der in den vorigen Kapiteln erwähnten Kriterien für eine Funktion war, dass sie in der Lage sein muss, auf verschiedene Situationen flexibel zu reagieren. Das ist natürlich schon dadurch gegeben, dass sie verschiedene Werte für ihre Argumente erhält. Eine Funktion, die immer gleich reagiert, kann aber auch sinnvoll sein. Wir kennen ja bereits (textscr). Diese Funktion bewirkt immer nur ein Umschalten auf den Textbildschirm (bzw. das Textfenster) und ist dabei absolut unflexibel.

Man muss aber berücksichtigen, dass es hier um eine hundertprozentige Nebeneffekt-Funktion geht. Funktionen, deren Haupteffekte immer gleich sind, und die keine Nebeneffekte haben, sind jedoch absolut sinnlos, da man sie auch als Konstanten wie z.B. pi definieren könnte. Man müsste also einfach den Wert an ein Symbol binden und hätte den gleichen Nutzen. Beispiel: Eine Funktion, die immer Wurzel aus 2 berechnet, kann durch eine Konstante ersetzt werden:
(defun wurzel-zwei()(sqrt 2))
;ist Unsinn und sollte durch
(setq wurzel-zwei (sqrt 2))
                  
ersetzt werden. Am Rande: Man kann in AutoLisp keine echten Konstanten erzeugen, deren Wert sich nicht mehr ändern lässt. Das Wort Konstante ist also eine blosse Absichtserklärung des Programmierers, den Wert einer Variablen nach dem Setzen nicht mehr zu ändern.

Wie kann man nun aber noch mehr Flexibilität in Funktionen hineinbringen? Was wir brauchen, ist eine Möglichkeit der Entscheidung in der Art WENN dies-der-Fall-ist DANN tue-dieses SONST tue-jenes. Erst eine solche Entscheidungsfreiheit macht es möglich, wirklich sinnvolle Funktionen zu schreiben. LISP stellt uns dazu die Funktion (if ...) zur Verfügung, die entweder zwei oder drei Argumente erhält:
(if <ausdruck1> <ausdruck2> [<ausdruck3>])
                  
ausdruck3 kann vorhanden sein oder nicht, dies wird durch die eckigen Klammern angezeigt.

ausdruck1 kann ein völlig beliebiger Ausdruck sein, der entweder nil oder etwas anderes zurückgibt. Gibt er etwas anderes als nil zurück, wird dann ausdruck2 evaluiert, anderenfalls wird (sofern vorhanden) ausdruck3 evaluiert. In der Praxis werden in ausdruck1 meistens irgendwelche Testfunktionen eingesetzt, von denen LISP eine ganze Reihe zur Verfügung stellt. Wir sollten uns daher zunächst mit einigen dieser Testfunktionen befassen:
(> x y) testet, ob x grösser als y ist
(< x y) testet, ob x kleiner als y ist
(= x y) testet, ob x gleich y ist
                  
Diese Funktionen können übrigens auch mit mehr als 2 Argumenten aufgerufen werden. So testet z.B. (> x y z), ob x grösser als y und y grösser als z ist. Mit anderen Worten: Es wird getestet, ob y zwischen x und z liegt.

Dann gibt es auch noch kombinierte Formen:
(>= x y) testet, ob x grösser oder gleich y ist
(<= x y) testet, ob x kleiner oder gleich y ist
                  
Schliesslich haben wir auch noch einen Test auf Ungleichheit:
(/= x y) testet, ob x ungleich y ist
                  
Die folgenden Funktionen bietet noch eine zusätzliche Möglichkeit:
(zerop x)
; ist äquivalent zu
(= x 0)
                  
testet, ein Wert gleich 0 ist.

Die bisher genannten Funktionen lassen sich auf Zahlen und auch auf Zeichenketten anwenden (zerop ist nur für Zahlen gedacht). Der Test auf Gleichheit bzw. Ungleichheit lässt sich aber auch auf Symbole anwenden.

Allen Testfunktionen ist gemeinsam, dass sie - wenn das Testergebnis logisch wahr ist - das Symbol T zurückgeben, im anderen Fall erhalten wir nil. Da jede Rückgabe ausser nil gleichbedeutend mit 'wahr' ist, kann es uns eigentlich auch ganz egal sein, was diese Funktionen zurückgeben, solange es - ja nach Testergebnis - nil oder etwas anderes ist.

Dies ist aber deshalb von besonderer Bedeutung, da sich das Symbol T um- oder wegdefinieren lässt, zumindest ist dies bis AutoCAD 14 der Fall. Ab AutoCAD 2000 ist das Symbol T geschützt und unveränderlich. Wir tun so etwas natürlich nicht absichtlich, aber es kann trotzdem passieren. Normalerweise ist der an das Symbol T gebundene Wert ebenfalls das Symbol T (Selbstbindung). Ist T aber versehentlich umdefiniert worden, dann hat T den Wert nil (oder irgendeinen anderen Wert).

Da die Testfunktionen aber immer das Symbol T und nicht dessen Wert zurückgeben, macht es nichts, wenn T umdefiniert wurde. Wenn Sie aber selbst weitere Testfunktionen schreiben, müssen Sie darauf achten, das Symbol T selbst (quotiert: also 'T) zurückzugeben und nicht dessen Wert. Ich weiss, dass dies ein etwas schwieriges Thema ist, dashalb wird in den Übungsaufgaben noch einmal gründlich darauf eingegangen.

Zunächst einmal zurück zur (if)-Funktion. Lassen Sie uns ein paar Beispiele mit den jetzt bekannten Testfunktionen begutachten:
(if(> zahl 100) 100 zahl)
                  
Dieser Ausdruck gibt uns zahl zurück, wenn zahl nicht grösser als 100 ist. Ist dies jedoch der Fall, wird 100 zurückgegeben. Der Ausdruck begrenzt also einen Zahlenwert auf maximal 100. Werfen Sie nun einen Blick auf das nächste Beispiel:
(if(< zahl 100) zahl nil)
                  
Dieser Ausdruck gibt dann nil zurück, wenn zahl grösser als 100 ist. Bei diesem Beispiel gibt es aber noch eine Feinheit zu beobachten. Wir können den Ausdruck verkürzen zu
(if(< zahl 100) zahl)
                  
Lassen Sie sich nicht zu der Annahme verleiten, dass dieser Ausdruck nichts zurückgibt, wenn zahl grösser als 100 ist. Jeder Ausdruck in LISP hat eine Rückgabe! Hier wird im Fall, dass zahl nicht zurückgegeben wird, das Ergebnis der Evaluation der Funktion (< ...) zurückgegeben, und das ist eben nil. Durch die vorgenommene Verkürzung des Ausdrucks ändert sich also nichts! Noch ein paar Beispiele:
(defun 3d-punkt(punkt)
  (if(=(length punkt)2)
    (append punkt(list 0.0))
    punkt
  )
)
                  
Diese Funktion gibt immer einen vollständigen 3D-Punkt mit Z=0 zurück.
(if
  (>=(- zahl(fix zahl))0.5)
  (1+(fix zahl))
  (fix zahl)
)
                  
Dieser Ausdruck rundet eine Realzahl auf oder ab.
(if(member dieses-symbol jene-liste)
  dieses-symbol
)
                  
Dieser Ausdruck verändert die (member)-Rückgabe so, dass nicht mehr der Rest der Liste zurückgegeben wird, sondern nur das gesuchte Symbol. Aber ganz am Rande: Das kann man auch mit
(car(member dieses-symbol jene-liste))
                  
erreichen, da (car nil) ja auch nil ergibt.


Übungsaufgaben

  1. Welche Testfunktionen sind im Ergebnis gleich mit den Konstruktionen
    (not(> ...))
    (not(= ...))
    (and(not ...)(not ...))