Skip to content

2. أساسيات لغة VB.NET

2.1. مقدمة

نتعامل مع لغة VB.NET في البداية كلغة برمجة تقليدية. وسنتناول الكائنات لاحقًا.

يوجد في البرنامج نوعان من العناصر

  • البيانات
  • الأوامر التي تعالجها

ونسعى عادةً إلى فصل البيانات عن التعليمات:

2.2. بيانات VB.NET

تستخدم البيانات الموجودة في VB.NET أنواع البيانات التالية:

  1. الأعداد الصحيحة، والأعداد الحقيقية، والأعداد العشرية
  1. الأحرف وسلاسل الأحرف
  2. القيم المنطقية
  3. التواريخ
  4. الكائنات

2.2.1. أنواع البيانات المحددة مسبقًا

النوع VB
النوع المكافئ .NET
الحجم
نطاق القيم
منطقية
System.Boolean
2 بايت
صحيح أو خطأ.
بايت
System.Byte
1 بايت
من 0 إلى 255 (غير موقعة).
Char
System.Char
2 بايت
من 0 إلى 65535 (غير موقعة).
التاريخ
System.DateTime
8 بايت
من 0:00:00 في 1 يناير 0001 إلى 23:59:59 في 31 ديسمبر 9999.
عشري
System.Decimal
16 بايت
من 0 إلى +/-79 228 162 514 264 337 593 543 950 335 بدون أرقام عشرية؛ من 0 إلى +/-7,9228162514264337593543950335 مع 28 رقمًا عشريًا؛ أصغر عدد غير صفر هو +/-0,0000000000000000000000000001 (+/-1E-28).
Double
System.Double
8 بايت
من -1،79769313486231E+308 إلى
-4,94065645841247E-324 للقيم السالبة؛ و4,94065645841247E-324 إلى 1,79769313486231E+308 للقيم الموجبة.
عدد صحيح
System.Int32
4 بايت
من -2 147 483 648 إلى 2 147 483 647.
طويل
System.Int64
8 بايت
-9 223 372 036 854 775 808 إلى 9 223 372 036 854 775 807.
الكائن
System.Object
4 بايت
يمكن تخزين أي نوع في متغير من نوع Object.
Short
System.Int16
2 بايت
من -32768 إلى 32767.
Single
System.Single
4 بايت
من -3،402823E+38 إلى -1،401298E-45 للقيم السالبة؛ ومن 1،401298E-45 إلى 3،402823E+38 للقيم الموجبة.
سلسلة
System.String (فئة)
 
من 0 إلى حوالي 2 مليار حرف Unicode.

في الجدول أعلاه، نجد أن هناك نوعين محتملين لعدد صحيح مكون من 32 بت: Integer و System.Int32. والنوعان قابلان للتبادل. وينطبق الأمر نفسه على الأنواع الأخرى VB وما يعادلها في منصة .NET. وفيما يلي مثال على برنامج:


Module types
    Sub Main()
        ' الأعداد الصحيحة
        Dim var1 As Integer = 100
        Dim var2 As Long = 10000000000L
        Dim var3 As Byte = 100
        Dim var4 As Short = 4
        ' الأعداد الحقيقية
        Dim var5 As Decimal = 4.56789D
        Dim var6 As Double = 3.4
        Dim var7 As Single = -0.000103F
        ' التاريخ
        Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
        ' قيمة منطقية
        Dim var9 As Boolean = True
        ' حرف
        Dim var10 As Char = "A"c
        ' سلسلة أحرف
        Dim var11 As String = "abcde"
        ' كائن
        Dim var12 As Object = New Object
        ' العروض
        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

يُنتج التنفيذ النتائج التالية:

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. ترميز البيانات الحرفية

Integer
145، -7، &FF (سداسي عشري)
Long
100000L
Double
134.789، -45E-18 (-45 × 10⁻¹⁸)
Single
134.789F، -45E-18F (-45 × 10⁻¹⁸)
Decimal
100000D
Char
"A"c
String
"اليوم"
Boolean
صحيح، خطأ
date
تاريخ جديد (2003، 1، 1) لـ 01/01/2003

