Gambas: Funktionen

Aus Wikibooks


Zurück[Bearbeiten]

Gambas


Allgemeines[Bearbeiten]

Funktionen sind Unterprogramme, die einen Wert ( Zahl, Text etc) an das Hauptprogramm zurückgeben.

Umgekehrt wird oft ein Wert vom Hauptprogramm an die Funktion übergeben, dort wird der Wert verarbeitet und das Ergebnis wiederzurückgegeben.

Funktionen sind am Anfang gewöhnungsbedürftig. Beim effektiven Gebrauch einer Programmiersprache sind sie aber irgendwann unverzichtbar, da sie die Programmerstellung erleichtern und die Programme verkürzen, wenn ein Programmteil öfter durchlaufen werden muss. Fast alle abgeleiteten Befehle einer Programmiersprache haben sich aus Funktionen entwickelt. Prozeduren sind mit den Funktionen verwandt, nur geben Sie keinen Wert zurück.

Ein ganz einfaches Beispiel[Bearbeiten]

Sie definieren eine Funktion Add die 2 Zahlen zusammenzählt.

Die 2 Zahlen , die addiert werden sollen, werden dabei einfach in der Klammer hinter dem Funktionsnamen angegeben.

Sie brauchen für das Beispiel:

  • Eine Form
  • Einen Commandbutton

Der Code lautet:

'Hauptprogramm
PUBLIC SUB Button1_Click()
 Message.Info(Add(6,10))
 'Funktionsaufruf und Rückgabe des Wertes
END
'Funktion als Unterprogramm
PUBLIC FUNCTION Add(a AS Integer, b AS Integer) AS Integer
    RETURN a + b
END 

Diese Funktion ist von den Werten a und b abhängig. Die Werte a und b können beliebig gewählt werden.

Beispiele von Funktionen:[Bearbeiten]

  • Time ( Die Systemzeit wird zurückgegeben)
  • Date ( Das Datum wird zurückgegeben)
  • Quadratwurzel ( Eine Zahl wird eingegeben , die Quadratwurzel kommt zurück) a*a wird zu sqr(a)
  • VGA Farbe in RGB umwandeln ( Eine der 16 VGA Farben wird eingegeben, der RGB-Wert kommt zurück)

Beispiel TIME: ( in die Funktion geht kein Parameter ein , es kommt trotzdem ein Wert zurück)[Bearbeiten]

Ein gutes Beispiel für eine einfache Funktion ist der Befehl Time ( = Zeit). Diese Funktion liefert die aktuelle Systemzeit. Sie können diese Funktion mit folgendem Befehl testen:

Print Time

Das folgende kleine Programm ohne Grafik gibt die Zeit im Direktfenster aus:

STATIC PUBLIC SUB Main()
 PRINT Time
END

Wenn Sie die Zeit immer wieder aktualisiert haben wollen, müssen Sie eine Endlosschleife einbauen. Das Programm schaut dann so aus:

STATIC PUBLIC SUB Main()
DIM i AS Integer
i = 1 
DO WHILE i <= 10 
 PRINT Time
LOOP
END

Ein ähnliches Beispiel für die Grafikausgabe aktualisiert die Zeitausgabe immer wieder. Dazu nutzt man den Timer, das Zeitgeber-Steuerelement. Dieser hat zunächst mit der aktuellen Zeit nichts zu tun, sondern löst ein Ereignis nach einer bestimmten Zeit aus.

Das folgende kleine Beispielprogramm kombiniert den Timer und die Timefunktion zu einer ständig aktualisierten Zeitangabe, wie sie diese auch rechts unten an ihrem PC finden.

Starten Sie ein neues Projekt. Nennen Sie es Zeitausgabe. Platzieren Sie anschließend eine Textbox auf Ihrer Form. Außerdem brauchen Sie das Zeitgebersteuerelement mit dem Uhrsymbol. Holen Sie sich beides mit F6 und einem Doppelclick auf das Symbol aus der Werkzeugkiste. Achten Sie darauf, dass der Zeitgeber mit der Enabled Eigenschaft erst angeschaltet werden muß. Dies können Sie bei den Eigenschaften des Timers zur Entwurfszeit einstellen oder Sie können es auch im Programmcode mit der Zeile

