Documente Academic
Documente Profesional
Documente Cultură
Componenţa formulelor implică, într-o tratare pe puncte a problemei, construirea a trei structuri
repetitive cu un număr cunoscut de paşi sau într-o tratare cumulată a punctelor a) - c) a uneia
singure.
Citeşte
PS= 0
NU =
0
NV =
0
I =1
2
PS=PS+uI vI
NU = NU + uI2
NV = NV + vI2
I=I+1
NV = NV NU = NU I≤
n 2
Scrie
PS,Nu,NV
Stop
Figura 3.1.1
c2) Schemele logice cu proceduri sînt schemele logice care conţin, pe lîngă structurile de bază
discutate pînă în prezent, una sau mai multe structuri de tip procedură şi operaţii de intrare/ieşire.
Cu toate că întocmirea lor cere din partea programatorului experienţă, totuşi ele se recomandă
chiar şi în rezolvarea unor probleme simple sau în cazul programatorilor începători. Cu atît mai
mult, acestea se impun în cazul problemelor dificile pentru că, pe de o parte evidenţiază
componentele mari ce intervin în analiza acestora şi fixează părţile complexe ale lor prin apeluri
de procedură iar, pe de alta facilitează lucru în echipă.
Schema logică cu proceduri se defineşte printr-un ansamblu format dintr-o schemă logică
de program şi una sau mai multe structuri de tip procedură. Schema logică care apelează una sau
mai multe proceduri se numeşte schema logică principală sau apelantă, iar structura de tip
procedură apare sub denumirea de schemă logică apelată.
Cu alte cuvinte, schema logică cu proceduri se defineşte printr-un ansamblu format dintr-o
schemă logică apelantă şi una sau mai multe scheme logice apelate.
Deci, tratarea unei proceduri se realizează din două unghiuri:
- la nivel funcţional, ca o componentă a unei scheme logice principale, prin care se descrie un
apel de procedură, apel simbolizat grafic printr-un bloc de tipul 7 (vezi, secţiunea 1.2).
- la nivel structural, ca o structură de bază de tip procedură (descrisă în secţiunea 1.4.3).
La apelul unei proceduri se realizează următoarele operatii:
- parametri actuali vor înlocui parametri formali;
- procedura preia datele furnizate de schema logică apelantă. Nu toţi parametrilor actuali sînt
furnizori de date pentru procedură;
- se execută procedura în totalitate. Datelor de intrare primite din schema logică principală li se
adaugă şi cele declarate în procedura activată, atunci cînd este cazul;
- se dezactivează procedura;
- se revine în schema logică principală, la blocul care urmează imediat apelul de procedură.
Rezultatele caculate de procedură se transmit prin intermediul variabililor, din lista parametrilor
2
actuali, pregătite în acest scop. Între cele două categorii de parametri trebuie să existe o
corespondenţă de număr, tip, loc şi dimensiune. Orice tip de neconcordanţă declanşează eroare în
execuţia programului corespunzător, indiferent de limbajul de programare utilizat în codificarea
acestuia. Datele furnizate de procedură pot deveni, în continuare, date de ieşire, date intermediare
sau chiar date de intrare pentru aceeaşi procedură sau nu.
Grafic, legătura dintre schema logică apelantă şi o procedură se prezintă în figura 3.1.2. În prima
apelare a procedurii P intervin parametri actuali PA1, PA2, …, PAn, iar în a doua PB1, PB2, …,
PBn. Parametrii formali sînt desemnaţi prin PF1, PF2, …, PFn.
Linia punctată marchează “legătura” subînţeleasă între cele două tipuri de schemă logică.
P(PF1, ...,
P(PA1,...,P
Stop
Observaţie. În descrierea unei proceduri se poate face apel la alte proceduri. Numele procedurii
face legătura între o schemă logică apelantă şi una apelată sau între două scheme logice apelate.
Acesta este fixat de către programator, după regulile furnizate de limbajul de programare utilizat
în codificarea variabililor (vezi, secţiunea 1.1). Contextul în care se impune utilizarea
procedurilor în rezolvarea unei probleme precum şi o serie de reguli strict necesare în utilizarea
procedurilor au fost făcute deja în secţiunea 1.2, punctul 7).
Exemplu 6. Fie u şi v doi vectori cu aceeaşi dimensiune n. Construind o procedură care
determină produsul scalar pentru doi vectori formali x şi y de dimensiune m, să se
determine:
a) produsul scalar al celor doi vectori;
b) norma vectorului u ;
c) norma vectorului v .
Procedura cerută în problemă se desemnează simbolic cu numele PRODS şi are ca
parametri formali următoarele entităţi: dimensiunea vectorilor x şi y , vectorul x , vectorul y
şi produsul scalar al celor doi vectori, cu notaţia PS.
În procedura PRODS apare succesiunea logică a operaţiilor de aflare a produsului scalar
pentru vectorii fictivi x şi y , a căror componente sînt stocate într-o zonă specială din memoria
calculatorului, desemnată prin stivă. Cum problema se rezolvă în această fază doar formal, din
procedură lipsesc blocurile de intrare /ieşire, fapt care poate fi evidenţiat în majoritatea
procedurilor.
m
Pentru aflarea valorii lui PS avem : PS = ∑x
I =1
I yI .
3
Simbolizarea grafică a acestei formule se face printr-o structură repetitivă cu m paşi.
Procedura PRODS este chemată în schema logică principală de 3 ori, cu următoarele liste
de parametri actuali:
- n, u , v , PS pentru aflarea produsului scalar al vectorilor u şi v ;
- n, u , u , NU pentru aflarea normei vectorului u ;
- n, v , v , NV pentru aflarea normei vectorului v .
Notaţiile PS, NU şi NV au aceeaşi semnificaţie ca în exemplul de mai sus.
Indifernt de conţinutul listei parametrilor actuali, un apel al procedurii PRODS determină
realizarea unui număr fix de tipuri de operaţii, iar valorile parametrilor actuali concretizează
operaţiile de executat.
Deci, în cadrul unui apel al procedurii PRODS se execută următoarele operaţii:
- parametrii actuali iau locul parametrilor formali;
- cu datele primite se execută în totalitate procedura şi se determină o valoare adecvată
pentru produsul scalar;
- dezactivarea procedurii la atingerea lui Stop;
- revenirea în schema logică principală imediat după blocul care a generat apelul, cu
returnarea rezultatului calculat în procedură.
Schema logică principală şi procedura PRODS se prezintă mai jos:
Start
PRODUS(m,
,,PS)
Citeşte(n,,)
PS = 0
I=1 PRODUS(n,,PS)
PS=PS+xI .
yI PRODUS(n,,,NU)
4
I=I+1
NU=
NU
Im
PRODUS(n,,
Stop
NV= NV
Figura 3.1.3
ScriePS,NU,N
Stop
Figura 3.1.4
5
Utilizarea procedurilor în rezolvarea problemelor oferă multe facilităţi în programare şi,
în mod special, la lucru în echipă. În cele ce urmează, se enumeră cîteva dintre acestea :
- descrierea unei proceduri se face o singură dată, iar apelarea ei, în aceeaşi schemă logică
sau în scheme logice diferite, poate să apară, ori de cîte ori este nevoie, cu valori diferite pentru
parametri actuali;
- procedurile se elaborează independent de schemele logice care le apelează, iar
elaborarea lor poate fi făcută de către diverşi programatori;
- utilizarea procedurilor constituie un mijloc de liniarizare şi de simplificare a schemei
logice apelante, fapt care pe de o parte, uşurează citirea schemei logice apelante, iar pe de alta,
marchează părţile dificile şi punctele cheie în rezolvarea unei probleme;
- codificarea procedurilor poate fi făcută în acelaşi limbaj de programare sau sau în
limbaje de programare diferite.
Observaţie. Majoritatea limbajelor de programare permit organizarea a două tipuri de
subprograme pentru codificarea unei structuri de tip procedură:
- subprograme de tip procedură (procedure), utilizate în orice situaţie (indiferent de
numărul valorilor returnate programului principal);
- subprograme de tip funcţie (function), care pot întoarce programului apelant cel mult o
valoare. Vom vedea în capitolul următor că funcţia este singurul tip de subprogram utilizat în
construcţia programelor C++ .
2
programare la altul. De exemplu, în limbajul Pascal atribuirea se notează cu :=, iar egalitatea cu
=, pe cînd în limbajele de tip C atribuirea se notează cu =, iar egalitatea cu ==.
Pentru variabila x există mai multe alternative de a i se afecta o valoare, şi anume: prin operaţia
de citire sau operaţia de iniţializare, prin execuţia unui procedură sau prin evaluarea unei expresii
matematice.
De asemenea, prin procedeul de iniţializare se fixează prima valoare a oricărui contor. Partea de
început a unei structuri repetitive cu un număr cunoscut de paşi se rezumă la un bloc de
iniţializare, unde contorului i se atribuie valoarea iniţială.
3) Ultimul procedeu nu este specificat în literatura de specialitate şi foarte puţini programatori
reuşesc să-l stăpînească şi să-l folosească corect în activitatea de rezolvare a unei probleme cu
ajutorul calculatorului electonic. Un interes deosebit se acordă acestui procedeu în activitatea de
programare structurată.
Comutatorul sau bascula este o variabilă de lucru care poate primi două sau mai multe valori şi
are rolul de a comuta sau de a bascula pe o valoare dinainte fixată atunci când se parcurge o
anumită secvenţă de schemă logică sau de formulări în limbajul pseudocod.
În funcţie de numărul valorilor primite, comutatorii se clasifică în două categorii:
- comutatori simpli sau bivalenţi;
- comutatori multipli sau multivalenţi.
Unui comutator simplu i se atribuie numai două valori care reprezintă o logică bivalentă în
rezolvarea unei probleme. Poziţionarea lui pe o valoare marchează parcurgerea de mai multe ori a
unei anumite secvenţă de schemă logică sau de formulări în limbajul pseudocod. Poziţionarea
este acceptată doar la început şi întrebarea “comutatorul are valoarea dată anterior?” pare în plus
pînă când în anumite condiţii acesta comută pe altă valoare.
Această comutare barează trecerea spre secvenţa de schemă logică sau de formulări în limbajul
pseudocod executată anterior şi deschide o nouă trecere spre altă parte din reprezentarea
respectivă.
Un comutator multiplu are acelaşi efect ca un comutator simplu, numai că acesta poate comuta pe
mai multe valori anterior precizate. Sigur că, fiecare comutare este precedată de întrebarea
specificată între ghilimele în descrierea comutatorului simplu. În orice moment trebuie să existe
un control riguros asupra valorilor afectate comutatorilor, în caz contrar utizarea lor constituie o
sursă importantă de erori în rezolvarea unei probleme.
Exemplu 7. Fie trei numere naturale N1, N2 şi N3. Să se specifice pentru fiecare număr
calificativul de “admis” sau de “respins”, după cum numărul este sau nu un număr prim.
Fie K variabila care contorizează numărul de divizori a unui număr natural oarecare N, care va
fi înlocuit pe rând cu numerele N1, N2 sau N3 după cum bascula multiplă T va comuta pe 1, 2
sau 3.
Cînd K are valoarea 2, numărul se consideră prim şi se afişează “admis “, în caz contrar
se afişează “respins”.
3
Figura 3.2.1
4
III. Analiza corectitudinii schemelor logice
Construcţiile făcute cu simboluri sau cu formulări standard în limbajul pseudocod nu oferă
întodeauna certitudinea că o problemă este rezolvată corect.
Pentru analiza corectitudinii unei scheme logice, ultimele cercetări evidenţiază instrumente
matematice adecvate de formalizare, pentru care se poate utiliza calculatorul în aplicarea lor.
De fapt, se poate discuta numai de o corectitudine parţială a rezolvării problemei, deoarece
analiza corectitudinii unei scheme logice se referă doar la situaţia cînd acestea îşi încetează
activitatea.
Metoda utilizată în analiza corectitudinii unei scheme logice este una intuitivă şi constă în
completarea unui tabel care conţine atît variabilile cu care se lucrează în problemă, precum şi
istoricul valorilor fiecărei variabile.
Completarea tabelului se realizează pentru un caz paricular al problemei care include toate
posibilitaţile şi pentru care se ştie soluţia corectă. Prin parcurgerea sistematică a schemei logice
de la început spre sfîrşit, urmînd săgeţile de la sursa către ţintă, în tabel se înscriu valorile ce se
atribuie variabilelor cu care se lucrează. În finalul tabelului trebuie să apară soluţia cunoscută a
problemei.
În cazul cînd soluţia nu este corectă, rezultă că logica de rezolvare a problemei este eronată şi se
impune refacerea schemei logice.
În mod similar se procedează atunci cînd algoritmul de rezolvare al problemei se reprezintă prin
formulări standard în limbajul pseudocod.
Forma şi structura unui astfel de tabel se prezintă în figura 3.3.1.
Tabelul 3.3.1
Cel de al doilea procedeu are ca obiectiv nu verificarea corectitudinii schemei logice, ci cea a
programului scris într-un anumit limbaj după această schemă logică. Însă, acest procedeu nu se
recomandă începătorilor deoarece, în situaţia în care logica programului este greşită, traseul de
reparare al erorii este mai lung, în sensul că trebuie să se refacă atît schema logică cît şi
programul.
Abordarea altor metode pentru analiza corectitudinii schemelor logice, care au la bază un suport
matematic solid, nu poate fi făcută decât într-un cadru teoretic adecvat. Din acelaşi motiv, nici
abordarea problemei corectitudinii totale nu este posibilă
Exemplu 8. Fie succesiunea de k numere reale: Z =( z1, z2, ..., zk). Să se afle valoarea şi
poziţia elementului maxim.
Elementul maxim se notează cu Max, iar poziţia acestuia cu p.
5
Figura 3.3.2
Citeşte k, Z
Scrie Max,
Max=z
1
Stop
p=1
i=2
Max<
zzi
Max=z
i
p=i
i=i+1
1 ik
Tabelul este completat cu date ce se referă la şirul de numere: (-4, 0, 5, 7, 2). Soluţia corectă a
problemei este: Max = 7 şi p = 4.
6
IV. Reprezentarea algoritmilor în limbajul pseudocod
7
(10) nume_ procedură(listă_parametri actuali);
rezolvă un apel de procedură, iar (11) Citeşte (listă_variabile_intrare); şi
(12) Scrie(listă_variabile-ieşire); descriu operaţiile de intrare/ieşire.
Se observă că descrierea operaţiilor dintr-un algoritm de rezolvare al unei probleme trece
de la lucru pe verticală, în cazul schemelor logice, la lucru pe orizontală, în cazul construcţiilor
sintactice utilizate în limbajul pseudocod. Pe lîngă faptul că o construcţie sintactică cu formulări
standard nu ocupă mult loc, aceasta oferă şi alte avantaje, şi anume:
- lucrează cu un numar de formulări standard dinainte fixat;
- formulările standard pot fi cuprinse una în alta fără ca vreuna să-şi piardă indentitatea;
- permite rezolvarea problemei pe etape;
- sintaxa formulărilor standard este mult mai apropiată de cea a instrucţiunilor
componente limbajelor de programare evoluate (PASCAL, C, C++, etc.);
erorile de programare apar mai rar.
Exemplu 1. Fie expresiile: E1 = a2 + (b + c)i
E2 = (a + b + c3)5 – 5abc
E3 = (E1 –E2)j - a2i + b/5.
Să se determine E1, E2 şi E3, ştiind că a, b, c, i şi j primesc ca valori numere reale.
Modul de reprezentare al algoritmului de rezolvare a acestei probleme este următorul:
Start
Citeşte(a, b, c, i, j);
E1 = a2 + (b + c)i; Scrie(E1);
E2 = (a + b + c3)5 – 5abc; Scrie( E2);
E3 = (E1 –E2)j - a2i + b/5; Scrie(E3);
Stop.
Spre deosebire de schema logică prezentată în cursul anterior, aici se adaugă după
evaluarea unei expresii aritmetice comanda de scriere a valorii obţinute.
Exemplu 2. Să se determine:
( x 3 − 5 y) /( x + y), dacă x + y > 0 şi y > 0;
3
F= ( x + 5 y) /( x + y) dacă x + y > 0 şi y ≤ 0;
7 xy 3 , dacă x + y ≤ 0.
Etapele care se parcurg în aflarea valorii lui F sînt:
- citirea valorilor variabililor x şi y;
- determinarea lui F în funcţie de condiţiile impuse în enunţul problemei;
- scrierea valorii lui F.
Algoritmului de rezolvare a acestei probleme se reprezintî astfel:
Start
Citeşte(x, y);
Dacă x + y > 0 atunci
Dacă y > 0 atunci F = (x3 – 5y)/(x + y)
altfel F = (x3 + 5y)/(x + y)
altfel F = 7xy3;
Scrie(F);
Stop.
8
Pentru indentificarea corectă a celor două condiţii se recomandă ca scrierea lor să se facă pe mai
multe rînduri, astfel ca alinierea cuvintelor “atunci” şi “altfel” să se producă din aceeaşi coloană
după principiul de grupare “ultimul atunci - cu primul altfel”. O remarcă similară a fost făcută la
sfîrşitul exemplului anterior pentru perechea de paranteze Start - Stop.