تجدر الإشارة إلى النقاط التالية:

  • 100000L، حيث يشير الحرف L إلى أن الرقم يُعتبر عددًا صحيحًا طويلًا
  • 134.789F، حيث يشير الحرف F إلى أن الرقم يُعتبر عددًا حقيقيًا بدقة بسيطة
  • 100000D، حيث يشير الحرف D إلى أن الرقم يُعتبر عددًا حقيقيًا عشريًا
  • "A"c، لتحويل سلسلة الأحرف "A" إلى الحرف 'A'
  • يُحاط سلسلة الأحرف بحرف ".". وإذا كان يجب أن تحتوي السلسلة على حرف "."، فيجب تكراره كما في "abcd""e" لتمثيل السلسلة [abcd"e].

2.2.3. إعلان البيانات

2.2.3.1. دور الإعلانات

يعالج البرنامج البيانات التي تتميز باسم ونوع. يتم تخزين هذه البيانات في الذاكرة. عند ترجمة البرنامج، يخصص المُجمِّع لكل بيانات موقعًا في الذاكرة يتميز بعنوان وحجم. ويقوم بذلك بالاعتماد على الإعلانات التي أدرجها المبرمج. كما تسمح هذه الإعلانات للمترجم بالكشف عن أخطاء البرمجة. وهكذا، ستُعتبر العملية x=x*2 خاطئة إذا كانت x سلسلة أحرف على سبيل المثال.

2.2.3.2. إعلان الثوابت

صيغة إعلان الثابت هي كما يلي:

const المعرف as النوع=القيمة

على سبيل المثال [const PI as double=3.141592]. لماذا نعلن الثوابت؟

  1. سيكون قراءة البرنامج أسهل إذا أُعطيت الثابتة اسمًا ذي معنى: [const taux_tva as single=0.186F]
  2. سيكون تعديل البرنامج أسهل إذا تغيرت «الثابتة». وهكذا، في الحالة السابقة، إذا ارتفعت نسبة ضريبة القيمة المضافة إلى 33٪، فإن التعديل الوحيد الذي يجب إجراؤه هو تعديل التعليمات التي تحدد قيمتها: [const taux_tva as single=0.336F]. أما لو كنا قد استخدمنا الرقم 0.186 صراحةً في البرنامج، لكان علينا تعديل العديد من الأوامر.

2.2.3.3. إعلان المتغيرات

يتم تعريف المتغير باسم ما ويرتبط بنوع من أنواع البيانات. لا يميز VB.NET بين الأحرف الكبيرة والصغيرة. وبالتالي، فإن المتغيرين FIN و«fin» متطابقان. يمكن تهيئة المتغيرات عند إعلانها. وصيغة إعلان متغير واحد أو أكثر هي:

dim variable1,variable2,...,variablen as identifier_of_type

حيث identificateur_de_type هو نوع محدد مسبقًا أو نوع يحدده المبرمج.

2.2.4. التحويلات بين الأعداد وسلاسل الأحرف

nombre -> chaîne
nombre.ToString أو "" & رقم أو CType(رقم, String)
objet -> chaîne
objet.ToString
chaine -> Integer
Integer.Parse(سلسلة) أو Int32.Parse
chaîne -> Long
Long.Parse (سلسلة) أو Int64.Parse
chaîne -> Double
Double.Parse (سلسلة)
chaîne -> Single
Single.Parse (سلسلة)

قد يفشل تحويل سلسلة إلى رقم إذا كانت السلسلة لا تمثل رقمًا صالحًا. وعندئذٍ يتم إنشاء خطأ فادح يُسمى استثناءً في VB.NET. يمكن معالجة هذا الخطأ باستخدام الجملة التالية 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

إذا لم تولد الدالة استثناءً، ننتقل إلى التعليمات التالية، وإلا ننتقل إلى نص الجملة catch ثم إلى التعليمات التالية. سنعود لاحقًا إلى موضوع معالجة الاستثناءات. فيما يلي برنامج يعرض التقنيات الرئيسية للتحويل بين الأرقام وسلاسل الأحرف. في هذا المثال، تعرض الدالة قيمة معلمتها على الشاشة. وهكذا، فإن affiche(S) تعرض قيمة S على الشاشة.


' التوجيهات
Option Strict On

' مساحات الأسماء المستوردة
Imports System

' وحدة الاختبار
Module Module1

    Sub Main()
        ' الإجراء الرئيسي
        ' البيانات المحلية
        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

        ' عدد --> سلسلة
        affiche(CType(i, String))
        affiche(CType(l, String))
        affiche(CType(f, String))
        affiche(CType(d, String))

        'قيمة منطقية --> سلسلة
        Const b As Boolean = False
        affiche(b.ToString)

        ' سلسلة --> عدد صحيح
        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

        ' سلسلة --> عدد طويل
        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

        ' سلسلة --> دبل
        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

        ' سلسلة --> عدد أحادي
        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

    ' عرض
    Public Sub affiche(ByVal S As String)
        Console.Out.WriteLine("S=" + S)
    End Sub
End Module

النتائج التي تم الحصول عليها هي كما يلي:

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.

تجدر الإشارة إلى أن الأعداد الحقيقية في شكل سلسلة أحرف يجب أن تستخدم الفاصلة وليس النقطة العشرية. لذا نكتب Dim d As Double = -14.98 ولكن Dim d1 As Double = Double.Parse("100,87")

2.2.5. مصفوفات البيانات

المصفوفة VB.NET هي كائن يسمح بتجميع البيانات من نفس النوع تحت معرّف واحد. ويتم إعلانها على النحو التالي:

Dim Tableau(n) as type أو Dim Tableau() as type=New type(n) {}

حيث n هو مؤشر العنصر الأخير في المصفوفة. تشير الصيغة Tableau(i) إلى البيانات رقم i حيث i ينتمي إلى النطاق [0,n]. أي إشارة إلى البيانات Tableau(i) حيث لا ينتمي i إلى النطاق [0,n] ستؤدي إلى حدوث استثناء. يمكن تهيئة المصفوفة في نفس وقت إعلانها. في هذه الحالة، لا داعي للإشارة إلى رقم العنصر الأخير.


        Dim entiers() As Integer = {0, 10, 20, 30}

تحتوي المصفوفات على خاصية «Length» التي تمثل عدد عناصر المصفوفة. وفيما يلي مثال على برنامج:


Module tab0
    Sub Main()
        ' جدول أول
        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

        ' جدول ثانٍ
        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

ونتيجة تنفيذه:

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

يمكن تعريف مصفوفة ثنائية الأبعاد على النحو التالي:

Dim Tableau(n,m) as Type أو Dim Tableau(,) as Type=New Type(n,m) {}

حيث n+1 هو عدد الصفوف، وm+1 هو عدد الأعمدة. تشير الصيغة Tableau(i,j) إلى العنصر j في الصف i من Tableau. يمكن أيضًا تهيئة المصفوفة ثنائية الأبعاد في نفس الوقت الذي يتم فيه إعلانها:


        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}

يمكن الحصول على عدد العناصر في كل بُعد من خلال الدالة GetLenth(i) حيث يمثل i=0 البُعد المقابل للمؤشر الأول، وi=1 البُعد المقابل للمؤشر الثاني، ... وفيما يلي برنامج نموذجي:


Module Module2
    Sub Main()
        ' جدول أول
        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

        ' جدول ثانٍ
        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

وإليكم نتائج تنفيذه:

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

يتم إعلان مصفوفة المصفوفات على النحو التالي:

Dim Tableau(n)() as Type أو Dim Tableau()() as Type=new Type(n)()

يؤدي الإعلان أعلاه إلى إنشاء مصفوفة مكونة من n+1 صفوف. كل عنصر Tableau(i) هو مرجع مصفوفة أحادي البعد. لا يتم إنشاء هذه المصفوفات عند إجراء الإعلان أعلاه. يوضح المثال أدناه كيفية إنشاء مصفوفة من المصفوفات:


        ' جدول من الجداول
        Dim noms()() As String = New String(3)() {}
        ' التهيئة
        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

هنا، noms(i) هو مصفوفة مكونة من i+1 عنصرًا. وبما أن noms(i) هي مصفوفة، فإن noms(i).Length يمثل عدد عناصرها. وفيما يلي مثال يجمع بين الأنواع الثلاثة من المصفوفات التي عرضناها للتو:


' التوجيهات
Option Strict On
Option Explicit On 

' الاستيرادات
Imports System

' فئة الاختبار
Module test
    Sub main()
        ' مصفوفة أحادية البعد تم تهيئتها
        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

        ' مصفوفة ثنائية الأبعاد تم تهيئتها
        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

        ' مصفوفة من المصفوفات
        Dim noms()() As String = New String(3)() {}

        ' التهيئة
        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

        ' العرض
        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

عند التنفيذ، نحصل على النتائج التالية:

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. التعليمات الأساسية لـ VB.NET

يمكن التمييز بين

1 الأوامر الأساسية التي ينفذها الكمبيوتر.

2 الأوامر التي تتحكم في سير البرنامج.

تتضح الأوامر الأساسية عند النظر إلى بنية الحاسوب الصغير وأجهزته الطرفية.

  1. قراءة المعلومات الواردة من لوحة المفاتيح

  2. معالجة المعلومات

  3. كتابة المعلومات على الشاشة

  4. قراءة المعلومات من ملف على القرص

  5. كتابة المعلومات في ملف على القرص

2.3.1. الكتابة على الشاشة

توجد تعليمات مختلفة للكتابة على الشاشة:

Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)

حيث يمثل expression أي نوع من البيانات يمكن تحويله إلى سلسلة أحرف لعرضه على الشاشة. في الأمثلة التي رأيناها حتى الآن، لم نستخدم سوى الأمر Console.Out.WriteLine(التعبير).