timer1.Enabled = TRUE

erreichen.


PUBLIC SUB Timer1_Timer()
timer1.Enabled = TRUE
textbox1.Text = Time
END

Das Programm zeigt in der Textbox die aktuelle Zeit an. Diese wird jede Sekunde ( = 1000 millisekunden ) aktualisiert.

Beispiel UCASE : ( in die Funktion geht ein Parameter ein und es kommt ein umgewandelter Wert zurück)[Bearbeiten]

Die Funktion UCase ( = Großschreibung) ist eine einfache Funktion, die nur die Übergabe eines Strings benötigt. Um so etwas ( Variablen, Konstanten oder Strings ) zu übergeben, müssen diese in Klammern eingeschlossen werden und nach dem Funktionsnamen stehen.

Erstellen Sie eine Form mit einer Textbox und einem Commandbutton. Schreiben Sie für den Commandbutton folgenden Code:

PUBLIC SUB Button1_Click()
 Textbox1.Text = UCase(Textbox1.text)
END

Starten Sie das Programm, tippen Sie beliebigen Text in das Textfeld und clicken Sie auf den Befehlsbutton. Als Ergebnis steht der Text in Großbuchstaben in der Textbox.

Folgender Code funktioniert erstaunlichwerweise nicht:

PUBLIC SUB TextBox1_KeyRelease()
IF Key.return THEN UCase(Textbox1.text)
END

Der Text wird in der Version 0.99 nicht groß geschrieben.

Obwohl folgender Code für die KeyReleasemethode funktioniert. Meines Erachtens liegt hier noch ein Programmfehler vor.

PUBLIC SUB TextBox1_KeyRelease()
IF Key.return THEN textbox1.visible = FALSE
END

Die Textbox wird unsichtbar.

Wenn Sie die Funktionen UCase und LCase ( = Kleinschreibung) noch einmal zusammen in einem einfachen Programm anschauen wollen, dann probieren Sie folgenden Code ohne Grafik:

STATIC PUBLIC SUB Main()
DIM a AS String 
a = "Test"
PRINT a
PRINT LCase(a)
PRINT UCase(a)
END

( Siehe dazu im Abschnitt Erste Schritte , Drittes Programm: Programme im Terminalfenster ohne Grafik )

Beispiel 3: (mehrere Parameter)[Bearbeiten]

Werden mehrere Werte übergeben , dann müssen sie in der Klammer nach dem Funktionsnamen durch Kommata voneinander getrennt werden.

In Beispiel 2 gab die Funktion unterschiedlichen Text zurück, abhängig von der Zeichenkette, die ihr übergeben wurde. Andere Funktionen benötigen zusätzliche Parameter, um ihr zu sagen, wie sie diese Parameter handhaben soll. Zum Beispiel übernimmt die Funktion Mid$ ( = Text aus der Mitte herausschneiden)

  • einen Parameter für den benutzen Text,
  • einen Parameter um den Startpunkt zu fixieren (gemessen in Zeichenanzahl),
  • und dann einen dritten und optionellen Parameter um festzulegen, wieviele Zeichen zurückgegeben werden sollen.

Im folgenden Beispiel werden alle Möglichkeiten der Stringbearbeitung = Zeichenfolgenmanipulation die Gambas kennt, zusammgefasst. Auch die Funktion Mid$ ist dabei. Sie brauchen nur eine leer Form um das Programm in Gang zu bringen.

PUBLIC SUB Form_Open()
DIM Wort$ AS String
Wort$ = "Kleinstaatengrenze"
PRINT Len(Wort$)
PRINT Left$(Wort$,7) 
PRINT Right$(Wort$,6)
PRINT Mid$(Wort$,3,5)
PRINT Mid$(Wort$,6)
PRINT Instr(Wort$,"eng")
PRINT Instr(Wort$,"Tomate")
PRINT Instr(Wort$,"eng", 12)
PRINT Instr(Wort$,"e",11)
END

