Lange haben wir darauf gewartet - aber pünktlich zum 5-jährigen Jubiläum von vb@rchiv hatte Ralf Ehlert das zweite Kapitel seines eBooks fertig. Und diese Themen erwarten uns:
Und nun viel Spaß beim Lesen. 2. GRUNDLAGEN DER SPRACHE VB.NET In diesem Kapitel lernen Sie die Grundlagen der Sprache Visual Basic .NET. Ich werde versuchen, alles mit einem kleinen Beispiel zu illustrieren. Bevor wir aber mit der Theorie beginnen, wollen wir erst mal ein kleines Beispielprojekt (ein Währungsrechner, der einige Währungen in Euro-Beträge umrechnet; gut erweiterbar) umsetzen. Ich gebe Schritt-für-Schritt-Anleitungen für #Develop, beim VS.NET funktioniert es ähnlich. Die größten Änderungen liegen im Aussehen der IDE und an den Namen der Menübefehle. Der eingegebene Code bleibt gleich. 2.1. Ein erstes Beispiel Schritt 1 Wenn Sie #Develop gestartet haben, klicken Sie auf DATEI|NEU|COMBINE. Es öffnet sich der Dialog NEUES PROJEKT:
Unter NAME tragen Sie den Projektnamen ein, unter VERZEICHNIS können Sie den Pfad ändern, indem das Projekt gespeichert werden soll. Klicken Sie zum Anlegen auf OK. Schritt 2 Bevor der eigentliche Code eingegeben wird, gestaltet man bei Windows-Anwendungen zuerst die Benutzeroberfläche. Klicken Sie dazu zuerst ganz unten auf den Registerreiter DESIGN. Ziehen Sie danach aus TOOLS (Ansicht-Tools) (Registerkarte Windows Forms) 4 Labels, 2 ComboBoxen, einen Button und eine Textbox auf die Form. Das Ergebnis könnte so aussehen:
Schritt 3 Als nächstes setzen wir einige Eigenschaften und passen die Größe der Controls und der Form an. Um Eigenschaften zu ändern, klicken Sie das gewünschte Control an, und ändern Sie den Wert der gewünschten Eigenschaft im Fenster Eigenschaften. Tabelle 2.1 zeigt die Werte für die Eigenschaften:
Tabelle 2.1 - Eigenschaften der Controls Jetzt die Controls noch positionieren und der Entwurf könnte so aussehen:
Bevor wir unser Programm zum ersten Mal starten, müssen wir noch eine Option ändern. Klicken Sie mit der rechten Mautaste im Projektmappenexplorer auf den Projektnamen und wählen Sie Eigenschaften. Wählen Sie bei Startobjekt MainForm aus. Bestätigen Sie die Änderungen mit OK. Um das Programm zu starten, drücken Sie auf die Taste F5. Wenn Sie genau hinschauen, finden Sie einige Eigenschaftswerte wieder. Schritt 4 Sie werden aber festgestellt haben, dass nichts passiert. Wie auch, das müssen Sie per Code machen. Und das machen wir jetzt. Drücken Sie mal auf F7 und Sie werden folgenden Code sehen: Public Class MainForm Inherits System.Windows.Forms.Form Vom Windows Form Designer generierter Code End Class Alles (besser, fast alles) was sich hinter Vom Windows Form Designer generierter Code verbirgt, haben Sie mit dem Designer erstellt und dies sollten Sie auch nur mit dem Designer ändern. Falsche Änderungen können die komplette Datei unbrauchbar machen! Also, Finger weg! Schritt 5 Da ich bemüht bin, Ihnen gleich von Anfang an einen guten Programmierstil beizubringen (schlechter kann zu sehr schwer zu verstehendem Code führen, trotzdem sollten Sie einen gewissen persönlichen Stil entwickeln), fügen Sie oberhalb von Public Class MainForm folgenden Code ein: Option Explicit On Option Strict On Imports System Was sich dahinter verbirgt, werden Sie im Laufe dieses Kurses lernen. Schritt 6 Fügen Sie nach Inherits… folgende Zeilen ein: Private Const DM As Decimal = 1.95583D ' Deutsche Mark Private Const BEF As Decimal = 40.3399D ' Belgische Francs Private Const ATS As Decimal = 13.7603D ' Österreichische Schilling Private Const FRF As Decimal = 6.55957D ' Französische Francs Sie werden bemerkt haben, dass Ihnen bei der Eingabe das Visual Studio .NET Vorschläge macht. Übernehmen können Sie einen mit der Tab-Taste. Mit diesen Anweisungen haben Sie 4 Konstanten definiert, die den Umrechnungskurs für die einzelnen Währungen darstellen. Alles nach dem Apostroph ( ' ) sind Kommentare und werden ignoriert. Hier können Sie Erklärungen oder andere Dinge schreiben, die ignoriert werden sollen. Schritt 7 Um Fehleingaben des Benutzers zu verhindern, behandeln wir das Ereignis KeyPress unserer Textbox. Um dieses zu behandeln, wählen Sie in der oberen linken Auswahlliste txtBetrag aus, in der rechten KeyPress. VS.NET generiert den Ereignishandler und wir geben folgenden Code ein: Select Case AscW(e.KeyChar) Case 46, 48 To 57, 8 ' Dezimalkomma, Ziffern und Backspace zulassen Case Else e.Handled = True End Select Mit diesem Code erlauben wir nur die Eingabe der Ziffern und der Backspace-Taste. Jede andere Taste wird ignoriert. Schritt 8 Öffnen Sie die Entwurfsansicht der Form und klicken Sie doppelt auf den Button. Damit fügen Sie einen Ereignishandler für das Click-Ereignis ein. Geben Sie folgendes ein: Dim Betrag As Decimal = CDec(txtBetrag.Text) Dim Ergebnis As Decimal Select Case cmbFrom.SelectedItem Case cmbFrom.Items.Item(0) ' Euro in Euro umrechnen? lblErgebnis.Text = "Sie können nur in Euro umrechnen." Case cmbFrom.Items.Item(1) ' DM in Euro umrechnen Ergebnis = Math.Round(Betrag / DM, 2) lblErgebnis.Text = txtBetrag.Text & " DM sind " & _ "umgerechnet " & Ergebnis.ToString() & " Euro." Case cmbFrom.Items.Item(2) ' Belgische Francs in Euro umrechnen Ergebnis = Math.Round(Betrag / BEF, 2) lblErgebnis.Text = txtBetrag.Text & " BEF sind " & _ "umgerechnet " & Ergebnis.ToString() & " Euro." Case cmbFrom.Items.Item(3) ' Französische Francs in Euro umrechnen Ergebnis = Math.Round(Betrag / FRF, 2) lblErgebnis.Text = txtBetrag.Text & " FRF sind " & _ "umgerechnet " & Ergebnis.ToString() & " Euro." Case cmbFrom.Items.Item(4) ' Österreichische Schilling in Euro umrechnen Ergebnis = Math.Round(Betrag / ATS, 2) lblErgebnis.Text = txtBetrag.Text & " ATS sind " & _ "umgerechnet " & Ergebnis.ToString() & " Euro." End Select Wenn Sie jetzt das Projekt starten, funktioniert es. Die Texte werden korrekt ausgegeben und das Ergebnis wird ebenfalls auf 2 Stellen nach dem Komma gerundet. Sie haben hiermit Ihr erstes Programm entwickelt. Im Verlauf der nächsten Kapitel werden Sie die Funktionsweise des Programms vollständig verstehen. 2.2. Variablen und Kontrollstrukturen In diesem Kapitel soll es um Variablen und um Kontrollstrukturen gehen. Mit Variablen können Sie Werte temporär speichern, um sie später weiter zu verarbeiten. Mit Kontrollstrukturen können Sie den Programmfluss beeinflussen, wie z.B. die Ausführung von bestimmten Befehlen von Bedingungen abhängig machen oder sie wiederholen. 2.2.1. Kommentare 2.2.2. Variablen 2.2.2.1. Die Variablendeklaration Dim AnzahlSpieler Dim Summe, Differenz, Produkt, Quotient Wie Sie sehen, können auch mehrere Variablen in eine Zeile deklariert werden, indem die einzelnen Bezeichner mit einem Komma getrennt werden (Leerzeichen können nach dem Komma folgen, müssen es aber nicht). Für den Variablenbezeichner gibt es folgende Beschränkungen:
Der Bezeichner sollte ausdrücken, was in der Variable gespeichert werden soll. Sie wissen nun, dass alles nach einem Dim-Befehl eine Variablendeklaration ist, aber was ist denn das, was im Beispielprojekt nach diesem As kommt? Dies ist der Variablentyp, dieser gibt an, welche Daten in der Variable gespeichert werden können (der Wertebereich der Variable). Außerdem wird mit dem Typ auch angegeben, wie viele Bytes die Variable im Arbeitsspeicher belegt. Nachfolgende Tabelle zeigt Ihnen erst mal, welche Typen möglich sind:
Die Variablentypen im Detail In diesem Abschnitt werden die Variablentypen näher beschrieben. Boolean: Byte: Char: Short, Integer, Long: Single, Double: Decimal: String: Date: Dim Datum As Date ' beliebiges Datum zuweisen Datum = #2/29/2000# ' beliebige Uhrzeit zuweisen Datum = #10:05 AM# ' Datum und Uhrzeit zuweisen Datum = #12/31/2005 11:59:59 PM# Wenn Sie das VS.NET verwenden, dann konvertiert das VS.NET Uhrzeitangaben im 24-Stunden-Format automatisch in das 12-Stunden-Format. Das Datum müssen Sie aber korrekt im Format m/tt/jjjj angeben. Object: 2.2.2.2. Variableninitialisierung und Wertzuweisung Dim AnzahlSpieler As Byte = 4 Dim Punkte As Integer ' Der Variable Punkte den Wert 1000 zuweisen Punkte = 1000 ' Der initialisierten Variable AnzahlSpieler ' einen neuen Wert zuweisen AnzahlSpieler = 8 Wie Sie sehen, ist der =-Operator für die Wertzuweisung zuständig. Eine Variableninitialisierung ist optional, also sie muss nicht stattfinden, aber man sollte vor der ersten lesenden Verwendung der Variable ihr einen Wert zugewiesen haben. 2.2.2.3. Überlauf und Unterlauf Dim Zahl1 As Integer = Integer.MaxValue Dim Zahl2 As Integer = Integer.MaxValue - 5 Dim Ergebnis As Integer = Zahl1 + Zahl2 ' erzeugt Überlauf Dieser Code erzeugt bei der Ausführung eine OverflowException, was nichts Anderes heißt, dass ein Überlauf aufgetreten ist. Ein Unterlauf tritt dann ein, wenn ein Wert zugewiesen wird, der für den Datentyp zu klein ist. Bei Gleitkommatypen wird allerdings keine OverflowException ausgelöst, sondern es wird mit Unendlich weitergerechnet. Unterschieden wird zwischen PositivInfinity (positiv unendlich) oder NegativeInfinity (negativ unendlich), je nach dem, ob der Wert zu groß oder zu klein ist. 2.2.2.4. Konstanten Um eine Konstante zu deklarieren, verwenden Sie das Const-Schlüsselwort. Hier ein paar Beispiele: Const PI As Double = 3.14159 Const SpielerProTeam As Byte = 11 Const MwSt As Integer = 16 Konstanten müssen gleich bei der Deklaration initialisiert werden, weil eine nachträgliche Änderung nicht möglich ist. Wie Sie sehen, sind Konstanten eine Sonderform der Variable, da man auch genauso Variablen verwenden könnte. Nur ist bei Konstanten eine fälschliche Wertzuweisung nicht möglich, bei Variablen schon. Vor solchen Fehlern warnt Sie kein Compiler, da man an Variablen Werte zuweisen kann. Schließlich weiß der Compiler nicht, wofür Sie die Variable verwenden wollen. Um solche Fehler von vorn herein auszuschließen, verwenden Sie Konstanten. 2.2.2.5. Literale und Literalzeichen Dim Meldung As String = "Hallo Welt!" Dim Silvester As Date = #12/31/2005 11:59 PM# Dim Preis As Double = 24.90 Dim Hausnummer As Integer = 27 Jedes Literal zwischen zwei Anführungszeichen bekommt den Datentyp String, zwischen zwei Doppelkreuzen ( # ) wird es als Date behandelt. Literale mit Nachkommastellen werden standardmäßig als Double behandelt und Ganzzahlliterale je nach Größe als Integer oder Long (wenn für Integer zu groß). Wenn Sie einen anderen Typ zuweisen wollen, setzen Sie hinter dem Literal unmittelbar das jeweilige Literalzeichen (zwischen dem Literal und dem Literalzeichen dürfen keine andere Zeichen stehen, also auch keine Leerzeichen). Folgende Tabelle listet die jeweiligen Literalzeichen mit dem entsprechenden Datentyp auf sowie ein Beispiel:
2.2.3. Operatoren 2.2.3.1. Der =-Operator Dim Zahl1, Zahl2 As Integer Zahl1 = 1 Zahl2 = Zahl1 2.2.3.2. Die mathematischen Operatoren + - * / \ ^ Mod Für die Division stehen uns zwei Operatoren zur Auswahl: "/" für Kommazahlen und "\" für Ganzzahlen (Integerdivision). Bei der Integerdivision werden die Nachkommastellen einfach abgeschnitten. Dazu ein paar Beispiele: Dim a As Single = 5 \ 2 ' ergibt 2 Dim b As Single = 5 / 2 ' ergibt 2.5 Dim c As Single = 7.5 \ 2.5 ' ergibt 4 Dim d As Single = 7.5 / 2.5 ' ergibt 3 Dim e As Single = 1.5 \ 0.5 ' erzeugt eine DivideByZeroException Dim f As Single = 1.5 / 0.5 ' Gibt 3 Die ersten beiden Zahlenpaare dürften verständlich sein, beim Dritten wird's interessant. Zuerst werden die Nachkommazahlen abgeschnitten, aus 1.5 wird 1 und aus 0.5 wird 0. Und jetzt würde man 1 durch 0 dividieren wollen, was auch in der Programmierwelt nicht geht und als "Strafe" bekommen wir eine DivideByZeroException an den Kopf geworfen (was genau Exceptions sind, erfahren Sie in einem späteren Abschnitt).ü> Der ^-Operator potenziert zwei Zahlen und der Mod-Operator ermittelt den Rest bei einer Division: Dim Zahl1 As Integer = 5 Mod 2 ' ergibt 1 Dim Zahl2 As Integer = 2 ^ 3 ' ergibt 8 2.2.3.3. Der &-Operator Dim Teil1 As String = "Hallo " Dim Teil2 As String = "Welt!" Dim Zusammen As String = Teil1 & Teil2 ' ergibt "Hallo Welt!" 2.2.3.4. Die Operatoren für Faule: += -= *= /= \= ^= &= Dim wert As Integer wert = 1 wert = wert + 2 ' erhöht wert um 2 In VB.NET können Sie dies kürzer schreiben: Dim wert As Integer = 1 wert += 2 ' erhöht wert um 2 Diese kürzere Schreibweise funktioniert mit jedem Operator, die wir bis jetzt kennen (außer dem Mod-Operator). 2.2.3.5. Die boolean'schen Operatoren
Außerdem gibt es noch die Operatoren AndAlso und OrElse. Um diese zu erklären, muss ich etwas vorgreifen. Angenommen, Sie haben zwei Funktionen, die einen Boolean-Wert zurückgeben und die zweite brauchen wir nicht, wenn die erste True zurückgibt. Mit unserem jetzigen Wissen könnten wir dies so anstellen: Dim b As Boolean = func1() Or func2() Nur würde jetzt auch die zweite Funktion aufgerufen werden, auch wenn die erste True zurückgibt. Anders sieht es aus, wenn wir OrElse benutzen: Dim b As Boolean = func1() OrElse func2() Wenn jetzt func1() True zurückgibt, wird func2() nicht mehr ausgeführt, da das Ergebnis auf jeden Fall True ist (True Or False ist True, s. Tabelle). Mit AndAlso verhält es sich umgekehrt: Dim b As Boolean = func1() AndAlso func2() Wenn jetzt func1() False zurückgibt wird func2() gar nicht erst ausgeführt, da es keinen Einfluss auf das Ergebnis hat (False And True ist False, s. Tabelle). 2.2.3.6. Die binären Operatoren Beginnen wir mit dem Not-Opertor: Nehmen wir die Zahl 15, binär: Ich hoffe, dass das Prinzip verstanden wurde: Auf jede Zahl wird Not angewendet. Hier mal noch ein Beispiel mit And: 10000110 (dezimal 134) AND Die binären Operatoren kann man in bestimmten Situationen sinnvoll einsetzen, allerdings interessieren einen die einzelnen Bits in den meisten Fällen nicht. 2.2.3.7. Die Bitverschiebungsoperatoren Die Bitverschiebungsoperatoren werden auf die Ganzzahltypen angewendet, um die Bits um eine bestimmte Anzahl von Bits zu verschieben. Wichtig ist hier, dass man die Länge der einzelnen Typen beachtet und dass das erste Bit ganz links das Vorzeichen bei Short, Integer und Long angibt (0 für positiv, 1 für negativ). Nehmen wir mal die Zahl 1247, die in einen Short (16 Bit) gespeichert wird: 0000010011011111 Wenn wir jetzt 7 Bits nach links verschieben wollen, sieht dies so aus: Dim Zahl As Short = 1247 Dim Ergebnis As Short = Zahl << 7 ' ergibt 28544 Was ist geschehen? Die ersten 7 Bits sind herausgefallen, also haben wir noch 011011111, da aber Short 16 Bits hat, werden die restlichen fehlenden Bits von rechts mit 0 aufgefüllt, dass am Ende 0110111110000000 herauskommt, was dezimal 28544 entspricht. Wenn jetzt das erste Bit eine 1 wäre, dann wäre die Zahl negativ. Bei der Rechtsverschiebung verhält es sich umgekehrt: Die Bits fallen auf der rechten Seite heraus und werden auf der linken Seite mit 0 aufgefüllt. Das obige Beispiel jetzt noch einmal, nur als rechts Verschiebung: Dim Zahl As Short = 1247 Dim Ergebnis As Short = Zahl >> 7 ' ergibt 9 Vor der Verschiebung: 00000100111011111 2.2.3.8. Die Vergleichsoperatoren
Das Ergebnis ist immer ein Boolean-Wert: entweder es stimmt (True) oder es stimmt nicht (False). 2.2.3.9. Die Priorität der Operatoren
Wenn mehrere Operatoren des gleichen Ranges vorkommen, dann werden diese von links nach rechts aufgelöst. Mit Klammern kann man erreichen, dass sie zuerst aufgelöst wird, wobei gilt, Klammern von innen nach außen lösen. 2.2.4. Option Strict Sie können im VS.NET Option Strict projektweit festlegen, indem Sie im Menü PROJEKT|EIGENSCHAFTEN VON <PROJEKTNAME>…|ERSTELLEN klicken und im erscheinenden Dialog Option Strict auf On oder Off stellen. Sie können aber auch am Anfang jeder Datei Option Strict On schreiben, womit Sie dasselbe erreichen. 2.2.5. Casten
Falls gerundet werden muss, wird kaufmännisch gerundet (< 0.5 → 0, >= 0.5 → 1). 2.2.6. Entscheidungen 2.2.6.1. Die If-Anweisung Dim Zahl1 As Integer = 5 Dim Zahl2 As Integer = 27 If Zahl1 < Zahl2 Then Console.WriteLine("Zahl1 ist kleiner als Zahl2") End If Hier wird geprüft, ob die Variable Zahl1 kleiner als die Variable Zahl2 ist und es wird eine Textzeile auf der Konsole ausgegeben (dies ist ein Ausschnitt aus einem Konsolenprogramm, wie dies komplett aufgebaut ist, erfahren Sie nach dem Abschnitt "Konsolenanwendungen"). Folgendes Beispiel macht von der Operatorenreihenfolge und von Klammern Gebrauch: Dim Zahl1 As Integer = 27 Dim Zahl2 As Integer = 5 If Zahl1 * Zahl2 * (Zahl1 Mod Zahl2) < Zahl1 << Zahl2 Then Console.WriteLine("Die Bedingung der If-Anweisung ist True") End If Diese Bedingung ist gar nicht so einfach. Nun die Frage, wird der String "Die Bedingung der If-Anweisung ist True" auf der Konsole ausgegeben oder nicht? Schauen wir uns die Bedingung mal im Detail an: Zahl1 * Zahl2 = 27 * 5 = 135 If (Zahl1 * Zahl2 * (Zahl1 Mod Zahl2)) < (Zahl1 << Zahl2) Then Hier sieht man gleich, was in welcher Reihenfolge ausgewertet wird, das Ergebnis ist aber das Gleiche. Falls Sie die Operatorenprioritäten nicht aus dem Kopf wissen oder nicht immer nachschlagen wollen, setzen Sie lieber ein paar Klammern mehr, denn solche „Kleinigkeiten" können die Fehlersuche ganz schön erschweren. Die logischen Operatoren können für die Bedingung verwendet werden, wodurch man sehr komplizierte Bedingungen erstellen kann. 2.2.6.2. Ausbaustufe I der If-Anweisung - der Else-Teil Dim Valid As Boolean = EingabenKorrekt(…) ' die Funktion EingabenKorrekt soll überprüfen, ob die Eingaben des ' Benutzers korrekt sind. Da wir Funktionen später behandeln, stehen in ' Klammern statt den Parametern nur 3 Punkte, uns interessiert erst mal nur ' der Rückgabewert If Valid Then Console.WriteLine("Ihre Eingaben sind korrekt.") Else Console.WriteLine("Ihre Eingaben sind nicht korrekt.") End If Die Variable Valid bekommt von der Funktion EingabeKorrekt einen Boolean-Wert zugewiesen, der angibt, ob die Eingaben des Benutzers korrekt sind. Jetzt soll überprüft werden, was nun in Valid steht und eine entsprechende Meldung ausgegeben werden. True steht für korrekte Eingaben, False für falsche Eingaben. Nun, der If-Befehl überprüft dies, bei True wird "Ihre Eingaben sind korrekt." ausgegeben, ansonsten wird der Else-Teil ausgeführt und eine entsprechende Meldung ausgegeben. 2.2.6.3. Ausbaustufe II der If-Anweisung - der ElseIf-Teil Dim Punkte As Short = 1500 Const Bonus As Short = 100 If Punkte = 0 Then Console.WriteLine("Das war nichts.") ElseIf Punkte < 500 Then Console.WriteLine("Kann nur besser werden.") ElseIf Punkte < 1000 Then Console.WriteLine("Nicht schlecht.") ElseIf Punkte > 1000 Then Console.WriteLine("Das gibt Bonus.") Punkte += Bonus Else Console.WriteLine("Punktzahl nicht ermittelbar.") End If Es soll überprüft werden, wie hoch die Punktzahl ist und je nach Punktzahl eine Meldung ausgegeben werden. Es wird zuerst überprüft, ob die Punktzahl 0 ist. Über die 3 ElseIf-Blöcke werden verschiedene Zahlenbereiche untersucht. Der Else-Teil wird ausgeführt, wenn keine der obigen Bedingungen zutrifft. Nehmen wir mal an, die Punktzahl beträgt 400, welche Meldung/Meldungen wird/werden angezeigt? Eigentlich müsste "Kann nur besser werden." und "Nicht schlecht" ausgegeben werden, da 400 kleiner als 500 ist und auch kleiner als 1000 ist. Es wird aber nur "Kann nur besser werden." ausgegeben. Nämlich sobald eine zutreffende Bedingung gefunden wird, wird der If-Block verlassen und evtl. vorhandene ElseIf-Anweisungen werden nicht überprüft. 2.2.6.4. Implizite und Explizite Schreibung Dim Bedingung As Boolean = True If Bedingung Then ' Irgendetwas machen End If Und jetzt explizit: Dim Bedingung As Boolean = True If Bedingung = True Then' Irgendetwas machenEnd If Der einzige Unterschied zwischen den beiden Schreibweisen liegt darin, dass die implizite Variante um ein paar Nanosekunden schneller ist als die explizite. Welche Schreibweise Sie verwenden, ist unerheblich, Sie sollten aber beide Schreibweisen verstehen. Ich verwende die implizite, da diese kürzer ist als die explizite (bin schreibfaul). 2.2.6.5. Die Select Case-Anweisung Hier ist die Syntax für die Select Case-Anweisung: Select Case VARIABLE Case WERT Anweisungen Case WERT[, WERT] Anweisungen Case Is > WERT Anweisungen Case Is > WERT, Is < WERT Anweisungen Case Else Anweisungen End Select Die Bezeichner in Großbuchstaben stehen für konkrete Werte (VARIABLE für eine konkrete Variable, WERT für einen konkreten Variablenwert). Alles was zwischen zwei eckigen Klammern ( [ ] ) eingeschlossen wird, ist optional, also kann folgen, muss es aber nicht. Dies sind in etwa alle Möglichkeiten der Select Case-Anweisung, hier mal ein Beispiel: Select Case Wert Case 1 Console.WriteLine("Wert ist 1") Case 2 Console.WriteLine("Wert ist 2") Case 3, 4, 5 Console.WriteLine("Wert ist 3,4 oder 5") Case Is > 10 Console.WriteLine("Wert ist größer 10") Case Is >= 5, Is <= 10 Console.WriteLine("Wert liegt zwischen 5 und 10") Case Else Console.WriteLine("Wert liegt nicht zwischen 1 und 10 & ist auch nicht größer 10.") End Select Die Variable Wert soll eine zufällige Zahl zwischen 0 und 15 enthalten und es soll ausgewertet werden, welche Zahl Wert enthält. Die ersten beiden Case-Zweige prüfen, ob Wert 1 oder 2 ist. Danach wird überprüft, ob Wert 3, 4 oder 5 ist. Das vierte Case überprüft, ob Wert größer als 10 ist. Anschließend, ob Wert zwischen 5 und 10 liegt und zu letzt wird der Case Else-Zweig durchlaufen, wenn keine der obigen Bedingung zutrifft (z.B. bei Wert = 0). Auch bei Select Case wird nur ein Case-Zweig ausgeführt, sobald VB einen passenden Case-Zweig gefunden hat und die Befehle ausgeführt hat. Danach springt es zur End Select-Anweisung.
2.2.7. Konsolenanwendungen Bevor wir uns mit den Schleifen befassen, möchte ich Ihnen zeigen, wie ein einfaches Programm aufgebaut ist. Es gibt verschiedene Programmarten, z.B. Windowsanwendungen, Webanwendungen und die Konsolenanwendungen. Auch wenn die Konsolenanwendungen optisch nicht gerade ansprechend sind, kann man mit ihnen die Grundlagen einer Sprache leicht ausprobieren, da man sich um (fast) nichts kümmern muss. Mit Windowsanwendungen beschäftigen wir uns im 3.Kapitel, da diese im Gegensatz zu Konsolenanwendungen einen erhöhten Codeaufwand erfordern und das Wissen aus diesem Kapitel voraussetzen. 2.2.7.1. Der Grundaufbau einer Konsolenanwendung ' Als erstes kommen Option-Anweisungen Option Explicit On Option Strict On ' Danach folgende Imports-Anweisungen Imports System ' Jetzt folgt der eigentliche Code Public Module MainModule Public Sub Main() Console.WriteLine("Hallo Welt") Console.ReadLine() End Sub End Module Jetzt betrachten wir uns das Programm Zeile für Zeile. Die ersten Anweisungen in einer Codedatei sind die Option-Anweisungen, die das grundlegende Verhalten festlegen. Hier eine Übersicht über die möglichen Option-Anweisungen
Mit der Imports-Anweisung können Namespaces importiert werden, wodurch man Tipparbeit spart. Also statt System.Console.WriteLine(…) braucht man nach dem Import des Namespaces System nur noch Console.WriteLine(…) schreiben. Es können beliebig viele Namespaces importiert werden. Namespaces und Namespacealiases werden im Kapitel Klassen weiter unten ausführlich behandelt. Nach den Imports-Anweisungen folgt nun der eigentliche Code, wobei ein Modul erstellt wird mit der Prozedur Main(), welche der Einstiegspunkt der Anwendung ist und existieren muss. In der Main-Prozedur steht der Code, der ausgeführt werden soll. Als erstes wird der Text "Hallo Welt!" ausgegeben mit Console.WriteLine(). Mit Console.ReadLine() wird die Anwendung erst dann beendet, wenn die Enter-Taste gedrückt wurde. 2.2.7.2. Lesen und Schreiben aus / in die Konsole Um Eingaben von der Konsole auszulesen, bietet uns die Console-Klasse die Methoden Read() und ReadLine() an. Die Read()-Methode gibt einen Integer zurück (Tastencode für das eingegebene Zeichen), sobald die Eingabe beendet wurde (z.B. mit ENTER). Um sich Ärger mit dem Zeilenabschlusszeichen zu sparen, verwenden Sie lieber die ReadLine()-Methode, welche die komplette Zeile einliest (das Zeilenabschlusszeichen ist in dem zurückgegebenen String nicht mit enthalten). Hier ein kleiner "Zufallszahlengenerator" als Beispiel: Option Explicit On Option Strict On Imports System Module MainModule Sub Main() Dim gelesen As String ' enthält die gelesene Zahl als String Dim zahl As Integer ' speichert die Zufallszahl Console.WriteLine("Glückszahlgenerator") Console.Write("Geben Sie eine Startzahl ein: ") gelesen = Console.ReadLine() Dim r As New Random(Integer.Parse(gelesen)) zahl = r.Next(0, 9) Console.WriteLine("Ihre Glückzahl ist die {0}.", zahl.ToString()) Console.ReadLine() End Sub End Module Die ersten 8 Zeilen sind nichts Unbekanntes. In der Sub Main() werden zunächst zwei Variablen deklariert, die im weiteren Programmverlauf benötigt werden (eigentlich wären keine Variablen nötig, aber durch die Verwendung von Variablen ist der Code leichter zu lesen). In den nächsten zwei Zeilen werden je eine Meldung ausgegeben und dann wird die eingegebene Zahl ausgelesen und in die Variable gelesen gespeichert. In Zeile 14 wird eine Instanz der Klasse Random mit dem Namen r erstellt, mit der wir auf die Methoden der Klasse zugreifen, die eine "zufällige" Zahl erstellt. Um die Zahlen wirklich zufällig zu erstellen, wird ein Initiationswert für die Klasse angegeben, da ansonsten immer dieselben Zahlen ausgegeben werden würden. Dieser Initiationswert ist die eingegebene Zahl vom Benutzer. Leider haben wir diese nur als String vorliegen, wir brauchen sie aber als Integer. Die Lösung - wir parsen den String in einen Integer (ein CInt wäre auch möglich, ist letztlich aber egal). r.Next() gibt uns eine Zufallszahl zurück, die wir in die Variable zahl zwischenspeichern. Dann geben wir die Zufallszahl aus und fügen am Ende noch ein Console.ReadLine() ein, damit das Programm erst bei Betätigung der ENTER-Taste beendet wird. Damit wir die letzte Zeichenkette nicht zerlegen müssen, setzen wir für die Variable zahl den Platzhalter {0} ein, schreiben unseren String fertig, setzen ein Komma und Konvertieren unsere Zahl in einen String. Diese Platzhalter werden einfach durchnummeriert und die Nummerierung beginnt mit jeder neuen Codezeile wieder von vorne. Mehr gibt es über die Konsole eigentlich nicht zu sagen, da mehr Funktionen nicht enthalten sind (zumindest im .NET Framework 1.1). Sie können zum Lesen und Schreiben auch eine Instanz der TextReader- bzw. der TextWriter-Klasse verwenden, aber diese Klassen werden im Kapitel 6 ausführlich behandelt. 2.2.8. Schleifen 2.2.8.1. Die For…Next-Schleife Die Syntax ist recht einfach: For VARIABLE = STARTWERT To ENDWERT Step SCHRITTWEITE Anweisungen Next [VARIABLE] Zur Erklärung: Eine Variable wird einem Startwert zugewiesen gefolgt vom To-Schlüsselwort mit dem Endwert, bei dem die Schleife dann beendet werden soll. Mit der Step-Angabe kann man angeben, um wie viele Schritte die Variable erhöht / vermindert werden soll. Mit einem negativen Step wird eine Variable runtergezählt. For i As Integer = 10 To 0 Step -1 Console.WriteLine(i.ToString()) Next i Hinweis: Wer das .NET Framework in der Version 1.0 verwendet, der kann keine Variablen direkt in der Schleife deklarieren. Diese Deklaration muss ausgelagert werden. Das obige Beispiel sieht umgeschrieben dann so aus: Dim i As Integer For i = 10 To 0 Step -1 Console.WriteLine(i.ToString()) Next i Wenn Sie eine Single-, Double oder Decimalvariable verwenden, können Sie als Step auch eine Kommazahl verwenden. 2.2.8.2. Die For Each…Next-Schleife 2.2.8.3. Die Do…Loop-Schleife Wiederholung solange die Bedingung True ist Dim zahl As Integer = 10 Do While zahl >= 0 Console.WriteLine(zahl.ToString()) zahl -= 1 Loop Wenn die Bedingung am Schleifenende geprüft werden soll, dann schreiben Sie das While-Schlüsselwort mit der Bedingung nach dem Loop. Dann sieht die Schleife so aus: Dim zahl As Integer = 10 Do Console.WriteLine(zahl.ToString()) zahl -= 1 Loop While zahl >= 0 Wiederholung bis die Bedingung True wird Dim zahl As Integer = 10 Do Until zahl = -1 Console.WriteLine(zahl.ToString()) zahl -= 1 Loop Wenn die Bedingung am Ende geprüft werden soll, dann passiert dasselbe wie bei der While-Variante - das Until mit der Bedingung wird hinter dem Loop gesetzt und fertig. 2.2.8.4. Die While…End While-Schleife Dim zahl As Integer = 10 While zahl >= 0 Console.WriteLine(zahl.ToString()) zahl -= 1 End While Im Gegensatz zu der Do…Loop-Schleife muss bei der While…End While-Schleife nach dem While eine Bedingung folgen, ansonsten wird ein Compilerfehler generiert. 2.2.8.5. Schleifen vorzeitig beenden Dim zahl As Integer = 0 Do Console.WriteLine(zahl.ToString()) zahl += 1 If zahl = 100 Then Exit Do End If Loop Ohne die If-Anweisung würde diese Schleife unendlich lang durchlaufen werden. Sobald aber die If-Anweisung zutrifft, wird die Schleife abgebrochen.
2.3 Arrays und Auflistungen In diesem Abschnitt soll es um Arrays und Auflistungen (im englischen Collections) gehen. 2.3.1 Arrays Was sind Arrays? Arrays sind Variablen, die über einen Index angesprochen werden, wodurch Sie mehrere Werte in einer Variable speichern können. 2.3.1.1. Arrayinitialisierung Dim Sprachen(2) As String = {"VB.NET", "C#", "C++"} Dieses Beispiel erstellt ein Array mit 3 Elementen (die Zählung beginnt bei Null). 2.3.1.2. Zugriff auf einzelne Arrayelemente Dim Wurzeln(19) As Double For i As Integer = 0 To Wurzeln.GetUpperBound(0) Wurzeln(i) = Math.Sqrt(i) Next i Wenn Sie auf jedes Element nacheinander zugreifen (durch iterieren) wollen, dann können Sie auch die For Each-Schleife verwenden: For Each Wurzel As Double In Wurzeln Console.WriteLine(Wurzel) Next Allgemein sieht die For Each-Schleife so aus: For Each EINZELWERT In ARRAY Anweisungen() Next 2.3.1.3. Dynamische Arrays ReDim Sprachen(4) Wenn Sie dies aber ausführen, werden Sie feststellen, dass Ihre Daten verschwunden sind. Ursache liegt im Speicher: Bei einem ReDim-Befehl muss VB.NET (oder besser gesagt, die CLR) das Array neu aufbauen. Aus Performancegründen wird standardmäßig auf ein Kopieren der Werte verzichtet. Um ein kopieren der Werte zu erzwingen, setzen Sie nach dem ReDim noch ein Preserve: ReDim Preserve Sprachen(4) 2.3.1.4. Funktionen für Arrays
Arrayfunktionen 2.3.1.5. Mehrdimensionale Arrays Dim Array(,) As Integer = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} Dim i, j As Integer For i = 0 To 2 For j = 0 To 2 Console.Write(Array(i, j) & " ") Next j Console.WriteLine() Next i Hiermit möchten wir unseren "Array-Exkurs“ beenden. Wer mehr über Arrays lesen möchte, dem sei einem Blick in die VB.NET-Hilfe (entweder MSDN Online oder die MSDN Library) empfohlen. 2.3.2. Auflistungen Unter einer Auflistung, oder im englischen Collection, versteht man eine Klasse, die die Elemente nach einem ganz bestimmten Muster ordnet. Die .NET Framework-Klassenbibliothek enthält viele Collectionklassen, wie z.B. Stack, Queue, ArrayList, Hashtable, ListDirectory, HybridDirectory oder SortedList. In diesem Abschnitt wollen wir uns einige Auflistungen genauer anschauen. Auch hier ist ein Blick in die .NET Framework-Dokumentation sinnvoll. Die meisten Auflistungen finden Sie im Namespace System.Collections, die spezialisierten Auflistungen im Namespace System.Collections.Specialized. Leider haben die Collections einen Nachteil (außer die spezialisierten) – sie nehmen alle Object-Variablen an, was es aber dagegen gibt, erfahren Sie weiter unten. 2.3.2.1. Ein erstes Beispiel: ArrayList Wenn Sie ein Element an einer ganz bestimmten Stelle einfügen wollen, dann verwenden Sie die Insert-Methode, welcher Sie einen Index und einen Wert übergeben. Es gibt auch eine InsertRange-Methode, die genauso funktioniert wie die Insert-Methode, nur dass diese Methode mehrere Elemente hinzufügt. Wollen Sie ein ganz bestimmtes Element entfernen? Dann verwenden Sie die Remove-Methode. Oder wollen Sie ein Element an einer ganz bestimmten Stelle löschen? Kein Problem für RemoveAt(). Mehrere Elemente in einem Rutsch zu entfernen – dafür gibt es RemoveRange(). Dies sind die wichtigsten Methoden der ArrayList und dazu gibt es jetzt noch kleines Beispiel: Option Explicit On Option Strict On Imports System Imports System.Collections Module MainModule Sub Main() ' "Begrüßung" ausgeben Console.WriteLine("ArrayList-Beispiel") Console.WriteLine() ' Collection erzeugen und mit Werten füllen Dim CarCollection As New ArrayList Dim Cars() As String = {"Opel Astra", "Audi A4", "VW Golf", _ "BMW Z3", "Mercedes S-Serie"} CarCollection.AddRange(Cars) ' Werte ausgeben Console.WriteLine("Diese Elemente wurden hinzugefügt:") For Each item As String In CarCollection Console.WriteLine(item) Next Console.WriteLine() ' Element nach dem ersten Element hinzufügen CarCollection.Insert(1, "Trabi") Console.WriteLine("Folgendes Element wurde nach dem 1. eingefügt:") Console.WriteLine(CarCollection.Item(1)) Console.WriteLine() ' Element "Mercedes S-Serie" entfernen CarCollection.Remove("Mercedes S-Serie") Console.WriteLine("'Mercedes S-Serie' wurde entfernt") Console.WriteLine() ' Collection sortieren und ausgeben CarCollection.Sort() Console.WriteLine("Die ArrayList wird nun sortiert ausgegeben:") For Each item As String In CarCollection Console.WriteLine(item) Next Console.WriteLine() ' Die letzten beiden Elemente werden entfernt Console.WriteLine("Es werden Elemente entfernt.") CarCollection.RemoveRange(3, 2) Console.WriteLine() ' Verbliebene Elemente ausgeben Console.WriteLine("Diese Elemente sind noch enthalten:") For Each item As String In CarCollection Console.WriteLine(item) Next Console.ReadLine() End Sub End Module Die anderen Collections funktionieren fast genauso wie die ArrayList. Da sich vieles gleicht und wiederholt, möchte ich hiermit nur auf die .NET Framework Dokumentation verweisen, dort sind die einzelnen Collections beschrieben inkl. Beispiele. 2.3.2.2. Typsicherheit in Collections Option Explicit On Option Strict On Imports System Imports System.Collections.Generic Module MainModule Sub Main() Dim StringList As New List(Of String) ' Weitere Verwendung hier End Sub End Module Wie Sie sehen, geben Sie nach dem Of an, von welchem Typ die Collection sein soll (hier eine Liste). Sie können jeden beliebigen Typ da hinschreiben, auch selbst definierte Typen (Strukturen und Klassen), zu denen wir aber später kommen. Natürlich können Sie auch selber generische Klassen erstellen, aber dies führt zu weit. Wenn Sie sich dafür interessieren, dann kann ich Ihnen nur die MSDN Webcasts und die Beta 2 von VB.NET 2005 empfehlen.
2.4. Prozeduren und Funktionen In diesem Abschnitt werden Sie lernen, was Prozeduren und Funktionen eigentlich sind und wie Sie diese einsetzen und eigene schreiben können. Außerdem lernen Sie einige wichtige Prozeduren und Funktionen kennen, die im .NET Framework enthalten sind. 2.4.1. Was sind Prozeduren und Funktionen? Prozeduren und Funktionen fassen mehrere Programmanweisungen unter einem Namen zusammen und diese können Sie mit diesem Namen beliebig oft aufrufen. Damit spart man sich das mehrmalige schreiben derselben Codezeilen und Änderungen müssen nur an einer Stelle zentral gemacht werden und nicht an vielen, wodurch Zeit gespart wird. Damit der Compiler weiß, dass es sich um eine Prozedur oder Funktion handelt, folgt nach dem Namen ein Paar runder Klammern ( () ). 2.4.2. Schreiben und Aufrufen von Prozeduren & Funktionen Prozeduren werden wie folgt definiert: Sub ProzedurName() Anweisungen End Sub Als erstes kommt das Sub-Schlüsselwort, mit dem Sie die Definition einer Prozedur einleiten. Nach dem Sub-Schlüsselwort folgt der Name der Prozedur, der die gleichen Beschränkungen wie Variablennamen aufweist, gefolgt von einem Paar runden Klammern, die evtl. Parameter angeben (mehr zu Parametern und Argumenten später). Danach gibt man die Befehle ein, die ausgeführt werden sollen, wenn die Prozedur aufgerufen wird. Beendet wird die Prozedur mit End Sub. Hier ein komplettes Beispiel: Option Explicit On Option Strict On Imports System Module MainModule ' Diese Prozedur gibt auf der Konsole den angemeldeten User aus Sub CurrentUser() Console.WriteLine("Angemeldeter User: {0}", Environment.UserName) End Sub Sub Main() ' Aufruf unserer Methode 2x nacheinander CurrentUser() CurrentUser() Console.ReadLine() End Sub End Module In dem Modul wird zuerst eine eigene Prozedur definiert mit dem Namen CurrentUser(). Diese gibt auf der Konsole aus, welcher User gerade am System angemeldet ist. Der Benutzername wird mit Environment.UserName ermittelt. In der Sub Main() wird unsere Prozedur zweimal nacheinander aufgerufen. Wie Sie sehen, wird eine Prozedur aufgerufen, indem man einfach ihren Namen hinschreibt gefolgt von ein Paar runden Klammern, in denen die s.g. Argumente stehen (mehr dazu später). 2.4.2.2. Funktionen Function Funktionsname() As Rückgabetyp Anweisungen Return Wert End Function Die Definition beginnt mit dem Function-Schlüsselwort gefolgt von dem Namen der Funktion. In runden Klammern stehen Parameter (wenn vorhanden). Da Funktionen einen Wert zurückgeben, muss natürlich auch angegeben werden, von welchem Typ der zurückgegebene Wert ist. Dies wird mit der As-Klausel erreicht. In der Funktion werden die auszuführenden Anweisungen hineingeschrieben. Der Wert, der zurückgegeben werden soll, sollte mit Return zurückgegeben werden. Es gibt auch eine andere Variante, die auch unter VB6 verwendet wurde, aber ich finde die Verwendung von Return eleganter, sodass ich Ihnen den alten "Mist" verschweige. Das folgende Beispiel veranschaulicht die Definition und Verwendung von Funktionen: Option Explicit On Option Strict On Imports System Module MainModule Function Zufallszahl() As Integer Dim r As New Random(Environment.TickCount) Return r.Next(0, 10) End Function Sub Main() Dim zahl As Integer = Zufallszahl() Console.WriteLine("Ihre Zufallszahl ist die {0}.", _ zahl.ToString()) Console.ReadLine() End Sub End Module In dem Modul wird als erstes eine eigene Funktion mit dem Namen Zufallszahl definiert, die einen Integer zurückgibt. Wenn die Funktion aufgerufen wird, wird zuerst eine Instanz der Klasse Random erstellt und mit Return r.Next(0, 10) wird eine Zufallszahl zwischen 0 und 10 zurückgegeben. In unserer Sub Main() wird eine Variable mit dem Namen zahl definiert und sie bekommt ihren Wert durch unsere Funktion. Der Rest der Sub Main() dürfte verständlich sein. Wenn Sie den Rückgabewert einer Funktion nicht in einer Variablen speichern, geht dieser verloren. Wenn Sie natürlich den Rückgabewert nicht benötigen, dann brauchen Sie ihn auch nicht speichern. 2.4.3. Parameter und Argumente In diesem Abschnitt lernen Sie kennen, was Parameter und Argumente sind und erweitern Ihr Wissen über Prozeduren und Funktionen, da diese erst bei Verwendung von Parametern richtig nützlich werden. 2.4.3.1. Was sind Parameter und Argumente? Wenn Sie also eine Prozedur / Funktion erstellen, legen Sie die Parameter fest, wenn Sie Ihre Prozedur / Funktion aufrufen, dann übergeben Sie Argumente, also im Endeffekt beides dasselbe, aber je nach Kontext werden sie anders benannt. 2.4.3.2. Definieren von Parametern Function Zufallszahl(ByVal minimum As Integer, _ ByVal maximum As Integer) As Integer Dim r As New Random(Environment.TickCount) Return r.Next(minimum, maximum) End Function Wie Sie sehen, ist die Definition von Parametern einfach und dürfte keine Probleme bereiten. Wie viele Parameter Sie angeben oder von welchem Typ sie sind, legen Sie fest. Vergeben Sie als Parameternamen aussagekräftige Namen, damit man auch nach längerer Zeit noch weiß, was die Prozedur / Funktion erwartet. 2.4.3.3. ByVal vs. ByRef Sub Main() Dim i As Integer = 1 ByValAdd(i) Console.WriteLine("i nach dem Aufruf der ByVal-Funktion: " & i) ByRefAdd(i) Console.WriteLine("i nach dem Aufruf der ByRef-Funktion: " & i) End Sub Function ByValAdd(ByVal zahl As Integer) As Integer zahl += 1 End Function Function ByRefAdd(ByRef zahl As Integer) As Integer zahl += 1 End Function Das Programm erzeugt folgende Ausgabe: 1 2 Wie Sie sehen, hat sich der Wert der Variable i nach dem Aufruf der Funktion ByRefAdd erhöht, bei ByValAdd nicht. Dies würde bedeuten, dass die ByRefAdd-Funktion den Wert direkt ändert. Und so ist es auch, wenn Sie eine Variable mit ByVal - By Value - übergeben, dann übergeben Sie nur eine Kopie des Variablenwertes und die Variable selbst wird nicht verändert. Im Gegensatz zu ByRef - By Reference - hier wird die Referenz (Verweis, Zeiger) der Variable übergeben und Änderungen haben Auswirkungen auf die Variable, eine "Sicherungskopie" gibt es nicht. Da sich durch die Verwendung von ByRef schnell Fehler einschleichen können, ist ByVal Standard. Mit ByRef ergibt sich auch die Möglichkeit, mehr als einen Wert "zurückzugeben" - dies kann in einigen Situationen recht nützlich sein, wenn mehrere Werte auf einmal zurückgegeben werden müssen. 2.4.3.4. Optionale Parameter Sub PrintText(Optional text As String = "Hallo Welt!") Console.WriteLine(text) End Sub Folgende Aufrufe sind möglich: PrintText("Dies ist ein Testaufruf mit eigenem Text.") PrintText() Diese Aufrufe ergeben dann folgende Ausgabe: Dies ist ein Testaufruf mit eigenem Text.
Hallo Welt!
Ich denke, die Funktionsweise von optionalen Parametern ist verstanden worden. 2.4.3.5. Beliebig viele Parameter übergeben Sub PrintStringsToConsole(ByVal ParamArray strings() As String) For Each s As String In strings Console.WriteLine(s) Next End Sub 2.4.4. Funktionen überladen Neu in VB.NET ist es, Funktionen zu überladen. Beim Überladen definieren Sie Funktionen (natürlich auch Prozeduren), welche zwar alle denselben Namen haben, aber ihre Signatur so unterschiedlich ist, dass eine Unterscheidung möglich ist und der Compiler weiß, welche Funktion er aufrufen soll. Die Signatur einer Funktion oder Prozedur ist die erste Zeile (also die, wo das Sub- bzw. Function-Schlüsselwort auftaucht). Zur Signatur zählt:
Zur Signatur zählt nicht:
Um eine Prozedur oder Funktion zu überladen, setzt man vorne ran das Schlüsselwort Overloads (Overloads wird standardmäßig angenommen, also Sie brauchen es nicht anzugeben, ich persönlich schreibe es explizit davor um zu verdeutlichen, dass eine Prozedur/Funktion überladen ist). Hier das Beispiel zur Überladung von Funktionen: Option Explicit On Option Strict On Imports System Module MainModule Overloads Function Dividieren(ByVal zahl1 As Integer, _ ByVal zahl2 As Integer) As Integer Return zahl1 \ zahl2 End Function Overloads Function Dividieren(ByVal zahl1 As Double, _ ByVal zahl2 As Double) As Double Return zahl1 / zahl2 End Function Sub Main() Dim i1 As Integer = 45 Dim i2 As Integer = 9 Dim i3 As Integer = Dividieren(i1, i2) Dim d1 As Double = 43.58 Dim d2 As Double = 6.42 Dim d3 As Double = Dividieren(d1, d2) Console.WriteLine("{0} durch {1} ist {2}.", i1, i2, i3) Console.WriteLine("{0} durch {1} ist {2}.", d1, d2, d3) Console.ReadLine() End Sub End Module 2.4.5 Rekursive Funktionen Rekursive Funktionen sind Funktionen, die sich selber aufrufen. Dies klingt erst mal komisch, findet aber, vor allem in der Mathematik, Verwendung. So wird die Fakultät so definiert: n! = (n-1)*n Dies lässt sich natürlich gut in eine rekursive Funktion stecken: Function Fakultät(ByVal zahl As Integer) As Integer If zahl = 1 Then Return 1 Return Fakultät(zahl - 1) End Function Und so funktioniert die Funktion: Als erstes wird überprüft, ob der Parameter den Wert 1 hat, wenn ja, gibt die Funktion 1 zurück. Ansonsten ruft die Funktion sich selbst mit dem um eins verminderten Wert auf. Dass die Funktion überprüft, ob der Parameter den Wert 1 hat, ist wichtig. Wenn diese Überprüfung nicht wäre, würde die Funktion sich unendlich lange aufrufen (na gut, nicht unendlich lange, sondern solange, bis der Stack überläuft - jedenfalls, die Funktion läuft ziemlich lange). Eine rekursive Funktion kann man zwar auch in eine Schleife umwandeln, dies ist meistens aber weniger elegant und auch weniger verständlich. Achten Sie nur auf eine Abbruchbedingung, die auch erfüllt wird, und nichts geht schief.
2.4.6. Mathematische Funktionen Das .NET Framework enthält natürlich die mathematischen Funktionen wie Sinus, Kosinus, Tangens, Absolutbetrag, … Diese Funktionen müssen Sie nicht selber schreiben, sondern für den ganzen mathematischen Kram gibt es eine Klasse - Math im System-Namespace. 2.4.6.1. Die Math-Klasse | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||


Mein Einstieg in VB.NET, Kapitel 2