تتيح الفئة System.Console الوصول إلى عمليات الكتابة على الشاشة (Write، WriteLine). تحتوي الفئة Console على خاصيتين هما Out و Error، وهما تدفقات كتابة من النوع StreamWriter:

  • تعتبر الدالة Console.WriteLine() مكافئة للدالة Console.Out.WriteLine() وتكتب على تدفق Out المرتبط عادةً بالشاشة.
  • تقوم الدالة Console.Error.WriteLine() بالكتابة على تدفق Error، والذي يرتبط عادةً هو الآخر بالشاشة.

يتم ربط التدفقين Out و Error بالشاشة بشكل افتراضي. ولكن يمكن إعادة توجيههما إلى ملفات نصية أثناء تشغيل البرنامج كما سنرى لاحقًا.

2.3.2. قراءة البيانات المكتوبة على لوحة المفاتيح

يُشار إلى تدفق البيانات الواردة من لوحة المفاتيح بالكائن Console.In من النوع StreamReader. يتيح هذا النوع من الكائنات قراءة سطر نصي باستخدام الطريقة ReadLine:


        Dim ligne As String = Console.In.ReadLine()

يتم تخزين السطر الذي تم كتابته على لوحة المفاتيح في المتغير ligne ويمكن بعد ذلك استخدامه بواسطة programme.Le، ويمكن إعادة توجيه تدفق In إلى ملف مثل تدفقي Out وError.

2.3.3. مثال على عمليات الإدخال والإخراج

فيما يلي برنامج قصير يوضح عمليات الإدخال والإخراج عبر لوحة المفاتيح/الشاشة:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
Imports System

' وحدة
Module io1
    Sub Main()
        ' الكتابة في دفق Out
        Dim obj As New Object
        Console.Out.WriteLine(("" & obj.ToString))

        ' الكتابة في دفق Error
        Dim i As Integer = 10
        Console.Error.WriteLine(("i=" & i))

        ' قراءة سطر تم إدخاله عبر لوحة المفاتيح
        Console.Out.Write("Tapez une ligne : ")
        Dim ligne As String = Console.In.ReadLine()
        Console.Out.WriteLine(("ligne=" + ligne))
    End Sub
End Module

ونتيجة التنفيذ:

System.Object
i=10
Tapez une ligne : ceci est un essai
ligne=ceci est un essai

التعليمات


        Dim obj As New Object
        Console.Out.WriteLine(obj.ToString)

موجودة هنا فقط لإظهار أن أي كائن يمكن عرضه. لن نسعى هنا إلى شرح معنى ما يتم عرضه.

2.3.4. إعادة توجيه الإدخال/الإخراج

يوجد في نظام DOS/Windows ثلاثة أجهزة قياسية تسمى:

  1. جهاز الإدخال القياسي - يشير افتراضيًا إلى لوحة المفاتيح ويحمل الرقم 0
  2. جهاز الإخراج القياسي - يشير افتراضيًا إلى الشاشة ويحمل الرقم 1
  3. جهاز الخطأ القياسي - يشير افتراضيًا إلى الشاشة ويحمل الرقم 2

في نظام VB.NET، يكتب تدفق الكتابة Console.Out على الجهاز 1، ويكتب تدفق الكتابة Console.Error على الجهاز 2، ويقرأ تدفق القراءة Console.In البيانات الواردة من الجهاز 0. عند تشغيل برنامج في نافذة DOS في نظام Windows، يمكن تحديد الأجهزة 0 و1 و2 للبرنامج الذي يتم تنفيذه. لنأخذ السطر التالي من الأوامر كمثال:

pg arg1 arg2 .. argn

من خلال المعلمات argi الخاصة بالبرنامج pg، يمكن إعادة توجيه أجهزة الإدخال/الإخراج القياسية إلى ملفات:

0<in.txt
يتم إعادة توجيه تدفق الإدخال القياسي رقم 0 إلى الملف in.txt. وبالتالي، سيستمد تدفق Console.In في البرنامج بياناته من الملف in.txt.
  
1>out.txt
يعيد توجيه المخرج رقم 1 إلى الملف out.txt. وهذا يعني أن تدفق Console.Out في البرنامج سيكتب بياناته في الملف out.txt
   
1>>out.txt
كما سبق، ولكن البيانات المكتوبة تُضاف إلى المحتوى الحالي للملف out.txt.
   
2>error.txt
يعيد توجيه المخرج رقم 2 إلى الملف error.txt. وهذا يعني أن تدفق Console.Error في البرنامج سيكتب بياناته في الملف error.txt
   
2>>error.txt
نفس الشيء، لكن البيانات المكتوبة تُضاف إلى المحتوى الحالي للملف error.txt.
   
1>out.txt 2>error.txt
يتم إعادة توجيه كل من الجهازين 1 و 2 إلى ملفات
   

تجدر الإشارة إلى أنه لإعادة توجيه تدفقات الإدخال/الإخراج للبرنامج pg إلى ملفات، لا يلزم تعديل البرنامج pg. فالبرنامج OS هو الذي يحدد طبيعة الأجهزة 0 و1 و2. لننظر إلى البرنامج التالي:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
Imports System

' عمليات إعادة التوجيه
Module console2
    Sub Main()
        ' قراءة تدفق In
        Dim data As String = Console.In.ReadLine()
        ' كتابة تدفق «Out»
        Console.Out.WriteLine(("écriture dans flux Out : " + data))
        ' كتابة تدفق Error
        Console.Error.WriteLine(("écriture dans flux Error : " + data))
    End Sub
End Module

لنقوم بتجميع هذا البرنامج:

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

لنقم بالتنفيذ الأول:

dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test

التشغيل السابق لا يعيد توجيه أي من تدفقات الإدخال/الإخراج القياسية In و Out و Error. سنقوم الآن بإعادة توجيه التدفقات الثلاثة. سيتم إعادة توجيه التدفق In إلى ملف in.txt، وسيتم إعادة توجيه التدفق Out إلى الملف out.txt، والتدفق Error إلى الملف error.txt. تتم عملية إعادة التوجيه هذه في سطر الأوامر بالشكل التالي

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

ويؤدي التنفيذ إلى النتائج التالية:

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

من الواضح أن التدفقين Out و Error لا يكتبان على نفس الأجهزة.

2.3.5. تعيين قيمة تعبير إلى متغير

نركز هنا على العملية «متغير = تعبير». يمكن أن يكون التعبير من النوع: الحسابي، أو العلائقي، أو المنطقي، أو النصي.

2.3.5.1. قائمة العوامل الحسابية

الإجراء
عنصر اللغة
Arithmétique
^، –، *، /، \، Mod، +، =
Assignation
=، ^=، *=، /=، \=، +=، -=، &=
Comparaison
=، <>، <، >، <=، >=، Like، Is
Concaténation
&، +
Opérations logiques/de bits
Not، And، Or، Xor، AndAlso، OrElse
Opérations diverses
AddressOf، GetType