Ergebnis

  • 18 ( Länge des Wortes )
  • Kleinst ( Die 7 ersten Buchstaben )
  • grenze ( Die 6 letzten Buchstaben )
  • einst ( 5 mittlere Buchstaben beginnend beim 3.)
  • staatengrenze ( Buchstaben beginnend ab dem 6. Buchstaben )
  • 11 ( "eng" steht an der 11.Position im Wort )
  • 0 ( Tomate findet sich nicht )
  • 0 ( eng findet er nicht, wenn erst ab der 12.Position gesucht werden soll )
  • 11 ( "e" findet er an 11.Position , wenn erst ab der 11.Position gesucht werden soll.)

ACHTUNG: In VB kann man den Befehl Mid$() nutzen um eine Buchstabenfolge aus einem Text herauszuschneiden und dafür einen anderen Text einzusetzen. Das geht in Gambas nicht.

Beispiel:

rem VB: 
MyString = "Der Hund springt"
Mid$(MyString, 5, 4) = "Ball"

Ergebnis MyString = "The fox jumps".

In Gambas geht das nicht, Dafür kann man folgendes machen:

MyString = "Der Hund springt"
MyString = Left$(MyString, 4) & "Ball" & Mid$(MyString, 9)

Ein komplettes Programm dazu ( ohne Grafik) schaut so aus:

STATIC PUBLIC SUB Main()
DIM MyString AS String
MyString = "Der Hund springt"
PRINT MyString
'in VB moeglich: Mid$(MyString, 5, 4) = "Ball" in Gambas nicht 
MyString = Left$(MyString, 4) & "Ball" & Mid$(MyString, 9)
PRINT MyString
END

Befehle zur Stringbearbeitung = Zeichenfolgenmanipulation[Bearbeiten]

& Zusammenkleben von Strings
InStr() Man bekommt die Position eines Zeichens oder Substrings zurück
left() Substrings von Links beginnend abtrennen
like Vergleich von 2 Strings oder Substrings
LTrim() Wegschneiden von Leerzeichen am Beginn eines Strings
mid() Schneidet einen Substring aus der Mitte heraus
right() Substrings von Rechts beginnend abtrennen
RTrim() Wegschneiden von Leerzeichen am Ende eines Strings
split() Aufteilung eines Strings in einzelne Wörter
Trim() Wegschneiden von Leerzeichen am Beginn und am Ende eines Strings
CStr() Einen Ausdruck in einen String umwandeln.
Str() Einen Ausdruck in einen String umwandeln. (Umkehrfunktion oder Gegenteil von val())
val() Verwandelt einen String in eine Zahl, eine Fließkommazahl oder sonst etwas.

Funktionen selber programmieren[Bearbeiten]

Richtig versteht man Funktionen erst, wenn man sie selbst programmiert hat. Dann erkennt man auch Ihre praktische Bedeutung. Man kann Sie nämlich meist völlig unverändert in andere Programme übernehmen.

Hoch3[Bearbeiten]

Im Folgenden soll eine Funktion programmiert, werden die eine Zahl hoch 3 nimmt. Dazu starten Sie ein neues grafisches Gambasprojekt: Auf der Form plazieren Sie 2 Textboxen und einen Befehlsbutton. Die Textboxen befreien Sie mittels Eigenschaftsfenster F4 von ihrem Text. Beim Commandbutton geben Sie folgenden Code ein:

PUBLIC SUB Button1_Click()
DIM b AS Integer
b = Val(Textbox1.text)
textbox2.Text = Cstr(Hoch(b))
END
'-Hier fängt die Funktion an ------------------------------------
PUBLIC FUNCTION Hoch(a AS Integer ) AS Integer 
a = a^3
RETURN a
END

Vergessen Sie nicht den Return Befehl in Ihrer Funktion. Sonst bekommen Sie nichts zurück geliefert.

Die Programmierung von Funktionen in Gambas unterscheidet sich etwas von der Programmierung in VB. In Gambas kann man den Funktionsnamen in der Funktion nicht aufrufen, in VB ist das möglich.

Dritte Wurzel ( hoch 1/3 )[Bearbeiten]

