Grundlagen der Smalltalk-Programmierung und Übungen

Eingeordnet in Informatik

Geschrieben am in Deutsch mit einer Größe von 22,7 KB

1. Unäre Ausdrücke berechnen

Berechnen Sie die folgenden Ausdrücke in der Smalltalk-Umgebung und zeichnen Sie die Ergebnisse auf, d.h. wie jeder Fall funktioniert.

  • a) Summe von Zahlen

    5 + 6 -> 11 (gibt das Ergebnis der Summe der Zahlen 5 und 6)

  • b) Fakultät

    20 factorial -> 2432902008176640000 (gibt das Ergebnis der Fakultät von 20)

  • c) Zeichenkettenlänge

    'This is a test' size -> 18 (zählt die Anzahl der Zeichen zwischen den einfachen Anführungszeichen, einschließlich Leerzeichen)

  • d) Element an Position

    #(1 3 5 7) at: 2 -> 3 (gibt an, was sich an der Position befindet, die als Parameter übergeben wurde)

  • e) Array-Prüfung

    'Paradigmen' isArray -> false (prüft, ob die übergebene Zeichenkette ein Array ist)

  • f) Produkt

    5 * 7 -> 35 (berechnet das Produkt zweier Objekte)

  • g) Ganzzahlige Division

    5 // 2 -> 2 (führt ganzzahlige Division aus und gibt den Quotienten zurück)

  • h) Divisionsrest

    4 \\ 3 -> 1 (führt die Division aus und gibt den Rest zurück)

  • i) Division

    2 / 6 -> (1/3) (führt die Division aus)

  • j) Summe von Dezimal- und Exponentialzahl

    1.5 + 6.3e2 -> 631.5 (berechnet die Summe einer Dezimalzahl und einer Exponentialzahl)

  • k) Array-Instanziierung

    Array new -> #() (instanziiert ein neues Objekt der Klasse Array)

  • l) Aktuelles Datum

    Date today -> (z.B. 29 August 2008) (liefert das aktuelle Systemdatum)

  • m) Aktuelle Zeit

    Time now -> (z.B. 09:30:30) (liefert die aktuelle Systemzeit)

2. Unäre Nachrichten berechnen

  • a) Array-Größe

    #('unter' 'der' 'strings') size -> 3 (angewendet auf ein Array, gibt die Anzahl der Elemente im Array zurück)

  • b) Zeichenkette in Großbuchstaben

    'Heute ist Sonntag' asUpperCase -> 'HEUTE IST SONNTAG' (konvertiert die Zeichenkette in Großbuchstaben)

  • c) Zeichenkette umkehren

    'Hallo hier bin ich' reversed -> 'hci nib reih ollaH' (kehrt die Reihenfolge der Zeichen in der Zeichenkette um)

  • d) Array umkehren

    #(4 'five' 6 7) reversed -> #(7 6 'five' 4) (kehrt die Reihenfolge der Elemente im Array um)

  • e) ASCII-Wert eines Zeichens

    $A asciiValue -> 65 (konvertiert das Zeichen in seinen entsprechenden ASCII-Wert)

  • f) Zeichen aus ASCII-Wert

    65 asCharacter -> $A (konvertiert den Wert 65 in das entsprechende ASCII-Zeichen)

  • g) Länge einer Zeichenkette

    'Die die Länge dieser Satz?' size -> 26 (gibt die Länge der Zeichenkette zurück)

3. Binäre Nachrichten berechnen

  • a) Objekte verketten

    'Hallo', ' Hier bin ich' -> 'Hallo Hier bin ich' (verkettet Objekte)

  • b) Arrays verketten

    #(1 2 3), #(4 5 6) -> #(1 2 3 4 5 6) (verkettet die Elemente zweier Arrays zu einem neuen Array)

  • c) Gleichheitsprüfung

    4 = 5 -> false (prüft die Gleichheit von Objekten)

  • d) Arrays verketten (gemischt)

    #(1 2 $a), #($b 'cd') -> #(1 2 $a $b 'cd') (verkettet die Elemente zweier Arrays zu einem neuen Array)