2.3.5.2. التعبير الحسابي

المُشغِّلات المستخدمة في التعبيرات الحسابية هي التالية:

Arithmétique
^، –، *، /، \، Mod، +، =

+: الجمع، -: الطرح، *: الضرب، /: القسمة العشرية، \: حاصل القسمة الصحيحة، Mod: باقي القسمة الصحيحة، ^: الرفع إلى القوة. وبالتالي، فإن البرنامج التالي:


' المُشغِّلات الحسابية
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

يعطي النتائج التالية:

4/3=1,33333333333333
4\3=1
4 mod 3=1
4,1/3,6=1,13888888888889
4,1^2=16,81
-0,989992496600445

هناك العديد من الدوال الرياضية. وفيما يلي بعض منها:


Public Shared Function Sqrt(ByVal d As Double ) As Double
الجذر التربيعي

[Visual Basic]
Public Shared Function Cos(ByVal d As Double ) As Double
جيب التمام

Public Shared Function Sin(ByVal a As Double) As Double
جيب

[Visual Basic]
Public Shared Function Tan(ByVal a As Double) As Double
المماس

[Visual Basic]
Public Shared Function Pow(ByVal x As Double,ByVal y As Double) As Double
x أس y (x>0)

[Visual Basic]
Public Shared Function Exp(ByVal d As Double) As Double
الأسية

[Visual Basic]
Overloads Public Shared Function Log( ByVal d As Double ) As Double
اللوغاريتم النبيري

Overloads Public Shared Function Abs(ByVal value As Double ) As Double
القيمة المطلقة
....
 

جميع هذه الدوال مُعرَّفة في فئة تُسمى .NET تُسمى Math. عند استخدامها، يجب أن تُسبق باسم الفئة التي تم تعريفها فيها. وبالتالي، سنكتب:

        Dim r1, r2 As Double
        r2 = Math.Sqrt(9)
        r1 = Math.Cos(3)

التعريف الكامل للفئة Math هو كما يلي:

E
يمثل أساس اللوغاريتم الطبيعي المحدد بالثابت e.
   
PI
يمثل نسبة محيط الدائرة إلى قطرها، المحددة بالثابت π.
   
Abs
مُثبَّت. تُرجع القيمة المطلقة لعدد محدد.
  
Acos
تُرجع الزاوية التي يكون جيب جيبها هو العدد المحدد.
  
Asin
تُرجع الزاوية التي يكون جيبها هو العدد المحدد.
  
Atan
تُرجع الزاوية التي يكون ظلها هو العدد المحدد.
  
Atan2
تُرجع الزاوية التي يكون ظلها هو حاصل قسمة عددين محددين.
  
BigMul
يُنشئ حاصل الضرب الكامل لعددين من 32 بت.
  
Ceiling
تُرجع أصغر عدد صحيح يساوي أو يزيد عن العدد المحدد.
  
Cos
تُرجع جيب التمام للزاوية المحددة.
  
Cosh
تُرجع جيب التمام الزائدي للزاوية المحددة.
  
DivRem
مُعاد تعريفه. تُرجع حاصل قسمة عددين، مع تمرير الباقي كمعلمة إخراج.
  
Exp
تُرجع قيمة e مرفوعة إلى القوة المحددة.
  
Floor
تُرجع أكبر عدد صحيح لا يزيد عن العدد المحدد.
  
IEEERemainder
تُرجع باقي قسمة عدد محدد على عدد آخر.
  
Log
مُعرَّف. تُرجع اللوغاريتم لعدد محدد.
  
Log10
تُرجع اللوغاريتم العشري لعدد محدد.
  
Max
مُعاد تعريفه. يُرجع الأكبر من بين عددين محددين.
  
Min
مُعرَّف. تُرجع الأصغر من بين عددين.
  
Pow
تُرجع العدد المحدد مرفوعًا إلى القوة المحددة.
  
Round
مُعاد تعريفه. يُرجع العدد الأقرب إلى القيمة المحددة.
  
Sign
مُثبَّت. تُرجع قيمة تشير إلى إشارة العدد.
  
Sin
تُرجع جيب الزاوية المحددة.
  
Sinh
تُرجع الجيب الزائدي للزاوية المحددة.
  
Sqrt
تُرجع الجذر التربيعي لعدد محدد.
  
Tan
تُرجع الظل الزاوي للزاوية المحددة.
  
Tanh
تُرجع الظل الزائدي للزاوية المحددة.
  

عندما تُصنف دالة على أنها «مُثبَّتة»، فهذا يعني أنها موجودة لأنواع مختلفة من المعلمات. على سبيل المثال، الدالة Abs(x) موجودة لـ x من أنواع Integer و Long و Decimal و Single و Float. ويوجد تعريف منفصل للدالة Abs لكل نوع من هذه الأنواع. وعندئذٍ يُقال إنها مُثبَّتة.

2.3.5.3. أولويات تقييم التعبيرات الحسابية

أولوية العوامل الحسابية عند تقييم تعبير حسابي هي كما يلي (من الأعلى إلى الأدنى):

الفئة
المُشغِّلات
Primaire
جميع التعبيرات التي لا تحتوي على عوامل حسابية: الدوال، الأقواس
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -

2.3.5.4. التعبيرات العلائقية

المشغلات هي كما يلي:

Comparaison
=، <>، <، >، <=، >=، Like، Is

=: يساوي، <>: يختلف عن، <: أصغر من (بشكل صارم)، >: أكبر من (بشكل صارم)، <=: أصغر من أو يساوي، >=: أكبر من أو يساوي، Like: يطابق نموذجًا، Is: تطابق الكائنات. جميع هذه العوامل لها نفس الأولوية. يتم تقييمها من اليسار إلى اليمين. نتيجة التعبير العلائقي هي قيمة منطقية.

مقارنة سلاسل الأحرف: لنفترض البرنامج التالي:


' مساحات الأسماء
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

ونتيجة تنفيذه:

A<B=True
A<a=True
chat<chien=True
chat<chaton=True
chat<CHAT=False
chaton like chat*=True

لنفترض أن هناك حرفين هما C1 و C2. يمكن مقارنتهما باستخدام العوامل التالية: <، <=، =، <>، >، >=. وعندئذ يتم مقارنة قيم Unicode الخاصة بهذين الحرفين، وهي أرقام. ووفقًا لترتيب يونيكود، تكون العلاقات كما يلي:

مسافة < .. < '0' < '1' < .. < '9' < .. < 'A' < 'B' < .. < 'Z' < .. < 'a' < 'b' < .. < 'z'

تُقارن سلاسل الأحرف حرفًا حرفًا. أول عدم تساوي يُلاحظ بين حرفين يؤدي إلى عدم تساوي بنفس الاتجاه بين السلاسل. وبناءً على هذه التفسيرات، يُدعى القارئ إلى دراسة نتائج البرنامج السابق.