Im Folgenden soll eine Funktion programmiert werden, die aus einer Zahl die dritte Wurzel zieht . Dazu starten Sie ein neues grafisches Gambasprojekt: Auf der Form plazieren Sie 2 Textboxen und einen Befehlsbutton. Die Textboxen befreien Sie mittels Eigenschaftsfenster F4 von ihrem Text. Beim Commandbutton geben Sie folgenden Code ein:

PUBLIC SUB Button1_Click()
DIM b AS Integer
b = Val(Textbox1.text)
textbox2.Text = Cstr(wurzel(b))
END
'-Hier fängt die Funktion an -
PUBLIC FUNCTION wurzel(a AS Float ) AS Float
a = a^(1/3)
RETURN a
END

Wenn Sie jetzt in die Textbox eine positive Zahl eingeben und auf den Befehlsbutton clicken, wird aus ihr die dritte Wurzel errechnet.

Warum wurde hier die Funktionsvariable als float-Zahl definiert. Probieren Sie dasselbe mit einer Integervariablen aus. Vergessen Sie nicht den Return Befehl in Ihrer Funktion. Sonst bekommen Sie nichts zurück geliefert.

Texte Zusammenkleben mit einer Funktion[Bearbeiten]

Das nächste Beispiel Programm zeigt Ihnen den Aufruf einer Funktion zum Kleben zwei Textteile.

Sie brauchen eine Textbox und 2 Befehlsbuttons, um das Programm in Gang zu bekommen.

' Gambas class file
PUBLIC SUB Button1_Click()
 DIM b AS String
 Textbox1.Text = wort(b) & "Franz"
END
'------------
PUBLIC SUB Button2_Click()
 Textbox1.Text = wort & "Fritz"
 'Dieser Aufruf der Funktion ergibt eine Fehlermeldung, da der erwartete Parameter nicht mitübergeben wurde.
END
'--------------------
PUBLIC FUNCTION wort ( a AS String) AS String
 a = "Hallo "
 RETURN a
END 

Wenn Sie auf den Button 1 Clicken wird die Funktion korrekt aufgerufen. Wenn Sie auf den Button 2 Clicken ergibt sich eine Fehlermeldung. Verstehen Sie auch warum ?. Wie könnte man den Code der Funktion umändern , so dass der Code unter dem Button 2 auch korrekt abläuft ?

Lösung:

' Gambas class file
PUBLIC SUB Button1_Click()
 DIM b AS String
 Textbox1.Text = wort(b) & "Franz"
END
PUBLIC SUB Button2_Click()
 Textbox1.Text = worte() & "Fritz"
END
PUBLIC FUNCTION wort ( a AS String) AS String
 a = "Hallo "
 RETURN a
END 
PUBLIC FUNCTION worte() AS String
 a AS String
 a = "Hallo "
 RETURN a
END

Fakultaet[Bearbeiten]

Im folgenden Beispiel soll die Fakultät einer Zahl berechnet werden.

Die Fakultät zu einer Zahl (mathematische Darstellung: "n!", wird gesprochen: "n Fakultät") ist das Produkt der natürlichen, d.h. ganzzahlig, positiven Zahlen von 1 bis n.

Symbol:  ! = Ausrufezeichen

Es gilt:

  • 0! = 1
  • 1! = 1
  • 2! = 1*2 = 2
  • 3! = 1*2*3 = 6
  • 4! = 1*2*3*4 = 24
  • 5! = 1*2*3*4*5 = 120
  • 6! = 1*2*3*4*5*6 = 720
  • .......
  • n! = n * (n - 1)!

Die höchste Zahl, deren Fakultät sich in Gambas Basic ohne Kunstgriffe zur Emulation eines größeren Wertebereichs berechnen lässt, ist 170. Bei dem Programm unten ist 13 die Obergrenze Sie brauchen für das Programm einen Befehlsknopf = Commandbutton und zwei Textboxen.

' Gambas class file
PUBLIC SUB Button1_Click()
 DIM a AS Integer
 a = Val(textbox1.text)
 ' textbox2.Text = Fakultaet(Val(textbox1.text))
 textbox2.Text = Fakultaet(a) 
