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










Wir haben im vorigen Kapitel eine Vorstellung von einfachen if-Verzweigungen entwickelt. Was aber, wenn die Sachverhalte komplizierter werden? Es könnte ja sein, dass Sie im WENN-Fall nicht nur einen Ausdruck evaluieren lassen möchten, sondern gleich mehrere? Nehmen wir folgendes an: Sie untersuchen eine Liste. Ist ihre Länge grösser als 10, soll die Variable zu-lange-liste auf 'T gesetzt werden und nur das erste Element zurückgegeben werden. Im SONST-Fall soll die Liste unverändert zurückgegeben werden. Der gutgemeinte folgende Versuch funktioniert leider nicht, sondern endet mit einer Fehlermeldung:
(if (> (length liste) 10) ; Fehler!!!
  ((setq zu-lange-liste 'T)(car liste))
  liste
)
                  
Dieser Versuch, mit einer umgebenden Klammer zwei Ausdrücke zusammenzufassen, ist zum Scheitern verurteilt, da - wenn der Ausdruck evaluiert wird - das erste Element kein Funktionsaufruf ist. Wenn wir mehrere Ausdrücke zusammenfassen wollen, müssen wir uns der Funktion (progn) bedienen, die folgendes leistet: (progn) fasst beliebige Ausdrücke zu einem einzigen Ausdruck zusammen und sorgt dafür, daá sie von links nach rechts abgearbeitet werden.

(progn) quotiert übrigens alle seine Argumente automatisch, so dass Sie erst beim Aufruf von (progn) evaluiert werden, aber nicht schon bei der Übergabe an (progn). Wir können jetzt, da wir sowieso schon dabei sind, auch einmal klären, wie sich (if) in dieser Hinsicht verhält: Die Evaluation des zweiten und des dritten Argumentes wird verhindert, d.h. die Evaluation findet erst dann statt, wenn die if-Entscheidung getroffen wurde.

Wir müssen also unser letztes Beispiel noch einmal abändern, damit es funktioniert:
(if (> (length liste) 10)
  (progn
    (setq zu-lange-liste 'T)
    (car liste)
  )
  liste
)
                  
if-Ausdrücke können aber auch dadurch komplizierter werden, dass mehrere Bedingungen gleichzeitig getestet werden sollen: Sie könnten z.B. eine Funktion brauchen, die testet, ob ein Punkt innerhalb eines bestimmten (orthogonalen) Rechteckes angesiedelt ist, und dann die Variable punkt-ist-ok auf den entsprechenden Wert ('T oder nil) setzt. Um mehrere Testbedingungen zu verknüpfen, stehen uns die Logik-Funktionen (and), (or) und (not) zur Verfügung.

(and) und (or) geben immer entweder T oder nil zurück, es gibt aber einen wichtigen Unterschied: (and ...) gibt dann T zurück, wenn alle seine Argumente wahr sind. Es müssen also alle Argumente evaluiert werden. (or ...) arbeitet anders: Es gibt dann T zurück, wenn eines seiner Argumente wahr ist. Daher werden bei (or) die Argumente ebenfalls von links nach rechts abgearbeitet, aber nicht unbedingt alle: Sobald eines gefunden wurde, das nicht nil ergibt, stellt (or ...) die Arbeit ein und evaluiert nicht mehr weiter.

(not ...) kann immer nur ein einziges Argument bekommen. Ist dieses whar, wird nil zurückgegeben, ist es nil, wird 'T zurückgegeben.

Mit (and ...) können wir unsere gestellte Aufgabe erst einmal so lösen:
(if
  (and
    (< x rechte-grenze)
    (> x linke-grenze)
    (< y obere-grenze)
    (> y untere-grenze)
  )
  (setq punkt-ist-ok 'T)
  (setq punkt-ist-ok nil)
)
                  
Beim näheren Hinsehen lässt sich feststellen, dass auch diese Lösung sich noch verkürzen lässt:
(setq punkt-ist-ok
  (and
    (< x rechte-grenze)
    (> x linke-grenze)
    (< y obere-grenze)
    (> y untere-grenze)
  )
)
                  
Sie sehen, dass die (if)-Anweisung, obwohl gerade erst gelernt, sich hier als überflüssig erweist. Wir kommen da zu einem wichtigen Punkt. Man sollte nicht nur wissen, wie man (if) anwendet, sondern auch, wann man es besser weglässt. Der Prototyp der überflüssigen (if)-Anweisung lautet:
(if irgend-ein-ausdruck 'T nil)
                  
Diese Formulierung ist immer dann überflüssig, wenn irgend-ein-ausdruck auch nur T oder nil zurückgibt, also eine Testfunktion ist. Eine solche (if)-Konstruktion plappert also wie ein Papagei nur den Effekt des Testausdrucks nach. Sinnvoll kann diese Konstruktion nur sein, wenn der Testausdruck etwas anderes als T zurückgibt (wie z.B. (member)). Aber auch dann kann man meist darauf verzichten, da ja alles, was nicht nil ist, wahr ist. Schauen Sie sich noch einmal folgendes Programmfragment an:
(if(member dieses-element jene-liste)
  (tu-dieses ...)
  (tu-jenes ...)
)
                  
(member ...) gibt ja nicht das Symbol T zurück, sondern eine Liste, die mit dieses-element beginnt, falls es in jene-liste enthalten ist. Wenn das nicht der Fall ist, kommt eben die leere Liste (= nil) zurück. Diese Konstruktion macht auch besonders deutlich, warum nil die Abkürzung für 'Not In List' ist.


Übungsaufgaben

  1. Etwas weiter oben hatten wir den Ausdruck (setq punkt-ist-ok ...), der bereits eine verkürzte Form der Vorgängerversion ist. Denken Sie daran, was Sie über die Vergleichsfunktionen (< ...) und (> ...) gelernt haben und verkürzen Sie den Ausdruck um weitere zwei Zeilen. Sie benötigen dann nur noch eine der beiden Vergleichsfunktionen.

  2. Definieren Sie eine Funktion, die testet, ob ein 2D-Punkt im rechten oberen Quadranten des Koordinatensystems liegt. Machen Sie die Funktion so kurz wie möglich.

  3. Definieren Sie eine Funktion, die testet, ob ein 2D-Punkt innerhalb eines Kreises um den Mittelpunkt M liegt. Wenn der Punkt genau auf der Kreislinie liegt, gilt er noch als innerhalb. Benutzen Sie dazu die Funktion (distance p1 p2), die den Abstand zwischen zwei Punkten berechnet.

  4. Lösen Sie die vorige Aufgabe noch einmal, ohne (distance) zu verwenden, d.h. Sie benötigen den Satz des Pythagoras.