2.3.5.5. التعبيرات المنطقية

المُشغِّلات هي التالية:

Opérations logiques/de bits
Not، And، Or، Xor، AndAlso، OrElse

Not: «و» المنطقية، Or: «أو» المنطقية، Not: النفي، Xor: «أو» الحصري.

op1 AndAlso op2: إذا كان op1 خطأً، فلا يتم تقييم op2 وتكون النتيجة خطأً.

op1 OrElse op2: إذا كانت op1 صحيحة، لا يتم تقييم op2 وتكون النتيجة صحيحة.

ترتيب أولوية هذه العوامل فيما بينها هو كما يلي:

NOT logique
Not
AND logique
And، AndAlso
OR logique
أو، OrElse
XOR logique
Xor

نتيجة التعبير المنطقي هي قيمة منطقية.

2.3.5.6. معالجة البتات

نجد من ناحية نفس العوامل المستخدمة في العمليات المنطقية مع نفس الأولوية. كما نجد عاملين للإزاحة هما: << و >>. لنفترض أن i و j عددان صحيحان.

i<<n
يُزحزح i بمقدار n بتات إلى اليسار. والبتات الواردة هي أصفار.
i>>n
يُزحزح i بمقدار n بتات إلى اليمين. إذا كان i عددًا صحيحًا مُعلَّمًا (signed char، int، long)، يتم الحفاظ على بت الإشارة.
i & j
يقوم بإجراء عملية المنطقية ET بين i و j بتًا بتًا.
i | j
يقوم بإجراء عملية المنطقية بين i و j بتًا بتًا.
~i
يحول i إلى 1
i^j
يقوم بـ OU EXCLUSIF لـ i و j

لنفترض أن البرنامج التالي:


Module operationsbit
    Sub main()
        ' معالجة البتات
        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

يؤدي تنفيذه إلى النتائج التالية:

i<<4=23F0
i>>4=123
k>>4=712
i and 4=4
i or k =123F
not i=EDC0

2.3.5.7. المُشغِّل المرتبط بعملية التعيين

يمكن كتابة a+=b، وهو ما يعني a=a+b. وفيما يلي قائمة بالمعاملات التي يمكن دمجها مع عملية التعيين:

combinaison d'opérateurs
^=، *=، /=، \=، +=، -=، &=

2.3.5.8. الأولوية العامة للمشغلات

الفئة
المشغلون
Primaire
جميع التعبيرات التي لا تحتوي على عوامل
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -
Concaténation
&
Déplacement
<<, >>
Relationnel
=، <>، <، >، <=، >=، Like، Is، TypeOf...Is
NOT logique
ليس
AND logique
و، AndAlso
OR logique
أو، OrElse
XOR logique
Xor

عندما يتم وضع معامل بين عاملين لهما نفس الأولوية، فإن قابلية التجميع للعوامل تحدد الترتيب الذي يتم فيه تنفيذ العمليات. جميع العوامل قابلة للتجميع من اليسار، مما يعني أن العمليات يتم تنفيذها من اليسار إلى اليمين. يمكن التحكم في الأولوية وقابلية التجميع باستخدام التعبيرات الموضوعة بين الأقواس.

2.3.5.9. تحويلات الأنواع

يوجد عدد من الدوال المحددة مسبقًا التي تسمح بالتحويل من نوع بيانات إلى آخر. وفيما يلي قائمة بها:

CBool,CByte,CChar,CDate,CDbl,CDec,CInt,CLng,CObj,CShort,CSng,CStr

تقبل هذه الدوال كمعامل تعبيرًا رقميًا أو سلسلة أحرف. ويرد نوع النتيجة في الجدول التالي:

الدالة
النتيجة
نطاق قيم معلمة الدالة
CBool
منطقية
أي سلسلة أو تعبير رقمي صالح.
CByte
بايت
من 0 إلى 255؛ يتم تقريب الأجزاء الكسرية.
CChar
حرف
أي تعبير String صالح؛ يمكن أن تتراوح القيمة بين 0 و65535.
CDate
Date
أي تمثيل صالح للتاريخ والوقت.
CDbl
Double
-1,79769313486231E+308 إلى
-4,94065645841247E-324 للقيم السالبة؛ 4,94065645841247E-324 إلى 1,79769313486231E+308 للقيم الموجبة.
CDec
Decimal
+/-79 228 162 514 264 337 593 543 950 335 للأعداد التي لا تحتوي على أرقام عشرية. نطاق قيم الأعداد المكونة من 28 رقمًا عشريًا هو
+/-7,9228162514264337593543950335. أصغر عدد غير صفر هو 0,0000000000000000000000000001.
CInt
عدد صحيح
من -2 147 483 648 إلى 2 147 483 647؛ ويتم تقريب الكسور.
CLng
عدد طويل
من -9 223 372 036 854 775 808 إلى 9 223 372 036 854 775 807؛ يتم تقريب الكسور.

CObj
الموضوع
أي تعبير صالح.
CShort
قصير
من -32 768 إلى 32 767؛ يتم تقريب الكسور.
CSng
مفرد
من -3،402823E+38 إلى -1،401298E-45 للقيم السالبة؛ ومن 1،401298E-45 إلى 3،402823E+38 للقيم الموجبة.
CStr
سلسلة
تعتمد القيم التي ترجعها الدالة Cstr على الوسيطة expression.

فيما يلي مثال على البرنامج:


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

وإليكم نتائج تنفيذه:

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

يمكن أيضًا استخدام الدالة CType(expression, type) كما يوضح البرنامج التالي:


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

والذي يعطي النتائج التالية:

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. تعليمات مراقبة سير البرنامج

2.4.1. إيقاف

تسمح الطريقة Exit المُعرَّفة في الفئة Environment بإيقاف تنفيذ البرنامج:


[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )

توقف العملية الجارية وتُرجع القيمة exitCode إلى العملية الأم. ويمكن لهذه الأخيرة استخدام قيمة exitCode. في حالة DOS، يتم إرجاع متغير الحالة هذا إلى DOS في متغير النظام ERRORLEVEL، والذي يمكن اختبار قيمته في ملف دفعي. في نظام Unix، المتغير $? هو الذي يسترد قيمة exitCode.

    Environment.Exit(0)

سيوقف تنفيذ البرنامج بقيمة حالة تساوي 0.

2.4.2. هيكل اختيار بسيط

if condition then
    actions_alors
else
    actions_sinon
end if
  • كل إجراء في سطر منفصل
  • قد تكون العبارة else غائبة.

يمكن تداخل هياكل الاختيار كما يوضح المثال التالي:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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

النتيجة التي تم الحصول عليها:

10 est > 4

2.4.3. هيكل الحالات

الصيغة هي كما يلي:

select case expression
    case liste_valeurs1
        actions1
case liste_valeurs2
        actions2
...
case else
        actions_sinon