4. Schlüsselwort-Nachrichten auswerten

  • a) Zeichen an Position

    'Das ist ein Test' at: 3 -> $s (zeigt an, was sich an Position 3 befindet)

  • b) Zeichenkette enthält

    'Hallo' includes: $o -> true (prüft, ob das Objekt den übergebenen Parameter enthält)

  • c) Zeichen an Position ändern

    'Hallo' at: 1 put: $H -> 'Hallo' (ändert das Zeichen an der angegebenen Position)

  • d) Teilzeichenkette kopieren

    'Paradigmen der Programmierung' copyFrom: 4 to: 9 -> 'digmen' (kopiert einen Teil der Zeichenkette von Position 4 bis 9)

  • e) Array-Element an Position

    #(9 8 7 6 5) at: 3 -> 7 (gibt an, was sich an Position 3 befindet)

  • f) Array enthält

    #(1 #(2 3) 4 5) includes: #(2 3) -> true (prüft, ob das Objekt den übergebenen Parameter enthält, gibt true oder false zurück)

  • g) Array-Elemente kopieren

    #(9 8 7 6 5) copyFrom: 1 to: 2 -> #(9 8) (kopiert die Elemente 1 und 2 des Arrays)

  • h) Neues Array instanziieren

    Array new: 10 -> #(nil nil nil nil nil nil nil nil nil nil) (instanziiert ein neues Array mit 10 Positionen)

5. Verschachtelte Nachrichten auswerten

  • a) Größe und Addition

    'Hallo' size + 4 -> 9 (wertet zuerst die Größe der Zeichenkette 'Hallo' (5) aus und addiert dann 4 zum Ergebnis (5+4=9))

  • b) Mehrere Größen und Summe

    'jetzt' size + #(1 2 3 4) size -> 9 (wertet zuerst die Größe von 'jetzt' (5) aus, dann die Größe von #(1 2 3 4) (4) und schließlich die Summe (5+4=9))

  • c) Array enthält Fakultät

    #(1 12 24 36) includes: 4 factorial -> true (prüft, ob die Fakultät von 4 (24) im Array enthalten ist)

  • d) Arithmetische Reihenfolge

    3 + 4 * 2 -> 14 (berechnet (3 + 4) * 2 = 14, da binäre Nachrichten in Smalltalk von links nach rechts ausgewertet werden)

  • e) Klammern in Arithmetik

    3 + (4 * 2) -> 11 (wertet zuerst den Ausdruck in Klammern aus (4 * 2 = 8) und addiert dann das Ergebnis (3 + 8 = 11))

  • f) Zwischenprüfung mit Ausdrücken

    4 factorial between: (3 + 4) and: ('Hallo' size * 7) -> true (prüft, ob die Fakultät von 4 (24) zwischen 7 und 35 liegt. (3+4=7, 'Hallo' size * 7 = 5 * 7 = 35))

  • g) Verschachtelte Array- und Zeichenkettenzugriffe

    'Hallo' at: (#(5 3 1) at: 2) -> $l (bei Klammern wird von innen nach außen ausgewertet: zuerst wird das Element an Position 2 des Arrays (#(5 3 1)) ermittelt (3), dann wird das Zeichen an Position 3 der Zeichenkette 'Hallo' ermittelt ($l))

  • h) Summe als Zeichenkette

    (6 + 9) asString -> '15' (berechnet die Summe und konvertiert das Ergebnis in eine Zeichenkette)

  • i) Array mit Elementen instanziieren

    Array with: 1 with: 'Hallo' with: (1 / 3) -> #(1 'Hallo' (1/3)) (instanziiert ein neues Array mit den übergebenen Elementen)

6. Globale Variablen auswerten

  • a) Bildschirmobjekt

    Display (repräsentiert den Bildschirm)

  • b) Transkript-Objekt

    MDITranscript (repräsentiert das MDI-Transkript)

  • c) Nullwert

    nil (repräsentiert den Nullwert)

  • d) Verzeichnis auf Disk

    Disk 'C:\STEXPRES\' (repräsentiert ein Verzeichnis auf Laufwerk C)

  • e) Distanz-Variable (nil)

    Distance nil (repräsentiert einen Nullwert für Distanz)

  • f) Distanz-Variable (Zuweisung)

    Distance := 15 -> 15 (weist der Variablen 'Distance' den Wert 15 zu)

