2. Podstawy języka VB.NET
2.1. Wprowadzenie
Na początku traktujemy VB.NET jako klasyczny język programowania. Kwestie związane z obiektami omówimy w dalszej części.
W programie występują dwa rodzaje elementów
- dane
- instrukcje, które nimi operują
Zazwyczaj staramy się oddzielić dane od instrukcji:
![]() |
2.2. Dane z VB.NET
VB.NET wykorzystuje następujące typy danych:
- liczby całkowite, rzeczywiste i dziesiętne
- znaki i ciągi znaków
- wartości logiczne
- daty
- obiekty
2.2.1. Wstępnie zdefiniowane typy danych
Typ VB | Typ .NET – odpowiednik | Rozmiar | Zakres wartości |
Boolean | System.Boolean | 2 bajty | True lub False. |
Bajt | System.Byte | 1 bajt | od 0 do 255 (bez znaku). |
Znak | System.Char | 2 bajty | Od 0 do 65 535 (bez znaku). |
Data | System.DateTime | 8 bajtów | Od 0:00:00 1 stycznia 0001 r. do 23:59:59 31 grudnia 9999 r. |
Liczba dziesiętna | System.Decimal | 16 bajtów | Od 0 do +/-79 228 162 514 264 337 593 543 950 335 bez miejsc po przecinku; od 0 do +/-7,9228162514264337593543950335 z 28 miejscami po przecinku; najmniejsza liczba różna od zera to +/-0,0000000000000000000000000001 (+/-1E-28). |
Double | System.Double | 8 bajtów | od -1,79769313486231E+308 do -4,94065645841247E-324 dla wartości ujemnych; od 4,94065645841247E-324 do 1,79769313486231E+308 dla wartości dodatnich. |
Liczba całkowita | System.Int32 | 4 bajty | od -2 147 483 648 do 2 147 483 647. |
Long | System.Int64 | 8 bajtów | od -9 223 372 036 854 775 808 do 9 223 372 036 854 775 807. |
Obiekt | System.Object | 4 bajty | W zmiennej typu Object można przechowywać dowolny typ. |
Short | System.Int16 | 2 bajty | od -32 768 do 32 767. |
Single | System.Single | 4 bajty | od -3,402823E+38 do -1,401298E-45 dla wartości ujemnych; od 1,401298E-45 do 3,402823E+38 dla wartości dodatnich. |
Ciąg znaków | System.String (klasa) | Od 0 do około 2 miliardów znaków Unicode. |
Z powyższej tabeli wynika, że istnieją dwa możliwe typy dla liczby całkowitej 32-bitowej: Integer i System.Int32. Oba typy są zamienne. To samo dotyczy pozostałych typów VB i ich odpowiedników na platformie .NET. Oto przykładowy program:
Module types
Sub Main()
' liczby całkowite
Dim var1 As Integer = 100
Dim var2 As Long = 10000000000L
Dim var3 As Byte = 100
Dim var4 As Short = 4
' liczby rzeczywiste
Dim var5 As Decimal = 4.56789D
Dim var6 As Double = 3.4
Dim var7 As Single = -0.000103F
' data
Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
' wartość logiczna
Dim var9 As Boolean = True
' znak
Dim var10 As Char = "A"c
' ciąg znaków
Dim var11 As String = "abcde"
' obiekt
Dim var12 As Object = New Object
' wyświetlenia
Console.Out.WriteLine("var1=" + var1.ToString)
Console.Out.WriteLine("var2=" + var2.ToString)
Console.Out.WriteLine("var3=" + var3.ToString)
Console.Out.WriteLine("var4=" + var4.ToString)
Console.Out.WriteLine("var5=" + var5.ToString)
Console.Out.WriteLine("var6=" + var6.ToString)
Console.Out.WriteLine("var7=" + var7.ToString)
Console.Out.WriteLine("var8=" + var8.ToString)
Console.Out.WriteLine("var9=" + var9.ToString)
Console.Out.WriteLine("var10=" + var10)
Console.Out.WriteLine("var11=" + var11)
Console.Out.WriteLine("var12=" + var12.ToString)
End Sub
End Module
Wykonanie programu daje następujące wyniki:
var1=100
var2=10000000000
var3=100
var4=4
var5=4,56789
var6=3,4
var7=-0,000103
var8=01/01/2003 12:08:04
var9=True
var10=A
var11=abcde
var12=System.Object
2.2.2. Zapis danych literałowych
145, -7, &FF (szesnastkowo) | |
100000L | |
134,789, -45E-18 (-45 × 10⁻¹⁸) | |
134.789F, -45E-18F (-45 10-18) | |
100000D | |
„A”c | |
„dzisiaj” | |
prawda, fałsz | |
New Date(2003, 1, 1) dla daty 01.01.2003 |
Należy zwrócić uwagę na następujące kwestie:
- 100000L, litera L oznacza, że liczba jest traktowana jako liczba całkowita typu long
- 134.789F, litera F oznacza, że liczba jest traktowana jako liczba rzeczywista o pojedynczej precyzji
- 100000D, litera D oznacza, że liczba jest traktowana jako liczba zmiennoprzecinkowa
- „A”c, aby przekształcić ciąg znaków „A” w znak „A”
- Ciąg znaków jest ujęty w znak ". Jeśli ciąg ma zawierać znak ", należy go powtórzyć, tak jak w "abcd""e", aby przedstawić ciąg [abcd"e].
2.2.3. Deklaracja danych
2.2.3.1. Rola deklaracji
Program operuje na danych charakteryzujących się nazwą i typem. Dane te są przechowywane w pamięci. Podczas kompilacji programu kompilator przypisuje każdej danym miejsce w pamięci określone adresem i rozmiarem. Czyni to na podstawie deklaracji wprowadzonych przez programistę. Ponadto deklaracje te pozwalają kompilatorowi wykrywać błędy programistyczne. Na przykład operacja x=x*2 zostanie uznana za błędną, jeśli x jest ciągiem znaków.
2.2.3.2. Deklaracja stałych
Składnia deklaracji stałej jest następująca:
const identyfikator as typ=wartość
na przykład [const PI as double=3.141592]. Po co deklarować stałe?
- Czytanie programu będzie łatwiejsze, jeśli nadamy stałej znaczącą nazwę: [const taux_tva as single=0.186F]
- Modyfikacja programu będzie łatwiejsza, jeśli „stała” ulegnie zmianie. Tak więc w powyższym przypadku, jeśli stawka VAT wzrośnie do 33%, jedyną zmianą, jaką trzeba będzie wprowadzić, będzie zmiana instrukcji definiującej jej wartość: [const taux_tva as single=0.336F]. Gdyby w programie użyto bezpośrednio wartości 0,186, konieczna byłaby modyfikacja wielu instrukcji.
2.2.3.3. Deklaracja zmiennych
Zmienna jest identyfikowana przez nazwę i odnosi się do typu danych. W nazwie VB.NET nie rozróżnia się wielkich i małych liter. Zatem zmienne FIN i fin są identyczne. Zmienne można zainicjować podczas ich deklaracji. Składnia deklaracji jednej lub kilku zmiennych jest następująca:
dim zmienna1, zmienna2, ..., zmienna n as identyfikator_typu
gdzie identificateur_de_type jest typem predefiniowanym lub typem zdefiniowanym przez programistę.
2.2.4. Konwersje między liczbami a ciągami znaków
nombre.ToString lub "" & liczba lub CType(liczba, String) | |
objet.ToString | |
Integer.Parse(ciąg znaków) lub Int32.Parse | |
Long.Parse (łańcuch) lub Int64.Parse | |
Double.Parse (łańcuch) | |
Single.Parse (ciąg znaków) |
Konwersja ciągu znaków na liczbę może się nie powieść, jeśli ciąg ten nie reprezentuje prawidłowej liczby. W takim przypadku generowany jest błąd krytyczny zwany wyjątkiem o nazwie VB.NET. Błąd ten można obsłużyć za pomocą następującej klauzuli try/catch:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception
traiter l'exception e
end try
instruction suivante
Jeśli funkcja nie generuje wyjątku, przechodzi się do następnej instrukcji, w przeciwnym razie przechodzi się do treści klauzuli catch, a następnie do następnej instrukcji. Do kwestii obsługi wyjątków powrócimy w późniejszym terminie. Poniżej przedstawiono program ilustrujący główne techniki konwersji między liczbami a ciągami znaków. W tym przykładzie funkcja wyświetla na ekranie wartość swojego parametru. Tak więc affiche(S) wyświetla na ekranie wartość S.
' dyrektywy
Option Strict On
' importowane przestrzenie nazw
Imports System
' moduł testowy
Module Module1
Sub Main()
' procedura główna
' dane lokalne
Dim S As String
Const i As Integer = 10
Const l As Long = 100000
Const f As Single = 45.78F
Dim d As Double = -14.98
' liczba --> ciąg znaków
affiche(CType(i, String))
affiche(CType(l, String))
affiche(CType(f, String))
affiche(CType(d, String))
'wartość logiczna --> ciąg znaków
Const b As Boolean = False
affiche(b.ToString)
' ciąg znaków --> liczba całkowita
Dim i1 As Integer = Integer.Parse("10")
affiche(i1.ToString)
Try
i1 = Integer.Parse("10.67")
affiche(i1.ToString)
Catch e As Exception
affiche("Erreur [10.67] : " + e.Message)
End Try
' ciąg znaków --> long
Dim l1 As Long = Long.Parse("100")
affiche("" + l1.ToString)
Try
l1 = Long.Parse("10.675")
affiche("" & l1)
Catch e As Exception
affiche("Erreur [10.675] : " + e.Message)
End Try
' ciąg znaków --> double
Dim d1 As Double = Double.Parse("100,87")
affiche(d1.ToString)
Try
d1 = Double.Parse("abcd")
affiche("" & d1)
Catch e As Exception
affiche("Erreur [abcd] : " + e.Message)
End Try
' ciąg znaków --> single
Dim f1 As Single = Single.Parse("100,87")
affiche(f1.ToString)
Try
d1 = Single.Parse("abcd")
affiche(f1.ToString)
Catch e As Exception
affiche("Erreur [abcd] : " + e.Message)
End Try
End Sub
' wyświetla
Public Sub affiche(ByVal S As String)
Console.Out.WriteLine("S=" + S)
End Sub
End Module
Otrzymane wyniki są następujące:
S=10
S=100000
S=45,78
S=-14,98
S=False
S=10
S=Erreur [10.67] : Le format de la chaîne d'entrée est incorrect.
S=100
S=Erreur [10.675] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
Należy zauważyć, że liczby rzeczywiste w postaci ciągu znaków muszą być zapisane z przecinkiem, a nie kropką. W związku z tym należy zapisać: Dim d As Double = -14.98, ale Dim d1 As Double = Double.Parse("100,87")
2.2.5. Tablice danych
Tablica VB.NET to obiekt służący do gromadzenia danych tego samego typu pod jednym identyfikatorem. Jej deklaracja wygląda następująco:
Dim Tablica(n) as typ lub Dim Tablica() as typ = New typ(n) {}
gdzie n jest indeksem ostatniego elementu tablicy. Składnia Tableau(i) odnosi się do danych o numerze i, gdzie i należy do przedziału [0,n]. Każde odwołanie do danych o numerze Tableau(i), gdzie i nie należy do przedziału [0,n], spowoduje wyjątek. Tablicę można zainicjować jednocześnie z jej zadeklarowaniem. W takim przypadku nie ma potrzeby podawania numeru ostatniego elementu.
Dim entiers() As Integer = {0, 10, 20, 30}
Tablice posiadają właściwość Length, która określa liczbę elementów tablicy. Oto przykładowy program:
Module tab0
Sub Main()
' pierwszą tablicę
Dim tab0(5) As Integer
For i As Integer = 0 To UBound(tab0)
tab0(i) = i
Next
For i As Integer = 0 To UBound(tab0)
Console.Out.WriteLine("tab0(" + i.ToString + ")=" + tab0(i).tostring)
Next
' druga tabela
Dim tab1() As Integer = New Integer(5) {}
For i As Integer = 0 To tab1.Length - 1
tab1(i) = i * 10
Next
For i As Integer = 0 To tab1.Length - 1
Console.Out.WriteLine("tab1(" + i.ToString + ")=" + tab1(i).tostring)
Next
End Sub
End Module
oraz jego wykonanie:
tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50
Dwuwymiarową tablicę można zadeklarować w następujący sposób:
Dim Tablica(n,m) as Typ lub Dim Tablica(,) as Typ = New Typ(n,m) {}
gdzie n+1 to liczba wierszy, a m+1 to liczba kolumn. Składnia Tablica(i,j) oznacza element o indeksie j w wierszu i tablicy Tablica. Tablicę dwuwymiarową można również zainicjować w momencie jej deklaracji:
Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
Liczbę elementów w każdym z wymiarów można uzyskać za pomocą metody GetLenth(i), gdzie i=0 oznacza wymiar odpowiadający pierwszemu indeksowi, i=1 – wymiar odpowiadający drugiemu indeksowi, … Oto przykładowy program:
Module Module2
Sub Main()
' pierwsza tabela
Dim tab0(2, 1) As Integer
For i As Integer = 0 To UBound(tab0)
For j As Integer = 0 To tab0.GetLength(1) - 1
tab0(i, j) = i * 10 + j
Next
Next
For i As Integer = 0 To UBound(tab0)
For j As Integer = 0 To tab0.GetLength(1) - 1
Console.Out.WriteLine("tab0(" + i.ToString + "," + j.ToString + ")=" + tab0(i, j).tostring)
Next
Next
' druga tabela
Dim tab1(,) As Integer = New Integer(2, 1) {}
For i As Integer = 0 To tab1.GetLength(0) - 1
For j As Integer = 0 To tab1.GetLength(1) - 1
tab1(i, j) = i * 100 + j
Next
Next
For i As Integer = 0 To tab1.GetLength(0) - 1
For j As Integer = 0 To tab1.GetLength(1) - 1
Console.Out.WriteLine("tab1(" + i.ToString + "," + j.ToString + ")=" + tab1(i, j).tostring)
Next
Next
End Sub
End Module
oraz wyniki jego wykonania:
tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50
Tablica tablic jest deklarowana w następujący sposób:
Dim Tablica(n)() as Typ lub Dim Tablica()() as Typ = new Typ(n)()
Powyższa deklaracja tworzy tablicę o n+1 wierszach. Każdy element Tablica(i) jest odwołaniem do tablicy jednowymiarowej. Tablicy te nie są tworzone podczas powyższej deklaracji. Poniższy przykład ilustruje tworzenie tablicy tablic:
' tabela tabel
Dim noms()() As String = New String(3)() {}
' inicjalizacja
For i = 0 To noms.Length - 1
noms(i) = New String(i) {}
For j = 0 To noms(i).Length - 1
noms(i)(j) = "nom" & i & j
Next
Next
W tym przypadku noms(i) jest tablicą zawierającą i+1 elementów. Ponieważ noms(i) jest tablicą, noms(i).Length stanowi liczbę jej elementów. Oto przykład łączący trzy rodzaje tablic, które właśnie omówiliśmy:
' dyrektywy
Option Strict On
Option Explicit On
' importy
Imports System
' klasa testowa
Module test
Sub main()
' zainicjowana tablica jednowymiarowa
Dim entiers() As Integer = {0, 10, 20, 30}
Dim i As Integer
For i = 0 To entiers.Length - 1
Console.Out.WriteLine("entiers[" & i & "]=" & entiers(i))
Next
' zainicjowana tablica dwuwymiarowa
Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
Dim j As Integer
For i = 0 To réels.GetLength(0) - 1
For j = 0 To réels.GetLength(1) - 1
Console.Out.WriteLine("réels[" & i & "," & j & "]=" & réels(i, j))
Next
Next
' tablica tablic
Dim noms()() As String = New String(3)() {}
' inicjalizacja
For i = 0 To noms.Length°- 1
noms(i) =°New String(i) {}
For j = 0 To noms(i).Length - 1
noms(i)(j) = "nom" & i & j
Next
Next
' wyświetlanie
For i = 0 To noms.Length°- 1
For j = 0 To noms(i).Length - 1
Console.Out.WriteLine("noms[" & i & "][" & j & "]=" & noms(i)(j))
Next
Next
End Sub
End Module
Podczas wykonywania otrzymujemy następujące wyniki:
entiers[0]=0
entiers[1]=10
entiers[2]=20
entiers[3]=30
réels[0,0]=0,5
réels[0,1]=1,7
réels[1,0]=8,4
réels[1,1]=-6
noms[0][0]=nom00
noms[1][0]=nom10
noms[1][1]=nom11
noms[2][0]=nom20
noms[2][1]=nom21
noms[2][2]=nom22
noms[3][0]=nom30
noms[3][1]=nom31
noms[3][2]=nom32
noms[3][3]=nom33
2.3. Podstawowe instrukcje dotyczące VB.NET
Rozróżnia się
1 polecenia podstawowe wykonywane przez komputer.
2 instrukcje sterujące przebiegiem programu.
Instrukcje podstawowe stają się jasne, gdy przyjrzymy się budowie mikrokomputera i jego urządzeń peryferyjnych.
![]() |
-
odczyt informacji z klawiatury
-
przetwarzanie informacji
-
zapisywanie informacji na ekranie
-
odczyt informacji z pliku na dysku
-
zapisywanie informacji do pliku na dysku
2.3.1. Zapis na ekranie
Istnieją różne instrukcje zapisywania na ekranie:
Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)
gdzie expression oznacza dowolny typ danych, który można przekonwertować na ciąg znaków w celu wyświetlenia na ekranie. W dotychczasowych przykładach używaliśmy wyłącznie instrukcji Console.Out.WriteLine(wyrażenie).
Klasa System.Console zapewnia dostęp do operacji zapisu na ekranie (Write, WriteLine). Klasa Console posiada dwie właściwości: Out i Error, które są strumieniami zapisu typu StreamWriter:
- Console.WriteLine() jest równoważne Console.Out.WriteLine() i zapisuje dane do strumienia Out, zwykle powiązanego z ekranem.
- Funkcja Console.Error.WriteLine() zapisuje dane do strumienia Error, który zazwyczaj jest również powiązany z ekranem.
Strumienie Out i Error są domyślnie powiązane z ekranem. Można je jednak przekierować do plików tekstowych w trakcie wykonywania programu, co omówimy wkrótce.
2.3.2. Odczyt danych wprowadzonych z klawiatury
Strumień danych pochodzących z klawiatury jest reprezentowany przez obiekt Console.In typu StreamReader. Ten typ obiektów umożliwia odczytanie wiersza tekstu za pomocą metody ReadLine:
Dim ligne As String = Console.In.ReadLine()
Wpisany na klawiaturze wiersz jest zapisywany w zmiennej ligne i może być następnie przetwarzany przez obiekt programme.Le. Strumień wejściowy (In) może zostać przekierowany do pliku, podobnie jak strumienie wyjściowe (Out) i błędów (Error).
2.3.3. Przykład operacji wejścia-wyjścia
Oto krótki program ilustrujący operacje wejścia i wyjścia z klawiatury/ekranu:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
' moduł
Module io1
Sub Main()
' zapis do strumienia Out
Dim obj As New Object
Console.Out.WriteLine(("" & obj.ToString))
' zapis do strumienia Error
Dim i As Integer = 10
Console.Error.WriteLine(("i=" & i))
' odczyt linii wprowadzonej z klawiatury
Console.Out.Write("Tapez une ligne : ")
Dim ligne As String = Console.In.ReadLine()
Console.Out.WriteLine(("ligne=" + ligne))
End Sub
End Module
oraz wyniki wykonania:
Instrukcje
Dim obj As New Object
Console.Out.WriteLine(obj.ToString)
służą jedynie pokazaniu, że dowolny obiekt może zostać wyświetlony. Nie będziemy tutaj wyjaśniać znaczenia tego, co jest wyświetlane.
2.3.4. Przekierowanie wejścia/wyjścia
W systemie DOS/Windows istnieją trzy standardowe urządzenia o nazwach:
- standardowe urządzenie wejściowe – domyślnie oznacza klawiaturę i ma numer 0
- standardowe urządzenie wyjściowe – domyślnie oznacza ekran i ma numer 1
- standardowe urządzenie błędów – domyślnie oznacza ekran i ma numer 2
W systemie VB.NET strumień zapisu Console.Out zapisuje dane na urządzeniu 1, strumień zapisu Console.Error zapisuje dane na urządzeniu 2, a strumień odczytu Console.In odczytuje dane z urządzenia 0. Uruchamiając program w oknie DOS w systemie Windows, można określić, które urządzenia będą oznaczone jako 0, 1 i 2 dla uruchamianego programu. Rozważmy następujący wiersz poleceń:
Korzystając z opcji programu pg, można przekierować standardowe urządzenia wejścia/wyjścia do plików:
standardowy strumień wejściowy nr 0 jest przekierowywany do pliku in.txt. W programie strumień Console.In będzie zatem pobierał dane z pliku in.txt. | |||
przekierowuje strumień wyjściowy nr 1 do pliku out.txt. W związku z tym w programie strumień Console.Out zapisze swoje dane do pliku out.txt | |||
to samo, ale zapisane dane są dodawane do aktualnej zawartości pliku out.txt. | |||
przekierowuje strumień nr 2 do pliku error.txt. Powoduje to, że w programie strumień Console.Error zapisze swoje dane do pliku error.txt | |||
to samo, ale zapisane dane są dodawane do aktualnej zawartości pliku error.txt. | |||
Urządzenia 1 i 2 są przekierowane do plików | |||
Należy zauważyć, że aby przekierować strumienie wejścia/wyjścia programu pg do plików, nie ma potrzeby modyfikowania programu pg. To właśnie program OS określa charakter urządzeń 0, 1 i 2. Rozważmy następujący program:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
' przekierowania
Module console2
Sub Main()
' odczyt strumienia In
Dim data As String = Console.In.ReadLine()
' zapis strumienia Out
Console.Out.WriteLine(("écriture dans flux Out : " + data))
' zapis strumienia Error
Console.Error.WriteLine(("écriture dans flux Error : " + data))
End Sub
End Module
Skompilujmy ten program:
dos>vbc es2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.
dos>dir
24/02/2004 15:39 416 es2.vb
11/03/2004 08:20 3 584 es2.exe
Przeprowadźmy pierwsze uruchomienie:
dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test
Poprzednie uruchomienie nie przekierowuje żadnego ze standardowych strumieni wejścia/wyjścia: In, Out, Error. Teraz przekierujemy wszystkie trzy strumienie. Strumień In zostanie przekierowany do pliku in.txt, strumień Out do pliku out.txt, a strumień Error do pliku error.txt. Przekierowanie to odbywa się w wierszu poleceń w postaci
Wykonanie daje następujące wyniki:
dos>more in.txt
un second test
dos>es2.exe 0<in.txt 1>out.txt 2>error.txt
dos>more out.txt
écriture dans flux Out : un second test
dos>more error.txt
écriture dans flux Error : un second test
Wyraźnie widać, że przepływy Out i Error nie zapisują danych na tych samych urządzeniach.
2.3.5. Przypisanie wartości wyrażenia do zmiennej
W tym miejscu skupiamy się na operacji variable=expression. Wyrażenie może być typu: arytmetycznego, relacyjnego, boolowskiego lub znakowego.
2.3.5.1. Lista operatorów
Działanie | Element języka |
^, –, *, /, \, Mod, +, = | |
=, ^=, *=, /=, \=, +=, -=, &= | |
=, <>, <, >, <=, >=, Like, Is | |
&, + | |
Not, And, Or, Xor, AndAlso, OrElse | |
AddressOf, GetType |
2.3.5.2. Wyrażenie arytmetyczne
Operatory wyrażeń arytmetycznych są następujące:
^, –, *, /, \, Mod, +, = |
+: dodawanie, -: odejmowanie, *: mnożenie, /: dzielenie zmiennoprzecinkowe, \: iloraz dzielenia całkowitego, Mod: reszta z dzielenia całkowitego, ^: potęgowanie. Zatem następujący program:
' operatory arytmetyczne
Module operateursarithmetiques
Sub Main()
Dim i, j As Integer
i = 4 : j = 3
Console.Out.WriteLine(i & "/" & j & "=" & (i / j))
Console.Out.WriteLine(i & "\" & j & "=" & (i \ j))
Console.Out.WriteLine(i & " mod " & j & "=" & (i Mod j))
Dim r1, r2 As Double
r1 = 4.1 : r2 = 3.6
Console.Out.WriteLine(r1 & "/" & r2 & "=" & (r1 / r2))
Console.Out.WriteLine(r1 & "^2=" & (r1 ^ 2))
Console.Out.WriteLine(Math.Cos(3))
End Sub
End Module
daje następujące wyniki:
Istnieje wiele funkcji matematycznych. Oto kilka z nich:
| pierwiastek kwadratowy |
| cosinus |
| Sinus |
| Tangens |
| x do potęgi y (x>0) |
| Funkcja wykładnicza |
| Logarytm naturalny |
| wartość bezwzględna |
Wszystkie te funkcje są zdefiniowane w klasie o nazwie .NET o nazwie Math. Korzystając z nich, należy poprzedzić je nazwą klasy, w której są zdefiniowane. W ten sposób napiszemy:
Pełna definicja klasy Math jest następująca:
Oznacza podstawę logarytmu naturalnego określoną przez stałą e. | |||
Oznacza stosunek obwodu koła do jego średnicy, określony przez stałą π. | |||
Przedefiniowana. Zwraca wartość bezwzględną podanej liczby. | |||
Zwraca kąt, którego cosinus jest równy podanej liczbie. | |||
Zwraca kąt, którego sinus jest równy podanej liczbie. | |||
Zwraca kąt, którego tangensem jest podana liczba. | |||
Zwraca kąt, którego tangens jest ilorazem dwóch podanych liczb. | |||
Generuje iloczyn całkowity dwóch liczb 32-bitowych. | |||
Zwraca najmniejszą liczbę całkowitą większą lub równą podanej liczbie. | |||
Zwraca cosinus podanego kąta. | |||
Zwraca cosinus hiperboliczny podanego kąta. | |||
Przedefiniowana. Zwraca iloraz dwóch liczb, przekazując resztę jako parametr wyjściowy. | |||
Zwraca e podniesione do podanej potęgi. | |||
Zwraca największą liczbę całkowitą nie większą niż podana liczba. | |||
Zwraca resztę z dzielenia podanej liczby przez inną liczbę. | |||
Przedefiniowana. Zwraca logarytm podanej liczby. | |||
Zwraca logarytm dziesiętny podanej liczby. | |||
Przeładowana. Zwraca większą z dwóch podanych liczb. | |||
Przepełnienie. Zwraca mniejszą z dwóch liczb. | |||
Zwraca podaną liczbę podniesioną do podanej potęgi. | |||
Przedefiniowana. Zwraca liczbę najbliższą podanej wartości. | |||
Przedefiniowana. Zwraca wartość wskazującą znak liczby. | |||
Zwraca sinus podanego kąta. | |||
Zwraca sinus hiperboliczny podanego kąta. | |||
Zwraca pierwiastek kwadratowy z podanej liczby. | |||
Zwraca tangens podanego kąta. | |||
Zwraca tangens hiperboliczny podanego kąta. | |||
Gdy funkcja jest określana jako „przeciążona”, oznacza to, że istnieje dla różnych typów parametrów. Na przykład funkcja Abs(x) istnieje dla x typu Integer, Long, Decimal, Single, Float. Dla każdego z tych typów istnieje osobna definicja funkcji Abs. Mówi się wówczas, że jest ona przeciążona.
2.3.5.3. Priorytety przy obliczaniu wyrażeń arytmetycznych
Priorytet operatorów podczas obliczania wyrażenia arytmetycznego jest następujący (od najwyższego do najniższego):
Kategoria | Operatory |
Wszystkie wyrażenia bez operatorów: funkcje, nawiasy | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - |
2.3.5.4. Wyrażenia relacyjne
Dostępne są następujące operatory:
=, <>, <, >, <=, >=, Like, Is |
=: równe, <>: nie równe, <: mniejsze niż (ściśle), >: większe niż (ściśle), <=: mniejsze lub równe, >=: większe lub równe, Like: pasuje do wzorca, Is: tożsamość obiektów. Wszystkie te operatory mają ten sam priorytet. Są one obliczane od lewej do prawej. Wynikiem wyrażenia relacyjnego jest wartość logiczna.
Porównanie ciągów znaków: rozważmy następujący program:
' przestrzenie nazw
Imports System
Module string1
Sub main()
Dim ch1 As Char = "A"c
Dim ch2 As Char = "B"c
Dim ch3 As Char = "a"c
Console.Out.WriteLine("A<B=" & (ch1 < ch2))
Console.Out.WriteLine("A<a=" & (ch1 < ch3))
Dim chat As String = "chat"
Dim chien As String = "chien"
Dim chaton As String = "chaton"
Dim chat2 As String = "CHAT"
Console.Out.WriteLine("chat<chien=" & (chat < chien))
Console.Out.WriteLine("chat<chaton=" & (chat < chaton))
Console.Out.WriteLine("chat<CHAT=" & (chat < chat2))
Console.Out.WriteLine("chaton like chat*=" & ("chaton" Like "chat*"))
End Sub
End Module
oraz wynik jego wykonania:
Niech C1 i C2 będą dwoma znakami. Można je porównać za pomocą operatorów: <, <=, =, <>, >, >=. Porównywane są wówczas ich wartości Unicode, które są liczbami. Zgodnie z kolejnością Unicode zachodzą następujące relacje:
spacja < .. < „0” < „1” < .. < „9” < .. < „A” < „B” < .. < „Z” < .. < „a” < „b” < .. < „z”
Ciągi znaków są porównywane znak po znaku. Pierwsza napotkana nierówność między dwoma znakami powoduje nierówność o tym samym znaczeniu w odniesieniu do ciągów znaków. Mając te wyjaśnienia, czytelnik powinien przeanalizować wyniki poprzedniego programu.
2.3.5.5. Wyrażenia boolowskie
Dostępne są następujące operatory:
Not, And, Or, Xor, AndAlso, OrElse |
Not: i logiczne, Or: lub logiczne, Not: negacja, Xor: lub wykluczające.
op1 AndAlso op2: jeśli op1 jest fałszywe, op2 nie jest obliczane, a wynik jest fałszywy.
op1 OrElse op2: jeśli op1 jest prawdziwe, op2 nie jest obliczane, a wynik jest prawdziwy.
Kolejność pierwszeństwa tych operatorów względem siebie jest następująca:
Not | |
And, AndAlso | |
Lub, OrElse | |
XOR |
Wynikiem wyrażenia boolowskiego jest wartość logiczna.
2.3.5.6. Operacje bitowe
Z jednej strony mamy te same operatory co w przypadku operatorów boolowskich, o tej samej kolejności pierwszeństwa. Znajdują się tu również dwa operatory przesunięcia: << i >>. Niech i oraz j będą dwiema liczbami całkowitymi.
przesuwa i o n bitów w lewo. Nowe bity to zera. | |
przesuwa i o n bitów w prawo. Jeśli i jest liczbą całkowitą ze znakiem (signed char, int, long), bit znaku pozostaje zachowany. | |
wykonuje operację logicznego OR bit po bicie na i i j. | |
wykonuje operację logicznego OR bit po bicie między i a j (OU). | |
zwiększa i o 1 | |
tworzy OU EXCLUSIF z i i j |
Oto następujący program:
Module operationsbit
Sub main()
' operacje na bitach
Dim i As Short = &H123F
Dim k As Short = &H7123
Console.Out.WriteLine("i<<4=" & (i << 4).ToString("X"))
Console.Out.WriteLine("i>>4=" & (i >> 4).ToString("X"))
Console.Out.WriteLine("k>>4=" & (k >> 4).ToString("X"))
Console.Out.WriteLine("i and 4=" & (i And 4).ToString("X"))
Console.Out.WriteLine("i or 4 =" & (i Or 4).ToString("X"))
Console.Out.WriteLine("not i=" & (Not i).ToString("X"))
End Sub
End Module
Jego wykonanie daje następujące wyniki:
2.3.5.7. Operator powiązany z operacją przypisania
Można zapisać a+=b, co oznacza a=a+b. Lista operatorów, które można łączyć z operacją przypisania, jest następująca:
^=, *=, /=, \=, +=, -=, &= |
2.3.5.8. Ogólna kolejność operacji
Kategoria | Operatory |
Wszystkie wyrażenia bez operatorów | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - | |
& | |
<<, >> | |
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is | |
Not | |
And, AndAlso | |
Lub, OrElse | |
XOR |
Gdy operand znajduje się pomiędzy dwoma operatorami o tej samej priorytecie, kolejność wykonywania operacji określa asocjatywność operatorów. Wszystkie operatory są asocjatywne z lewej strony, co oznacza, że operacje są wykonywane od lewej do prawej. Priorytet i asocjatywność można kontrolować za pomocą wyrażeń w nawiasach.
2.3.5.9. Konwersje typów
Istnieje szereg predefiniowanych funkcji umożliwiających konwersję jednego typu danych na inny. Ich lista przedstawia się następująco:
Funkcje te przyjmują jako argument wyrażenie liczbowe lub ciąg znaków. Typ wyniku podano w poniższej tabeli:
funkcja | wynik | Zakres wartości parametru funkcji |
Boolean | Dowolny prawidłowy ciąg znaków lub wyrażenie liczbowe. | |
Bajt | Od 0 do 255; ułamki są zaokrąglane. | |
Znak | Dowolny prawidłowy ciąg znaków; wartość może wynosić od 0 do 65 535. | |
Data | Dowolny prawidłowy zapis daty i godziny. | |
Double | -1,79769313486231E+308 do -4,94065645841247E-324 dla wartości ujemnych; od 4,94065645841247E-324 do 1,79769313486231E+308 dla wartości dodatnich. | |
Liczba dziesiętna | +/-79 228 162 514 264 337 593 543 950 335 dla liczb bez miejsc po przecinku. Zakres wartości liczb z 28 miejscami po przecinku wynosi +/-7,9228162514264337593543950335. Najmniejsza liczba różna od zera to 0,0000000000000000000000000001. | |
Liczba całkowita | od -2 147 483 648 do 2 147 483 647; ułamki są zaokrąglane. | |
Liczba długa | od -9 223 372 036 854 775 808 do 9 223 372 036 854 775 807; ułamki są zaokrąglane. | |
| Obiekt | Dowolne prawidłowe wyrażenie. |
Krótki | Od -32 768 do 32 767; ułamki są zaokrąglane. | |
Single | od -3,402823E+38 do -1,401298E-45 dla wartości ujemnych; od 1,401298E-45 do 3,402823E+38 dla wartości dodatnich. | |
Ciąg znaków | Wartości zwracane przez funkcję Cstr zależą od argumentu expression. |
Oto przykładowy program:
Module conversion
Sub main()
Dim var1 As Boolean = CBool("true")
Dim var2 As Byte = CByte("100")
Dim var3 As Char = CChar("A")
Dim var4 As Date = CDate("30 janvier 2004")
Dim var5 As Double = CDbl("100,45")
Dim var6 As Decimal = CDec("1000,67")
Dim var7 As Integer = CInt("-30")
Dim var8 As Long = CLng("456")
Dim var9 As Short = CShort("-14")
Dim var10 As Single = CSng("56,78")
Console.Out.WriteLine("var1=" & var1)
Console.Out.WriteLine("var2=" & var2)
Console.Out.WriteLine("var3=" & var3)
Console.Out.WriteLine("var4=" & var4)
Console.Out.WriteLine("var5=" & var5)
Console.Out.WriteLine("var6=" & var6)
Console.Out.WriteLine("var7=" & var7)
Console.Out.WriteLine("var8=" & var8)
Console.Out.WriteLine("var9=" & var9)
Console.Out.WriteLine("var10=" & var10)
End Sub
End Module
oraz wyniki jego wykonania:
var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
Można również użyć funkcji CType(expression, type), jak pokazano w poniższym programie:
Module ctype1
Sub main()
Dim var1 As Boolean = CType("true", Boolean)
Dim var2 As Byte = CType("100", Byte)
Dim var3 As Char = CType("A", Char)
Dim var4 As Date = CType("30 janvier 2004", Date)
Dim var5 As Double = CType("100,45", Double)
Dim var6 As Decimal = CType("1000,67", Decimal)
Dim var7 As Integer = CType("-30", Integer)
Dim var8 As Long = CType("456", Long)
Dim var9 As Short = CType("-14", Short)
Dim var10 As Single = CType("56,78", Single)
Dim var11 As String = CType("47,89", String)
Dim var12 As String = 47.89.ToString
Dim var13 As String = "" & 47.89
Console.Out.WriteLine("var1=" & var1)
Console.Out.WriteLine("var2=" & var2)
Console.Out.WriteLine("var3=" & var3)
Console.Out.WriteLine("var4=" & var4)
Console.Out.WriteLine("var5=" & var5)
Console.Out.WriteLine("var6=" & var6)
Console.Out.WriteLine("var7=" & var7)
Console.Out.WriteLine("var8=" & var8)
Console.Out.WriteLine("var9=" & var9)
Console.Out.WriteLine("var10=" & var10)
Console.Out.WriteLine("var11=" & var11)
Console.Out.WriteLine("var12=" & var12)
Console.Out.WriteLine("var13=" & var13)
End Sub
End Module
co daje następujące wyniki:
var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
var11=47,89
var12=47,89
var13=47,89
2.4. Instrukcje dotyczące kontroli przebiegu programu
2.4.1. Zatrzymanie
Metoda Exit zdefiniowana w klasie Environment umożliwia zatrzymanie wykonywania programu:
[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )
zatrzymuje bieżący proces i zwraca wartość exitCode do procesu nadrzędnego. Ten ostatni może wykorzystać wartość exitCode. W przypadku wartości DOS ta zmienna statusowa jest zwracana do DOS w zmiennej systemowej ERRORLEVEL, której wartość można sprawdzić w pliku wsadowym. W systemie Unix wartość exitCode jest przechwytywana przez zmienną $?.
przerwie wykonywanie programu z wartością stanu równą 0.
2.4.2. Prosta struktura wyboru
- każda akcja znajduje się w osobnym wierszu
- klauzula else może nie występować.
Struktury wyboru można zagnieżdżać, jak pokazuje poniższy przykład:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module if1
Sub main()
Dim i As Integer = 10
If i > 4 Then
Console.Out.WriteLine(i & " est > " & 4)
Else
If i = 4 Then
Console.Out.WriteLine(i & " est = " & 4)
Else
Console.Out.WriteLine(i & " est < " & 4)
End If
End If
End Sub
End Module
Uzyskany wynik:
2.4.3. Struktura przypadków
Składnia jest następująca:
select case expression
case liste_valeurs1
actions1
case liste_valeurs2
actions2
...
case else
actions_sinon
end select
- Typ [expression] musi być jednym z następujących typów:
- klauzula [case else] może nie występować.
- [liste_valeursi] to możliwe wartości wyrażenia. [listes_valeursi] reprezentuje listę warunków: warunek1, warunek2, ..., warunekx. Jeśli [expression] spełnia jeden z warunków, wykonywane są działania związane z klauzulą [liste_valeursi]. Warunki mogą mieć następującą postać:
- val1 to val2: prawdziwe, jeśli [expression] należy do dziedziny [val1,val2]
- val1: prawdziwe, jeśli [expression] jest równe val1
- is > val1: prawdziwe, jeśli [expression] > val1. Słowo kluczowe [is] może nie występować
- to samo dotyczy operatorów =, <, <=, >, >=, <>
- wykonane zostaną tylko te akcje, które są związane z pierwszym sprawdzonym warunkiem.
Rozważmy następujący program:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module selectcase1
Sub main()
Dim i As Integer = 10
Select Case i
Case 1 To 4, 7 To 8
Console.Out.WriteLine("i est dans l'intervalle [1,4] ou [7,8]")
Case Is > 12
Console.Out.WriteLine("i est > 12")
Case Is < 15
Console.Out.WriteLine("i est < 15")
Case Is < 20
Console.Out.WriteLine("i est < 20")
End Select
End Sub
End Module
Daje to następujące wyniki:
2.4.4. Struktura powtórzeń
2.4.4.1. Znana liczba powtórzeń
For counter [ As datatype ] = start To end [ Step step ]
actions
Next [ counter ]
Operacje są wykonywane dla każdej wartości przyjmowanej przez zmienną [counter]. Rozważmy następujący program:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module for1
Sub main()
Dim somme As Integer = 0
Dim résultat As String = "somme("
For i As Integer = 0 To 10 Step 2
somme += i
résultat += " " + i.ToString
Next
résultat += ")=" + somme.ToString
Console.Out.WriteLine(résultat)
End Sub
End Module
Wyniki:
Inną strukturą iteracji o znanej liczbie iteracji jest następująca:
For Each element [ As datatype ] In groupe
[ actions ]
Next [ element ]
- groupe to zbiór obiektów. Zbiorem obiektów, który już znamy, jest tablica
- datatype jest typem obiektów w tej kolekcji. W przypadku tablicy byłby to typ elementów tablicy
- element jest zmienną lokalną pętli, która będzie kolejno przyjmować wszystkie wartości z kolekcji.
Zatem poniższy kod:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module foreach1
Sub main()
Dim amis() As String = {"paul", "hélène", "jacques", "sylvie"}
For Each nom As String In amis
Console.Out.WriteLine(nom)
Next
End Sub
End Module
wyświetliłby:
2.4.4.2. Nieznana liczba powtórzeń
W tym przypadku istnieje wiele struktur w formacie VB.NET.
Do { While | Until } condition
[ statements ]
Loop
Pętla jest wykonywana tak długo, jak długo warunek jest spełniony (while) lub do momentu, gdy warunek zostanie spełniony (until). Pętla może nigdy nie zostać wykonana.
Do
[ statements ]
Loop { While | Until } condition
Pętla jest wykonywana tak długo, jak długo warunek jest spełniony (while) lub do momentu, gdy warunek zostanie spełniony (until). Pętla jest zawsze wykonywana co najmniej raz.
While condition
[ statements ]
End While
Pętla jest wykonywana tak długo, jak długo warunek jest spełniony. Pętla może nigdy nie zostać wykonana. Poniższe pętle obliczają sumę pierwszych 10 liczb całkowitych.
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module boucles1
Sub main()
Dim i, somme As Integer
i = 0 : somme = 0
Do While i < 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do Until i = 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop Until i = 11
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop While i < 11
Console.Out.WriteLine("somme=" + somme.ToString)
End Sub
End Module
2.4.4.3. Instrukcje dotyczące zarządzania pętlą
wyjście z pętli do ... loop | |
wyjście z pętli for |
2.5. Struktura programu VB.NET
Program VB.NET, który nie wykorzystuje klas zdefiniowanych przez użytkownika ani funkcji innych niż funkcja główna Main, może mieć następującą strukturę:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports espace1
Imports ....
Module nomDuModule
Sub main()
....
End Sub
End Module
- Dyrektywa [Option Explicit on] wymusza deklarowanie zmiennych. W przypadku VB.NET nie jest to obowiązkowe. Zmienna niezadeklarowana ma wówczas typ Object.
- Dyrektywa [Option Strict on] zabrania wszelkich konwersji typów danych, które mogą prowadzić do utraty danych, oraz wszelkich konwersji między typami liczbowymi a ciągami znaków. Należy wówczas wyraźnie korzystać z funkcji konwersji.
- Program importuje wszystkie przestrzenie nazw, których potrzebuje. Nie wprowadziliśmy jeszcze tego pojęcia. W poprzednich programach często spotykaliśmy instrukcje typu:
W rzeczywistości powinniśmy byli napisać:
gdzie System to przestrzeń nazw zawierająca klasę [Console]. Importując przestrzeń nazw [System] za pomocą instrukcji Imports, VB.NET będzie ją systematycznie przeszukiwać, gdy napotka nieznaną klasę. Będzie powtarzać wyszukiwanie we wszystkich zadeklarowanych przestrzeniach nazw, aż znajdzie poszukiwaną klasę. Piszemy zatem:
' przestrzenie nazw
Imports System
....
Console.Out.WriteLine(unechaine)
Przykładowy program mógłby wyglądać następująco:
' opcje
Option Explicit On
Option Strict On
'przestrzenie nazw
Imports System
' moduł główny
Module main1
Sub main()
Console.Out.WriteLine("main1")
End Sub
End Module
Ten sam program można zapisać w następujący sposób:
' opcje
Option Explicit On
Option Strict On
'przestrzenie nazw
Imports System
' klasa testowa
Public Class main2
Public Shared Sub main()
Console.Out.WriteLine("main2")
End Sub
End Class
W tym przypadku wykorzystujemy pojęcie klasy, które zostanie omówione w następnym rozdziale. Gdy taka klasa zawiera procedurę statyczną (shared) o nazwie main, zostaje ona wykonana. Wprowadzamy ten zapis tutaj, ponieważ język C#, będący odpowiednikiem VB.NET, zna wyłącznie pojęcie klasy, c.a.d, co oznacza, że każdy wykonywany kod musi koniecznie należeć do klasy. Pojęcie klasy należy do programowania obiektowego. Narzucanie go przy projektowaniu każdego programu jest nieco nieuzasadnione. Widać to tutaj w wersji 2 poprzedniego programu, gdzie jesteśmy zmuszeni do wprowadzenia pojęcia klasy i metody statycznej tam, gdzie nie jest to konieczne. Dlatego też w dalszej części będziemy wprowadzać pojęcie klasy tylko wtedy, gdy będzie to konieczne. W pozostałych przypadkach będziemy korzystać z pojęcia modułu, tak jak w wersji 1 powyżej.
2.6. Kompilacja i uruchomienie programu VB.NET
Kompilacja programu VB.NET wymaga jedynie pliku SDK.NET. Rozważmy następujący program:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module boucles1
Sub main()
Dim i, somme As Integer
i = 0 : somme = 0
Do While i < 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do Until i = 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop Until i = 11
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop While i < 11
Console.Out.WriteLine("somme=" + somme.ToString)
End Sub
End Module
Załóżmy, że znajduje się on w pliku o nazwie [boucles1.vb]. Aby go skompilować, postępujemy w następujący sposób:
dos>dir boucles1.vb
11/03/2004 15:55 583 boucles1.vb
dos>vbc boucles1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.
dos>dir boucles1.*
11/03/2004 16:04 601 boucles1.vb
11/03/2004 16:04 3 584 boucles1.exe
Program vbc.exe to kompilator VB.NET. Tutaj znajdował się on w pliku PATH z pliku DOS:
dos>path
PATH=E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;E:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;E:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;E:\WINNT\Microsoft.NET\Framework\v1.1.4322;e:\winnt\system32;e:\winnt;
dos>dir E:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc.exe
21/02/2003 10:20 737 280 vbc.exe
Kompilator [vbc] generuje plik .exe, który może być uruchomiony przez maszynę wirtualną .NET:
2.7. Przykład IMPOTS
Zamierzamy napisać program umożliwiający obliczenie podatku podatnika. Rozważamy uproszczony przypadek podatnika, który ma do zadeklarowania wyłącznie swoje wynagrodzenie:
- obliczamy liczbę udziałów pracownika nbParts = nbEnfants/2 + 1, jeśli jest on osobą stanu wolnego, nbEnfants/2+2, jeśli jest żonaty, gdzie nbEnfants to liczba jego dzieci.
- jeśli ma co najmniej troje dzieci, przysługuje mu dodatkowa połowa udziału
- oblicza się jego dochód podlegający opodatkowaniu R = 0,72 * S, gdzie S to jego roczne wynagrodzenie
- oblicza się jego współczynnik rodzinny QF = R / nbParts
- oblicza się jego podatek I. Rozważmy następującą tabelę:
12620,0 | 0 | 0 |
13190 | 0,05 | 631 |
15640 | 0,1 | 1290,5 |
24 740 | 0,15 | 2072,5 |
31810 | 0,2 | 3309,5 |
39 970 | 0,25 | 4900 |
48360 | 0,3 | 6898,5 |
55790 | 0,35 | 9316,5 |
92970 | 0,4 | 12106 |
127 860 | 0,45 | 16754,5 |
151250 | 0,50 | 23147,5 |
172 040 | 0,55 | 30710 |
195 000 | 0,60 | 39312 |
0 | 0,65 | 49062 |
Każdy wiersz zawiera 3 pola. Aby obliczyć podatek I, należy znaleźć pierwszy wiersz, w którym QF <= pole1. Na przykład, jeśli QF = 23000, znajdziemy wiersz
Podatek I wynosi wówczas 0,15*R – 2072,5*nbParts. Jeśli QF jest takie, że relacja QF <= pole1 nigdy nie jest spełniona, wówczas stosuje się współczynniki z ostatniego wiersza. W tym przypadku:
co daje podatek I = 0,65*R – 49062*nbParts. Odpowiedni program VB.NET wygląda następująco:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module impots
' ------------ main
Sub Main()
' tabele danych niezbędne do obliczenia podatku
Dim Limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
Dim CoeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}
' pobieramy stan cywilny
Dim OK As Boolean = False
Dim reponse As String = Nothing
While Not OK
Console.Out.Write("Etes-vous marié(e) (O/N) ? ")
reponse = Console.In.ReadLine().Trim().ToLower()
If reponse <> "o" And reponse <> "n" Then
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
Else
OK = True
End If
End While
Dim Marie As Boolean = reponse = "o"
' liczba dzieci
OK = False
Dim NbEnfants As Integer = 0
While Not OK
Console.Out.Write("Nombre d'enfants : ")
reponse = Console.In.ReadLine()
Try
NbEnfants = Integer.Parse(reponse)
If NbEnfants >= 0 Then
OK = True
Else
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End If
Catch
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End Try
End While
' wynagrodzenie
OK = False
Dim Salaire As Integer = 0
While Not OK
Console.Out.Write("Salaire annuel : ")
reponse = Console.In.ReadLine()
Try
Salaire = Integer.Parse(reponse)
If Salaire >= 0 Then
OK = True
Else
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End If
Catch
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End Try
End While
' obliczanie liczby udziałów
Dim NbParts As Decimal
If Marie Then
NbParts = CDec(NbEnfants) / 2 + 2
Else
NbParts = CDec(NbEnfants) / 2 + 1
End If
If NbEnfants >= 3 Then
NbParts += 0.5D
End If
' dochód podlegający opodatkowaniu
Dim Revenu As Decimal
Revenu = 0.72D * Salaire
' współczynnik rodzinny
Dim QF As Decimal
QF = Revenu / NbParts
' wyszukiwanie przedziału podatkowego odpowiadającego QF
Dim i As Integer
Dim NbTranches As Integer = Limites.Length
Limites((NbTranches - 1)) = QF
i = 0
While QF > Limites(i)
i += 1
End While
' podatek
Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)
' wyświetla się wynik
Console.Out.WriteLine(("Impôt à payer : " & impots))
End Sub
End Module
Program kompiluje się w oknie DOS za pomocą polecenia:
dos>vbc impots1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
dos>dir impots1.exe
24/02/2004 15:42 5 632 impots1.exe
W wyniku kompilacji powstaje plik wykonywalny impots.exe. Należy zauważyć, że plik impots.exe nie jest bezpośrednio wykonywalny przez procesor. W rzeczywistości zawiera on kod pośredni, który można wykonać wyłącznie na platformie .NET. Uzyskane wyniki są następujące:
dos>impots1
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : 3
Salaire annuel : 200000
Impôt à payer : 16400
dos>impots1
Etes-vous marié(e) (O/N) ? n
Nombre d'enfants : 2
Salaire annuel : 200000
Impôt à payer : 33388
dos>impots1
Etes-vous marié(e) (O/N) ? w
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? q
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : q
Réponse incorrecte. Recommencez
Nombre d'enfants : 2
Salaire annuel : q
Réponse incorrecte. Recommencez
Salaire annuel : 1
Impôt à payer : 0
2.8. Argumenty programu głównego
Procedura główna Main może przyjmować jako parametr tablicę ciągów znaków:
Sub main(ByVal args() As String)
Parametr args to tablica ciągów znaków, która przechwytuje argumenty przekazane w wierszu poleceń podczas wywołania programu.
- args.Length to liczba elementów tablicy args
- args(i) to element i tablicy
Jeśli uruchomimy program P za pomocą polecenia: P arg0 arg1 … argn i jeśli procedura Main programu P jest zadeklarowana w następujący sposób:
Sub main(ByVal args() As String)
to otrzymamy arg(0)="arg0", arg(1)="arg1" … Oto przykład:
' wytyczne
Option Strict On
Option Explicit On
' przestrzenie nazw
Imports System
Module arg
Sub main(ByVal args() As String)
' liczba argumentów
console.out.writeline("Il y a " & args.length & " arguments")
Dim i As Integer
For i = 0 To args.Length - 1
Console.Out.WriteLine("argument n° " & i & "=" & args(i))
Next
End Sub
End Module
Wykonanie daje następujące wyniki:
2.9. Wyliczenia
Wymiennik to typ danych, którego domena wartości stanowi zbiór stałych całkowitoliczbowych. Rozważmy program, który ma zarządzać ocenami z egzaminu. Jest ich pięć: „Zadowalająco”, AssezBien, „Dobrze”, TrèsBien, „Doskonale”. Można by zatem zdefiniować wymiennik dla tych pięciu stałych:
Enum mention
Passable
AssezBien
Bien
TrésBien
Excellent
End Enum
Wewnętrznie te pięć stałych jest kodowanych za pomocą kolejnych liczb całkowitych, zaczynających się od 0 dla pierwszej stałej, 1 dla następnej itd. Zmienną można zadeklarować tak, aby przyjmowała te wartości z wyliczenia:
' zmienna przyjmująca wartości z wymienionej wyliczalnej
Dim maMention As mention = mention.Passable
Można porównać zmienną z różnymi możliwymi wartościami z tej wyliczalnej listy:
' test z wartością z wyliczenia
If (maMention = mention.Passable) Then
Console.Out.WriteLine("Peut mieux faire")
End If
Można uzyskać wszystkie wartości wyliczenia:
For Each m In mention.GetValues(maMention.GetType)
Console.Out.WriteLine(m)
Next
Podobnie jak typ prosty Integer jest równoważny strukturze Int32, tak typ prosty Enum jest równoważny strukturze Enum. Klasa ta posiada metodę statyczną GetValues, która pozwala uzyskać wszystkie wartości typu wyliczeniowego przekazanego jako parametr. Parametr ten musi być obiektem typu Type, który jest klasą zawierającą informacje o typie danych. Typ zmiennej v uzyskuje się za pomocą funkcji v.GetType(). Zatem w tym przypadku funkcja maMention.GetType() zwraca obiekt Type z wyliczenia mentions, a funkcja Enum.GetValues(maMention.GetType()) zwraca listę wartości wyliczenia mentions.
Ilustruje to poniższy program:
' dyrektywy
Option Strict On
Option Explicit On
' przestrzenie nazw
Imports System
Public Module enum2
' wyliczenie
Enum mention
Passable
AssezBien
Bien
TrèsBien
Excellent
End Enum
' strona testowa
Sub Main()
' zmienna pobierająca wartości z wymienionej listy wyliczeniowej
Dim maMention As mention = mention.Passable
' wyświetlanie wartości zmiennej
Console.Out.WriteLine("mention=" & maMention)
' test z wartością z wyliczenia
If (maMention = mention.Passable) Then
Console.Out.WriteLine("Peut mieux faire")
End If
' lista wartości literałowych
For Each m As mention In [Enum].GetValues(maMention.GetType)
Console.Out.WriteLine(m.ToString)
Next
' lista pełnych wpisów
For Each m As Integer In [Enum].GetValues(maMention.GetType)
Console.Out.WriteLine(m)
Next
End Sub
End Module
Wyniki wykonania są następujące:
2.10. Obsługa wyjątków
Wiele funkcji VB.NET może generować wyjątki, czyli błędy. Gdy funkcja może wygenerować wyjątek, programista powinien go obsłużyć, aby uzyskać programy bardziej odporne na błędy: należy zawsze unikać niekontrolowanego „zawieszenia” aplikacji.
Obsługa wyjątku odbywa się zgodnie z poniższym schematem:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception e)
traiter l'exception e
end try
instruction suivante
Jeśli funkcja nie generuje wyjątku, przechodzi się do następnej instrukcji; w przeciwnym razie przechodzi się do treści klauzuli catch, a następnie do następnej instrukcji. Należy zwrócić uwagę na następujące kwestie:
- e jest obiektem pochodnym typu Exception. Można być bardziej precyzyjnym, używając typów takich jak IOException, SystemException itp.: istnieje kilka rodzajów wyjątków. Pisząc catch e as Exception, wskazujemy, że chcemy obsłużyć wszystkie typy wyjątków. Jeśli kod klauzuli try może generować kilka typów wyjątków, możemy chcieć być bardziej precyzyjni, obsługując wyjątek za pomocą kilku klauzul catch:
try
appel de la fonction susceptible de générer l'exception
catch e as IOException
traiter l'exception e
catch e as SystemException
traiter l'exception e
end try
instruction suivante
- Do klauzul try/catch można dodać klauzulę finally:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception
traiter l'exception e
finally
code exécuté après try ou catch
end try
instruction suivante
Niezależnie od tego, czy wystąpi wyjątek, czy nie, kod klauzuli finally zostanie zawsze wykonany.
- W klauzuli catch może się zdarzyć, że nie będziemy chcieli korzystać z dostępnego obiektu Exception. Zamiast pisać catch e as Exception, piszemy wówczas catch.
- Klasa Exception posiada właściwość Message, która zawiera komunikat opisujący wystąpiły błąd. Jeśli więc chcemy go wyświetlić, napiszemy:
catch e as Exception
Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
...
end try
- Klasa Exception posiada metodę ToString, która zwraca ciąg znaków wskazujący typ wyjątku oraz wartość właściwości Message. Można zatem napisać:
catch ex as Exception
Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
...
end try
Poniższy przykład przedstawia wyjątek wygenerowany w wyniku użycia nieistniejącego elementu tablicy:
' opcje
Option Explicit On
Option Strict On
' przestrzenie nazw
Imports System
Module tab1
Sub Main()
' deklaracja i inicjalizacja tablicy
Dim tab() As Integer = {0, 1, 2, 3}
Dim i As Integer
' wyświetlanie tablicy za pomocą pętli for
For i = 0 To tab.Length - 1
Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
Next i
' wyświetlanie tablicy za pomocą pętli for each
Dim élmt As Integer
For Each élmt In tab
Console.Out.WriteLine(élmt)
Next élmt
' generowanie wyjątku
Try
tab(100) = 6
Catch e As Exception
Console.Error.WriteLine(("L'erreur suivante s'est produite : " & e.Message))
End Try
End Sub
End Module
Wykonanie programu daje następujące wyniki:
dos>exception1
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
0
1
2
3
L'erreur suivante s'est produite : L'index se trouve en dehors des limites du tableau.
Oto kolejny przykład obsługi wyjątku spowodowanego przypisaniem ciągu znaków do liczby, gdy ciąg ten nie reprezentuje liczby:
' opcje
Option Strict On
Option Explicit On
'importy
Imports System
Public Module console1
Public Sub Main()
' Zapytanie o nazwę
System.Console.Write("Nom : ")
' odczyt odpowiedzi
Dim nom As String = System.Console.ReadLine()
' zapytanie o wiek
Dim age As Integer
Dim ageOK As Boolean = False
Do While Not ageOK
' pytanie
Console.Out.Write("âge : ")
' odczyt i weryfikacja odpowiedzi
Try
age = Int32.Parse(System.Console.ReadLine())
If age < 0 Then Throw New Exception
ageOK = True
Catch
Console.Error.WriteLine("Age incorrect, recommencez...")
End Try
Loop
' wyświetlenie końcowe
Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
End Sub
End Module
Kilka wyników wykonania:
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans
2.11. Przekazywanie parametrów do funkcji
W tym miejscu zajmiemy się sposobem przekazywania parametrów do funkcji. Rozważmy funkcję:
Sub changeInt(ByVal a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
W definicji funkcji a nazywany jest parametrem formalnym. Znajduje się on tam wyłącznie na potrzeby definicji funkcji changeInt. Równie dobrze mógłby nosić nazwę b. Rozważmy teraz przykładowe wykorzystanie tej funkcji:
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
W instrukcji changeInt(wiek) parametr rzeczywisty age przekaże swoją wartość do parametru formalnego a. Interesuje nas sposób, w jaki parametr formalny pobiera wartość odpowiadającego mu parametru rzeczywistego.
2.11.1. Przekazywanie przez wartość
Poniższy przykład pokazuje, że parametry funkcji/procedury są domyślnie przekazywane przez wartość: oznacza to, że wartość parametru rzeczywistego jest kopiowana do odpowiadającego mu parametru formalnego. Mamy do czynienia z dwoma odrębnymi jednostkami. Jeśli funkcja modyfikuje parametr formalny, parametr rzeczywisty pozostaje niezmieniony.
' opcje
Option Explicit On
Option Strict On
' przekazywanie parametrów jako wartości do funkcji
Imports System
Module param1
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
Sub changeInt(ByVal a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
End Module
Otrzymane wyniki są następujące:
Wartość 20 parametru rzeczywistego została skopiowana do parametru formalnego a. Ten ostatni został następnie zmodyfikowany. Parametr rzeczywisty pozostał natomiast niezmieniony. Ten sposób przekazywania nadaje się do parametrów wejściowych funkcji.
2.11.2. Przekazywanie przez odwołanie
W przypadku przekazywania przez odwołanie parametr rzeczywisty i parametr formalny stanowią jedną i tę samą jednostkę. Jeśli funkcja modyfikuje parametr formalny, modyfikowany jest również parametr rzeczywisty. W przypadku VB.NET przed parametrem formalnym musi znajdować się słowo kluczowe ByRef. Oto przykład:
' opcje
Option Explicit On
Option Strict On
' przekazywanie parametrów przez wartość do funkcji
Imports System
Module param2
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
Sub changeInt(ByRef a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
End Module
oraz wyniki wykonania:
Parametr rzeczywisty został dostosowany do zmiany parametru formalnego. Ten sposób przekazywania nadaje się do parametrów wyjściowych funkcji.