end select
  • يجب أن يكون نوع [expression] أحد الأنواع التالية:
Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, Object, Short, Single et String
  • يمكن أن تكون العبارة [case else] غائبة.
  • [liste_valeursi] هي القيم المحتملة للتعبير. [listes_valeursi] تمثل قائمة بالشروط condition1، condition2، ...، conditionx. إذا تحقق [expression] من أحد الشروط، يتم تنفيذ الإجراءات المرتبطة بالجملة [liste_valeursi]. يمكن أن تتخذ الشروط الشكل التالي:
  • val1 to val2: صحيح إذا كان [expression] ينتمي إلى المجال [val1,val2]
  • val1: صحيح إذا كان [expression] يساوي val1
  • is > val1: صحيح إذا كان [expression] > val1. قد تكون الكلمة الرئيسية [is] غائبة
  • وينطبق الأمر نفسه على العوامل =، <، <=، >، >=، <>
  • يتم تنفيذ الإجراءات المرتبطة بالشرط الأول الذي تم التحقق منه فقط.

لنأخذ البرنامج التالي كمثال:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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

ويعطي النتائج التالية:

i est < 15

2.4.4. هيكل التكرار

2.4.4.1. عدد التكرارات معروف


For counter [ As datatype ] = start To end [ Step step ]
   actions
Next [ counter ]

يتم تنفيذ الإجراءات لكل قيمة من القيم التي تتخذها المتغير [counter]. لنأخذ البرنامج التالي كمثال:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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

النتائج:

somme( 0 2 4 6 8 10)=30

فيما يلي بنية تكرار أخرى ذات عدد تكرارات معروف:


For Each element [ As datatype ] In groupe
   [ actions ]
Next [ element ]
  • groupe هي مجموعة من الكائنات. المجموعة التي نعرفها بالفعل هي المصفوفة
  • datatype هو نوع الكائنات في المجموعة. بالنسبة للمصفوفة، سيكون هذا هو نوع عناصر المصفوفة
  • element هو متغير محلي للحلقة سيأخذ بالتتابع جميع قيم المجموعة كقيم له.

وبالتالي، فإن الكود التالي:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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

سيعرض:

paul
hélène
jacques
sylvie

2.4.4.2. عدد التكرارات غير معروف

توجد العديد من الهياكل في VB.NET لهذه الحالة.


Do { While | Until } condition
   [ statements ]
Loop

يستمر التكرار طالما تم استيفاء الشرط (while) أو حتى يتم استيفاء الشرط (until). قد لا يتم تنفيذ الحلقة أبدًا.


Do
   [ statements ]
Loop { While | Until } condition

يتم تكرار الحلقة طالما أن الشرط صحيح (while) أو حتى يتحقق الشرط (until). يتم دائمًا تنفيذ الحلقة مرة واحدة على الأقل.


While condition
   [ statements ]
End While

يتم تكرار الحلقة طالما أن الشرط صحيح. وقد لا يتم تنفيذ الحلقة أبدًا. تحسب الحلقات التالية جميعها مجموع الأعداد الصحيحة العشرة الأولى.


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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
somme=55
somme=55
somme=55
somme=55

2.4.4.3. تعليمات إدارة الحلقة

exit do
يخرج من حلقة do ... loop
exit for
الخروج من حلقة for

2.5. بنية برنامج VB.NET

يمكن أن يكون للبرنامج VB.NET الذي لا يستخدم فئة محددة من قبل المستخدم ولا وظائف أخرى غير الوظيفة الرئيسية Main البنية التالية:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
Imports espace1
Imports ....

Module nomDuModule
    Sub main()
....
    End Sub
End Module
  • تفرض التوجيهية [Option Explicit on] الإعلان عن المتغيرات. أما في VB.NET، فإن الإعلان عن المتغيرات ليس إلزامياً. وبالتالي، يكون نوع المتغير غير المعلن عنه هو Object.
  • يحظر التوجيه [Option Strict on] أي تحويل لأنواع البيانات قد يؤدي إلى فقدان البيانات، وأي تحويل بين الأنواع الرقمية والسلاسل. لذا يجب استخدام دوال التحويل بشكل صريح.
  • يستورد البرنامج جميع مساحات الأسماء التي يحتاجها. لم نتطرق إلى هذا المفهوم بعد. وقد صادفنا في البرامج السابقة في كثير من الأحيان تعليمات من النوع التالي:
        Console.Out.WriteLine(unechaine)

كان ينبغي علينا في الواقع كتابة:

        System.Console.Out.WriteLine(unechaine)

حيث System هو مساحة الأسماء التي تحتوي على الفئة [Console]. عند استيراد مساحة الأسماء [System] باستخدام تعليمة Imports، ستقوم VB.NET بالبحث فيها بشكل منهجي كلما صادفت فئة غير معروفة لها. وستكرر البحث في جميع مساحات الأسماء المُعلنة حتى تعثر على الفئة المطلوبة. لذا نكتب:


' مساحات الأسماء
Imports System
....

        Console.Out.WriteLine(unechaine)

قد يكون مثال البرنامج كما يلي:


' خيارات
Option Explicit On 
Option Strict On

'مساحات الأسماء
Imports System

' الوحدة الرئيسية
Module main1
    Sub main()
        Console.Out.WriteLine("main1")
    End Sub
End Module

يمكن كتابة البرنامج نفسه بالطريقة التالية:


' خيارات
Option Explicit On 
Option Strict On

'مساحات الأسماء
Imports System

' فئة الاختبار
Public Class main2
    Public Shared Sub main()
        Console.Out.WriteLine("main2")
    End Sub
End Class

هنا، نستخدم مفهوم الفئة الذي سيتم تقديمه في الفصل التالي. عندما تحتوي هذه الفئة على إجراء ثابت (مشترك) يُسمى main، يتم تنفيذه. وإذا ما أدخلنا هذه الصيغة هنا، فذلك لأن لغة C#، التي تعتبر اللغة التوأم لـ VB.NET، لا تعرف سوى مفهوم الفئة، c.a.d، أي أن كل كود يتم تنفيذه ينتمي بالضرورة إلى فئة ما. ينتمي مفهوم الفئة إلى البرمجة الكائنية. وفرض استخدامه في تصميم أي برنامج يعد أمراً غير ملائم بعض الشيء. ونرى ذلك هنا في الإصدار 2 من البرنامج السابق حيث نضطر إلى إدخال مفهوم الفئة والطريقة الثابتة في مكان لا حاجة فيه إلى ذلك. ولذلك، لن نستخدم مفهوم الفئة إلا عند الضرورة. في الحالات الأخرى، سنستخدم مفهوم الوحدة النمطية كما في الإصدار 1 أعلاه.

2.6. ترجمة وتنفيذ برنامج VB.NET

لا يتطلب ترجمة برنامج VB.NET سوى SDK.NET. لنأخذ البرنامج التالي:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
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