END
'---Hier beginnt die Funktion ---------------------------------------
FUNCTION Fakultaet(F AS Integer) AS Integer
DIM k AS Integer
DIM z AS Integer
IF F = 0 THEN F = 1 
z = F - 1
FOR k = 1 TO z
 F = F*k
NEXT
RETURN F
END

Binominalkoeffizient[Bearbeiten]

Will man eine Summe potenzieren, dann kann man dazu gut den Binominalkoeffizienten gebrauchen .

Beispiel:

(a+b)^2 = 1*a^2 + 2*a*b + 1*b^2
(a+b)^3 = 1*a^3 + 3*a^2*b + 3*a*b^2 + 1*b^3
(a+b)^4 = 1*a^4 + 4*a^3*b + 6*a^2*b^2 + 4*a*b^3 + 1*b^4

Die Zahlen vor den verschiedenen a-und-b Gliedern werden Koeffizienten genannt und gehorchen den Regeln des Pascalschen Dreiecks. Siehe http://www.madeasy.de/2/pascal.htm

Die Regel des Dreiecks ist einfach: jede Zahl (außer der 1 am Rand) erhält man durch Addition der beiden Zahlen, die über ihr liegen (siehe Beispiel).


| Bild

Man kann die Zahlen aber auch mit der Formel für den Binominalkoeffizienten ausrechnen:

| Bild

Auch in der Statistik und Kombinatorik findet man immer wieder diese Formel, deswegen soll sie im folgenden programmiert werden.

Schreiben wir die Formel zunächst von der obigen grafischen Darstellung in eine Textdarstellung um:

N-ueber-k = N! / k! / (N-k)! 
wobei N! = 1*2*3*4*.....*(N-1)*N = N Fakultät

Dabei muss immer gelten N > 0 und k > 0 und N > k oder N = k .

Zu Eingabe und Ausgabe der Werte brauchen Sie 3 Textboxen und zum Starten der Berechnung einen Befehlsbutton. Das ganze schaut dann so aus:

Will man die Formel programmieren, kann man das ohne Funktionsaufruf tun, dies zeigt der der folgende Programmcode:

' Gambas class file
PUBLIC SUB Button1_Click()
DIM N AS Integer
DIM k AS Integer
DIM F AS Integer
DIM x AS Integer
DIM nf AS Integer ' N Fakultät
DIM nmk AS Integer ' n minus k Fakultät
DIM kf AS Integer ' k Fakultät
DIM nuk AS Integer 
N = Val(textbox1.text) 
k = Val(textbox2.text) 
F = 1 
FOR x = 1 TO N 
 F = F * x 
NEXT 
nf = F 
F = 1 
FOR x = 1 TO k 
 F = F * x 
NEXT 
kf = F 
F = 1 
FOR x = 1 TO (n- k) 
 F = F * x 
NEXT 
nmk = F 
nuk = nf / nmk / kf 
textbox3.Text = nuk
END

Probieren Sie jetzt einmal die Werte für (a+b)^4 aus . Dabei ist N = 4 und k steigt von 0 bis 4 an . Setzen Sie diese Werte 4 und 0, 4 und 1, 4 und 2 , 4 und 3, 4 und 4 in Ihr Programm ein und Sie erhalten die Koeffizienten der Binomischen Gleichung und der entsprechenden Zeile im Pascalschen Dreieck.

Eleganter funktioniert die Programmierung , wenn man die Fakultätsberechnung einer Funktion übergibt.

Pascalsche Dreieck[Bearbeiten]

Wenn man den Binominalkoeffizienten n über k auch einer Funktion anvertraut , kann man in einer Doppelschleife alle Werte des Pascalschen Dreiecks beispielsweise von Zeile 1 bis Zeile 20 berechnen.

Da die Ausgabe in einer grafischen Form schwierig ist, kann man es im Terminalmodus programmieren:

Das Programm schaut so aus

For Zeile = 1 to Zeile = 12
	Berechne N ueber K 
       wobei N = Zeile und k von 0 bis N wächst 
       Ausgabe als Print zeilenweise getrennt durch Kommas