7. Objekte vergleichen und Fehler anzeigen

  • a) Kleiner als

    3 < 4 -> true (prüft, ob Objekt 3 kleiner ist als Objekt 4)

  • b) Array-Gleichheit

    #(1 2 3 4) = #(1 2 3 4) -> true (vergleicht, ob die Elemente der Arrays gleich sind)

  • c) Lexikographischer Vergleich

    'Hallo' <= 'Auf Wiedersehen' -> false (vergleicht Zeichenkette mit Zeichenkette; 'Hallo' ist lexikographisch größer als 'Auf Wiedersehen')

  • d) Ungültiger Vergleich

    5 = 2 + 3 (Dies kann nicht direkt ausgewertet werden, da zuerst die Summe berechnet werden muss, bevor der Vergleich erfolgt. In Smalltalk: 5 = (2 + 3) wäre true)

  • e) Gültiger Vergleich mit Klammern

    5 = (2 + 3) -> true (wertet zuerst die Summe aus und vergleicht dann die Gleichheit beider Seiten)

8. Code-Blöcke auswerten

(Denken Sie daran, dass ein Block Argumente entgegennehmen kann)

  • a) Vokalprüfung ($a)

    [$a isVowel] value -> true (prüft, ob das Zeichen ein Vokal ist)

  • b) Vokalprüfung ($b)

    [$b isVowel] value -> false (prüft, ob das Zeichen ein Vokal ist)

  • c) Block mit mehreren Ausdrücken

    [3 + 4. 'Hallo' asUpperCase] value -> 'HALLO' (berechnet die Summe von 3 und 4 und konvertiert dann die Zeichenkette 'Hallo' in Großbuchstaben. Der Wert des Blocks ist der Wert des letzten Ausdrucks.)

  • d) Block-Zuweisung und Auswertung (ohne Argumente)

    | block |
    block := ['Hallo', ' how are you?'].
    ^ block value -> 'Hallo how are you?'
    

    (Zuerst wird die Variable block definiert, dann wird ihr ein Block zugewiesen, und schließlich wird der Wert des Blocks ausgewertet.)

  • e) Block mit Argument (Vokalprüfung)

    [:c | c isVowel] value: $a -> true (definiert eine lokale Variable c in einem Block, prüft, ob c ein Vokal ist, und wertet den Block mit $a aus)

  • f) Block mit Argument (Vokalprüfung)

    [:c | c isVowel] value: $b -> false (definiert eine lokale Variable c in einem Block, prüft, ob c ein Vokal ist, und wertet den Block mit $b aus)

  • g) Block mit mehreren Argumenten

    | block resp |
    block := [:a :b | a, b].
    resp := block value: 'Hallo' value: ' how are you?'.
    ^ resp -> 'Hallo how are you?'
    

    (Definiert zwei lokale Variablen: block und resp. block wird ein Block zugewiesen, der zwei Argumente verkettet. resp wird das Ergebnis der Auswertung des Blocks mit 'Hallo' und ' how are you?' zugewiesen. Schließlich wird resp zurückgegeben.)

9. Boolesche Ausdrücke

  • a) ODER-Verknüpfung

    5 < 2 or: [$a isVowel] -> true (vergleicht, ob 5 kleiner als 2 ist, ODER ob das Zeichen ein Vokal ist. Da $a ein Vokal ist, ist das Ergebnis true.)

  • b) Kleiner als

    5 < 2 -> false (prüft, ob 5 kleiner als 2 ist)

  • c) NICHT-Verknüpfung

    (5 < 2) not -> true (prüft, ob 5 kleiner als 2 ist, und negiert das Ergebnis. Da false negiert wird, ist das Ergebnis true.)

  • d) UND-Verknüpfung

    5 < 2 and: [$a isVowel] -> false (vergleicht, ob 5 kleiner als 2 ist, UND ob das Zeichen ein Vokal ist. Da die erste Bedingung false ist, ist das Ergebnis false.)

  • e) UND-NICHT-Verknüpfung

    (5 < 2) not and: [$a isVowel] -> true (vergleicht, ob 5 NICHT kleiner als 2 ist, UND ob das Zeichen ein Vokal ist. Da beide Bedingungen true sind, ist das Ergebnis true.)

  • f) Komplexe Boolesche Verknüpfung

    (5 < 2) or: ['Hallo' size < 2 and: [$a isVowel]] not -> true (vergleicht, ob 5 kleiner als 2 ist, ODER ob die Zeichenkette 'Hallo' NICHT kleiner als 2 ist UND das Zeichen ein Vokal ist. Das Ergebnis ist true.)