لنفترض أنه موجود في ملف يسمى [boucles1.vb]. لتجميعه، نتبع الخطوات التالية:

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

البرنامج vbc.exe هو المُجمِّع VB.NET. هنا، كان موجودًا في PATH التابع لـ 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

يُنتج المُجمِّع [vbc] ملفًا .exe قابلاً للتنفيذ بواسطة الآلة الافتراضية .NET:

dos>boucles1
somme=55
somme=55
somme=55
somme=55

2.7. المثال IMPOTS

نقترح كتابة برنامج يسمح بحساب الضريبة المستحقة على أحد دافعي الضرائب. سنأخذ الحالة المبسطة لدافع ضرائب ليس لديه سوى راتبه الوحيد ليصرح عنه:

  • نحسب عدد حصص الموظف nbParts=nbEnfants/2 +1 إذا كان غير متزوج، nbEnfants/2+2 إذا كان متزوجًا، حيث nbEnfants هو عدد أطفاله.
  • وإذا كان لديه ثلاثة أطفال على الأقل، يحصل على نصف حصة إضافية
  • يُحسب دخله الخاضع للضريبة R=0.72*S حيث S هو راتبه السنوي
  • يُحسب معامل الأسرة الخاص به QF = R/nbParts
  • نحسب ضريبته I. لننظر إلى الجدول التالي:
12620.0
0
0
13190
0.05
631
15640
0.1
1290.5
24740
0.15
2072.5
31810
0.2
3309.5
39970
0.25
4900
48360
0.3
6898.5
55790
0.35
9316.5
92970
0.4
12106
127860
0.45
16754.5
151250
0.50
23147.5
172040
0.55
30710
195000
0.60
39312
0
0.65
49062

يحتوي كل سطر على 3 حقول. لحساب الضريبة I، نبحث عن أول سطر حيث QF <= الحقل 1. على سبيل المثال، إذا كان QF = 23000، فسنجد السطر

    24740        0.15        2072.5

وعندئذٍ تكون الضريبة I مساوية لـ 0.15*R - 2072.5*nbParts. إذا كان QF بحيث لا تتحقق العلاقة QF<=champ1 أبدًا، فسيتم استخدام معاملات السطر الأخير. وهنا:

    0                0.65        49062

مما يعطي الضريبة I=0.65*R - 49062*nbParts. البرنامج VB.NET المقابل هو التالي:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
Imports System

Module impots
    ' ------------ الرئيسي
    Sub Main()

        ' جداول البيانات اللازمة لحساب الضريبة
        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}

        ' يتم استرداد الحالة الاجتماعية
        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"

        ' عدد الأبناء
        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
        ' الراتب
        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
        ' حساب عدد الحصص
        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
        ' الدخل الخاضع للضريبة
        Dim Revenu As Decimal
        Revenu = 0.72D * Salaire

        ' الحصة العائلية
        Dim QF As Decimal
        QF = Revenu / NbParts

        ' البحث عن شريحة الضرائب المطابقة لـ 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
        ' الضريبة
        Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)

        ' عرض النتيجة
        Console.Out.WriteLine(("Impôt à payer : " & impots))
    End Sub
End Module

يتم ترجمة البرنامج في نافذة DOS بواسطة:

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

ينتج عن عملية التجميع ملف قابل للتنفيذ باسم impots.exe. تجدر الإشارة إلى أن ملف impots.exe لا يمكن تنفيذه مباشرةً بواسطة المعالج. فهو يحتوي في الواقع على كود وسيط لا يمكن تنفيذه إلا على منصة .NET. النتائج التي تم الحصول عليها هي كما يلي:

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. معلمات البرنامج الرئيسي

يمكن للإجراء الرئيسي Main أن يقبل مصفوفة من السلاسل كمعلمة:


    Sub main(ByVal args() As String)

المعلمة args هي مصفوفة من سلاسل الأحرف تستقبل المعلمات التي يتم تمريرها عبر سطر الأوامر عند استدعاء البرنامج.

  • args.Length هو عدد عناصر المصفوفة args
  • args(i) هو العنصر i من المصفوفة

إذا تم تشغيل البرنامج P باستخدام الأمر: P arg0 arg1argn وإذا تم تعريف الإجراء Main في البرنامج P على النحو التالي:


    Sub main(ByVal args() As String)

فسيكون arg(0)="arg0"، arg(1)="arg1" … وإليك مثالاً:


' التوجيهات
Option Strict On
Option Explicit On 

' مساحات الأسماء
Imports System

Module arg
    Sub main(ByVal args() As String)
        ' عدد الوسيطات
        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

يؤدي التنفيذ إلى النتائج التالية:

dos>arg1 a b c
Il y a 3 arguments
argument n° 0=a
argument n° 1=b
argument n° 2=c

2.9. التعدادات

التعداد هو نوع من أنواع البيانات يكون مجال قيمه مجموعة من الثوابت الصحيحة. لنفترض أن هناك برنامجًا يتعين عليه إدارة درجات الامتحانات. قد تكون هناك خمس درجات: مقبول، AssezBien، جيد، TrèsBien، ممتاز. يمكننا إذن تعريف تعداد لهذه الثوابت الخمس:


    Enum mention
        Passable
        AssezBien
        Bien
        TrésBien
        Excellent
    End Enum

داخليًا، يتم ترميز هذه الثوابت الخمس بأعداد صحيحة متتالية تبدأ بـ 0 للثابت الأول، و1 للثابت التالي، وهكذا... يمكن إعلان متغير بحيث يأخذ هذه القيم في التعداد:


        ' متغير يأخذ قيمه من قائمة التعداد المذكورة
        Dim maMention As mention = mention.Passable

يمكن مقارنة متغير بالقيم المختلفة الممكنة في التعداد:


        ' اختبار بقيمة من قائمة التعداد
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

يمكن الحصول على جميع قيم التعداد:


        For Each m In mention.GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next

وبنفس الطريقة التي يكون بها النوع البسيط Integer مكافئًا للبنية Int32، فإن النوع البسيط Enum مكافئ للبنية Enum. تحتوي هذه الفئة على طريقة ثابتة GetValues تسمح بالحصول على جميع قيم نوع معدد يتم تمريره كمعلمة. ويجب أن تكون هذه المعلمة كائنًا من نوع Type، وهي فئة تحتوي على معلومات حول نوع البيانات. يتم الحصول على نوع متغير v بواسطة الدالة v.GetType(). لذا، هنا تُرجع الدالة maMention.GetType() الكائن Type الخاص بالتعداد mentions، وتُرجع الدالة Enum.GetValues(maMention.GetType()) قائمة قيم التعداد mentions.

وهذا ما يوضحه البرنامج التالي:


' التوجيهات
Option Strict On
Option Explicit On 

' مساحات الأسماء
Imports System