Next Zeile 

Verfeinern wird das Programm in der inneren Schleife

For Zeile = 1 to Zeile = 20
  For K = 0 To N = zeile 
	Berechne N ueber K 
       Print N ueber k;
  Next k 
Print ' fuegt einen Zeilenvorschub ein 
Next Zeile 

Das komplette Programm schaut dann so aus :

' Gambas class file
STATIC PUBLIC SUB Main()
 DIM Zeile AS Integer
 DIM N AS Integer
 DIM k AS Integer
 DIM F AS Integer
 DIM x AS Integer
 DIM nf AS Integer ' N Fakultät
 DIM nmk AS Integer ' n minus k Fakultät
 DIM kf AS Integer ' k Fakultät
 DIM nuk AS Integer 
 FOR Zeile = 1 TO 12
  N = Zeile
   FOR k = 0 TO N
    F = 1 
    FOR x = 1 TO N 
     F = F * x 
    NEXT 
    nf = F 
    F = 1 
    FOR x = 1 TO k 
     F = F * x 
    NEXT 
    kf = F 
    F = 1 
    FOR x = 1 TO (n- k) 
     F = F * x 
    NEXT 
    nmk = F 
    nuk = nf / nmk / kf 
    PRINT nuk & "  ";
   NEXT
   PRINT
 NEXT
END

Das Ergebnis im Direktfenster schaut so aus.

1  1  
1  2  1  
1  3  3  1  
1  4  6  4  1  
1  5  10  10  5  1  
1  6  15  20  15  6  1  
1  7  21  35  35  21  7  1  
1  8  28  56  70  56  28  8  1  
1  9  36  84  126  126  84  36  9  1  
1  10  45  120  210  252  210  120  45  10  1  
1  11  55  165  330  462  462  330  165  55  11  1  
1  12  66  220  495  792  924  792  495  220  66  12  1 

Ein schiefes , aber doch erkennbares Pascalsches Dreieck.

Man kann das Programm deutlich vereinfachen, wenn man sich n uber k und die Fakultät als Funktion ausrechnen laesst.

Vordefinierte Konstanten[Bearbeiten]

gb.Null Null value
gb.Boolean Boolean value
gb.Byte Byte integer number
gb.Short Short integer number
gb.Integer Integer number
gb.Float Floating point number
gb.Date Date and time value
gb.String Character string
gb.Variant Variant
gb.Object Object reference

Datei Typen[Bearbeiten]

gb.File Regular file
gb.Directory Directory
gb.Device Special file for a device
gb.Pipe Named pipe
gb.Socket Special file for a socket
gb.Link Symbolic link

String Konstanten[Bearbeiten]

gb.NewLine Newline character. Equivalent to Chr$(10)
gb.Tab Tab character. Equivalent to Chr$(9)

Sortierungen[Bearbeiten]

gb.Binary Binary sort
gb.Case Case insensitive sort
gb.Lang Language based sort

Wochentage[Bearbeiten]

gb.Monday Monday
gb.Tuesday Tuesday
gb.Wednesday Wednesday
gb.Thursday Thursday
gb.Friday Friday
gb.Saturday Saturday
gb.Sunday Sunday

Vorgegebene Zahlenformate[Bearbeiten]

gb.GeneralNumber Write a number with twelve decimal digits. Use scientific format if its absolute value is lower than 10-4 or greater than 107.
gb.Fixed Equivalent to "0.00"
gb.Percent Equivalent to "###%"
gb.Scientific Write a number with its exponent and eighteen decimal digits.

Vorgegebene Datums- und Zeitformate[Bearbeiten]

gb.GeneralDate Write a date only if the date and time value has a date part, and write a time only if it has a date part.
gb.LongDate Long date format.
gb.MediumDate Medium date format.
gb.ShortDate Short date format.
gb.LongTime Long time format.
gb.MediumTime Medium time format.
gb.ShortTime Short time format.

Verschiedene Formate[Bearbeiten]

gb.Standard Use gb.GeneralNumber for formatting numbers and gb.GeneralDate for formatting dates and times.