Instructiuni repetitive: Do While, For

Instructiunea Do While :

    Instructiunea Do While Se foloseste pentru a executa repetitiv o instructiune sau o secventa de instructiuni atata timp cat o expresie este adevarata.
  • Formatul instructiunii:

        Formatul instructiunii
        Do While (expresie)
          instructiuni
        Loop

        Instructiunea se executa repetat atīta timp cīt valoarea expresiei este adevarata. Testul are loc īnaintea fiecarei executii a instructiunii. Modul de functionare al instructiunii este urmatorul:
  •      Se testeaza expresia din paranteze. Daca ea este adevarata (sau expresia din paranteze are o valoare diferita de zero)
  •      Se executa corpul instructiunii while
  •      Se reia testarea si executia pana expresia devine falsa (sau valoarea expresiei din paranteze este zero)
  •      Se continua executia cu instructiunea de dupa corpul instructiunii while, deci instructiunea while se termina.



        Sa realizam un program care afiseaza primele 10 numere naturale.

    Module Module1
        ' Utilizarea instructiunilor repetitive
        ' Programul afiseaza primele 10 numere naturale
    
        Sub Main()
            Dim i As Integer = 1
            Console.Write("Numerele sunt: ")
            Do While (i <= 10)
                Console.Write(i & " ")
                i = i + 1
            Loop
            Console.ReadKey()
        End Sub
    End Module
    


        Schema logica de de mai jos, calculeaza n!. Sa realizam programul care implementeaza aceasta schema logica.



    Module Module1
        ' Utilizarea instructiunilor repetitive
        ' Programul calculeaza n Factorial
        Sub Main()
            Dim i, n As Integer
            Dim fact As Double = 1
            Console.WriteLine("Programul calculeaza n Factorial")
            Console.Write("Introduceti numarul n: ")
            n = Console.ReadLine
            i = 1
            Do While (i <= n)
                fact = fact * i
                i = i + 1
            Loop
            Console.Write(n & "!" & "=" & fact)
            Console.ReadKey()
        End Sub
    End Module
    


        Instructiunile repetitive se pot utiliza pentru calculul integralelor functiilor pe diverse intervale.
        Tinand cont ca integrala reprezinta aria suprafetei delimitata de functie pe intervalul dat, aceasta arie se poate calcula prin insumarea ariei dreptunghiurilor cuprinse sub graficul functiei pe intervalul dat. Spre exemplu integrala functiei x2 pe intervalul x0 - x1 este reprezenta in imaginea de jos.



        Cu cat impartim intervalul in mai multe dreptunghiuri, calculul integralei se face cu precizie mai mare.
        Se poate realiza deci o aplicatie pentru calculul integralei functiei f(x)=x2 pe intervalul x0-x1 astfel:

    Module Module1
        ' Utilizarea instructiunilor repetitive
        ' Programul calculeaza integrala functiei x^2 pe intervalul 0-10
        Sub Main()
            Dim s As Double = 0
            Dim x As Double
            Dim x0 As Double = 0
            Dim x1 As Double = 10
            Dim nr_pasi As Integer = 1000000
            Dim pas As Double = 0
            x = x0
            pas = (x1 - x0) / nr_pasi
    
            Console.WriteLine("Programul calculeaza n Factorial")
            Do While (x <= x1)
                s = s + x * x * pas
                x = x + pas
            Loop
            Console.Write("Integrala este: " & s)
            Console.ReadKey()
        End Sub
    End Module
    

        Primitiva functiei x2 este x3/3. Pe intervalul [0-10] integrala este 1000/3=333.333
        Daca se ruleaza programul cu nr_pasi=1000 obtinem rezultatul 333.834
        Daca se ruleaza programul cu nr_pasi=10000 obtinem rezultatul 333.383
        Daca se ruleaza programul cu nr_pasi=100000 obtinem rezultatul 333.338
        Daca se ruleaza programul cu nr_pasi=1000000 obtinem rezultatul 333.334
        Daca se ruleaza programul cu nr_pasi=10000000 obtinem rezultatul 333.333
        Se observa ca eroarea depinde de finetea pasului (numarul de pasi).

        Instructiunea Do While se foloseste la fel si in modul grafic Windows Forms Application. Sa folosim instructiunea while pentru a afisa o serie de dreptunghiuri concentrice de forma celor de mai jos:



         n_dreptunghiuri


        Deschidem un nou proiect Windows Forms Application intitulat "n_dreptunghiuri". De aceasta data nu mai plasam nici un Buton. Vom pune procedura noastra sa se execute odata cu deschiderea aplicatiei.
        Completam procedura deschisa pe evenimentul paint al form-ului cu:

        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    
            Dim i, j, h, w, d, n As Integer
            'i contor dreptunghiuri concentrice
            'n nr dreptunghiuri concentrice
            n = 10
            h = Me.Height - 30  'inaltimea maxima a dreptunghiurilor
            w = Me.Width          'latimea maxima a dreptunghiului
            d = h / 2 / n         'distanta intre doua dreptunghiuri concentrice			
            i = 0
            Dim Desen As Graphics = Me.CreateGraphics
            Dim creion_albastru As Pen
            creion_albastru = New Pen(Brushes.Blue, 1)
            Do While (i <= d * n)
                Desen.DrawRectangle(creion_albastru, i + 10, i + 10, (w - 30 - 2 * i), (h - 30 - 2 * i))
                i = i + d
            Loop
        End Sub
    

        Instructiunea: Desen.DrawRectangle(Creion_albastru, i+10, i+10, (w-30-2*i), (h-30-2*i)); traseaza un dreptunghi incepand cu pozitia x1=i la care s-a adaugat o margine de 10 pixeli si y1=i la care s-a adaugat o margine de 10 pixeli. Latimea dreptunghiului este w latimea maxima calculata - 2 margini de 15 pixeli adica 30 -2*i adica. I se incrementeaza cu d, d fiind distanta calculata intre doua dreptunghiuri Inaltimea este h -30-2*i similar cu latimea dreptunghiului.

        Ingineria electrica se ocupa in general de studiul si utilizarea semnalelor electice de diferite forme, valori si intensitati. Un mare rol important il are analiza semnalelor electrice, analiza care presupune in primul rand vizualizarea acestora. Exista o serie de dispozitive menite sa afiseze formele de unda a diferitelor semnale electrice (osciloscoape, vobuloscoape, analizoare spectrale etc..). De multe ori aceste semnale pot fi modelate matematic si simulate pe calculator. Vom incerca in continuare sa folosim programarea in mod grafic pentru a afisa diverse forme de unda ale diferitelor semnale electrice. Vom incepe prin a genera un grid peste care urmeaza in viitor sa trasam formele de unda.
        Sa incercam sa realizam aplicatia care traseaza urmatorul grid pe ecran:



         grid


        Deschidem un nou proiect Windows Forms Application intitulat "grid". Nu inseram nici un obiect pe form.
        Completam procedura deschisa pe evenimentul paint al form-ului cu:

        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim Desen As Graphics = Me.CreateGraphics
            Dim Creion_gri As Pen
            Creion_gri = New Pen(Brushes.Gray, 1)
            'linii verticale
            Dim i As Integer
            Do While (i <= Me.Width)
                Desen.DrawLine(Creion_gri, i, 0, i, Me.Height)
                i = i + 10
            Loop
            'linii orizontale
            i = 0
            Do While (i <= Me.Height)
                Desen.DrawLine(Creion_gri, 0, i, Me.Width, i)
                i = i + 10
            Loop
    
        End Sub
    

        Sa desenam acum graficul functiei sinus

        Deschidem un nou proiect Windows Forms Application intitulat "sinus_v0". Procedura de desenare se va execute odata cu deschiderea aplicatiei pe evenimentul paint.
        Completam procedura deschisa pe evenimentul paint al form-ului cu:

        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim i, y As Integer
            Dim factor_s As Integer = Me.Height / 2 - 22
            Dim Desen As Graphics = Me.CreateGraphics
            Dim Creion_albastru As Pen
            creion_albastru = New Pen(Brushes.Blue, 1)
            Desen.Clear(Me.BackColor)
            Do While (i <= Me.Width)
                y = 5 + factor_s * (1 - Math.Sin(0.0314 * i))
                Desen.DrawLine(Creion_albastru, i, Me.Height, i, y)
                i = i + 2
            Loop
        End Sub
    

        Dupa rularea programului ecranul aplicatiei afieaza:



         sinus_v0

        Dupa cum se vede in procedura ce se activeaza pe evenimentul "paint" al form-ului s-a folosit variabila "factor_s" pentru a defini factorul de scala. Avand in vedere ca vrem sa afisam graficul functiei sin(i) si sa dimensionam graficul in functie de marimea ferestrei deschise, definim acest factor de scala ca fiind:
    Me.Height/2-22 adica inaltimea form-ului curent/2-22( 22 de pixeli pentru a scadea latimea benzii de sus a formului in jur de 17 pixeli +5 pixeli loc liber) pentru a marca mijlocul form-ului.
        Stiind ca sin(i) poate lua valori inte +1 si -1, inmultim cu factorul de scala si graficul va fi desfasurat pe aproape toata zona libera din form.
        Valorile functiei sin(i) se calculeaza cu expresia:y=5+factor_s*(1-Math.Sin(0.0314*i));, unde am adaugat 5 pixeli pentru margine si valoarea functiei sin inmultita cu factorul de scala. I ia valori intre 0 si latimea form-ului cu increment 2. Am folosit increment 2 deoarece pentru increment 1 nu s-ar mai vedea liniile, ele fiind una langa alta, s-ar vedea o zona compacta. De ce am folosit sin(0.0314*i) si nu sin(i)?
        I ia valori intre 0 si this->Width. Am vrea sa afisam o semi-perioada pe 100 de puncte. Perioada functiei sin fiid 2 pi radiani ar rezulta 3,14/100 adica 0.0314.
        Putem imbunatati aplicatia de sus si sa cerem numarul de perioade care sa fie afisate, iar afisarea sa nu se mai faca folosind linii verticale ci linii care sa uneasca doua puncte consecutive. Vom introduce un obiect NumericUpDown cu numele "numericUpDown1" iar pe evenimentul "ValueChanged" vom introduce procedura:

        Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
            Dim x, rad As Double
            Dim i, y, y_v, lat, factor_s As Integer
            Dim Desen As Graphics = Me.CreateGraphics
            Dim Creion_albastru As Pen
            Creion_albastru = New Pen(Brushes.Blue, 1)
            Desen.Clear(Me.BackColor)
            y_v = 0
            i = 0
            factor_s = Me.Height / 2 - 37
            rad = Me.NumericUpDown1.Value
            lat = Me.Width
            Do While i <= lat
                x = i * rad * Math.PI / (lat - 10)
                y = 35 + factor_s * (1 - Math.Sin(x))
                Desen.DrawLine(Creion_albastru, i - 1, y_v, i, y)
                y_v = y
                i = i + 1
            Loop
        End Sub
    

        Rulam aplicatia, setam butonul numericUpDown1 la valoarea 10 si obtinem:



         sinus_v1

        Se observa ca:


    Instructiuni Do While imbricate:

        Instructiunile Do While se pot insera unele in altele pe oricate nivele. Se spune ca s-a imbricat o instructiune while in alta instructiune while.
        Folosind instructiunile Do Whilem se pot implementa algoritmi cu un grad inalt de complexitate.
        Sa incercam sa afisam pe ecran cercuri de diametru 25, cercuri asezate pe linii si coloane astfel incat sa umplem tot ecranul indiferent de marimea form-ului deschis. Vezi imaginea de jos



         cercuri


        Deschidem un nou proiect Windows Forms Application intitulat "cercuri".
        Completam procedura deschisa pe evenimentul paint al form-ului cu:

    Public Class Form1
    
        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim i, j As Integer
            Dim Desen As Graphics = Me.CreateGraphics
            Dim Creion_rosu As Pen
            Creion_rosu = New Pen(Brushes.Red, 1)
            Do While j <= Me.Height - 50
                i = 0
                Do While i <= Me.Width - 30
                    Desen.DrawEllipse(Creion_rosu, i, j, 25, 25)
                    i = i + 30
                Loop
                j = j + 30
            Loop
        End Sub
    End Class
    


    Instructiunea Do Until :
        Formatul instructiunii
        Do Until (expresie)
          instructiuni
        Loop

        Instructiunea se executa repetat pana cand valoarea expresiei devine adevarata.
        Testul are loc īnaintea fiecarei executii a instructiunii.
        Instructiunea Do Until se foloseste atunci cand se cunoaste conditia finala pana la care se repeta secventa de instructiuni
        Sa realizam un program care utilizeaza instructiunea Do Until pentru a afisa patratele primelor 10 numere naturale.

    Module Module1
        ' Utilizarea instructiuni repetitive Do Until
        ' Programul afiseaza patratele primelor 10 numere naturale
        Sub Main()
            Dim i As Integer = 1
            Console.Write("Numerele sunt: ")
            Do Until (i = 10)
                Console.Write(i * i & " ")
                i = i + 1
            Loop
            Console.ReadKey()
        End Sub
    End Module
    


        De multe ori e nevoie sa afisam pe un grafic valorile mai multor parametrii sau componente. La analiza spectrala de exemplu e necesara afisarea continutului de diferite substante dintr-un anumit compus. Un semnal electric poate contine o serie de armonici adica semnale sinusoidale de diferite frecvente si amplitudini. Un spectrometru poate afisa sub forma de histograma aceste armonici. Ne propunem sa folosim generatorul de numere aleatoare pentru a simula o histograma.
        Deschidem un nou proiect Windows Forms Application intitulat "histo" .
        Completam procedura deschisa pe evenimentul paint al form-ului cu:

    Public Class Form1
        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim i As Integer = 0
            Dim w_r, w_a As Double
            Dim Desen As Graphics = Me.CreateGraphics
            Dim n As Random
            Dim Creion_rosu, Creion_albastru As Pen
            Creion_rosu = New Pen(Brushes.Red, 2)
            Creion_albastru = New Pen(Brushes.Blue, 5)
            n = New Random()
            Desen.DrawLine(Creion_rosu, 7, 0, 7, Me.Height - 40)
            Desen.DrawLine(Creion_rosu, 6, Me.Height - 40, Me.Width - 20, Me.Height - 40)
            i = 14
            Do Until i > Me.Width - 20
                Desen.DrawLine(Creion_albastru, i, Me.Height - 40, i, n.Next(Me.Height - 50))
                i = i + 10
            Loop
        End Sub
    End Class
    

        Dupa rularea programului obtinem:



         histograma


    Instructiunea For :

        Instructiunea For se foloseste pentru a executa repetitiv o instructiune sau o secventa de instructiuni. De obicei implementeaza structura ciclica cu numar cunoscut de pasi.
  • Formatul instructiunii:

        Instructiunea For are urmatorul format:

        For expresie1 To expresie2
            instructiuni;
        Next
         expresie1 constituie initializarea ciclului si se executa o singura data īnaintea ciclului.
         expresie2 specifica testul care controleaza ciclul. El se executa īnaintea fiecarei iteratii. Daca conditia din test este adevarata atunci se executa corpul ciclului, care consta de cele mai multe ori īn modificarea valorii variabilei de control al ciclului.
         Se incrementeaza variabila din expresie1
         Se revine apoi la reevaluarea conditiei. Ciclul se termina cīnd expresie2 devine falsa.


        Instructiunea do executa cel putin o data instructiunea sau secventa de instructiuni.

        sa realizam un program care afiseaza 500 de cifre aleatoare intre 0-9 despartite prin spatiu

    Module Module1
        ' Utilizarea instructiuni repetitive For Next
        ' programul afiseaza 500 de cifre aleatoare intre 0-10 despartite prin spatiu
        Sub Main()
            Dim i As Integer
            Dim r As Double
            ' Initializarea generatorului de numere aleatoare.
            Randomize()
            For i = 0 To 500
                ' Generarea  unui numar aleator intre 0 si 100
                r = 10 * Rnd()
                Console.Write(" " & CInt(r))
            Next
            Console.ReadKey()
        End Sub
    End Module
    

        Dupa rularea programului in "Command Prompt" se afiseaza:



        Pentru a afisa texte in mod grafic desigur se pot folosi etichete carora sa le atribuim textele dorite. De multe ori trebuie sa scriem multe texte si la pozitii diferite. Solutia este sa desenam textele la fel cum desenam formele geometrice. Va trebui sa definim si sa initializam un obiect grafic pe care sa "desenam" aceste texte. Ne propunem deci sa scriem texte pe form-ul deschis la diferite coordonate, fara a folosi obiecte de tip label.
        Folosindu-ne de modul de "desenare" ale caracterelor sa incercam sa scriem cifrele de la 1 la 20 pe un form la apasarea unui buton "Start"
        Deschidem un nou proiect Windows Forms Application intitulat "linie_numere" si plasam un Buton "Start" cu numele button1.
        Completam procedura deschisa pe evenimentul click al butonului1 cu:

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim i As Integer
            Dim Desen As Graphics = Me.CreateGraphics
            Dim font_nina As Font
            font_nina = New Font("Nina", 8)
            For i = i To 20
                Desen.DrawString(i, font_nina, Brushes.Blue, 10 + i * 15, 50)
            Next
        End Sub
    End Class	
    

        Dupa rularea programului ecranul aplicatiei arata astfel:



         linie_numere


    Imbricarea instructiunilor for :

        Instructiunile for imbricate ne dau posibilitatea sa rezolvam aplicatii in care sunt necesare repetitii in cadrul unor repetitii. In cazul masivelor de date, al matricilor este nevoie de astfel de instructiuni imbricate. O simpla afisare de numere pe ecran sub forma de linii si coloane necesita instructiuni for imbricate. Instructiunile for imbricate se folosesc de obicei atunci cand cunoastem numarul de iteratii pentru fiecare ciclu.

        Sa afisam de exemplu numerele de la 100 la 150 pe 15 linii a cate 10 caractere.

    Module Module1
        ' Utilizarea instructiuni repetitive For Next
        ' programul afiseaza 150 de cifre
        Sub Main()
            Dim i, j, k As Integer
            k = 100
            For j = 0 To 15
                For i = 0 To 10
                    Console.Write(" " & k)
                    k = k + 1
                Next
                Console.WriteLine(":")
            Next
            Console.ReadKey()
        End Sub
    End Module
    

        Dupa rularea programului in "Command Prompt" se afiseaza:


    Structuri repetitive realizate cu timere :

        Utilizarea timerelor
        Deschidem un nou proiect Windows Forms Application intitulat "n_random". Vom plasa un obiect de tipul "Timer" numit timer1.

        Setam proprietatea "Enabled" la "True" iar proprietatea "Interval" la 500. Completam procedura deschisa pe evenimentul "Tick" al butonului timer1 cu:

        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Dim i As Integer = 0
            Dim w_r, w_a As Double
            Dim Desen As Graphics = Me.CreateGraphics
            Dim n As Random
            Dim Creion_rosu, Creion_albastru As Pen
            Creion_rosu = New Pen(Brushes.Red, 1)
            Creion_albastru = New Pen(Brushes.Blue, 1)
            n = New Random()
            Int(i = 0)
            Desen.Clear(Me.BackColor)
            i = 0
            For i = 1 To 100
                Desen.DrawRectangle(Creion_albastru, n.Next(Me.Width), n.Next(Me.Height), n.Next(75), n.Next(50))
                Desen.DrawEllipse(Creion_rosu, n.Next(Me.Width), n.Next(Me.Height), n.Next(50), n.Next(75))
            Next
        End Sub
    




         n_random