Public Module enum2

    ' قائمة
    Enum mention
        Passable
        AssezBien
        Bien
        TrèsBien
        Excellent
    End Enum

    ' صفحة اختبار
    Sub Main()

        ' متغير يأخذ قيمه من قائمة التعداد المذكورة
        Dim maMention As mention = mention.Passable

        ' عرض قيمة المتغير
        Console.Out.WriteLine("mention=" & maMention)

        ' اختبار باستخدام قيمة من قائمة التعداد
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

        ' قائمة العناصر الحرفية
        For Each m As mention In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m.ToString)
        Next

        ' قائمة العناصر الكاملة
        For Each m As Integer In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next
    End Sub
End Module

نتائج التنفيذ هي كما يلي:


dos>enum2
mention=0
Peut mieux faire
Passable
AssezBien
Bien
TrèsBien
Excellent
0
1
2
3
4

2.10. إدارة الاستثناءات

قد تتسبب العديد من الوظائف VB.NET في حدوث استثناءات، أي أخطاء. عندما تكون إحدى الوظائف عرضة لتوليد استثناء، يجب على المبرمج معالجتها بهدف الحصول على برامج أكثر مقاومة للأخطاء: يجب دائمًا تجنب «تعطل» التطبيق بشكل مفاجئ.

تتم إدارة الاستثناء وفقًا للمخطط التالي:

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

إذا لم تولد الدالة استثناءً، فنتنتقل إلى التعليمات التالية، وإلا فإننا ننتقل إلى نص الجملة catch ثم إلى التعليمات التالية. تجدر الإشارة إلى النقاط التالية:

  • e هو كائن مشتق من النوع Exception. يمكننا أن نكون أكثر دقة باستخدام أنواع مثل IOException، SystemException، إلخ...: فهناك عدة أنواع من الاستثناءات. عند كتابة catch e as Exception، فإننا نشير إلى رغبتنا في معالجة جميع أنواع الاستثناءات. إذا كان من المحتمل أن يولد كود الجملة try عدة أنواع من الاستثناءات، فقد نرغب في أن نكون أكثر دقة من خلال معالجة الاستثناء باستخدام عدة جمل 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
  • يمكن إضافة جملة finally إلى الجمل try/catch:
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

سواء كان هناك استثناء أم لا، سيتم دائمًا تنفيذ كود البند finally.

  • في الجملة catch، قد لا نرغب في استخدام الكائن Exception المتاح. وبدلاً من كتابة catch e as Exception، نكتب catch.
  • تحتوي الفئة Exception على خاصية Message، وهي رسالة توضح تفاصيل الخطأ الذي حدث. لذا، إذا أردنا عرض هذه الرسالة، فسنكتب:
catch e as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
    ...
end try
  • تحتوي الفئة Exception على طريقة ToString التي تُرجع سلسلة أحرف تشير إلى نوع الاستثناء بالإضافة إلى قيمة الخاصية Message. وبذلك يمكننا كتابة:
catch  ex as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
    ...
end try

يوضح المثال التالي استثناءً ناتجًا عن استخدام عنصر مصفوفة غير موجود:


' خيارات
Option Explicit On 
Option Strict On

' مساحات الأسماء
Imports System

Module tab1
    Sub Main()
        ' إعلان وتهيئة مصفوفة
        Dim tab() As Integer = {0, 1, 2, 3}
        Dim i As Integer

        ' عرض المصفوفة باستخدام for
        For i = 0 To tab.Length - 1
            Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
        Next i

        ' عرض المصفوفة باستخدام حلقة for each
        Dim élmt As Integer
        For Each élmt In tab
            Console.Out.WriteLine(élmt)
        Next élmt

        ' توليد استثناء
        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

يؤدي تشغيل البرنامج إلى النتائج التالية:

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.

فيما يلي مثال آخر على كيفية معالجة الاستثناء الناتج عن تعيين سلسلة أحرف إلى رقم عندما لا تمثل السلسلة رقماً:


' خيارات
Option Strict On
Option Explicit On 

'الاستيرادات
Imports System

Public Module console1
  Public Sub Main()
    ' يُطلب الاسم
    System.Console.Write("Nom : ")

        ' قراءة الإجابة
    Dim nom As String = System.Console.ReadLine()

        ' يُطلب العمر
    Dim age As Integer
    Dim ageOK As Boolean = False
    Do While Not ageOK
      ' السؤال
      Console.Out.Write("âge : ")
      ' قراءة الإجابة والتحقق منها
      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

        ' العرض النهائي
    Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
  End Sub
End Module

بعض نتائج التنفيذ:

dos>console1
Nom : dupont
âge : 23
Vous vous appelez dupont et vous avez 23 ans
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans

2.11. تمرير المعلمات إلى دالة

نركز هنا على طريقة تمرير المعلمات إلى الدالة. لنفترض أن الدالة هي:


    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub    

في تعريف الدالة، يُسمى a «معلمة شكلية». وهي موجودة فقط لأغراض تعريف الدالة changeInt. وكان من الممكن أن تُسمى b أيضًا. لننظر الآن إلى أحد استخدامات هذه الدالة:


    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

هنا في التعليمات changeInt(age)، يُعد age هو المعلمة الفعلية التي ستنقل قيمتها إلى المعلمة الشكلية a. نحن مهتمون بكيفية استرداد المعلمة الشكلية لقيمة المعلمة الفعلية المقابلة لها.

2.11.1. التمرير بالقيمة

يوضح المثال التالي أن معلمات الدالة/الإجراء تُمرر افتراضيًا بالقيمة: أي أن قيمة المعلمة الفعلية تُنسخ إلى المعلمة الشكلية المقابلة. لدينا كيانان منفصلان. إذا قامت الدالة بتعديل المعلمة الشكلية، فإن المعلمة الفعلية لا تتغير على الإطلاق.


' خيارات
Option Explicit On 
Option Strict On

' تمرير المعلمات بالقيمة إلى دالة
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

النتائج التي تم الحصول عليها هي كما يلي:

Paramètre formel a=30
Paramètre effectif age=20

تم نسخ القيمة 20 للمعلمة الفعلية إلى المعلمة الشكلية a. ثم تم تعديل هذه المعلمة الشكلية. أما المعلمة الفعلية فقد بقيت دون تغيير. يناسب هذا النمط من التمرير معلمات الإدخال للدالة.

2.11.2. التمرير بالمرجع

في التمرير بالمرجع، يكون المعلمة الفعلية والمعلمة الشكلية كيانًا واحدًا. إذا قامت الدالة بتعديل المعلمة الشكلية، يتم تعديل المعلمة الفعلية أيضًا. في VB.NET، يجب أن يسبق المعلمة الشكلية الكلمة المفتاحية ByRef. فيما يلي مثال:


' خيارات
Option Explicit On 
Option Strict On

' تمرير المعلمات بالقيمة إلى دالة
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

ونتيجة التنفيذ:

Paramètre formel a=30
Paramètre effectif age=30

تبع المعلمة الفعلية تعديل المعلمة الشكلية. يناسب هذا النمط من التمرير معلمات الإخراج لدالة ما.