10. Klasse eines Objekts bestimmen

  • a) Array-Klasse

    #('Jackie' 'Marisa' 'Francesca' 'Bree') class -> Array

  • b) String-Klasse

    'Vijay Rakesh Charles Daniel Tyler' class -> String

  • c) SmallInteger-Klasse

    5 class -> SmallInteger

  • d) Bruch-Klasse

    (1 / 2) class -> Fraction

  • e) Float-Klasse

    5.2 class -> Float

11. Kaskadierende Nachrichten

Kaskadierende Nachrichten senden mehrere Nachrichten an dasselbe Objekt. Prüfen Sie diese beiden Ausdrücke und erklären Sie den Unterschied:

  • a) Kaskadierung

    3 factorial; factorial; factorial -> 6 (berechnet die Fakultät von 3 (6). Bei kaskadierenden Nachrichten werden alle Nachrichten an dasselbe Objekt gesendet, und das Ergebnis der Kaskade ist das Ergebnis der ersten Nachricht.)

  • b) Nachrichtenverkettung

    3 factorial factorial factorial -> (eine sehr große Zahl) (berechnet die Fakultät von 3 (6), dann die Fakultät dieses Ergebnisses (6! = 720), und dann die Fakultät dieses Ergebnisses (720! = sehr große Zahl). Hier wird das Ergebnis jeder Nachricht zum Empfänger der nächsten Nachricht.)

12. Der Smalltalk-Inspektor

Smalltalk hat ein Fenster namens Inspektor, mit dem Sie die Instanzvariablen eines Objekts anzeigen und ändern können. Werten Sie diesen Code aus und beschreiben Sie, was Sie beobachten würden:

  • a) Array im Inspektor ändern

    | a |
    a := #(1 2 'Sam' 'Joe' #(4 5)).
    a at: 2 put: (3 / 4).
    a inspect -> #(1 (3/4) 'Sam' 'Joe' #(4 5))
    

    (Definiert ein Array a, ändert das Element an Position 2 auf den Bruch 3/4 und öffnet dann den Inspektor für das Array a. Im Inspektor würde man das geänderte Array sehen.)

13. Bedingte Anweisungen

  • a) ifTrue:ifFalse: Beispiel 1

    3 < 4 ifTrue: ['Block true'] ifFalse: ['Block false'] -> 'Block true' (Wenn die Bedingung erfüllt ist, wird der ifTrue:-Block ausgeführt; andernfalls der ifFalse:-Block.)

  • b) ifTrue:ifFalse: Beispiel 2

    (5 > 2) ifTrue: [^ '5 ist größer als 2'] ifFalse: [^ 'false'] -> '5 ist größer als 2' (Wenn die Bedingung erfüllt ist, wird der ifTrue:-Block ausgeführt; andernfalls der ifFalse:-Block.)

  • c) ifTrue:ifFalse: Beispiel 3

    $b isVowel ifTrue: [^ 'ist ein Vokal'] ifFalse: [^ 'ist ein Konsonant'] -> 'ist ein Konsonant' (Wenn das Zeichen ein Vokal ist, wird der ifTrue:-Block ausgeführt; andernfalls der ifFalse:-Block.)

Programmierübungen

Hier sind einige Programmieraufgaben mit Smalltalk-Codebeispielen:

  • 1. Division und Multiplikation

    Führen Sie die Operationen Division (f / g) und Multiplikation (f * g) aus. Die Multiplikation soll mit aufeinanderfolgenden Additionen und die Division (optional) mit Subtraktionen implementiert werden.

    a) Division

    | f g quotient |
    quotient := 0.
    f := (Prompter prompt: 'Geben Sie den Wert für f ein:' default: '0') asInteger.
    g := (Prompter prompt: 'Geben Sie den Wert für g ein:' default: '0') asInteger.
    
    "Hinweis: Die folgende Zeile führt eine direkte Division durch, nicht mit sukzessiven Subtraktionen."
    quotient := f / g.
    
    MessageBox message: ('Das Verhältnis ist: ' , quotient asString).
    Transcript nextPutAll: ('Das Verhältnis ist: ' , quotient asString); cr.
    

    b) Multiplikation

    | f g product |
    product := 0.
    f := (Prompter prompt: 'Geben Sie den Wert für f ein:' default: '0') asInteger.
    g := (Prompter prompt: 'Geben Sie den Wert für g ein:' default: '0') asInteger.
    
    [g > 0] whileTrue: [
        product := product + f.
        g := g - 1.
    ].
    
    MessageBox message: ('Das Produkt ist: ' , product asString).
    Transcript nextPutAll: ('Das Produkt ist: ' , product asString); cr.
    
  • 2. Potenz berechnen (x^y)

    Berechnen Sie x hoch y (x^y).

    | x y z power |
    x := (Prompter prompt: 'Geben Sie die Basis (x) ein:' default: '0') asInteger.
    y := (Prompter prompt: 'Geben Sie den Exponenten (y) ein:' default: '0') asInteger.
    z := y. "Speichert den ursprünglichen Wert von y für die Ausgabe"
    power := 1.
    
    [y > 0] whileTrue: [
        power := power * x.
        y := y - 1.
    ].
    
    MessageBox message: (x asString , '^' , z asString , ' ist ' , power asString).
    
  • 3. Quadratische Gleichung lösen

    Fordern Sie den Benutzer auf, die Koeffizienten einer quadratischen Gleichung einzugeben und berechnen Sie die Nullstellen.

    Beispiel: Quadratische Gleichung: 1x² + 3x + 2, mit Nullstellen x1 = -1 und x2 = -2

    | a b c x1 x2 minusB bSquared discriminant twoA |
    a := (Prompter prompt: 'Geben Sie den ersten Koeffizienten (a) ein:' default: '0') asInteger.
    b := (Prompter prompt: 'Geben Sie den zweiten Koeffizienten (b) ein:' default: '0') asInteger.
    c := (Prompter prompt: 'Geben Sie den dritten Koeffizienten (c) ein:' default: '0') asInteger.
    
    minusB := (-1) * b.
    bSquared := b raisedTo: 2.
    discriminant := bSquared - (4 * a * c).
    
    "Prüfung auf negative Diskriminante für reelle Lösungen"
    discriminant < 0 ifTrue: [
        MessageBox message: 'Keine reellen Lösungen vorhanden (Diskriminante ist negativ).'.
        ^ self. "Beendet die Ausführung"
    ].
    
    discriminant := discriminant raisedTo: (1 / 2). "Wurzel ziehen"
    twoA := 2 * a.
    
    "Prüfung auf Division durch Null"
    twoA = 0 ifTrue: [
        MessageBox message: 'Division durch Null nicht möglich (a darf nicht 0 sein für eine quadratische Gleichung).'.
        ^ self. "Beendet die Ausführung"
    ].
    
    x1 := (minusB + discriminant) / twoA.
    x2 := (minusB - discriminant) / twoA.
    
    MessageBox message: ('Die erste Nullstelle ist: x1 = ' , x1 asString).
    MessageBox message: ('Die zweite Nullstelle ist: x2 = ' , x2 asString).
    
  • 4. Primzahlprüfung

    Fordern Sie den Benutzer auf, eine Zahl einzugeben und prüfen Sie, ob es sich um eine Primzahl handelt.

    | number count |
    number := (Prompter prompt: 'Geben Sie eine Zahl ein:' default: '0') asInteger.
    
    "Spezialfälle für 0, 1 und negative Zahlen"
    number <= 1 ifTrue: [
        MessageBox message: (number asString , ' ist keine Primzahl.').
        ^ self.
    ].
    
    count := 0.
    "Prüfe Teiler von 1 bis zur Zahl selbst"
    1 to: number do: [:i |
        (number \\ i = 0) ifTrue: [
            count := count + 1.
        ].
    ].
    
    (count = 2)
        ifTrue: [MessageBox message: (number asString , ' ist eine Primzahl.')]
        ifFalse: [MessageBox message: (number asString , ' ist keine Primzahl.')].
    
  • 5. Gerade oder Ungerade Zahl

    Fordern Sie den Benutzer auf, eine Zahl einzugeben und geben Sie an, ob sie gerade oder ungerade ist.

    | number |
    number := (Prompter prompt: 'Geben Sie eine Zahl ein:' default: '0') asInteger.
    
    (number \\ 2 = 0)
        ifTrue: [MessageBox message: (number asString , ' ist eine gerade Zahl.')]
        ifFalse: [MessageBox message: (number asString , ' ist eine ungerade Zahl.')].
    
  • 6. Vielfache zählen (2, 3, 5, 7)

    Schreiben Sie ein Programm, das eine Liste von Zahlen entgegennimmt und die Anzahl der Vielfachen von 2, 3, 5 und 7 berichtet.

    | number continue multiplesOf2 multiplesOf3 multiplesOf5 multiplesOf7 resultCounts |
    multiplesOf2 := 0.
    multiplesOf3 := 0.
    multiplesOf5 := 0.
    multiplesOf7 := 0.
    continue := 'yes'. "Initialisiere mit 'yes', um die Schleife zu starten"
    
    [continue = 'yes'] whileTrue: [
        number := (Prompter prompt: 'Geben Sie eine Zahl ein (oder 0 zum Beenden):' default: '0') asInteger.
    
        "Optional: Beenden, wenn 0 eingegeben wird"
        number = 0 ifTrue: [continue := 'no'. ^ self].
    
        (number \\ 2 = 0) ifTrue: [multiplesOf2 := multiplesOf2 + 1].
        (number \\ 3 = 0) ifTrue: [multiplesOf3 := multiplesOf3 + 1].
        (number \\ 5 = 0) ifTrue: [multiplesOf5 := multiplesOf5 + 1].
        (number \\ 7 = 0) ifTrue: [multiplesOf7 := multiplesOf7 + 1].
    
        continue := (Prompter prompt: 'Möchten Sie fortfahren? (yes/no)' default: 'yes') asString.
    ].
    
    resultCounts := Array with: multiplesOf2 with: multiplesOf3 with: multiplesOf5 with: multiplesOf7.
    MessageBox message: ('Anzahl der Vielfachen: ' , resultCounts asString).
    Transcript nextPutAll: ('Anzahl der Vielfachen von 2, 3, 5, 7: ' , resultCounts asString); cr.
    
  • 7. Perfekte Zahl prüfen

    Eine positive ganze Zahl ist perfekt, wenn sie die Summe aller ihrer Teiler (außer sich selbst) ist. Schreiben Sie eine Methode, um zu prüfen, ob eine Zahl perfekt ist.

    | number sumOfDivisors |
    number := (Prompter prompt: 'Geben Sie eine Zahl ein:' default: '0') asInteger.
    
    "Eine perfekte Zahl ist eine positive ganze Zahl"
    number <= 0 ifTrue: [
        MessageBox message: (number asString , ' ist keine positive ganze Zahl.').
        ^ self.
    ].
    
    sumOfDivisors := 0.
    "Finde alle Teiler außer der Zahl selbst"
    1 to: (number - 1) do: [:i |
        (number \\ i = 0) ifTrue: [
            sumOfDivisors := sumOfDivisors + i.
        ].
    ].
    
    (number = sumOfDivisors)
        ifTrue: [MessageBox message: (number asString , ' ist eine perfekte Zahl.')]
        ifFalse: [MessageBox message: (number asString , ' ist keine perfekte Zahl.')].
    
  • 8. Groß-/Kleinschreibung umkehren

    Bei einer Zeichenkette, geben Sie eine neue Zeichenkette zurück, in der Großbuchstaben durch Kleinbuchstaben und umgekehrt ersetzt wurden.

    | inputString resultString |
    inputString := (Prompter prompt: 'Geben Sie eine Zeichenkette ein:' default: 'Hallo').
    
    inputString isNil ifTrue: [^ nil].
    
    resultString := WriteStream on: (String new: inputString size).
    
    inputString do: [:char |
        char isLowercase
            ifTrue: [resultString nextPut: char asUppercase]
            ifFalse: [
                char isUppercase
                    ifTrue: [resultString nextPut: char asLowercase]
                    ifFalse: [resultString nextPut: char]. "Nicht-alphabetische Zeichen unverändert lassen"
            ].
    ].
    
    MessageBox message: ('Original: ' , inputString , ' -> Geändert: ' , resultString contents).
    ^ resultString contents.
    

Verwandte Einträge: