1. BAZE ŞI SISTEME DE NUMERAŢIE REPREZENTAREA DATELOR ÎN CALCULATOR ELEMENTE DE TEORIA CODURILOR... 36

Μέγεθος: px
Εμφάνιση ξεκινά από τη σελίδα:

Download "1. BAZE ŞI SISTEME DE NUMERAŢIE REPREZENTAREA DATELOR ÎN CALCULATOR ELEMENTE DE TEORIA CODURILOR... 36"

Transcript

1 CUPRINS 1. BAZE ŞI SISTEME DE NUMERAŢIE SISTEME ŞI BAZE DE NUMERAŢIE... 3 SUGESTII TEME DE LABORATOR EFECTUAREA OPERAŢIILOR ÎN DIFERITE BAZE DE NUMERAŢIE SUGESTII TEME DE LABORATOR REPREZENTAREA DATELOR ÎN CALCULATOR SUGESTII TEME DE LABORATOR ELEMENTE DE TEORIA CODURILOR SUGESTII TEME DE LABORATOR ALGORITMI ŞI SCHEME LOGICE EXEMPLE SUGESTII TEME DE LABORATOR TIPURI DE DATE. CITIREA ŞI TIPĂRIREA DATELOR EXEMPLE SUGESTII TEME DE LABORATOR INSTRUCŢIUNILE IF ŞI SWITCH EXEMPLE SUGESTII TEME DE LABORATOR CICLUL FOR ŞI INSTRUCŢIUNILE REPETITIVE DE TIP WHILE ŞI DO- WHILE EXEMPLE SUGESTII TEME DE LABORATOR TABLOURI UNIDIMENSIONALE PROBLEME DE ORDONARE EXEMPLE SUGESTII TEME DE LABORATOR TABLOURI BIDIMENSIONALE EXEMPLE SUGESTII TEME DE LABORATOR FUNCŢII DEFINITE DE UTILIZATOR EXEMPLE SUGESTII TEME DE LABORATOR POINTERI EXEMPLE SUGESTII TEME DE LABORATOR

2 12. ŞIRURI DE CARACTERE EXEMPLE SUGESTII TEME DE LABORATOR STRUCTURI EXEMPLE SUGESTII TEME DE LABORATOR LISTE EXEMPLE SUGESTII TEME DE LABORATOR RECURSIVITATE EXEMPLE SUGESTII TEME DE LABORATOR METODA DIVIDE ET IMPERA EXEMPLE SUGESTII TEME DE LABORATOR METODA BACKTRACKING EXEMPLE SUGESTII TEME DE LABORATOR GRAFURI ŞI ARBORI GRAFURI NEORIENTATE EXEMPLE GRAFURI ORIENTATE SUGESTII TEME DE LABORATOR MINICULEGERE DE PROBLEME

3 1. BAZE ŞI SISTEME DE NUMERAŢIE 1.1 SISTEME ŞI BAZE DE NUMERAŢIE Prezentare generală; definiţii Suntem atât de obişnuiţi cu sistemul de numeraţie zecimal, încât ni se pare că utilizarea lui este cel puţin cea mai bună alegere, sau, uneori, suntem tentaţi să credem chiar că este singura posibilitate şi nici nu ne mai punem problema ce «se ascunde» în spatele acestei reprezentari, care este, de fapt, doar una dintre multiplele posibilităţi de reprezentare a numerelor şi de efectuare a calculelor. Sa luăm, pentru exemplificare, numărul natural În mod evident, noi întelegem că este vorba de numărul «două sute nouă mii trei sute nouăsprezece», adică : ceea ce mai poate fi scris ca : , = Deci, orice număr natural poate fi scris ca o sumă de produse, fiecare termen al sumei fiind produsul dintre o cifră (de la 0 până la 9, aşa cu am învăţat în clasele primare ) şi o putere a lui 10. Puterile lui 10 descresc de la stânga spre dreapta, cea mai mare putere fiind determinată de mărimea numărului respectiv. Pentru un numar N oarecare vom avea, deci : N = a n 10 n + a n-1 10 n-1 + a n-2 10 n a a a , (1) unde coeficienţii a i sunt cifre de la 0 până la 9. După cum am fost învăţaţi, noi nu mai scriem puterile lui 10, ci doar înşiruirea acestor coeficienţi (cifrele din care este alcătuit numărul). Puterile corespunzătoare ale lui 10 le subînţelegem, după poziţia pe care o ocupă cifrele respective în alcătuirea numărului. Un astfel de sistem de numeraţie se numeşte sistem de numeraţie poziţional. Avem deci la dispoziţie 10 simboluri (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), cu ajutorul cărora vom putea reprezenta orice nuamăr, indiferent de mărimea sa. Aşa cum numărul era reprezentat ca (renunţând la scrierea puterilor lui 10, care înmulţesc de fapt fiecare cifră), numărul N = a n 10 n + a n-1 10 n-1 + a n-2 10 n a a a

4 va fi scris ca N = a n a n-1 a n-2 a 1 a 0, (2) prin aceasta neîntelegând înmulţirea între coeficienţii a i ci, aşa cum am arătat, interpretarea din formula (1). Coeficienţii a i sunt cifrele din care este format numarul N. Alegerea a 10 simboluri (cifrele de la 0 până la 9) nu este însă nici singura posibilitate si nici cea mai bună în orice ocazie. Antropologii sunt unanimi în a considera că această alegere se datorează în exclusivitate faptului că avem 10 degete la mâini. Mai mult, ea nu afost nici totdeauna nici pretutindeni valabilă. Se ştie cu certitudine că au existat reprezentări folosind : - 20 de simboluri urmările se pot vedea în limba franceză, unde numărul 99 se citeşte quatre vingt dix neuf, adică, mot-a-mot de 4 ori douăzeci şi nouăsprezece - 12 simboluri se regăsşte în sistemul de unităţi anglo-saxon (cu divizarea unităţilor de măsură în 12 părţi egale), sau în termenul românesc duzină, care, în mod riguros înseamnă o cantitate de 12 obiecte - 60 de simboluri utilizat în Egiptul antic Să revenim la numărul nostru (209319). El poate fi la fel de bine reprezentat ca o sumă de puteri ale lui 7 (de exemplu) şi nu ale lui 10 ; mai mult, putem face în aşa fel încât coeficienţii acestor puteri să ia valori numai într-o mulţime cu 7 elemente {0, 1, 2, 3, 4, 5, = , ceea ce poate fi verificat imediat, prin efectuarea calculelor ( = = = ). Pentru a putea deci să reprezentăm orice număr conform principiului enunţat, avem nevoie de două mulţimi : - o mulţime A de denumiri (numele cifrelor, de exemplu «zero», «unu», etc.) - o mulţime B de simboluri (reprezentarea grafică a cifrelor din mulţimea A ; de exemplu «1», «2», etc) Între cele două mulţimi există o corespondentă biunivocă. Numărul de elemente al mulţimii A (şi deci, în mod evident, şi al mulţimii B) poate fi oarecare, dar cel puţin 2. Astfel, în sistemul zecimal (sistemul cu care suntem astăzi obişnuiţi), acest număr este 10 (cifrele de la 0 până la 9). In exemplul anterior, acest număr este 7 (cifrele de la 0 până la 6). Putem utiliza şi un număr mai mare de simboluri (am văzut că vechii egipteni foloseau 60 ). Va trebui ca în afara celor cu care suntem familiarizaţi (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) să mai inventăm alte simboluri. În informatică s-a generalizat utilizarea literelor mari ale alfabetului latin. De exemplu, să presupunem că ne-am decis la utilizarea unui sistem de numeratie cu 18 de simboluri (cifre). Trebuie să adăugăm «cifrele» A, B, C, D, E, F, G, H. 4

5 Semnificaţiile acestor simboluri vor fi : 0 cifra (şi numărul natural) 0 1 cifra (şi numărul natural) 1 2 cifra (şi numărul natural) 2 3 cifra (şi numărul natural) 3 4 cifra (şi numărul natural) 4 5 cifra (şi numărul natural) 5 6 cifra (şi numărul natural) 6 7 cifra (şi numărul natural) 7 8 cifra (şi numărul natural) 8 9 cifra (şi numărul natural) 9 A cifra A, corespunzând numărului natural 10 din sistemul zecimal B cifra B, corespunzând numărului natural 11 din sistemul zecimal C cifra C, corespunzând numărului natural 12 din sistemul zecimal D cifra D, corespunzând numărului natural 13 din sistemul zecimal E cifra E, corespunzând numărului natural 14 din sistemul zecimal F cifra F, corespunzând numărului natural 15 din sistemul zecimal G cifra G, corespunzând numărului natural 16 din sistemul zecimal H cifra H, corespunzând numărului natural 17 din sistemul zecimal Având la dispoziţie aceste 18 simboluri, putem exprima numărul natural din sistemul zecimal ca o sumă de produse în care să apară puterile lui 18, iar coeficienţii să fie din mulţimea celor 18 simboluri de mai sus : N = = H G F 18 0 Pentru verificare, vom efectua calculele, ţinând seama de semnificaţia simbolurilor nou introduse : H G F 18 0 = = = = În sistemul zecimal, scrisesem numărul renunţând să mai scriem şi puterile lui 10, prin simpla înşiruire a coeficienţilor, care constituiau astfel cifrele constitutive ale numărului : Dacă vom face acelaşi lucru şi cu reprezentarea vom obţine H G F 18 0, N = 1HGOF. Suntem acum în măsură să generalizăm : Putem exprima orice număr natural dacă dispunem de doua mulţimi (A a denumirilor cifrelor şi B a simbolurilor grafice ale acestor cifre) între care s-a stabilit o corespondenţă biunivocă. Numărul de elemente ale mulţimii B se numeşte baza de numeraţie. 5

6 Orice număr natural se exprimă atunci ca o sumă de produse între nişte coeficienţi (cifre cuprinse între 0 şi b-1, unde b este baza de numeraţie) şi puterile corespunzătoare ale bazei b : N = a n b n + a n-1 b n a 2 b 2 + a 1 +b 1 + a 0 b 0, (3) unde coeficienţii a i iau, în mod evident, valori între 0 şi b-1. Dacă un număr este la forma (3), spunem că este exprimat sub formă polinomială. Dacă nu există posibilitatea de confuzie (ştim care este baza de numeraţie în care am reprezentat numărul), putem rennţa la scrierea polinimială (deci la transcrierea puterilor bazei), scriind doar înşiruirea coeficienţilor a i : N = a n a n-1 a n-2 a 1 a 0 (4), aşa cum procedam în cazul sistemului zecimal. Pentru a evita ambiguităţile, baza se scrie între paranteze în modul următor : N = a n a n-1 a n-2 a 1 a 0 (b) (5) În cuprinsul acestui capitol, vom utiliza reprezentările numerelor sub formele din formulele (3) şi (5). Exemplele pe care le-am prezentat anterior se sintetizează atunci în modul următor : N = (10) = (7) = 1HG0F (18) (este deci vorba de reprezentarea aceluiaşi număr în bazele de numeraţie 10, 7 şi 18). În studiul informaticii, importanţă practică prezintă următoarele baze de numeraţie : a) b=10 (sistemul zecimal) este forma exterioara în care se prezintă datele ce urmează a fi prelucrate şi rezultatele acestor prelucrări ; este sistemul de numeraţie cu care suntem obişnuiţi, sistem care utilizează cele 10 simboluri cunoscute (cifrele 0,1, 2, 3, 4, 5, 6, 7, 8, 9 cifre preluate de către europeni de la matematicienii arabi) b) b=2 (sistemul binar) este forma sub care se prezintă informaţiile în calculator ; aşa cum rezultă din definiţiile date până acum, utilizează doar două simboluri cifrele 0 şi 1 vom reveni pe larg asupra acestui sistem ; c) b=8 (sistemul octal) utilizează 8 simboluri (cifrele de la 0 până la 7) utilizarea sa este mai restânsă decât a sistemelor 2 si 16 ; d) b=16 (sistemul hexagesimal) constituie (aşa cum vom vedea) mai degrabă o formă «condensată» de reprezentare a sistemului binar ; utilizează 16 simboluri (cifrele de la 0 până la 9, la care se adauga 6 simboluri noi, cu semnificaţiile : 6

7 A cifra A, corespunzând numărului natural 10 din sistemul zecimal B cifra B, corespunzând numărului natural 11 din sistemul zecimal C cifra C, corespunzând numărului natural 12 din sistemul zecimal D cifra D, corespunzând numărului natural 13 din sistemul zecimal E cifra E, corespunzând numărului natural 14 din sistemul zecimal F cifra F, corespunzând numărului natural 15 din sistemul zecimal) Este evident că prima problemă care se pune, pentru a putea utiliza numere scrise în alte sisteme de numeraţie decât cel zecimal, este de a dispune de algoritmi pentru trecerea acestor numere în baza dorita (şi în general dintr-o bază în alta). Trecerea numerelor naturale din baza 10 intr-o baza b oarecare Să pornim tot de la un exemplu concret : reluăm numărul (10). Dorim să trecem acest număr în baza 5. Fără a spune (pentru început) cum am rezolvat această problemă, vom da deja rezultatul : N = (10) = (5) Chiar dacă nu ştim (deocamdată) cum am ajuns la acest rezultat, suntem deja în măsură să verificăm dacă este corect. Întra-adevăr, conform definiţiilor date şi a formulei (3), N = (5) = = = = = = = = unde toate calculele s-au efectuat în sistemul zecimal. Cum putem însă să ajungem la această reprezentare în baza 5 (corectă, dupa cum tocmai am demonstrat)? Conform definiţiei, numărul căutat este de forma : a a a a a a a a 0 5 0, care este scrierea polinomială a numărului nostru în baza 5 şi unde trebuie să determinăm coeficienţii a i (să ajngem pe o cale oarecare la concluzia că a 7 =2, a 6 =3, a 5 =1, a 4 =4, a 3 =4, a 2 =2, a 1 =3, a 0 =4). Dacă împărţim numărul la 5 (baza în care vrem să trecem numărul), obţinem : 5 = rest 4 Dacă în scrierea polinomială a numărului în baza 5 (care este acelaşi număr , altfel scris) scoatem factor comun pe 5, obţinem : N = 5(a a a a a a a )+ a 0, ceea ce înseamnă că împărţind la 5 obţinem cătul 7

8 C 0 = a a a a a a a şi restul R 0 = a 0. Cum am împărţit la 5 acelaşi număr (doar exprimat altfel), rezultă că C 0 =41863, şi, ceea ce este mai important, a 0 =4. Am determinat deci coeficientul a 0 din exprimarea numărului nostru în baza 5 ; el este chiar restul împărţirii lui la 5. Împărţind pe C 0 =41853 la 5 obţinem un nou cât şi un nou rest : C 0 : 5 = : 5 = 8372 rest 3 Dar, C 0 = a a a a a a a în care vom da din nou factor comun pe 5, obţinând : C 0 = 5(a a a a a a )+ a 1 şi, prin împărţire oţinem un cât şi un rest C 0 : 5 = C 1 rest R 1, unde C 1 = a a a a a a şi R 1 =a 1, de unde deducem că C 1 =8372 şi a 1 =3, adică am mai găsit o cifră din reprezentarea în baza 5 a numarului nostru : ea este restul împărţirii primului cât la 5 (baza în care dorim să trecem numărul. Continuând de aceeaşi manieră, obţinem succesiv : C 1 : 5 = 8372 : 5 = 1674 şi rest 2, cu C 1 = a a a a a a = =5(a a a a a )+ a 2 = =5 C 2 + a 2 ceea ce înseamnă că C 2 =1674 şi a 2 =2 C 2 : 5 = 1674 : 5 = 334 şi rest 4 C 2 = a a a a a = = 5(a a a a )+ a 3 = = 5 C 3 + a 3 ceea ce înseamnă ca C 3 =334 şi a 3 =4 C 3 : 5 = 334 : 5 = 66 şi rest 4 C 3 = a a a a = = 5(a a a )+ a 4 = = 5 C 4 + a 4 ceea ce înseamnă că C 4 =66 şi a 4 =4 C 4 : 5 = 66 : 5 = 13 şi rest 1 8

9 C 4 = a a a = = 5(a a )+ a 5 = = 5 C 5 + a 5 ceea ce înseamnă că C 5 =13 şi a 5 =1 C 5 : 5 = 13 : 5 = 2 şi rest 3 C 5 = a a = = 5(a ) + a 6 = = 5 C 6 + a 6 ceea ce înseamnă că C 6 =2 şi a 6 =3 C 6 : 5 = 2 : 5 = 0 şi rest 2 (ATENŢIE : Noul cât este zero!) C 6 = a = = 5 C 7 + a 7 ceea ce înseamnă că C 7 =0 (semnal de STOP) şi a 7 =2 Observăm cu uşurinţă că, împărţind rând pe rând numărul nostru din baza 10 şi apoi resturile succesive obţinute la 5 (noua bază în care dorim să exprimăm numărul dat), obţinem resturile a 0, a 1, a 2,,a 7, adică tocmai cifrele constitutive ale numărului nostru în baza 5 (în ordinea inversă în care apar ele în exprimarea polinomială). N == (10) = a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0 (5) = (5) = = Din mersul de calcul, este evident că acest lucru rămâne valabil oricare ar fi baza b în care dorim să exprimăm numărul nostru din baza 10, ceea ce poate fi demonstrat pornind de la formula (3) : N = a n b n + a n-1 b n a 2 b 2 + a 1 b 1 + a 0 b 0 = = b(a n b n-1 + a n-1 b n a 2 b 1 + a 1 b 0 )+ a 0 N: b = C 0 rest R 0 cu C 0 = a n b n-1 + a n-1 b n a 2 b 1 + a 1 b 0 = = b(a n b n-2 + a n-1 b n a 2 b 0 ) + a 1 R 0 =a 0 C 0 : b = C 1 rest R 1 cu C 1 = a n b n-2 + a n-1 b n a 3 b 1 + a 2 b 0 = = b(a n b n-3 + a n-1 b n a 3 b 0 ) + a 2 R 1 =a 1 C 1 : b = C 2 rest R 2 cu C 1 = a n b n-3 + a n-1 b n a 4 b 1 + a 3 b 0 = = b(a n b n-4 + a n-1 b n a 4 b 0 ) + a 3 R 2 =a 2. 9

10 Procedeul se repetă până când se obţine câtul 0 (semnalul de STOP); ultimul rest obţinut va reprezenta prima cifră a numărului exprimat în baza b. Aceasta reprezintă chiar algoritmul de trecere a unui număr natural din baza 10 într-o bază b oarecare : se împarte succesiv numărul din baza 10 (şi câturile succesive obţinute pe parcurs) la valoarea b ( baza în care dorim să trecem numarul); se reţin resturile succesive obţinute pe parcurs; procedeul se opreşte după ce s-a obţinut un cât egal cu zero (reţinându-se deci şi restul respectiv) ; resturile succesive obţinute constituie, în ordinea inversă, cifrele numărului exprimat in noua bază. Trecerea numerelor naturale dintr-o baza b oarecare in baza 10 În toate exemplele pe care le-am analizat anterior (de trecere a unui număr din baza 10 intr-o bază b oarecare), am verificat corectitudinea rezultatelor obţinute prin aplicarea formulei polinomiale (3). Aceasta constituie chiar metoda de trecere a unui număr natural dintr-o bază b oarecare în baza 10 : aplicarea formulei polinomiale (3). Trecerea numerelor naturale dintr-o baza b1 (oarecare) intr-o alta baza b2 (oarecare) Având la dispoziţie o metodă de trecere a unui număr natural dintr-o bază oarecare în baza 10 şi o metodă de trecere a unui număr natural din baza 10 într-o bază b oarecare, putem trece cu uşurinţă un număr dintr-o bază b 1 într-o bază b 2, prin aplicarea combinată a celor două metode : se trece numărul din baza b 1 în baza 10, apoi se trece rezultatul în baza b 2 prin metodele deja menţionate. Trecerea reciproca a numerelor naturale dintr-o baza b 1 intr-o baza b 2 =b 1 k În cazul particular în care cele două baze b 1 şi b 2 sunt legate între ele printr-o relaţie de forma b 2 = b 1 k, trecerea din baza b 1 în baza b 2 (şi reciproc) se poate face direct, fără a mai fi nevoie să mai trecem prin intermediul bazei 10. Să exprimăm acelaşi număr N în bazele b 2 şi b 1 ; conform formulei polinomiale (3), vom avea : N = α n b n 2 + α n-1 b n α n-2 b n α 2 b α 1 b α 0 b 0 2 = α n α n-1 α n- 2 α 2 α 1 α 0 (b 2 ) N = β n b n 1 + β n-1 b n β n-1 b n β 1 b β 1 b β 0 b 0 1 = β n β n-1 β n- 2 β 2 β 1 β 0 (b 1 ) unde : α i b 2-1, i = 1 n β j b 1-1, j = 1 m 10

11 şi, datorită faptului că b 2 = b 1 k, vom avea n m (acelaşi număr natural N are o reprezentare mai lungă în baza mai mică b 1 decât în baza mai mare b 2 ). Putem să calculăm mai exact valoarea lui m (în raport cu n), raţionând în modul următor : Din exprimarea numărului N în baza b 2 (unde am notat cu n cel mai mare exponent al bazei b 2 ) rezultă că N < b 2 n+1 (dacă n-ar fi aşa, în dezvoltarea polinomială ar trebui să apară şi puterea n+1). Ştiind că b 2 = b 1 k, putem deduce succesiv N < b 2 n+1 = (b 1 k ) n+1 Din exprimarea numărului N în baza b 1 (unde am notat cu m cel mai mare exponent al bazei b 1 ) şi, ţinând cont de rezultatul anterior, rezultă că m b 1 kn+k-1 ceea ce înseamnă că reprezentarea numărului N în baza b 1 va fi, de fapt : N = β kn+k-1 b kn+n-1 + β kn+k-2 b kn+n β 2 b 2 + β 1 b 1 + β 0 b 0 = β kn+k-1 β kn+k- 2 β 2 β 1 β 0 (b 1 ) Evident că, din acest punct de vedere, a trece numărul N din baza b 2 în baza b 1 revine la a determina coeficienţii β j (j kn+k-1) atunci când cunoaştem coeficienţii α i (i n). Să ne aducem aminte că dispunem deja de o metodă indirectă : aceea de a trece numărul din baza b 2 în baza 10, apoi din baza 10 în baza b 1, dar aşa cum anunţam anterior, în cazul particular în care ne găsim (b 2 = b 1 k ), există şi o metodă directă, fără a mai fi necesară trecerea prin intermediul bazei 10. Pentru aceasta să observăm că toţi coeficienţii α i sunt cifre (simboluri) în reprezentarea numărului în baza b 2 (α i b 2-1), dar exprimarea lor în baza b 1 constituie numere (formate din una sau mai multe cifre), din simplul motiv că în baza b 1 cifrele pot fi cel mult egale cu b 1-1 b 2-1. Să exprimăm pe oricare dintre coeficienţii α i în baza b 1 ; observăm, mai întâi, că α i b 2-1 = b 1 k -1 < b 1 k, ceea ce înseamnă că în exprimarea polinomială a oricăruia dintre coeficienţii α i în baza b 1 va apărea cel mult puterea k-1 a bazei b 1 ; conform formulei polinomiale, vom avea : α i = a i,k-1 b 1 k-1 + a i,k-2 b 1 k-2 + a i,k-3 b 1 k a i,2 b a i,1 b a i,0 b 1 0 = = a i,k-1 a i,k-2 a i,k-3 a i,2 a i,1 a i,0 (b 1 ), (unde coeficienţii a i,j respectă condiţia a i,j b 1-1). Înlocuind acum în dezvoltarea polinomială a numărului N în baza b 2 valoarea coeficienţilor α i pe care tocmai am calculat-o şi ţinând cont de faptul că b 2 = b 1 k, obţinem : N = α n b 2 n + α n-1 b 2 n-1 + α n-2 b 2 n α 2 b α 1 b α 0 b 2 0 = = (a n,k-1 b 1 k-1 + a n,k-2 b 1 k-2 + a n,k-3 b 1 k a n,2 b a n,1 b a n,0 b 1 0 )b 1 kn + = (a n-1,k-1 b 1 k-1 + a n-1,k-2 b 1 k-2 + a n-1,k-3 b 1 k a n-1,2 b a n-1,1 b a n-1,0 b 1 0 )b 1 kn + = (a n-2,k-1 b 1 k-1 + a n-2,k-2 b 1 k-2 + a n-2,k-3 b 1 k a n-2,2 b a n-2,1 b a n-2,0 b 1 0 )b 1 kn + = (a 2,k-1 b 1 k-1 + a 2,k-2 b 1 k-2 + a 2,k-3 b 1 k a 2,2 b a 2,1 b a 2,0 b 1 0 )b 1 kn + 11

12 = (a 1,k-1 b 1 k-1 + a 1,k-2 b 1 k-2 + a 1,k-3 b 1 k a 1,2 b a 1,1 b a 1,0 b 1 0 )b 1 kn + = (a 0,k-1 b 1 k-1 + a 0,k-2 b 1 k-2 + a 0,k-3 b 1 k a 0,2 b a 0,1 b a 0,0 b 1 0 )b 1 kn Observăm două lucruri : - am obţinut o sumă de produse între nişte coeficienţi a i,j b 1 şi puterile (strict descrescătoare) ale bazei b 1 ; - cea mai mare putere a bazei este kn+k-1 Acest lucru înseamnă că am obţinut tocmai reprezentarea căutată a numărului N în baza b 1, adică am determinat coeficienţii β j (j kn+k-1) atunci când cunoaştem coeficienţii α i (i n). Conform definiţiilor date, reprezentarea polinomială a numărului N în baza b 1 va consta din simpla înşiruire a coeficienţilor a i,j rezultaţi din desfacerea parantezelor şi renunţarea la a mai scrie puterile bazei b 1 : N = a n,k-1 a n,k-2 a n,k-3 a n,2 a n,1 a n,0 a n-1,k-1 a n-1,k-2 a n-1,k-3 a n-1,2 a n-1,1 a n-1,0 a n-2,k-1 a n-2,k-2 a n-2,k-3 a n-2,2 a n-2,1 a n- 2,0 a 2,k-1 a 2,k-2 a 2,k-3 a 2,2 a 2,1 a 2,0 a 1,k-1 a 1,k-2 a 1,k-3 a 1,2 a 1,1 a 1,0 a 0,k-2 a 0,k-3 a 0,2 a 0,1 a 0,0 Dar fiecare grupă de câte k cifre (coeficienţi) din această reprezentare constituie pur şi simplu reprezentarea în baza b 1 a cifrelor α i ale numărului N în baza b 2 (ne aducem aminte că am avut α i = a i,k-1 b 1 k-1 + a i,k-2 b 1 k-2 + a i,k-3 b 1 k a i,2 b a i,1 b a i,0 b 1 0 = = a i,k-1 a i,k-2 a i,k-3 a i,2 a i,1 a i,0 (b 1 ) ). Mai exact spus : a n,k-1 a n,k-2 a n,k-3 a n,2 a n,1 a n,0 = α n a n-1,k-1 a n-1,k-2 a n-1,k-3 a n-1,2 a n-1,1 a n-1,0 = α n-1 a n-2,k-1 a n-2,k-2 a n-2,k-3 a n-2,2 a n-2,1 a n-2,0 = α n-2 a 2,k-1 a 2,k-2 a 2,k-3 a 2,2 a 2,1 a 2,0 = α 2 a 1,k-1 a 1,k-2 a 1,k-3 a 1,2 a 1,1 a 1,0 = α 1 a 0,k-1 a 0,k-2 a 0,k-3 a 0,2 a 0,1 a 0,0 = α 0 Acest rezultat ne sugerează metoda de trecere a numărului natural N din baza b 2 în baza b 1 în cazul b 2 =b 1 k : Se exprimă toţi coeficienţii (cifrele) numărului N din baza b 2 pe câte exact k cifre în baza b 1 ; simpla înşiruire a acestor cifre (în ordinea în care au apărut) reprezintă numărul N în baza b 1 ; eventualele zerouri care apar la stânga numărului se neglijează. Reciproc, pentru trecerea numărului N din baza b 1 în baza b 2 =b 1 k : Se despart coeficienţii (cifrele) numărului N din baza b 1, începând de la dreapta spre stânga, în grupe de câte exact k cifre; se înlocuieşte fiecare astfel de grupe prin cifra corespunzătoare din baza b 2 ; dacă în urma despărţirii ultima grupă din stânga are mai puţin de k cifre, se completează la stânga cu numărul necesar de zerouri; simpla înşiruire a acestor cifre (în ordinea în care au rezultat) reprezintă numărul N scris în baza b 2. 12

13 EXEMPLE Exemplul 1 Să trecem numărul N = (10) în baza 6. Se utilizează 6 simboluri (cifrele de la 0 până la 5). N : 6 = : 6 = rest 3 C 0 =43886 R 0 =a 0 =3 C 0 : 6 = : 6 = 5814 rest 2 C 1 =5814 R 1 =a 1 =2 C 1 : 6 = 5814 : 6 = 969 rest 0 C 2 =969 R 2 =a 2 =0 C 2 : 6 = 969 : 6 = 161 rest 3 C 3 =161 R 3 =a 3 =3 C 3 : 6 = 161 : 6 = 26 rest 5 C 4 =26 R 4 =a 4 =5 C 4 6 = 26 : 6 =4 rest 2 C 5 =4 R 5 =a 5 =2 C 5 : 6 = 4 : 6 = 0 rest 4 C 6 =0 R 6 =a 6 =4 Am obţinut restul 0, deci procedeul se opreşte aici. Rezultă că numărul N= (10) se exprimă în baza 6 pe 7 cifre : Verificare : N = (10) = a 6 a 5 a 4 a 3 a 2 a 1 a 0 (6) = (6) (6) = = = = = = Exemplul 2 Să trecem numărul N = (10) în baza 19. Se utilizează 19 simboluri (cifrele de la 0 până la 9 şi literele mari A=10, B=11, C=12, D=13, E=14, F=15, G=16, H=17, I=18). N : 19 = : 19 = rest 15 C 0 =11016 R 0 =a 0 =15=F C 0 : 19 = : 19 = 579 rest 15 C 1 =579 R 1 =a 1 =15=F C 1 : 19 = 579 : 19 = 30 rest 9 C 2 =30 R 2 =a 2 =9 C 2 : 19 = 30 : 19 = 1 rest 11 C 3 =11 R 3 =a 3 =11=B C 3 : 19 = 1 : 19 = 0 rest 1 C 4 =0 R 4 =a 4 =1 Am obţinut restul 0, deci procedeul se opreşte aici. Rezultă că numărul N= (10) se exprimă în baza 19 pe 5 cifre : N = (10) = a 4 a 3 a 2 a 1 a 0 (19) = 1B9FF (19) 13

14 Verificare : 1B9FF (19) = B F F 19 0 = = = = = = = Exemplul 3 Să trecem numărul N = (10) în baza 2 (sistemul binar). Se utilizează 2 simboluri (cifrele 0 şi 1). N : 2 = : 2 = rest 1 C 0 = R 0 =a 0 =1 C 0 : 2 = : 2 = rest 1 C 1 =52329 R 1 =a 1 =1 C 1 : 2 = : 2 = rest 1 C 2 =26164 R 2 =a 2 =1 C 2 : 2 = : 2 = rest 0 C 3 =13082 R 3 =a 3 =0 C 3 : 2 = : 2 = 6541 rest 0 C 4 =6541 R 4 =a 4 =0 C 4 2 = 6541 : 2 =3270 rest 1 C 5 =3270 R 5 =a 5 =1 C 5 : 2 = 3270 : 2 = 1635 rest 0 C 6 =1635 R 6 =a 6 =0 C 6 : 2 = 1635 : 2 = 817 rest 1 C 7 =817 R 7 =a 6 =1 C 7 : 2 = 817 : 2 = 408 rest 1 C 8 =408 R 8 =a 7 =1 C 8 : 2 = 408 : 2 = 204 rest 0 C 9 =204 R 9 =a 8 =0 C 9 : 2 = 204 : 2 = 102 rest 0 C 10 =102 R 10 =a 9 =0 C 10 : 2 = 102 : 2 = 51 rest 1 C 11 =51 R 11 =a 10 =1 C 11 : 2 = 51 : 2 = 25 rest 1 C 12 =25 R 12 =a 11 =1 C 12 : 2 = 25 : 2 = 12 rest 1 C 13 =12 R 13 =a 12 =1 C 13 : 2 = 12 : 2 = 6 rest 0 C 14 =6 R 14 =a 13 =0 C 14 : 2 = 6 : 2 = 3 rest 0 C 15 =3 R 15 =a 15 =0 C 15 : 2 = 3 : 2 = 1 rest 1 C 16 =1 R 16 =a 16 =1 C 16 : 2 = 1 : 2 = 0 rest 1 C 17 =0 R 17 =a 17 =1 Am obţinut restul 0, deci procedeul se opreşte aici. Rezultă că numărul N= (10) se exprimă în baza 2 pe 18 cifre : Verificare : N = (10) = a 17 a 16 a 15 a 14 a 13 a 12 a 11 a 10 a 9 a 8 a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0 (2) = = (2) (2) = = = = =

15 Exemplul 4 Să trecem numărul N = (10) în baza 8 (sistemul octal). Se utilizează 8 simboluri (cifrele de la 0 până la 7). N : 8 = : 8 = rest 7 C 0 =26164 R 0 =a 0 =7 C 0 : 8 = : 8 = 3270 rest 4 C 1 =3270 R 1 =a 1 =4 C 1 : 8 = 3270 : 8 = 408 rest 6 C 2 =408 R 2 =a 2 =6 C 2 : 8 = 408 : 8 = 51 rest 0 C 3 =51 R 3 =a 3 =0 C 3 : 8 = 51 : 8 = 6 rest 3 C 4 =6 R 4 =a 4 =3 C 4 8 = 6 : 8 =0 rest 6 C 5 =0 R 5 =a 5 =6 Am obţinut restul 0, deci procedeul se opreşte aici. Rezultă că numărul N= (10) se exprimă în baza 8 pe 6 cifre : Verificare : N = (10) = a 5 a 4 a 3 a 2 a 1 a 0 (8) = (8) (6) = = = = = = Exemplul 5 Să trecem numărul N = (10) în baza 16 (sistemul hexagesimal). Se utilizează 16 simboluri (cifrele de la 0 până la 9 şi literele mari A=10, B=11, C=12, D=13, E=14, F=15). N : 16 = : 16 = rest 7 C 0 =13082 R 0 =a 0 =7 C 0 : 16 = : 16 = 817 rest 10 C 1 =817 R 1 =a 1 =10=A C 1 : 16 = 817 : 16 = 51 rest 1 C 2 =51 R 2 =a 2 =1 C 2 : 16 = 51 : 16 = 3 rest 3 C 3 =3 R 3 =a 3 =3 C 3 : 16 = 3 : 16 = 0 rest 3 C 4 =0 R 4 =a 4 =3 Am obţinut restul 0, deci procedeul se opreşte aici. Rezultă că numărul N= (10) se exprimă în baza 16 pe 5 cifre : Verificare : N = (10) = a 4 a 3 a 2 a 1 a 0 (16) = 331A7 (16) 331A7 (19) = A = = = = = = = Aplicând acelaşi procedeu, poate fi trecut numărul dat în orice bază (b 2). 15

16 Pentru un control al celor învăţate, vom da reprezentarea aceluiaşi număr (209319) în toate bazele de numeraţie de la baza b=2 (sistemul binar, şi totodată cea mai mică bază posibilă) până la baza b=20 : N = (10) = = (2) = = (3) = = (4) = = (5) = = (6) = = (7) = = (8) = = (9) = = (10) = = 1332A0 (11) = = A1173 (12) = = 74C376 (13) = = 563D5 (14) = = (15) = = 331A7 (16) = = 28A47 (17) = = 1HG0F (18) = = 1B9FF (19) = = 1635J (20) Exemplul 6 : trecerea reciprocă dintre bazele 2 şi 4 b 1 = 2; b 2 = 4 = 2 2 ; rezultă k = 2 (vom lucra deci pe câte 2 cifre în binar) N = (10) = (2) Despărţim reprezentarea binară în grupe de câte 2 cifre (de la dreapta la stânga) : şi reprezentăm fiecare grupă pe câte o singură cifră în baza 4 (pentru că am făcut un tabel de corespondenţe, putem să citim asta direct din tabel) ; obţinem succesiunea de cifre Se observă cu uşurinţă că am obţinut chiar reprezentarea numărului N în baza 4. Procedeul poate fi aplicat şi invers : În reprezentarea numărului N în baza 4 N = (10) = (4) înlocuim fircare cifră din baza 4 prin reprezentarea ei prin grupe de două cifre în baza 2 (binar) şi obţinem direct reprezentarea întregului număr N în baza 2 (binar). Exemplul 7 : trecerea reciprocă dintre bazele 2 şi 8 b 1 = 2; b 2 = 8 = 2 3 ; rezultă k = 3 (vom lucra deci pe câte 3 cifre în binar) N = (10) = (2) 16

17 Despărţim reprezentarea binară în grupe de câte 3 cifre (de la dreapta la stânga): şi reprezentăm fiecare grupă pe câte o singură cifră în baza 8 (pentru că am făcut un tabel de corespondenţe, putem să citim asta direct din tabel) ; obţinem succesiunea de cifre Se observă cu uşurinţă că am obţinut chiar reprezentarea numărului N în baza 8. Procedeul poate fi aplicat şi invers : În reprezentarea numărului N în baza 4 N = (10) = (8) înlocuim fircare cifră din baza 8 prin reprezentarea ei prin grupe de trei cifre în baza 2 (binar) şi obţinem direct reprezentarea întregului număr N în baza 2 (binar). Exemplul 8 : trecerea reciprocă dintre bazele 2 şi 16 b 1 = 2; b 2 = 16 = 2 4 ; rezultă k = 4 (vom lucra deci pe câte 4 cifre în binar) N = (10) = (2) Despărţim reprezentarea binară în grupe de câte 2 cifre (de la dreapta la stânga): Datorită faptului că în prima grupă din stânga am obţinut doar două cifre, completăm prima grupă cu două cifre de zero la stânga (ceea ce, evident, nu modifică valoarea) şi reprezentăm fiecare grupă pe câte o singură cifră în baza 8 (pentru că am făcut un tabel de corespondenţe, putem să citim asta direct din tabel) ; obţinem succesiunea de cifre 331A7 Se observă cu uşurinţă că am obţinut chiar reprezentarea numărului N în baza 16. Procedeul poate fi aplicat şi invers : În reprezentarea numărului N în baza 16 N = (10) = 331A7 (16) înlocuim fircare cifră din baza 16 prin reprezentarea ei prin grupe de patru cifre în baza 2 (binar) şi obţinem direct reprezentarea întregului număr N în baza 2 (binar). Exemplul 9 : trecerea reciprocă dintre bazele 4 şi 16 b 1 = 4; b 2 = 16 = 4 2 ; rezultă k = 2 (vom lucra deci pe câte 2 cifre în baza 4) N = (10) = (4) Despărţim reprezentarea în baza 4 în grupe de câte 2 cifre (de la dreapta la stânga) : Datorită faptului că în prima grupă din stânga am obţinut doar o cifră, completăm prima grupă cu o cifră de zero la stânga (ceea ce, evident, nu modifică valoarea) şi reprezentăm fiecare grupă pe câte o singură cifră în baza 16 (pentru că am făcut un tabel de corespondenţe, putem să citim asta direct din tabel) ; obţinem succesiunea de cifre 331A7 Se observă cu uşurinţă că am obţinut chiar reprezentarea numărului N în baza 16. Procedeul poate fi aplicat şi invers : În reprezentarea numărului N în baza 16 17

18 N = (10) = 331A7 (16) înlocuim fircare cifră din baza 16 prin reprezentarea ei prin grupe de două cifre în baza 4 (binar) şi obţinem direct reprezentarea întregului număr N în baza 4. Exemplul 10 : trecerea reciprocă dintre bazele 3 şi 9 Pentru ultima pereche de baze dintre cele pe care ni le-am propus, vom scrie mai întâi corespondenţa dintre bazele 10, 3 şi 9 (cu alte cuvinte, vom număra în aceste baze) : Baza b 1 = 3; b 2 = 9 = 3 2 ; rezultă k = 2 (vom lucra deci pe câte 2 cifre în baza 3) N = (10) = (3) Despărţim reprezentarea binară în grupe de câte 2 cifre (de la dreapta la stânga) : şi reprezentăm fiecare grupă pe câte o singură cifră în baza 9 (pentru că am făcut un tabel de corespondenţe, putem să citim asta direct din tabel) ; obţinem succesiunea de cifre Se observă cu uşurinţă că am obţinut chiar reprezentarea numărului N în baza 9. Procedeul poate fi aplicat şi invers : În reprezentarea numărului N în baza 9 N = (10) = (9) înlocuim fircare cifră din baza 9 prin reprezentarea ei prin grupe de două cifre în baza 3 şi obţinem direct reprezentarea întregului număr N în baza 3. 18

19 SUGESTII TEME DE LABORATOR A. Scrieţi pe o foaie de hârtie data naşterii, în formatul aaaallzi, fǎrǎ pauze sau caractere separatoare. Veţi folosi ca punct de plecare numǎrul de opt cifre astfel obţinut. (de exemplu, pentru o persoanǎ nǎscutǎ la data de 17 decembrie 1976, vom obţine numǎrul , iar pentru o persoanǎ nǎscutǎ la data de 9 mai 1980 vom obţine numǎrul ). Treceţi numǎrul astfel obţinut (considerat cǎ este scris în baza 10) în toate bazele de la 2 pânǎ la 16, utilizând algoritmul cu împǎrţiri successive. B. Verificaţi corectitudinea rezultatelor prin douǎ metode: - utilizând aplicaţia Bazenum de pe Desktopul calculatorului - Efectuând trecerea numerelor obţinute la punctul A în baza 10, utilizând formula polinomialǎ C. Efectuaţi urmǎtoarele schimbǎri de bazǎ: (8) în bazele 4, 12 şi 5 - ABC(16) în bazele 6, 7 şi 11 D. Pornind de la reprezentarea în baza 2 pe care a-ţi obţinut-o la punctual A., treceţi numǎrul direct în bazele 4, 8 şi 16, fǎrǎ a vǎ folosi de de baza 10 19

20 1.2 EFECTUAREA OPERAŢIILOR ÎN DIFERITE BAZE DE NUMERAŢIE Reprezentare numerelor fracţionare intr-o baza b (oarecare) Să pornim tot de la un exemplu concret: Q = ,6875 ceea ce înseamnă, evident, Q = în care apar şi puterile negative ale lui 10. Este uşor de generalizat acest lucru pentru reprezentarea unui număr fracţionar Q întro bază b oarecare : Q = a n b n + a n-1 b n a 2 b 2 + a 1 +b 1 + a 0 b a -1 b -1 + a -2 b -2 + a -3 b a -m +b -m = a n a n-1 a n-2 a 2 a 1 a 0, a -1 a -2 a -3 a -m (b) în care virgula (sau punctul, în sistemul anglo-saxon) desparte partea întreagă de partea fracţionară. Putem, evident, descompune numărul fracţionar Q în cele două componente ale sale componenta întreagă şi componenta fracţionară unde Q = Q 1 + Q 2 Q 1 = a n b n + a n-1 b n a 2 b 2 + a 1 +b 1 + a 0 b 0 = a n a n-1 a n-2 a 2 a 1 a 0 (b) Q 2 = a -1 b -1 + a -2 b -2 + a -3 b a -m +b -m = 0, a -1 a -2 a -3 a -m (b) Având în vedere că pentru partea înteagă dispunem deja de metode de trecere dintr-o bază în alta, rezultă că pentru a trece numărul Q dintr-o bază în alta mai avem nevoie doar de metode prin care să trecem un număr fracţionar fără parte întreagă în baza dorită. Pentru a trece un astfel de număr dintr-o bază b oarecare în baza 10, e sufficient să aplicăm formula polinomială. Exemplu Fie Q = 0,312 (4) 20

21 Conform formulei, vom avea Q = = 3 0, , ,05625 = = 0,75 + 0, ,03125 = 0,84375 (4) Pentru a trece numărul Q f din baza 10 într-o bază b oarecare, observăm următoarele : Q f b = (a -1 b -1 + a -2 b -2 + a -3 b a -m +b -m = 0, a -1 a -2 a -3 a -m ) b = = a -1 + a -2 b -1 + a -3 b a -m +b -m+1 = a -1 + Q f1 adică, prin înmulţirea numărului de la care am pornit cu baza b, se obţine trecerea în faţa virgulei a coeficientului a -1 (prima cifră din reprezentarea în baza b a numărului strict fracţionar Q f. Neglijând acum această cifră şi repetând înmulţirea cu b, pentru numărul Q f1 obţinut la pasul anterior, vom obţine cea de-a doua cifră din reprezenterea numărului iniţial Q f cifra a -2, şi aşa mai departe. Procedeul se opreşte când partea fracţionară devine zero, sau atunci când considerăm că am obţinut numărul cu precizia dorită. Să aplicăm regula obţinută pe un exemplu: să trecem numărul fracţionar Q f = 0,6875 (10) în baza 2. 0, = 1,375 a -1 = 1 0,375 2 = 0,75 a -2 = 0 0,75 2 = 1,5 a -3 = 1 0,5 2 = 1 a -4 = 1 şi, deoarece partea fracţionară a devenit egala cu zero, procedeul s-a încheiat ; am obţinut, deci : Verificare : Q f = 0,6875 (10) = 0,1011 (2) 0,1011 (2) = = = 1 0, , , ,0625 = = 0,6875 (10) Vom obţine atunci : Q = ,6875 (10) = ,1011 (2) 21

22 Observaţie importantă 1 : Dacă un număr fracţionar se poate reprezenta cu ajutorul unui număr finit de cifre (matematic exprimat : fără perioadă) într-o bază b 1, aceasta nu înseamnă că el se va putea reprezenta tot cu ajutorul unui număr finit de cifre în orice altă bază b 2. Deci, proprietatea de periodicitate a unui număr depinde de baza în care este exprimat. Exemplul 1 : Fie numărul 0,12 (3). După cum se vede, el se reprezintă cu ajutorul a doar două cifre după virgulă, în baza 3. Să-l trecem în baza 10. Conform formulei polinomiale : 0,12 (3) = = 1 1/3 +2 1/9 = 5/9 = 0, = 0,(5) (10) deci am obţinut un număr periodic în baza 10. Exemplul 2 : Fie numărul 0,7 (10). După cum se vede, el se reprezintă cu ajutorul unei singure cifre după virgulă, în baza 10. Să-l trecem în baza 2. Conform metodei pe care o cunoaştem, aceasta se face prin înmulţirea succesivă cu 2. pasul 1 0,7 2 = 1,4 a -1 = 1 păstrăm 0,4 pasul 2 0,4 2 = 0,8 a -2 = 0 păstrăm 0,8 pasul 3 0,8 2 = 1,6 a -3 = 1 păstrăm 0,6 pasul 4 0,6 2 = 1,2 a -4 = 1 păstrăm 0,2 pasul 5 0,2 2 = 0,4 a -5 = 0 păstrăm 0,4 pasul 6 0,4 2 = 1,8 a -6 = 1 păstrăm 0,8 şi este uşor de observat că de aici înainte se vor repeta la nesfârşit paşii 2, 3, 4, 5 şi 6, procesul neterminându-se niciodată. Vom avea deci : 0,7 (10) = 0, = 0,1(01100) (2), adică un număr periodic în baza 2. Observaţie importantă 2 : Metodele de trecere reciprocă între două baze b 1 şi b 2 legate între ele printr-o relaţie de tipul b 2 = b 1 k vor rămâne valabile, având grijă doar să despărţim în grupe de câte k cifre de la virgulă spre stânga, pentru partea întreagă, respectiv spre dreapta, pentru partea fracţionară. Dacă, pentru partea întreagă, ultima grupă de cifre pe care le-am despărţit (cea mai din stânga) este formată din mai puţin de k cifre, se completează la stânga cu numărul necesar de zerouri. Dacă, pentru partea fracţionară, ultima grupă de cifre pe care le-am despărţit (cea mai din dreapta) este formată din mai puţin de k cifre, se completează la dreapta cu numărul necesar de zerouri. 22

23 Exemplu : Să trecem numărul ,6875 (10) în baza 16, ţinând cont că avem deja reprezentarea sa în baza 2. deoarece 16 = 2 4, înseamnă că k = 4, deci trebuie să despărţim cifrele din reprezentarea în bază 2 în grupe de câte ,6875 (10) = ,1011 (2) = = , 1011 = = , 1011 = = 331A7,B (16) unde am completat grupa din stânga cu două zerouri (la stânga), ceea ce, evident, nu modifică valoarea numărului. Efectuarea operaţiilor matematice într-o bază B oarecare Adunarea numerelor în diferite baze de numeraţie În orice bazǎ de numeraţie, adunarea se face dupǎ aceleaşi reguli ca şi în zecimal, cu observaţia cǎ cifra cea mai mare dintr-o bazǎ b va fi b 1, adicǎ 9 în zecimal, 7 în octal, 1 în binar şi F în hexazecimal. Dacǎ prin adunarea a douǎ cifre de rang i se va obţine un rezultat mai mare decît b 1, va apare un transport spre cifra de rang urmǎtor (i +1) iar pe poziţia de rang i va rǎmîne restul împǎrţirii rezultatului adunǎrii cifrelor de rang i + 1 la bazǎ. Transportul spre cifra de rang i + 1 va deveni o nouǎ unitate la suma cifrelor de rang i + 1. În tabelul 1 este prezentat un exemplu de adunare a numerelor în binar, octal şi hexazecimal. Tabelul 1. Adunarea numerelelor în diferite baze de numeraţie. Binar Octal Hexazecimal C6F Scǎderea numerelor în diferite baze de numeraţie Ca şi în cazul adunǎrii, pentru scǎderea numerelor în binar, octal şi hexazecimal (ca de altfel în orice bazǎ) se aplicǎ regulile de la scǎderea în zecimal: dacǎ nu se pot scǎdea douǎ cifre de rang i (adicǎ cifra descǎzutului este mai micǎ decât a scǎzǎtorului) se 23

24 face împrumut o unitate din cifra de rang urmǎtor i + 1. În cazul în care cifra din care se face împrumutul este 0, se face împrumutul mai departe, din cifra de rang urmǎtor. în tabelul 2 este prezentat un exemplu de scǎdere a numerelor în binar, octal şi hexazecimal. Tabelul 2. Scǎderea numerelelor în diferite baze de numeraţie Binar Octal Hexazecimal AF9 13F BA Înmulţirea şi împǎrţirea numerelor în binar Înmulţirea şi împǎrţirea numerelor în sistemul de numeraţie binar se efectueazǎ ca şi în cazul numerelor din sistemul zecimal. În cazul înmulţirii în binar (ca şi în zecimal) 1 1 = 1, 0 0 = 0 iar 0 1 = 0. Împǎrţirea numerelor în sistemul de numeraţie binar are acelaşi rezultat ca şi în zecimal, adicǎ un cât şi un rest. În tabelul 3 este prezentat cîte un exemplu de înmulţire şi împǎrţire a numerelor în binar Tabelul 3. înmulţirea şi împǎrţirea numerelor în binar înmulţire împǎrţire Notǎ: Dacǎ în urma împǎrţirii a douǎ numere în binar rezultǎ un rest diferit de zero şi mai mic decî împarţitorul, pentru obţinerea pǎrţii fracţionare se poate continua împǎrţirea astfel: se adauga cifra 0 la rest si virgula la cât si se continuǎ prin împǎrţirea restului la împarţitor, rezultatele fiind adǎugate la cât dupǎ virgulǎ 24

25 Reprezentarea binarǎ a numerelor negative Pentru reprezentarea numerelor negative în binar, bitul din stânga reprezentǎrii numǎrului este folosit ca bit de semn. Astfel avem bitul de semn: 0 - pentru numere pozitive (+) 1 - pentru numere negative (-) Restul de N 1 biţi sunt folosiţi pentru reprezentarea valorii Codul direct Numerele întregi se reprezintǎ prin valoare absolutǎ şi semn. în cazul codului direct, pentru numerele negative bitul de semn este 1 iar ceilalţi n 1 biţi servesc pentru reprezentarea valorii absolute a numǎrului. De exemplu, numǎrul N = 5 se poate reprezenta pe 8 biţi astfel: (2), unde valoarea absolutǎ este (2) iar primul bit este bitul de semn. Domeniul de reprezentare în cazul codului direct va fi: 2n 1 valori pozitive de la 0 la 2n 1 1 2n 1 valori negative de la (2n 1 1) la 0 Se poate observa cǎ existǎ douǎ reprezentǎri ale lui zero, respectiv şi , iar numǎrul maxim şi numǎrul minim dintr-un domeniu au aceeaşi valoare absolutǎ, respectiv şi Codul invers Pentru numerele negative reprezentate în codul invers (complement faţǎ de 1) bitul de semn este 1 iar ceilalţi n 1 biţi servesc la reprezentarea valorii absolute negate a numǎrului de reprezentat. Negarea se realizeazǎ la nivel de bit: biţii 0 devin 1 iar biţii 1 devin 0. De exemplu, numǎrul N = 5 se va reprezenta în codul invers astfel: (2), unde (2) reprezintǎ valoarea absolutǎ negatǎ a numǎrului (2). Matematic, complementul faţǎ de 1 al unui numǎr negativ N care se reprezintǎ pe n biţi se defineşte astfel C1(N ) = 2n 1 V 25

26 unde n - numǎrul de biţi al reprezentǎrii V - valoarea absolutǎ a numǎrului de reprezentat Codul complementar Pentru reprezentarea numerelor negative în codul complementar (complement faţǎ de 2) se aplicǎ urmǎtoarea regulǎ de complementare: se reprezintǎ numǎrul în valoare absolutǎ, apoi se inverseazǎ bit cu bit(inclusiv bitul de semn care devine 1); la rezultatul obţinut se adunǎ 1. Deci, complementul faţǎ de 2 se obţine din complementul faţǎ de 1 la care se adunǎ 1. De exemplu, numǎrul N = 5 în codul complementar va avea valoarea (inversare) Din punct de vedere matematic, complementul faţǎ de 2 al unui numǎr negativ N este C2(N ) = 2n V unde: n - numǎrul de biţi al reprezentǎrii V - valoarea absolutǎ a numǎrului de reprezentat În cazul codului complementar bitul din stânga rǎmâne tot timpul bit de semn. Avantajul reprezentǎrii în complement faţǎ de 2 este cǎ, adunînd un numǎr cu complementul sǎu faţǎ de 2, rezultatul este 0 (ignorând depǎşirea) ceea ce nu este valabil în cazul celorlalte reprezentǎri. Codul complementar este cel mai utilizat în reprezentarea numerelor algebrice în calculator 26

27 SUGESTII TEME DE LABORATOR 1) Sǎ se efectueze urmǎtoarele operaţii: a) (2) (2) b) (2) (2) c) 1733(8) + 234(8) d) 1022(8) (8) e) AC 97(16) + 33ED(16) f) 922A(16) (16) g) 10110(2) 1101(2) h) (2) 11101(2) i) 7100(8) 324(8) j) 1021(8) 261(8) k) AA31(16) 2F C(16) l) F D124(16) AF 3C(16) 2) Sǎ se efectueze urmǎtoarele operaţii:: a) (2) 11001(2) b) (2) 10011(2) c) (2) 1110(2) d) (2) 101(2) e) 10111(2) : 110(2) f ) 10101(2) : 100(2) g) (2) : 1101(2) h) (2) : 101(2) 3) Sǎ se reprezinte urmǎtoarele numere în sistemul binar, utilizînd codul direct, invers şi complementar: a) -314 b) -666 c) d) -34 e) -255 f) -256 g) -100 h) -1 27

28 2. REPREZENTAREA DATELOR ÎN CALCULATOR Reprezentarea numerelor în virgulă mobilă În cazul reprezentării în forma cu virgulă fixă, poziţia virgulei, stabilită prin proiectare, nu mai poate fi schimbată, cu toate că virgula nu mai este reprezentată fizic în calculator. Dacă virgula este amplasată după cifra de semn, se lucrează cu numere fracţionare subunitare. Deoarece nu toate numerele sunt subunitare, pentru a le aduce la această formă trebuie executate o serie de operaţii de scalare (multiplicare cu un anumit factor de scală) sau deplasare, ataşând numerelor factori de scală. Evidenţa acestora trebuie realizată prin program, motiv pentru care acestea se complică. Această dificultate se poate rezolva utilizând reprezentarea în virgulă mobilă (virgulă flotantă). În acest caz, factorul de scală devine o parte a cuvântului din calculator, poziţia virgulei variind pentru fiecare număr în mod automat, ceea ce conduce la simplificarea programelor. Un număr reprezentat în virgulă mobilă (VM) are două componente. Prima componentă este mantisa, care indică valoarea exactă a numărului într-un anumit domeniu, fiind reprezentată de obicei ca un număr fracţionar cu semn. A doua componentă este exponentul, care indică ordinul de mărime al numărului. Considerând un număr N, reprezentarea acestuia în VM poate avea forma următoare: N = ± M B ±E (3.1) unde M este mantisa, B este baza sistemului de numeraţie, iar E este exponentul. Această reprezentare poate fi memorată într-un cuvânt binar cu trei câmpuri: semnul, mantisa şi exponentul. De exemplu, presupunând un cuvânt de 32 de biţi, o asignare posibilă a biţilor la fiecare câmp poate fi următoarea: Aceasta este o reprezentare în mărime şi semn, deoarece semnul are un câmp separat faţă de restul numărului. Câmpul de semn constă dintr-un bit care indică semnul numărului: 0 pentru un nu- măr pozitiv şi 1 pentru un număr negativ. Nu există un câmp rezervat pentru baza B, deoarece această bază este implicită şi ea nu trebuie memorată, fiind aceeaşi pentru toate numerele. 28

29 De obicei, în locul exponentului se reprezintă o valoare numită caracteristică, care se obţine prin adunarea unui deplasament la exponent, astfel încât să rezulte întotdeauna o valoare pozitivă. Deci, nu se rezervă un câmp separat pentru semnul exponentului. Caracteristica C este deci exponentul deplasat: C = E + deplasament (3.2) Valoarea reală a exponentului se poate afla prin scăderea deplasamentului din caracteristica numărului. De exemplu, dacă pentru caracteristică se rezervă un câmp de 8 biţi, valorile caracteristicii pot fi cuprinse între 0 şi 255. Cu un deplasament de 128 (80h), exponentul poate lua valori între 128 şi +127, fiind negativ dacă C < 128, pozitiv dacă C > 128, şi 0 dacă C = 128. Exponentul este deci reprezentat în exces 128. Reprezentarea cu ajutorul caracteristicii va fi următoarea: În acest caz, semnul mantisei este acelaşi cu semnul numărului. Unul din avantajele utilizării exponentului deplasat constă în simplificarea operaţiilor execu- tate cu exponentul, datorită lipsei exponenţilor negativi. Al doilea avantaj se referă la modul de repre- zentare al numărului zero. Mantisa numărului zero are cifre de 0 în toate poziţiile. Exponentul numărului zero poate avea, teoretic, orice valoare, rezultatul fiind tot zero. În unele calculatoare, dacă un rezultat are mantisa zero, exponentul este lăsat la valoarea pe care o are în momentul respectiv, rezultând un zero impur. La majoritatea calculatoarelor, se recomandă ca numărul zero să aibă cel mai mic exponent posibil, rezultând astfel un zero pur. În cazul exponenţilor nedeplasaţi, exponentul cu cea mai mică valoare este cel mai mic număr negativ pe care îl poate avea exponentul, iar în cazul exponenţilor de- plasaţi, această valoare este 0. Deci, prin utilizarea caracteristicii, reprezentarea în VM a numărului zero este aceeaşi cu repre- zentarea în VF, adică toate poziţiile sunt 0. Aceasta înseamnă că se pot utiliza aceleaşi circuite pentru testarea valorii zero. În reprezentarea anterioară, mantisa constă din 23 de biţi. Deşi virgula binară nu este repre- zentată, se presupune că ea este aşezată înaintea bitului c.m.s. al mantisei. De exemplu, dacă B = 2, numărul 1,75 poate fi reprezentat sub mai multe forme: 29

30 Pentru simplificarea operaţiilor cu numere în VM şi pentru creşterea preciziei acestora, se utili- zează reprezentarea sub forma normalizată. Un număr în VM este normalizat dacă bitul c.m.s. al manti- sei este 1. Din cele două reprezentări ale numărului 1,75 ilustrate anterior, prima este cea normalizată. Deoarece bitul c.m.s. al unui număr normalizat în VM este întotdeauna 1, acest bit nu este de obicei memorat, fiind un bit ascuns la dreapta virgulei binare. Aceasta permite ca mantisa să aibă un bit semnificativ în plus. Astfel, câmpul de 23 de biţi este utilizat pentru memorarea unei mantise de 24 de biţi cu valori între 0,5 şi 1,0. Cu această reprezentare, Figura 2.1 indică gama numerelor care pot fi reprezentate într-un cu- vânt de 32 de biţi. Dacă se utilizează reprezentarea în C2, se pot reprezenta toate numerele întregi între 2 31 şi , cu un total de 2 32 numere diferite. Pentru formatul prezentat, se pot reprezenta numere în urmă- toarele domenii (Figura 3.1): Numere negative între ( ) şi 0, Numere pozitive între 0, şi ( ) Figura 3.1. Numere reprezentabile în formate tipice de 32 de biţi. Există cinci regiuni care nu sunt cuprinse în aceste domenii: Numere negative mai mici decât ( ) 2 127, apariţia acestora determinând o depăşire su- perioară negativă 30

31 Numere negative mai mari decât 0, , care determină o depăşire inferioară negativă Zero Numere pozitive mai mici decât 0, , care determină o depăşire inferioară pozitivă Numere pozitive mai mari decât ( ) 2 127, care determină o depăşire superioară pozitivă În unele cazuri, bitul ascuns se presupune poziţionat la stânga virgulei binare. Astfel, mantisa memorată M va reprezenta de fapt valoarea 1,M. În acest caz, numărul normalizat 1,75 va avea urmă- toarea formă: Presupunând că bitul ascuns este poziţionat la stânga virgulei binare în formatul prezentat, un număr normalizat diferit de zero reprezintă următoarea valoare: unde S indică bitul de semn. ( 1) S (1,M) 2 E 128 (3.3) În acest format se pot reprezenta numere în următoarele domenii: Numere negative între [1 + ( )] şi 1, Numere pozitive între 1, şi [1 + ( )] Problema care apare în cazul formatului prezentat este că nu există o reprezentare pentru va- loarea zero. Aceasta deoarece valoarea zero nu poate fi normalizată. Totuşi, reprezentările în VM cu- prind de obicei o combinaţie specială de biţi pentru reprezentarea valorii zero. Depăşirea superioară apare atunci când exponentul depăşeşte valoarea maximă, de exemplu peste 127 în cazul formatului prezentat. Depăşirea inferioară apare atunci când exponentul are o va- loare negativă prea mică, de exemplu sub 128. În cazul depăşirii inferioare, rezultatul se poate apro- xima cu 0. Coprocesoarele matematice au anumite mecanisme pentru detectarea, semnalarea şi tratarea depăşirii superioare şi a celei inferioare. Pentru alegerea unui format în VM trebuie realizat un compromis între dimensiunea mantisei şi cea a exponentului. Creşterea dimensiunii mantisei va conduce la creşterea preciziei numerelor, iar creşterea dimensiunii exponentului va conduce la creşterea domeniului numerelor care pot fi repre- zentate. Singura cale de a creşte atât precizia, 31

32 cât şi domeniul numerelor, este de a utiliza un număr mai mare de biţi pentru reprezentare. Cele mai multe calculatoare utilizează cel puţin două formate, în simplă precizie (de exemplu pe 32 de biţi), şi dublă precizie (de exemplu pe 64 de biţi). Reprezentarea numerelor în formatul IEEE 754 IEEE (Institute of Electrical and Electronics Engineers) a dezvoltat un standard pentru reprezentarea numerelor în VM şi operaţiile aritmetice în această reprezentare. Scopul era facilitarea portabilităţii programelor între diferite calculatoare. Standardul IEEE 754 a fost publicat în Cele mai multe coprocesoare aritmetice, printre care şi cele Intel pentru familia de microprocesoare 80x86, se conformează acestui standard. Standardul defineşte trei formate: Formatul scurt (precizie simplă): 4 octeţi Formatul lung (precizie dublă): 8 octeţi Formatul temporar (precizie extinsă): 10 octeţi Baza implicită este 2. Formatul scurt şi cel lung sunt prezentate în continuare. S indică semnul numărului. C reprezintă exponentul deplasat, deci caracteristica, pentru care se rezervă 8 biţi în formatul scurt şi 11 biţi în formatul lung. Pentru formatul scurt, deplasamentul este 127 (7Fh), iar pentru formatul lung deplasamentul este 1023 (3FFh). Valorile minime (0) şi cele maxi- me (255, respectiv 2047) ale caracteristicii nu sunt utilizate pentru numerele normalizate, ele având utilizări speciale. Bitul ascuns este utilizat şi la standardul IEEE 754, dar mantisa este reprezentată într-un mod diferit. Ea constă dintr-un bit implicit cu valoarea 1 (partea întreagă), virgula binară implicită, şi apoi cei 23, respectiv 52 de biţi ai fracţiei. Dacă toţi biţii fracţiei sunt 0, mantisa este 1,0; dacă toţi biţii fracţiei sunt 1, mantisa este cu puţin mai mică decât 2,0. Deci: Mantisa are valoarea: 1,0 <= M < 2,0 M = 1,Fracţie iar valoarea numărului în precizie simplă (NS), respectiv în precizie dublă (ND) este: NS = ( 1) s M 2 C-127 (3.4) ND = ( 1) s M 2 C-1023 (3.5) 32

33 Gama numerelor care pot fi reprezentate în precizie simplă este cuprinsă între aproximativ 2, şi 3, , iar cea a numerelor reprezentate în precizie dublă este cuprinsă între 2, şi 1, Formatul temporar este utilizat pentru reprezentarea numerelor în cadrul coprocesoarelor aritmetice, în scopul reducerii erorilor datorate rotunjirilor. Acest format este următorul: Bitul 63 reprezintă partea întreagă a mantisei, care nu este implicită. Numerele în formatul temporar nu sunt întotdeauna normalizate, de aceea nu încep în mod obligatoriu cu un bit de 1. De aceea acest bit este reprezentat explicit, fiind notat cu I în cadrul formatului. Deplasamentul exponen- tului este , iar valoarea numărului (NE) este: NE = ( 1) s * M * 2 C (3.6) Una din problemele care apare la calculele cu numere în VM se referă la modul de tratare al depăşirilor inferioare şi superioare, şi la reprezentarea valorilor nedefinite. În acest scop, pe lângă numerele normalizate, standardul mai permite şi reprezentări ale unor valori speciale, pentru care sunt rezervate valorile 0 şi 255 ale exponentului. Unele din aceste valori speciale sunt prezentate în continuare. În cazul obţinerii unui rezultat cu o valoare mai mică decât numărul normalizat cel mai mic posibil, în mod obişnuit rezultatul este setat la zero şi operaţiile se continuă, sau se semnalează o eroa- re de depăşire inferioară. Nici una din aceste soluţii nu este satisfăcătoare, astfel încât standardul per- mite utilizarea numerelor nenormalizate (denormalizate), care au caracteristica 0, iar fracţia diferită de 0. Pentru valoarea zero, atât caracteristica, cât şi fracţia, sunt egale cu 0. Există două reprezentări pentru valoarea 0, în funcţie de bitul de semn: +0, respectiv -0. Bitul de la stânga punctului binar este implicit 0 în loc de 1. Pentru cazul în care apare o depăşire superioară, există o reprezentare specială 33

34 pentru infinit, constând din caracteristica formată din biţi de 1 (255 pentru formatul scurt), şi o fracţie egală cu 0. Valoarea infinit se poate utiliza ca operand, de exemplu: + n = n / = 0 n / 0 = Astfel, utilizatorul poate decide dacă va trata depăşirea superioară ca o condiţie de eroare, sau va con- tinua calculele cu valoarea infinit. Pentru indicarea diferitelor condiţii de excepţie, ca în cazul nedefinirilor de forma /, * 0, 0/, s-a prevăzut un format special NaN (Not a Number). Caracteristica este formată din biţi de 1, iar fracţia este diferită de 0. Exemple 1) Care este reprezentarea binară a numărului 0,75 în simplă precizie? Numărul 0,75 poate fi scris ca 3/4 sau 0,11 în binar. Notaţia ştiinţifică a numărului este -0,11 2 0, iar forma normalizată a acestei notaţii este 1, Caracteristica va fi = 126 (7Eh). Reprezentarea numărului în precizie simplă este deci: 2) Care este numărul zecimal reprezentat de următorul cuvânt? Bitul de semn este 1, câmpul rezervat caracteristicii conţine 81h = 129, iar câmpul fracţiei conţine = 0,25. Valoarea numărului este: ( 1) 1 1,25 2 ( ) = 1, = 1,25 4 = 5,0 34

35 SUGESTII TEME DE LABORATOR A. Reprezentaţi în formatul IEEE 754 cu precizie simplă următoarele numere zecimale: a) 1; b) 1; c) 5; d) 5; e) 35,4; f) 35,4; g) 2,6; h) -192 Scrieţi rezultatele în hexazecimal. B. Reprezentaţi în formatul IEEE 754 cu precizie dublă următoarele numere zecimale: a) 1; b) 1,5; c) 2,5; d) 5; e) 35,4; f) 35,4 C. Scrieţi numerele zecimale corespunzătoare următoarelor reprezentări în formatul IEEE 754 cu precizie simplă: a) 41 8A 1E 94; b) A; c) BE CC CC CB; d) BD AB 40 C0 35

36 3. ELEMENTE DE TEORIA CODURILOR 6.1 Coduri binar-zecimale Aceste coduri se utilizează pentru codificarea cifrelor zecimale. Pentru codificarea fiecăreia din cele 10 cifre sunt necesari 4 biţi; din cele 16 valori posibile, 6 vor fi neutilizate. Prin stabilirea unor corespondenţe între mulţimea cifrelor zecimale şi mulţimea celor 16 cuvinte de 4 biţise obţin numeroase posibilităţi de codificare ( A 10 ). Dintre numeroasele coduri posibile se utilizează practic doar o mică parte. Codurile utilizate se împart în coduri ponderate şi neponderate. În cazul codurilor ponderate, o cifră zecimală este exprimată printr-o combinaţie de 4 cifre binare, în care fiecărei cifre i se asociază o anumită pondere. Ponderile pot fi pozitive sau negative. Valoarea cifrei zecimale se obţine prin suma biţilor din cod, fiecare bit fiind multiplicat cu valoarea ponderii asociate. Considerând un cod format din biţii b0, b1, b2, b3, ponderile asociate acestora fiind p0, p1, p2, respectiv p3, valoarea cifrei zecimale codificate este: N = p 0 b 0 + p 1 b 1 + p 2 b 2 + p 3 b 3 Ponderile fiecărui bit reprezintă valoarea corespunzătoare din denumirea codului. Pentru ponderile de sus, codul are denumirea p 3 p 2 p 1 p 0. În Tabelul 1 se prezintă exemple de coduri ponderate de 4 biţi mai des utilizate. Nr. zecimal Tabelul 1. Coduri binar-zecimale ponderate de 4 biţi 36

37 Exemple = = = (-2) 1 + (-1) 0 = 8 2 = În cazul codului 8421, deoarece fiecare bit are ponderea numărării în binar (2 0, 2 1, 2 2, 2 3 ), iar cuvintele de cod reprezintă numerele succesive în sistemul binar natural, codul se mai numeşte cod binar-zecimal natural (NBCD Natural Binary Coded Decimal). În mod obişnuit, acest cod se numeşte, impropriu, cod BCD. În cazul codului 2421, numit şi cod Aiken (după numele prof. Howard Aiken, care a realizat calculatorul MARK I), primele 5 cifre zecimale (0 4) au aceeaşi exprimare ca şi în codul Cifra zecimală 5 poate fi exprimată fie prin 0101, fie prin Deci, reprezentarea unor cifre zecimale nu este unică, această proprietate fiind valabilă şi pentru alte coduri. Pentru codificare s-a ales reprezentarea 1011, deoarece codul pentru cifra 5 se poate obţine atunci prin complementarea codului pentru cifra 4. Aceeaşi regulă se poate aplica pentru obţinerea codului cifrei 6 din codul cifrei 3, a codului cifrei 7 din codul cifrei 2 etc. Codurile care au această proprietate se numesc coduri autocomplementare. Un cod este autocomplementar dacă cuvântul de cod al complementului faţă de 9 al cifrei N (deci 9 N) se poate obţine din codul cifrei N, prin complementarea fiecăruia din cei 4 biţi. De exemplu, codul 8421 nu este autocomplementar, iar codurile 2421, 6423, 8421 sunt autocomplementare. ondiţia necesară pentru ca un cod ponderat să fie autocomplementar este ca suma ponderilor să fie egală cu 9. Autocomplementaritatea constituie un avantaj în construcţia unui dispozitiv aritmetic care lucrează cu numere zecimale reprezentate în codul respectiv. Observaţie. În forma internă, numerele sunt reprezentate şi prelucrate fie sub formă binară, fie codificate printr-un cod binar-zecimal. Trebuie sesizată diferenţa dintre conversia unui număr zecimal în echivalentul său binar şi codificarea binarzecimală a numărului zecimal. De exemplu: = (4 biţi) = ( ) BCD (8 biţi) Codurile neponderate pot avea un număr mai mare de 4 biţi. Codurile cele mai uzuale sunt prezentate în Tabelul 2. Nr. zecimal Exces 3 2 din 5 Gray

38 Codul Exces 3 este autocomplementar, şi derivă din codul 8421 (BCD) prin adăugarea la fiecare cifră a valorii 3. Utilizând acest cod, se poate face distincţie între lipsa unei informaţii înscrise într-un registru sau locaţie de memorie şi înscrierea valorii zero (0000 reprezintă lipsa unei informaţii, iar zero este codificat prin 0011). Codul 2 din 5 se utilizează pentru reprezentarea numerelor zecimale printr-un grup de 5 biţi. Denumirea derivă din faptul că fiecare cifră zecimală codificată în binar conţine doi biţi de 1 din cei 5 biţi. Codul Gray are proprietatea de adiacenţă, adică trecerea de la o cifră zecimală la următoarea sau precedenta necesită modificarea unui singur bit din cuvântul de cod. Este util pentru mărimile care cresc sau descresc succesiv. 6.2 Coduri detectoare de erori Transmiterea informaţiilor prin medii influenţate de zgomote poate fi însoţită de introducerea unor erori. Verificarea transmiterii corecte a informaţiilor se poate realiza cu ajutorul unor coduri speciale numite coduri detectoare de erori. Una din metodele de detectare a unei erori o constituie detectarea combinaţiilor interzise. În cazul codurilor binar-zecimale, deoarece se utilizează 10 din cele 16 combinaţii posibile de 4 biţi, celelalte combinaţii nu trebuie să apară. Aceste combinaţii interzise se pot utiliza pentru detectarea erorii. Dacă, de exemplu, în codul BCD 1000 apare o singură eroare, codul poate fi transformat în 0000, 1100, 1010 sau Dintre aceste combinaţii, a doua şi a treia constituie combinaţii interzise, astfel încât în aceste cazuri eroarea poate fi detectată. Celelalte combinaţii nu sunt interzise, deci în cazurile respective eroarea nu poate fi detectată. O modalitate de creştere a probabilităţii de detectare a erorilor constă în folosirea mai multor combinaţii interzise, care pot fi disponibile dacă codurile au mai mult de 4 biţi. De exemplu, în codul 2 din 5 apare o eroare ori de câte ori o cifră codificată are mai mult sau mai puţin de doi biţi de 1. Astfel, se pot detecta erori multiple. O altă metodă pentru detectarea erorilor constă în folosirea unor biţi suplimentari de verificare. De exemplu, un cod de n biţi poate fi format din m biţi de date şi r biţi redundanţi de verificare (n = m + r). Fiind date două cuvinte de cod, de exemplu şi , se poate determina numărul biţilor care diferă. În acest caz, există 3 biţi care diferă. Pentru determinarea numărului de biţi care diferă, se efectuează suma modulo 2 între cele două cuvinte de cod, şi se calculează numărul biţilor de 1 ai rezultatului. Numărul poziţiilor în care două cuvinte de cod diferă reprezintă distanţa Hamming. Dacă între două cuvinte de cod se află o distanţă Hamming d, sunt necesare d erori de câte un singur bit pentru trecerea de la un cod la al doilea cod. Proprietăţile de detectare a erorilor ale unui cod depind de distanţa sa Hamming. Pentru detectarea a d erori de câte un singur bit, este necesar un cod cu distanţa d+1, deoarece cu un asemenea cod nu există posibilitatea ca d erori de un singur bit să modifice un cuvânt de cod valid într-un alt cuvânt de cod valid. 38

39 Un exemplu simplu de cod detector de erori este un cod care conţine un bit suplimentar numit bit de paritate. Acest bit se poate alege astfel încât numărul total al biţilor având valoarea 1 în exprimarea numărului să fie par, respectiv impar. Dacă se utilizează paritatea pară, notând cu x 3 x 2 x 1 x 0 biţii cifrei zecimale şi cu p bitul de paritate, valoarea bitului de paritate determină ca suma modulo 2 a valorii tuturor biţilor să fie 0: x3 x2 x1 x0 p = 0 de unde rezultă p = x3 x2 x1 x0 Dacă se alege paritatea impară, trebuie ca: x3 x2 x1 x0 p = 1 p = x3 x2 x1 x0 1 Tabelul 2 Codul 8421 cu paritate pară Nr. zecimal Cod Un asemenea cod are distanţa 2, deoarece o eroare de un singur bit produce un cuvânt de cod cu paritatea eronată. La transmisia datelor se adaugă bitul de paritate pară sau impară, iar la recepţie se determină dacă paritatea este aceeaşi cu cea de la transmisie. Codurile 8421 cu paritate pară ale cifrelor zecimale sunt indicate în Tabelul Coduri corectoare de erori Verificarea parităţii nu poate detecta apariţia erorilor duble, deoarece aceste erori nu modifică suma modulo 2 a biţilor. Există coduri mai complexe, numite coduri corectoare de erori, care permit şi corectarea unui bit eronat sau a mai multor biţi eronaţi. Aceste coduri sunt utile atunci când retransmisia informaţiei nu este posibilă, sau necesită un timp care nu ar fi acceptabil. Presupunem un cod cu m biţi de date şi r biţi de verificare, cod care permite corectarea tuturor erorilor de un singur bit. Fiecăruia din cele 2 m cuvinte de cod valide îi corespund n cuvinte de cod ilegale cu distanţa 1. Acestea se formează prin inversarea 39

40 sistematică a fiecăruia din cei n biţi. Fiecare din cele 2 m cuvinte valide necesită n+1 combinaţii de biţi dedicate pentru cuvântul respectiv. Deoarece numărul total al combinaţiilor de biţi este 2 n, trebuie ca (n+1)2 m 2 n. Utilizând relaţia n = m + r, această cerinţă devine (m + r + 1) 2 r. Fiind dat m, aceasta impune o limită inferioară asupra numărului biţilor de verificare necesari pentru corectarea erorilor de un singur bit. De exemplu, pentru un cuvânt de m = 4 biţi, numărul minim al biţilor de verificare este r = 3, iar pentru un cuvânt de m = 8 biţi, numărul minim al biţilor de verificare este r = 4. Aceste limite teoretice pot fi atinse utilizând o metodă datorată lui Richard Hamming. Metoda poate fi utilizată pentru construirea codurilor corectoare de erori pentru cuvinte de cod de orice dimen- siune. Într-un cod Hamming, se adaugă r biţi de paritate la un cuvânt de m biţi, rezultând un nou cuvânt cu lungimea de m + r biţi. Biţii sunt numerotaţi începând cu 1 (şi nu cu 0), bitul 1 fiind bitul c.m.s. Toţi biţii ai căror număr este o putere a lui 2 sunt biţi de paritate, restul biţilor fiind utilizaţi pentru date. De exemplu, în cazul unui cuvânt de 4 biţi, biţii 1, 2 şi 4 sunt biţi de paritate. În total, cuvântul de cod va conţine 7 biţi (4 de date şi 3 de paritate). În exemplul prezentat se va utiliza în mod arbitrar paritatea pară. Fiecare bit de paritate verifică anumite poziţii de biţi. Aceste poziţii sunt ilustrate în Figura 1, unde prin pătrate s-a indicat poziţia biţilor de paritate, iar prin cercuri s-a indicat poziţia biţilor de informaţie. Figura 2. Construcţia codului Hamming pentru valoarea binară 0101 prin adăugarea a trei biţi de paritate. Poziţiile de biţi verificate de biţii de paritate sunt următoarele: Bitul 1 de paritate verifică biţii 1, 3, 5, 7. Bitul 2 de paritate verifică biţii 2, 3, 6, 7. Bitul 4 de paritate verifică biţii 4, 5, 6, 7. În general, bitul b este verificat de acei biţi b1, b2,, bj astfel încât b1 + b2 + + bj = b. De exemplu, bitul 5 este verificat de biţii 1 şi 4 deoarece = 5. Bitul 6 este verificat de biţii 2 şi 4 deoarece = 6. Se consideră exprimarea în cod 8421 a cifrei zecimale 5 (0101). Bitul 1 de paritate va trebui să determine un număr par de cifre de 1 pentru poziţiile 1, 3, 5 şi 7, deci va avea valoarea 0. Similar se determină valoarea bitului 2 de paritate, care va avea valoarea 1, şi a bitului 4 de paritate, care va avea valoarea 0. Dacă transmiterea cifrei zecimale se realizează corect, toţi biţii de paritate verifică în mod corect paritatea. Dacă apare o eroare de transmisie, fie la un bit de paritate, fie la un 40

41 bit de informaţie, acest cod poate corecta o singură eroare. De exemplu, presupunem că a apărut o eroare la transmiterea bitului de informaţie din poziţia 6. Codul recepţionat va fi în loc de Se verifică biţii de paritate, cu următoarele rezultate: Bitul 1 de paritate este corect (biţii 1, 3, 5, 7 conţin doi biţi de 1) Bitul 2 de paritate este incorect (biţii 2, 3, 6, 7 conţin trei biţi de 1) Bitul 4 de paritate este incorect (biţii 4, 5, 6, 7 conţin trei biţi de 1) Bitul incorect trebuie să fie unul din biţii testaţi de bitul 2 de paritate (2, 3, 6 sau 7). Deoarece bitul 4 de paritate este incorect, unul din biţii 4, 5, 6 sau 7 este incorect. Bitul eronat este unul din cei care se află în ambele liste, deci poate fi bitul 6 sau 7. Bitul 1 de paritate fiind corect, rezultă că şi bitul 7 este corect. Bitul eronat este deci bitul 6, şi valoarea acestui bit trebuie inversată. În acest fel, eroarea poate fi corectată. O metodă simplă pentru determinarea bitului eronat este următoarea. Se calculează biţii de paritate, şi dacă toţi biţii sunt corecţi, înseamnă că nu există eroare (sau există mai mult de o eroare). Se atribuie apoi biţilor de paritate ponderile 1, 2, respectiv 4, şi se adună ponderile biţilor de paritate eronaţi. Suma rezultată reprezintă poziţia bitului eronat. De exemplu, dacă biţii de paritate 2 şi 4 sunt eronaţi, bitul eronat este bitul Coduri alfanumerice Datele alfanumerice conţin cifre, litere şi semne speciale, numite, în general, caractere. Codurile care pot reprezenta asemenea caractere se numesc coduri alfanumerice. Codul ASCII Un cod alfanumeric foarte des utilizat este codul ASCII (American Standard Code for Information Interchange), care codifică literele mari şi mici ale alfabetului englez, cifrele zecimale, semnele de punctuaţie şi alte caractere speciale. Codul ASCII utilizează 7 biţi pentru a codifica 128 de caractere. Din cele 128 de caractere, 94 sunt caractere care pot fi tipărite, iar 34 sunt caractere utilizate pentru diferite funcţii de control. În Tabelul 3. se prezintă codurile ASCII. Cei 7 biţi ai codului sunt notaţi cu b0 până la b7, b7 fiind bitul c.m.s. De notat că cei trei biţi mai semnificativi ai codului determină coloana din tabelă, iar cei patru biţi mai puţin semnificativi determină linia din tabelă. De exemplu, litera A este reprezentată în ASCII prin codul binar (coloana 100, linia 0001). 41

42 Tabelul 3 Codurile ASCII b 6b 5b 4 b 3b 2b 1b NULL DLE P ` p 0001 SOH DC1! 1 A Q a q 0010 STX DC2 " 2 B R b r 0011 ETX DC3 # 3 C S c s 0100 EOT DC4 $ 4 D T d t 0101 ENQ NAK % 5 E U e u 0110 ACK SYN & 6 F V f v 0111 BEL ETB ' 7 G W g w 1000 BS CAN ( 8 H X h x b 6b 5b 4 b 3b 2b 1b HT EM ) 9 I Y i y 1010 LF SUB * : J Z j z 1011 VT ESC + ; K [ k { 1100 FF FS, < L \ l 1101 CR GS - = M ] m 1110 SO RS. > N ^ n ~ 1111 SI US /? O _ o DEL Cele 34 de caractere de control sunt desemnate în tabelul caracterelor ASCII prin nume abreviate. Caracterele de control se utilizează pentru transmisia datelor şi pentru aranjarea textului într-un anumit format. Există trei tipuri de caractere de control: de formatare, de separare a informaţiei şi de control al comunicaţiei. Dintre caracterele de formatare a textului menţionăm cele pentru deplasare înapoi BS (Backspace), retur de car CR (Carriage Return) şi tabulare orizontală HT (Horizontal Tabulation). Separatorii de informaţii se utilizează pentru separarea datelor în secţiuni, de exemplu în paragrafe şi pagini. Acestea cuprind caractere cum sunt separatorul de înregistrare RS (Record Separator) şi separatorul de fişier FS (File Separator). Caracterele de control al comunicaţiei se utilizează la transmisia textului. Exemple de asemenea caractere sunt STX (Start of Text) şi ETX (End of Text), care se pot utiliza pentru încadrarea unui mesaj transmis pe liniile de comunicaţie. Unicode şi ISO/IEC Unicode este un set de caractere specificat de un consorţiu de producători importanţi de calculatoare din SUA, definit cu scopul de a elimina dificultăţile datorate utilizării seturilor de caractere codificate diferit în programele elaborate pentru mai multe limbi. Începând cu versiunea 1.1, Unicode este compatibil cu standardul 10646, a cărui primă versiune a fost elaborată în 1993 de organizaţiile ISO (International Standards Organization) şi IEC International Electrotechnical Commission). Numele standardului este Universal Multiple-Octet Coded Character Set, întâlnit şi sub forma acronimului 42

43 UCS (Universal Character Set). Versiunea curentă a standardului este 3.0. UCS a fost primul set de caractere standardizat elaborat cu scopul de a include în final toate caracterele utilizate în toate limbile scrise din lume, ca şi alte simboluri, cum sunt cele matematice. UCS este utilizat atât pentru reprezentarea internă a datelor în sistemele de calcul, cât şi pentru comunicaţiile de date. În versiunile uzuale ale UCS, codul unui caracter este reprezentat prin patru cifre hexazecimale; aceasta corespunde formei pe doi octeţi, denumită UCS-2. A fost definită de asemenea şi o formă pe 4 octeţi, UCS-4, pentru a garanta faptul că spaţiul de codificare va fi suficient şi în viitor. În forma pe 2 octeţi a UCS, cele coduri sunt împărţite în 256 de linii de câte 256 de celule fiecare. Primul octet al codului unui caracter indică numărul liniei, iar al doilea numărul celulei. Primele 128 de caractere din linia 0 reprezintă caracterele ASCII. Întreaga linie 0 conţine aceleaşi caractere ca şi cele definite de standardul ISO/IEC Octetul reprezentând codul unui caracter ASCII sau ISO/IEC poate fi transformat simplu în reprezentarea sa UCS prin adăugarea cifrelor 00 în faţa acestuia. UCS cuprinde aceleaşi caractere de control ca şi cele din setul ASCII. În forma pe 4 octeţi, pot fi reprezentate peste 2 miliarde de caractere diferite. Primul bit al primului octet trebuie să fie 0, astfel încât se utilizează numai 31 de biţi din cei 32. Acest spaţiu de codificare este împărţit în 128 de grupe, fiecare conţinând 256 de planuri. Primul octet de cod indică numărul grupei, iar al doilea numărul planului. Al treilea şi al patrulea octet indică numărul liniei, respectiv al celulei. Caracterele care pot fi reprezentate în forma UCS-2 aparţin planului 0 din grupa 0, care este numit plan multilingv de bază sau BMP (Basic Multilingual Plane). Încă nu au fost alocate caractere poziţiilor în afara planului BMP, iar în practică se utilizează numai forma pe doi octeţi. În forma UCS-2, caracterele cu coduri cuprinse între 00A0h şi 00FFh formează setul Latin-1. Aceste coduri conţin litere suplimentare utilizate în principalele limbi din Europa de Vest, ca şi semne matematice şi de punctuaţie. Codurile din setul Latin-1 se bazează pe standardul ISO/IEC Tabelul 4. prezintă setul Latin-1. În acest tabel, primele trei cifre hexazecimale ale codului sunt cele care desemnează coloana, iar ultima cifră a codului este cea care desemnează linia. 00A 00B 00C 00D 00E 00F 0 À Ð à ð 1 ± Á Ñ á ñ 2 ² Â Ò â ò 3 ³ Ã Ó ã ó 4 Ä Ô ä ô 5 µ Å Õ å õ 6 Æ Ö æ ö 7 Ç ç 8 È Ø è ø 9 ¹ É Ù é ù A ª º Ê Ú ê ú B Ë Û ë û C ¼ Ì Ü ì ü D - ½ Í Ý í ý E ¾ Î Þ î þ F Ï ß ï ÿ Tabelul 4 Setul de caractere Latin 1 43

44 Există patru zone principale pentru asignarea codurilor UCS-2. Zona A conţine caractere alfabetice şi simboluri, având primele două cifre hexazecimale ale codului cuprinse între 00h şi 4Dh. De exemplu, această zonă cuprinde seturile Basic Latin, Latin-1, Latin Extended-A, Latin Extended-B; alfabetele grec, chirilic, armean, ebraic, arab, bengali, tamil, georgian; diferite simboluri, săgeţi, operatori matematici, forme geometrice etc. Literele ă, Ă, ş, Ş, ţ, Ţ din limba română fac parte din setul Latin Extended-A, în timp ce literele â, Â, î, Î fac parte din setul Latin-1. De menţionat că toate aceste caractere fac parte din setul de caractere ISO/IEC , care cuprinde caracterele speciale necesare pentru limbile ţărilor din Europa Centrală şi de Est. În Tabelul 5. se prezintă codurile ISO/IEC ale caracterelor speciale utilizate în limba română. Tabelul 5. Codurile ISO/IEC ale caracterelor speciale din limba română Caracter Cod hexa Caracter Cod hexa Ă ă Â 00 C2 â 00 E2 Î 00 CE î 00 EE Ş 01 5E ş 01 5F Ţ ţ Zona I conţine caractere ideografice, având primele două cifre hexazecimale ale codului cuprinse între 4Eh şi 9Fh. Un caracter ideografic reprezintă un cuvânt sau o unitate gramaticală inseparabilă. Există un mare număr de caractere ideografice în diferite limbi. Ca un principiu general de codificare, pentru ca un nou caracter să fie inclus în setul UCS, acest caracter trebuie să difere de toate caracterele deja incluse, atât în semnificaţie, cât şi ca formă. Formele grafice alternative ale caracterelor existente (variante de fonturi, hieroglife) nu au deci coduri distincte. În limbile chineză, japoneză şi coreeană există un mare număr de caractere ideografice care au aceeaşi origine istorică şi doar diferenţe minore ca formă în cele trei limbi. Acestor variante naţionale ale aceluiaşi caracter ideografic li s-a atribuit un cod UCS unificat, o soluţie cunoscută sub numele de unificare CJK. Zona I conţine asemenea caractere unificate. Zona O, având primele două cifre hexazecimale ale codului cuprinse între A0h şi DFh, este rezervată pentru versiunile ulterioare ale standardului. Zona R este o zonă pentru utilizare restrânsă, codurile având primele două cifre hexazecimale cuprinse între E0h şi FFh. Această zonă este împărţită la rândul ei în zona de utilizare privată, zona de compatibilitate a caracterelor ideografice CJK şi zona caracterelor speciale. Zona de utilizare privată este disponibilă pentru utilizatorii care necesită caractere speciale pentru programele lor de aplicaţii. De exemple, icoanele utilizate în meniuri pot fi specificate prin coduri de caractere în această zonă. Există posibilitatea utilizării unui număr de 6400 de caractere private, cu coduri având primele două cifre hexazecimale cuprinse între E0h şi F8h. Această zonă nu va fi ocupată de versiunile viitoare ale standardului. Zona de compatibilitate conţine caracterele care sunt mapate la alte zone în spaţiul de codificare. Caracterele disponibile în această zonă specială au o utilizare largă, dar nu sunt direct compatibile cu modul de reprezentare a caracterelor UCS, astfel încât nu pot fi incluse direct în alte zone. Codurile FFFEh şi FFFFh nu reprezintă coduri de caractere, fiind excluse din UCS. Există o problemă de ordonare a octeţilor din cadrul cuvintelor de 16 biţi reprezentând coduri de caractere în Unicode. În general, dacă octetul 0 se află în dreapta 44

45 cuvântului (în partea mai puţin semnificativă), iar octetul 1 se află în stânga, ordonarea octeţilor este numită little-endian. Dacă octetul 0 se află în stânga cuvântului (în partea mai semnificativă), iar octetul 1 se află în dreapta, ordonarea octeţilor este numită bigendian. Presupunem că un şir de 2n octeţi reprezentând n caractere Unicode sunt transferate de la un calculator cu ordonarea little-endian la un calculator cu ordonarea big-endian. Ordinea octeţilor din cuvintele de 16 biţi va fi atunci schimbată. Dacă la începutul şirului original se include codul FEFFh, care este un cod pentru marcajul ordinii octeţilor (Byte Order Mark), atunci prin inversarea octeţilor acesta va apare sub forma FFFEh, care este un cod invalid. Acest cod invalid indică faptul că ordinea octeţilor din cadrul tuturor cuvintelor este incorectă, şi deci ordinea trebuie inversată înaintea interpretării cuvintelor ca şi caractere. Astfel, prin plasarea codului FEFFh la începutul unui şir de caractere, o aplicaţie poate determina dacă octeţii trebuie inversaţi înainte de interpretarea codurilor. O situaţie similară apare la transferul de la un calculator cu ordonarea big-endian la un calculator cu ordonarea little-endian. 45

46 SUGESTII TEME DE LABORATOR A. Deduceţi algoritmii pentru adunarea şi scăderea a două cifre zecimale exprimate în codul Pentru deducerea algoritmului de adunare se va întocmi un tabel cu toate sumele posibile care se pot obţine prin adunarea a două cifre zecimale şi a unui eventual transport, indicând pentru fiecare din acestea suma corectă. Similar se va proceda pentru scădere, ţinând cont şi de un eventual împrumut. B. Deduceţi algoritmii pentru adunarea şi scăderea a două cifre zecimale exprimate în codul Exces 3. C. Deduceţi algoritmii pentru conversia din binar în codul Gray şi din codul Gray în binar. D. Construiţi codul Hamming pentru un cuvânt de 16 biţi, considerând paritatea impară. Explicaţi modul în care funcţionează corecţia unei erori. 46

47 4. ALGORITMI ŞI SCHEME LOGICE Algoritmul este conceptul fundamental al informaticii. este acela de algoritm. Algoritmul este un set de paşi prin care poate fi dusă la îndeplinire o sarcină. Exemplu: Algoritmul lui Euclid pentru determinarea celui mai mare divizor comun a 2 numere naturale. Pasul 1. Se notează cu M cea mai mare, iar cu N cea mai mică dintre cele 2 valori. Pasul 2. Se împarte M la N şi se notează restul cu R. Pasul 3. Dacă R este diferit de zero, se atribuie lui M valoarea N şi lui N valoarea R, apoi se revine la pasul 2; în caz contrar cel mai mare divizor al celor 2 numere este valoarea notată cu N. Algoritmii sunt reprezentaţi prin programe. Aceste programe formează ceea ce se numeşte software. Pentru ca un calculator să poată rezolva o anumită problemă, trebuie ca mai întâi să se descopere şi să se reprezinte sub formă de program un algoritm de rezolvare a problemei respective. La început studiul algoritmilor a făcut parte din matematică. Cu mult înainte de apariţia calculatoarelor, căutarea unor algoritmi a fost una dintre activităţile importante ale matematicienilor. Principalul obiectiv al acestora era descoperirea unui set mic de instrucţiuni care să descrie modul de rezolvare al oricărei probleme dintr-o anumită categorie de probleme. Unul dintre cele mai cunoscute rezultate obţinute în acest domeniu este algoritmul lui Euclid, prezentat anterior, care permite determinarea celui mai mare divizor comun a 2 numere întregi pozitive. După descoperirea algoritmului, efectuarea sarcinii repetitive nu va mai necesita înţelegerea principiilor care stau la baza acestuia, ci doar urmarea instrucţiunilor. Datorită acestei posibilităţi de captare şi transmitere a informaţiei prin intermediul algoritmilor, oamenii au putut să construiască maşini cu comportament inteligent. Prin urmare nivelul de cunoaştere al unei maşini este limitat de nivelul de cunoştinţe care poate fi transmis prin intermediul algoritmilor. Astfel, putem construi o maşină care să realizeze o anumită sarcină, dacă şi numai dacă găsim un algoritm care să precizeze modul în care sarcina respectivă poate fi dusă la bun sfârşit. Prin urmare, dacă nu există un astfel de algoritm, efectuarea sarcinii respective nu stă în puterea unei maşini. După descoperirea unui algoritm care rezolvă o anumită problemă, pasul următor este ca algoritmul respectiv să fie reprezentat într-o formă în are să poată fi comunicat unei maşini. Definiţie Un algoritm reprezintă o succesiune finită de paşi, bine determinaţi, prin care din mulţimea datelor de intrare ale unei probleme ce aparţine unei clase de probleme se produc date de ieşire corecte. 47

48 x x x y x y x y x y a f f f f f f f f a a f f a f a f a f f a a a a a a a a Proprietăţile algoritmilor 1) Determinarea Un algoritm trebuie astfel conceput încât operaţiile sale şi succesiunea executării lor să fie descrise clar, precis, fără ambiguităţi sau neclarităţi. 2) Generalitatea Algoritmul va fi conceput astfel încât să asigure rezolvarea unei clase de probleme şi nu a unei probleme particulare. 3) Finititudinea - executarea algoritmului trebuie să cuprindă un număr finit de operaţii, chiar dacă numărul acestora este foarte mare. Obiectele cu care lucrează algoritmii Constantele sunt date a căror valoare nu se modifică pe parcursul algoritmului. Constantele pot fi: - numerice; - alfanumerice; - logice. Variabile sunt date a căror valori se pot modifica pe parcursul execuţiei algoritmului. Variabilele pot fi numere întregi, reale, logice sau şiruri de caractere. Ele se notează cu litere sau simboluri care să le sugereze semnificaţia. Operaţiile - aritmetice: +, -, *, / - logice: - NOT (negaţia logică) : - AND (SI logic) : - OR (SAU logic) : Operaţiile logice se aplică unor operanzi logici, care pot avea valorile adevărat şi fals. Tabelele de adevăr corespunzătoare acestor operaţii sunt prezentate în cele ce urmează. - relaţionale: <,, >,, =,. Expresiile sunt formate din constante şi variabile legate între ele prin operaţii şi paranteze care să prezinte ordinea de evaluare a operaţiilor. Nu se vor folosi decât paranteze ( ). Expresiile pot fi: - aritmetice; - relaţionale; - logice. 48

49 Operaţiile de bază realizate de către un algoritm citirea unei variabile; scrierea unei variabile; atribuirea v expresie, unde este operator de atribuire; decizia - prin care se verifică o condiţie a cărei valoare de adevăr determină ramificarea algoritmului. Reprezentarea (descrierea) algoritmilor 1. Schema logică - constituie un mijloc foarte sugestiv (intuitiv) de a descrie un algoritm prin intermediul unor figuri geometrice numite blocuri care au o semnificaţie bine precizată. Schemele logice sunt foarte uşor de urmărit pentru algoritmi simpli, dar mai greu de urmărit pentru algoritmi lungi. 2. Limbajul convenţional numit şi limbaj pseudocod - este limbaj cu reguli sintactice foarte simple care permit exprimarea neambiguă a ordinii de execuţie a paşilor algoritmilor. Descrierea algoritmilor prin scheme logice Schema logică este o transcriere grafică a paşilor unui algoritm. Fiecărui pas i se ataşează un simbol numit bloc, sensul de parcurgere fiind indicat prin săgeţi. Blocurile folosite într-o schemă logică sunt următoarele: Bloc delimitator: - marchează începutul/sfârşitul algoritmului. Blocul de citire/scriere: Blocul de atribuire: Blocul de decizie: NU fals condiţie DA adevărat Blocul de procedură: Nume procedură Săgeată: Conector de blocuri: 49

50 Exemplu: Algoritmul pentru rezolvarea ecuaţiei de gradul I, ax + b = 0 : START a,b NU a = 0 DA x -b/a NU b = 0 DA Scrie x Scrie Ecuaţia nu are soluţie Scrie Ecuaţia are o infinitate de soluţii STOP Fig. 1. Algoritmul pentru rezolvarea ecuaţiei de gradul I. Principiile de bază ale programării structurate Programarea structurală iniţială de E.W. Dijkstra şi C.A.R. Hoare reprezintă o metodă de elaborare a algoritmilor care impune reguli extrem de severe de concepere a algoritmilor. Una dintre metodele curente de elaborare a algoritmilor este metoda programării structurate. Programarea structurată are la bază următoarele principii: 1) Proiectarea descendentă a algoritmilor care consideră că algoritmul are o structură complexă care se obţine prin descompuneri succesive, astfel la fiecare pas de descompunere un element de structură se descompune în conformitate cu una dintre schemele de descompunere fundamentale. 2) Utilizarea în algoritmi a doar 3 structuri de control: secvenţială, alternativă şi repetitivă. Algoritmii proiectaţi conform acestor principii se numesc algoritmi structuraţi. Programarea structurală are la bază teorema de structură a lui Bőhm şi Jacopini care precizează că un algoritm cu un singur punct de început şi un singur punct de sfârşit poate fi descris cu ajutorul celor 3 structuri de control, prezentate în figura 2. a) Structura secvenţială: b) Structura alternativă: a fals condiţie adevărat b b a 50

51 c) Structura repetitivă: condiţie NU DA a Fig. 2. Structuri de control utilizate în programarea structurată. Exemple 1. Un exemplu pentru structura alternativă îl constituie algoritmul pentru determinarea minimului a 3 valori a, b, c, a cărui reprezentare prin schemă logică este prezentată în figura Determinarea minimului unui şir de numere care se încheie cu valoarea 0, are algoritmul prezentat în figura 4. Observaţii: Deşi structura ciclică prezentată este suficientă pentru a descrie un algoritm ciclic, totuşi în anumite situaţii se mai utilizează şi structura ciclică cu test final, prezentată în figura 5. Ciclul cu test final poate fi transformat în ciclul cu test iniţial, conform figurii 6. 51

52 START START Citeşte a,b,c Citeşte a NU a < b DA max a min b min a a 0 NU DA NU min > c DA Citeşte a Scrie a STOP min c a > max DA max a Scrie min STOP Fig. 3. Determinarea minimului a trei numere. Fig. 4. Determinarea minimului unui şir de numere. a a cond NU NU cond DA DA a Fig. 5. Structura ciclică cu test final. Fig Structura ciclică cu test final. 52

53 Descrierea algoritmilor în limbaj pseudocod Există mai multe variante de limbaj pseudocod, care însă nu diferă esenţial. Un limbaj pseudocod nu este standardizat şi conţine, în general următoarele comenzi (comenzi care corespund structurilor de control utilizate în programarea structurată): 1) de atribuire: variabilă expresie 2) de citire: citeşte lista de variabile 3) de scriere: scrie listă de expresii 4) de ramificare: dacă condiţie atunci operaţie 1... operaţie n altfel operaţie1... operaţie n sfârşit dacă 5) de ciclare: a) cât timp condiţie execută operaţie 1... operaţie n sfârşit cât timp b c) repetă operaţie 1... operaţie n până când condiţie pentru contor val_initială, val_finală execută operaţie 1... operaţie n sfârşit pentru 6) de oprire: stop 53

54 Erorile în algoritmi Un algoritm devine eficient în măsura în care între resursele de calcul utilizate şi precizia rezultatelor se stabileşte un raport acceptabil. Cu toată precizia oferită de calculatoarele electronice, calitatea rezultatelor este influenţată de mulţi alţi factori. Soluţia unei probleme depinde de datele iniţiale, acestea fiind obţinute în urma unor observaţii, măsurători sau pe baza altor calcule prealabile. Precizia instrumentelor cu care se fac observaţiile, condiţiile în care au loc acestea, precizia calculelor necesare determinării unor parametrii iniţiali generează erori în datele iniţiale. O parte din parametrii utilizaţi în formulele de calcul nu au o valoare exprimabilă printr-un număr finit de zecimale (ex. 3, π, e, etc.). Erorile de aproximare a lor sunt cunoscute şi vor fi astfel alese încât să fie corelate cu precizia dorită pentru calculele în care intră aceşti parametri. O clasă importantă de erori o constituie erorile de rotunjire. Ele apar ca urmare a limitării numărului de zecimale cu care se poate reprezintă un număr în calculator. La rezolvarea, mai ales numerică a unei probleme se foloseşte o metodă matematică. De multe ori fenomenul analizat este supus unor condiţii simplificatoare, fapt ce poate genera erori de metodă. O altă categorie de erori sunt cele introduse în calculator de prezenţa unor funcţii cărora în analiza matematică le corespund serii infinite. Aceste erori se numesc erori reziduale. Exemplu: Calculul funcţiei trigonometrice sin(x) se face prin dezvoltare în serie x 3! x 5! Taylor: sin( x) = x Proiectarea algoritmilor Conceptele principale care s-au cristalizat în domeniul programării structurate sunt: proiectarea top-down, proiectarea modulară şi proiectarea structurală. Cele trei tipuri nu se exclud una pe cealaltă ci se intercorelează în obţinerea unor produse program. Proiectarea top-down (de sus în jos) presupune descompunerea de la general la particular a problemei date în subprobleme sau funcţii de prelucrat conducând la realizarea algoritmului în mai multe faze succesive, fiecare fază fiind o detaliere a fazei anterioare până când algoritmul este suficient de rafinat (detaliat) pentru a putea fi codificat. Proiectarea modularizată presupune descompunerea problemelor în părţi numite module, astfel încât fiecare din acestea să îndeplinească anumite funcţii bine definite. Descompunerea se poate face în mai multe faze (la mai multe niveluri) prin metoda topdown. Criteriile de descompunere depind în mare măsură de experienţa proiectanţilor (programatorilor). Proiectarea modularizată presupune pe lângă identificarea modulelor şi a relaţiilor dintre ele şi precizarea modului şi a ordinii în care sunt puse în lucru. Reprezentarea modularizată a programelor se realizează prin intermediul diagramelor (organigramelor) de tip arbore (figura 4.7.). 54

55 A B C B1 B2 C1 C2 C3 B11 B12 C21 C22 Figura 7. Reprezentarea modularizată a programelor Se disting modulele apelatoare: A, B, B1, C, C2 şi module apelate (B11, B12, B2, C1, C3). În implementarea în programe modulele pot fi interne sau externe după modul de apel şi locul de plasare faţă de unitatea apelatoare. Modulele interne sunt integrate în programul din care sunt apelate şi au acces la toate datele acestuia. Modulele externe nu sunt integrate în programele de care sunt apelate. Atât modulele interne cât şi cele externe pot fi constituite în blocuri cu semnificaţie de subprograme. Modul de lucru cu module diferă semnificativ de la un limbaj de programare la altul. Proiectarea structurată a algoritmilor constă dintr-o mulţime de reguli şi restricţii care forţează proiectantul (programatorul) să urmeze o formă strânsă de reprezentare şi codificare. Verificarea corectitudinii algoritmilor În procesul de elaborare al algoritmilor se pot structura formulări imprecise sau eronate. Verificarea corectitudini ar însemna verificarea faptului că pentru oricare set de date algoritmul furnizează rezultate corecte, lucru imposibil de realizat în practică. În practică se recomandă următoarele verificări ale corectitudinii algoritmilor simpli: 1. Încheierea algoritmilor după un număr finit de paşi. 2. Modul în care au fost construite selecţiile. 3. Asigurarea valorilor pentru toate variabilele referite în operaţii. Dacă cele trei tipuri de verificări au condus la concluzia de corectitudine se procedează la un test care presupune parcurgerea atentă operaţie cu operaţie a algoritmului pentru seturi de date de obicei cazuri limită. 55

56 Analiza algoritmilor Această etapă constă în: 1. Determinarea necesarului de memorie; 2. Determinarea timpului necesar execuţiei algoritmului; 3. Determinarea optimalităţii algoritmului. EXEMPLE Rezolvarea ecuaţiei de gradul al doilea 2 Să se rezolve ecuaţia de gradul II ax + bx + c = 0, coeficienţii a, b şi c fiind citiţi de la tastatură. Identificând toate situaţiile care pot să apară, obţiem organigrama în care semnificaţia mesajelor este următoarea: m1 : Aceasta nici macar nu e o ecuatie! m2 : Imposibil! m3 : Este, de fapt, o ecuatie de gradul I m4 : Asta da! Este o ecuatie de gradul II m5 : Radacini reale distincte m6 : Radacini reale confundate m7 : Radacini complexe 56

57 Prin identificarea modului în care instrucţiunile IF-THEN, respectiv IF-THEN-ELSE se includ unele pe altele şi a instrucţiunilor simple şi compuse, se obţine organigrama mai explicită: 57

58 SUGESTII TEME DE LABORATOR Pentru rezolvarea urmǎtoarelor probleme (pentru care algoritmii se dau parţial sau total), se cere detalierea algoritmilor, transpunerea lor în scheme logice (organigrame) şi scrierea programelor în pseudocod: A. Se citesc de la tastatură valorile pentru variabilele a, b şi c. Se va afişa pe monitor valoarea maximului dintre a, b şi c. B. Aceeaşi cerinţă, pentru patru valori a, b, c şi d. C. Să se afişeze în ordine crescătoare valorile de la problema A. D. Se citesc trei numere reale, în variabilele a, b, c. Dacă cele trei valori pot forma unghiurile unui triunghi, să se verifice dacă toate unghiurile sunt ascuţite; în caz contrar, verificati dacă există un unghi obtuz sau un unghi drept. Scrieti un mesaj corespunzator pentru fiecare caz. E. Se citesc valorile parametrilor a, b, c, d, e şi f pentru sistemul de douǎ ecuaţii liniare cu douǎ necunoscute ax + by = c dx + ey = f Sǎ se gǎseascǎ valorile rǎdǎcinilor x şi y. Se vor lua în calcul diferitele situaţii care pot interveni. F. Se citesc valorile pentru douǎ variabile, a şi b. Sǎ se gǎseascǎ cel mai mare divizor comun (cmmdc) şi cel mai mic multiplu comun (cmmmc) al celor douǎ numere, utilizând algoritmul lui Euclid cu scǎderi repetate. Se va ţine seama de diversele posibilitǎţi de introducere a valorilor pentru cele douǎ variabile de intrare, a şi b. G. Se citeşte valoarea variabilei întregi n. Sǎ se stabileascǎ dacǎ n este un numǎr prim, iar în caz contrar, sǎ se gǎseascǎ valoarea celui mai mic divizor propriu al lui n. 58

59 5. TIPURI DE DATE. CITIREA ŞI TIPĂRIREA DATELOR În limbajul C++ sunt utilizate următoarele tipuri simple de date numerice: Întreg Real Tipul de dată Lungime (octeţi) Domeniu de valori [signed] char ( ) unsigned char ( ) unsigned [int] [short] [int] unsigned long long [int] float 4 3.4* *1038 double 8 1.7* *10308 long double * * Cel mai adesea, pentru citirea/scrierea datelor se utilizează cin>>/cout<<, dar formatarea este în acest caz în seama utilizatorului; ca alternativă, se pot utiliza funcţiile scanf/printf din limbajul C. Funcţia getch( ) citeste fără ecou pe monitor un caracter de la tastatură Funcţia putch( ) tipăreşte un caracter pe ecran Funcţia getche( ) citeste cu ecou pe monitor un caracter de la tastatură Macro-ul getchar( ) citeşte un caracter tastat, după asarea tastei ENTER Macro-ul putchar( ) afişează un caracter pe monitor Macro-urile getchar si putchar(x) au prototipurile in header-ul <stdio.h> Funcţia gets( ) citeşte un şir de caractere Funcţia puts( ) afişează un şir de caractere FUNCŢIA scanf( ) Funcţia de citire cu format scanf( ) are sintaxa : scanf( lista de formate, adresa_var1, adresa_var2,..); 59

60 - citeşte din fişierul standard de intrare stdio o secvenţă de câmpuri de intrare,caracter cu caracter, până la terminarea introducerii câmpurilor şi apăsarea tastei < Enter > ; - formatează fiecare câmp conform formatului specificat în lista de formate. Dincaracterele citite se calculează valori numerice sau literale, conform tipului fiecăreivariabile, dimensiunilor de format specificate şi a separatorilor de câmpuripredefiniţi (spaţiu, tab şi enter) sau impuşi explicit ; - valorile astfel construite sunt stocate la adresele variabilelor specificate ca argumente; ordinea formatelor variabilelor trebuie să coincidă cu ordinea listei adreselor variabilelor în care se face citirea. Fiecare variabilă care se doreşte a fi citită trebuie corelată cu un format specific. Observaţie: indiferent de formatul folosit, la întâlnirea unui spaţiu în introducereadatelor, este terminată citirea variabilei. Pentru funcţia de citire scanf trebuie folosit operatorul adresă & Pentruvariabilele citite cu această funcţie trebuie precizate adresele la care se stochează înmemoria calculatorului valorile variabilelor. Funcţia va introduce valorile citite direct laacele adrese. Singurul caz în care nu este obligatorie folosirea operatorul adresăpentru citirea valorii unei variabile cu funcţia scanf este citirea unui şir de caractere. Observaţie: citirea cu ajutorul funcţiei scanf a şirurilor de caractere care conţin spaţii este imposibilă. În cazul în care formatul specificat este necorespunzător, rezultatul obţinut poate fi neprevăzut. Valoarea întoarsă de scanf în caz de succes, este numărul de variabile care au fost citite corect. Dacă nu a fost citită nici o variabilă (de exemplu s-a introdus un şir în loc de un număr) funcţia întoarce valoarea 0. Dacă apare o eroare înaintea oricărei citiri şi asignări, funcţia returnează EOF (constantă de sistem avândvaloarea întreagă 1). Specificatorii de format ai funcţiei scanf( ) : % c C i teşte u n c a racter % d C i teşte un înt reg zecimal % i C i teşte un înt reg ze c i mal % e C i teşte un nu măr float % f C i teşte un număr flo a t % g C i teşte un nu măr fl o a t %o C iteşte un număr octal f ără semn % s C i teşte u n şi r de caracte re %x Citeşte un număr hexazecimal fără semn % p C i teşte un po inte r %n Argumentul asociat primeşte o valoare întregă egală cu numărulde caractere deja citite %u C iteşte un număr întreg fără semn În specificatorul de format pot să apară şi modificatori de tip. - Modificatorul h, care poate precede caracterele de conversie d, i, o, u, x sau X, precizează că valoareaconvertită trebuie memorată ca un short int sau unsigned short int. 60

61 - Modificatorul l, poate precede caracterele de conversie d, i, o, u, x, X, caz în care valoarea trebuie memorată ca un long int sau unsigned long int, sau poate precede caracterele e, E, f, g, G, caz în care valoarea trebuie memorată ca un double. - Modificatorul L poate precede numai caracterele e, E, f, g, G şi precizează că valoarea convertită trebuie memorată ca un long double FUNCŢIA printf( ) Este perechea funcţiei scanf( ), semnificaţia caracterelor de control fiind asemănătoare. Sintaxa de utilizare este : int printf( mesaje si lista de formate, expr_1, expr_2,.,expr_n); Funcţia printf realizează următoarele : - acceptă o serie de argumente de tip expresie pe care, după ce le evaluează, letransformă în şiruri de caractere conform formatului specificat - scrie şirurile în fişierul standard de ieşire (sunt acceptate secvenţele de evitare). Dacă numărul de argumente specificate în format nu corespunde cu numărulargumentelor din lista de expresii, atunci apar rezultate neaşteptate care pot aveaefecte dăunătoare. Rezultatul întors de funcţie, în caz de succes, este numărul deocteţi scrişi, iar în caz de eroare, valoarea întoarsă este EOF. Specificatorii deformat folosiţi pentru printf sunt % e, % E Număr real de forma iiii.zzzzzz, unde nr.zecimale z este dat de precizie (6 implicit) % f Număr real de forma i.zzzzzz, unde nr. zecimale este dat deprecizie (6 implicit) şi pentru partea întreagă este folosită doar o cifră %g, %G Număr real care suprimă caracterele terminale c are nuinfluenţează valoarea, adică cifrele 0 de la sfârşit şipunctul zecimal, dacă are partea fracţionară 0 % i Număr întreg în baza 8, 10, sau 16 în funcţie de primul sauprimele două caractere % d Număr întreg în baza 10 % o Număr întreg în baza 8 ; nu este necesară scrierea cifrei 0la începutul numărului % x Număr întreg în baza 16 ; nu este necesară scriereasecvenţei 0x la începutul numărului % u Număr întreg fără semn % s Şir de caractere % c Un singur character Expresiile afişate se pot alinia la stânga sau la dreapta şi se poate forţa afişareasemnului astfel : - semnul plus (+) afişează explicit semnul expresiei 61

62 - semnul minus (-) aliniază expresia afişată la stânga - absenţa oricărui semn semnifică alinierea expresiei afişate la dreaptă Pentru numerele întregi şi pentru şirurile de caractere se poate specifica un număr care înseamnă spaţiul folosit pentru afişare. Dacă spaţiul necesar este mai mic sau egal cu numărul specificat, atunci se vor afişa suplimentar spaţii (sau zerouri,dacă numărul este precedat de cifra 0) până la completarea spaţiului de afişare. Pentru numerele reale se pot specifica, opţional, semnul pentru aliniere şi două numere separate prin punct. Primul precizează dimensiunea totală de afişare, iar al doilea precizia, adică numărul de zecimale afişate. În cazul şirurilor de caractere, specificarea a două numere separate prin punct indică faptul că primul număr reprezintă numărul de caractere din şir care se vor afişa, iar al doilea reprezintă limita superioară de tipărire, completarea făcându-se cu spaţii la dreapta sau stânga, în funcţie de modul de aliniere. Poate apare fenomenul de trunchiere a şirului afişat în cazul în care dimensiunea acestuia depăşeşte limitainferioară. În cazul unui număr întreg, al doilea număr indică o completare la stânga cu zerouri până se ajunge la dimensiunea de afişare specificată. În format se pot utiliza şi modificarii de tip h şi l, corespunzători lui short, respectiv long. Dacă h este urmat de un d, i, o, u, x sau X, atunci aceasta este o specificare de conversie relativ la short int sau unsigned short int Dacă l este urmat de d, i, o, u, x sau X, atunci specificarea de conversie se aplică unui argument long int sau unsigned long int. Modificatorul L poate fi urmat de e, E, f, g sau G şi atunci specificarea de conversie se plică unui argument long double 62

63 EXEMPLE A. Funcţiile getch( ) şi putch( ) #include <conio.h> // Functia getch() citeste fara ecou un caracter // Caracterul tastat va aparea pe ecran doar datorita lui putch(x) void main(void) { clrscr(); putch(getch()); getch(); B. Funcţia getche( ) #include <conio.h> // Functia getche() face acelasi lucru ca getch(), dar cu ecou pe monitor // Caracterul tastat va aparea de 2 ori (odata datorita lui getche(), // odata datorita lui putch(x) ). void main(void) { clrscr(); putch(getche()); getch(); C. Macrourile getchar( ) şi putchar( ) #include <conio.h> 63

64 #include <stdio.h> // Si macro-ul getchar citeste un caracter tastat, dar, spre deosebire // de functiile getch() si getche(), doar dupa apasarea tastei ENTER // Macro-urile getchar si putchar(x) au prototipurile in headerul stdio.h // (STanDard Input-Output) // conio.h este inclus pentru functia getch() void main(void) { clrscr(); putchar(getchar()); getch(); D. Secvenţele ESCAPE; funcţia puts( ) #include <conio.h> #include <stdio.h> // Functia puts(x) scrie pe monitor sirul x // Ghilimelele si apostroful, avand in mod normal semnificatii speciale, // se scriu precedate de un back-slash \, daca vrem sa apara ca atare in text // Acum, deoarece se vede ca si back-slashul are o semnificatie speciala, // trebuie si el precedat de un back-slash, daca vrem sa apara in text void main(void) { puts("ce frumoase ghilimele (\") avem!"); puts("si apostroful (\') este frumos!"); puts("nu trebuie uitat nici back-slash-ul (\\)!"); getch(); 64

65 E. Funcţia printf( ) pentru scrierea cu format #include <stdio.h> #include <conio.h> // Cea mai complexa functie de tiparire - printf - are prototipul in stdio.h; // permite afisarea datelor sub comanda unor formate introduse cu simbolul % // Back-slashul isi pastreaza semnificatia de introducere a unor comenzi // De ex. \n - trecerea la un rand nou // \t - tabulare orizontala etc. // In tot programul, introducerea se face cu funtia deja studiata getch() void main(void) { clrscr(); int i=123; printf("\n\nde aici incepe. Nu se va apasa niciodata tasta Enter!\n"); printf("tasteaza un caracter. Caracterul va fi afisat\n"); printf("%c\n\n",getch()); printf("tasteaza un caracter. Caracterul va fi aliniat la dreapta\n"); printf("*%4c*\n\n",getch()); printf("tasteaza un caracter. Caracterul va fi aliniat la stanga\n"); printf("*%-4c*\n\n",getch()); printf("apasa orice tasta. Va fi afisat sirul abc\n"); printf("%s\n\n","abc",getch()); printf("apasa orice tasta. Sirul abc va fi afisat aliniat la dreapta\n"); printf("*%10s*\n\n","abc",getch()); printf("apasa orice tasta. Sirul abc va fi afisat aliniat la stanga\n"); printf("*%-10s*\n\n","abc",getch()); printf("apasa orice tasta. Va fi afisata valoarea variabilei i (i=123).\n"); printf("%d\n\n",i,getch()); printf("apasa orice tasta. Valoarea lui i va fi afisata aliniata la dreapta\n"); printf("*%10d*\n\n",i,getch()); 65

66 printf("apasa orice tasta. Valoarea lui i va fi afisata aliniata la stanga\n"); printf("*%-10d*\n\n",i,getch()); printf("apasa orice tasta. Valoarea lui i va fi afisata cu zerouri in fata\n"); printf("*%010d*\n\n",i,getch()); printf("pentru terminare, apasati orice tasta"); getch(); F. Utilizarea funcţiilor printf( ) şi scanf ( ) #include <conio.h> #include <stdio.h> // Deosebirile intre introducerea datelor de tip sir cu functia gets(x) // si introducerea cu ajutorul functiei scanf(x) // Si tiparirea se va face cu doua functii diferite puts(x) si Printf(x) void main(void) { char sir[50]; clrscr(); printf("\nsiruri citite cu functia "); printf("gets()\n"); printf("\nintroduceti un sir FORMAT DIN MAI MULTE CUVINTE\n"); gets(sir); printf("\nsirul tiparit cu functia puts() :\n"); puts(sir); printf("\nsirul tiparit cu functia printf(%%s) :\n"); printf("%s\n",sir); printf("\npentru continuare, apasati o tasta!"); getch(); clrscr(); printf("\nsiruri citite cu functia "); printf("scanf(%%s)\n"); printf("\nintroduceti un sir FORMAT DIN MAI MULTE CUVINTE\n"); 66

67 scanf("%s",sir); printf("\nsirul tiparit cu functia puts() :\n"); puts(sir); printf("\nsirul tiparit cu functia printf(%%s) :\n"); printf("%s\n",sir); printf("\npentru terminare, apasati o tasta!"); getch(); G. Exerciţii asupra tipurilor de date #include <conio.h> #include <stdio.h> // Diferentele intre tipul intreg int (format de tiparire %d) // si tipul real double (format %lf) void main() { clrscr(); printf("se afiseaza valoarea polinomului 3x^2-8x+7\n\ pentru o valoare intreaga a lui x, introdusa de la tastatura\n"); int x; printf("tastati valoarea lui x="); scanf("%d",&x); printf("x=%d\tp(x)=%d\n\n",x,3*x*x-8*x+7); printf("\npentru a continua programul, apasati orice tasta\n\n"); getch(); printf("se afiseaza valoarea polinomului 3.5y^3-9.8y+3.7\n\ pentru o valoare flotanta dubla precizie a lui y,\n\ valoare introdusa de la tastatura\n"); double y; printf("tastati valoarea lui y="); scanf("%lf",&y); printf("y=%lf\tp(z)=%lf\n\n",y,3.5*y*y*y-9.8*y+3.7); printf("\npentru a continua programul, apasati orice tasta\n\n"); getch(); printf("\nprecizia maxima intr-un calcul este de cifre semnificative\n"); 67

68 printf("\n2/3=%20.18lf",2/3.0l); printf("\n\npentru a incheia programul, apasati orice tasta\n"); getch(); H. Formatele zecimal, octal şi hexagesimal #include <conio.h> #include <stdio.h> // Limbajul C poate tipari rezultatele in zecimal (formatul %d), // octal (formatul %o) sau hexagesimal (formatul %x) void main() { clrscr(); int x; printf("tastati valoarea lui x="); scanf("%d",&x); printf("valoarea in zecimal este\n"); printf("x(10)=%d\n\n",x); printf("valoarea in octal este\n"); printf("x(8)=%o\n\n",x); printf("valoarea in hexagesimal este\n"); printf("x(16)=%x\n\n",x); getch(); 68

69 SUGESTII TEME DE LABORATOR A. Se citesc de la tastatură coordonatele (xa, ya) şi (xb, yb) (valori întregi) a două puncte A şi B din plan. Să si tipărească pe monitor lungimea segmentului AB. B. Se citesc de la tastatură lungimile (valori reale) a, b şi c ale unui triunghi. Se va calcula cu ajutorul formulei lui Heron aria tringhiului şi se va afişa pe monitor, ca în exemplul următor: date de intrare: a=3, b=4, c=5; afişarea dorită: Aria triunghiului cu laturile de lungime 3, 4 şi 5 este 6; C. Se citesc de la tastatură valorile întregi a şi b; se va tipari câtul şi restul împărţirii întregi a lui a la b, ca în exemplul următor: date de intrare: a=14, b=3; afişarea dorită: a:b = 4 si rest 2 D. Se citesc de la tastatură valorile întregi a şi b; se va tipari câtul şi restul împărţirii întregi a lui a la b, ca în exemplul următor: date de intrare: a=14, b=3; afişarea dorită: 14:3 = 4 si rest 2 E. Se citesc trei valori reale a, b, şi c. Se calculează şi se afişează pe monitor valoarea polinomului P(x) = a*x 2 + bx + c pentru patru valori ale parametrului x, citite de la tastatură, ca în exemplul următor: Presupunând că s-au introdus pentru a, b şi c valorile 1, 2 şi 3 (respectiv), iar pentru cele patru valori ale parametrului x valorile succesive 0, 1, 2 şi 3, pe monitor trebuie să apară mesajele P(0) = 3 P(1) = 6 P(2) = 11 P(3) = 18 69

70 6. INSTRUCŢIUNILE IF ŞI SWITCH Instrucţiunile condiţionale determină programele să testeze diferite condiţii şi, în funcţie de acestea, să decidă execuţia anumitor comenzi. Avem la dispoziţie instrucţiunile condiţionale: if( ) - execută comenzile dorite atunci când o condiţie (scrisă între paranteze) este adevarată. if( )... else - execută anumite comenzi când o conditie (scrisă între paranteze) este adevarată şi alte comenzi când această condiţie este falsă. switch - selectează care comandă va fi executată. A. Instructiunea "if" "if( )" (dacă) este cea mai simplă instrucţiune condiţională. Forma generală a acestei instrucţiuni este: if (condiţie) { // Codul care va fi executat dacă este Adevarată condiţia unde 'condiţie' poate fi orice expresie alcatuită cu operatori raţionali, de egalitate şi logici. Dacă rezultatul evaluării condiţiei este TRUE, se execută codul dintre acolade, în caz contrar, când condiţia returnează FALSE, se trece peste acest cod. B. Instrucţiunea "if... else" Folosind instrucţiunea "if()... else" (dacă... altfel), putem stabili comenzi care să fie executate şi când condiţia instrucţiunii "if( )" este FALSE. Forma generala a instructiuni "if()... else" este: if (condiţie) { // codul care va fi executat dacă este Adevarată condiţia else { // codul ce va fi executat daca condiţia este falsă unde 'condiţie' poate fi orice expresie logică. Dacă rezultatul condiţiei este TRUE, se execută codul dintre primele acolade, care aparţin de "if()", în caz contrar, când condiţia returnează FALSE, sunt executate comenzile din acoladele de la "else". 70

71 Formula "else if( )" Cu "if()... else" sunt posibile execuţiile a doar două opţiuni, cea de la "if( )" sau de la "else". Dar sunt situaţii în care avem mai multe opţiuni, caz în care se foloseşte formula "else if( )" (altfel dacă). Cu aceasta se pot crea şi alte opţiuni (suplimentare) între cele două Sintaxa generală este: if (condiţie 1) { // codul care va fi executat dacă este Adevarată condiţia 1 else if (condiţie 2) { // codul ce va fi executat daca prima condiţie este Falsă şi este Adevarată condiţia 2 else if (condiţie 3) { // codul care va fi executat daca primele două condiţii sunt False şi este Adevarată condiţia 3 //... else { // codul executat dacă toate condiţiile sunt False Pot fi adaugate oricate optiuni "else if". B. Instrucţiunea switch Această instrucţiune e folosită pentru a compara o valoare cu altele dintr-o listă şi, în funcţie de acea valoare, se execută codul asociat ei în lista "switch". Sintaxa generala a instructiuni "switch" este: switch (expresie) { case valoare1: cod executat dacă expresie = valoare1 break; case valoare2: cod executat dacă expresie = valoare2 break; case valoare3: cod executat pt. expresie = valoare3 break; default : cod executat dacă expresie e diferit de valoare1, valoare2 sau valoare3 71

72 Prima dată este evaluată expresia scrisă între paranteze rotunde, la "switch( )", apoi valoarea expresiei este comparată pe rând cu fiecare valoare determinată de "case". Dacă se găseşte o identitate, se execută codul asociat acelui "case", apoi se iese din instrucţiunea "switch". Dacă, parcurgand fiecare "case", nu se găseşte o egalitate, se execută codul de la "default". Prin folosirea lui "break" se opreşte parcurgerea corpului instrucţiunii atunci când s-a găsit o valoare egală cu 'expresie' şi se iese din "switch". Instructiunea "switch" poate inlocui un şir de condiţii cu "else if". C. Operatori logici şi instrucţiunile condiţionale Operatorii logici sunt "&&" si " ". Rolul lor este asemănător cu cel al operatorilor relaţionali şi de egalitate, în sensul că şi aceştia compară valoarea a doi operanzi. Operatorii logici compară operatii, expresii de cod, iar rezultatul lor este unul din valorile TRUE (Adevărat) sau FALSE (Fals). exp1 && exp2 - Returnează True dacă şi "exp1" şi "exp2" sunt Adevărate; altfel, returneaza False. exp1 exp2 - Returneaza True dacă oricare dintre "exp1" sau "exp2" e Adevarat; altfel, dacă amândouă sunt false, returnează False. exp1 && exp2 exp3 - Returnează True dacă expresia (exp1 && exp2) sau "exp2" e Adevarată; altfel, returnează False. Datorita rezultatului True sau False pe care-l dau aceşti operatori logici, ei sunt folosiţi în instrucţiunile condiţionale, contribuind la efectuarea unor condiţii mai complexe în parantezele instructiunii "if()" si "else if()". D. Operatorul condiţional "? :" O alta metodă de a executa un cod în funcţie de faptul dacă o expresie este Adevarată sau Falsă e operatorul "? :" Acest operator condiţional, deşi la prima vedere arată diferit de ceilalţi, este o formă prescurtată a instrucţiunii "if( ) else". Sintaxa generală de folosire a lui este: expresie-condiţionala? dacă -TRUE : dacă -FALSE; Operatorul condiţional evaluează expresia condiţională. Dacă expresia are valoarea TRUE, operatorul condiţional returnează valoarea de la "daca-true"; în caz contrar, returnează valoarea de la "daca-false". Pe lângă atribuirea unei valori în funcţie de rezultatul unei expresii, acest operator condiţional poate fi utilizat în aceeaşi forma şi la determinarea apelării unei anumite funcţii, după rezultatul unei expresii logice. (expresie-logică)? dacătrue( ) : dacăfalse( ); unde "dacătrue( )" şi "dacăfalse( )" pot fi considerate doua funcţii. 72

73 EXEMPLE A. Sistemul de două ecuaţii de gradul I #include <conio.h> #include <stdio.h> void main(){ /* Rezolvarea sistemului liniar de doua ecuatii cu doua necunoscute ax+by=c dx+ey=f */ double a,b,c,d,e,f,x,y,det,det1,det2; printf("\n\nintroduceti coeficientii a,b,c,d,e,f\n"); /* Coeficientii se introduc pe aceeasi linie, separati de blancuri */ if (scanf("%lf %lf %lf %lf %lf %lf",&a, &b, &c, &d, &e, &f)!= 6) printf("coeficienti eronati\n"); else if ((det=a*e-b*d) == 0) printf("sistemul are determinantul nul\n"); else { det1=c*e-b*f; det2=a*f-c*d; x=det1/det; y=det2/det; printf("x=%g\ty=%g\n",x,y); getch(); B. Ecuaţia de gradul II 2 Să se rezolve ecuaţia de gradul II ax + bx + c = 0, coeficienţii a, b şi c fiind citiţi de la tastatură. Identificând toate situaţiile care pot să apară, obţiem organigrama 73

74 În care semnificaţia mesajelor este următoarea: m1 : Aceasta nici macar nu e o ecuatie! m2 : Imposibil! m3 : Este, de fapt, o ecuatie de gradul I m4 : Asta da! Este o ecuatie de gradul II m5 : Radacini reale distincte m6 : Radacini reale confundate m7 : Radacini complexe Prin identificarea modului în care instrucţiunile IF-THEN, respectiv IF-THEN-ELSE se include unele pe altele şi a instrucţiunilor simple şi compuse, se obţine organigrama mai explicită: 74

75 Codul corespunzător este: #include <conio.h> #include <iostream.h> #include <math.h> void main(){ float a, b, c, d, x, x1, x2, re, im; clrscr(); cout<<"a=";cin>>a; cout<<"b=";cin>>b; cout<<"c=";cin>>c; if(a==0) if(b==0) if(c==0) cout<<"aceasta nici macar nu e o ecuatie!"; else cout<<"imposibil!"; else{ cout<<"este, de fapt, o ecuatie de gradul I"<<endl; x=-c/b; cout<<"radacina este x="<<x; else{ cout<<"asta da! Este o ecuatie de gradul II"<<endl; d=b*b-4*a*c; if(d>0) { cout<<"radacini reale distincte"<<endl; x1=(-b-sqrt(d))/2/a; x2=(-b+sqrt(d))/2/a; 75

76 cout<<"x1="<<x1<<endl; cout<<"x2="<<x2; else if(d==0){ cout<<"radacini reale confundate"<<endl; x=-b/2/a; cout<<"x1=x2="<<x; else{ cout<<"radacini complexe"<<endl; re=-b/2/a; im=-sqrt(-d)/2/a; if(im<0)im=-im; cout<<"x1="<<re<<" - "<<im<<" i"<<endl; cout<<"x2="<<re<<" + "<<im<<" i"; getch(); C. Realizarea unui meniu Să se realizeze scheletul unui meniu pentru lucrul ulterior cu listele înlănţuite; programul va permite selectarea dintr-un meniu a unor acţiuni şi va afişa acţiunea viitoare, pe care programul o va efectua în momentul în care vor fi implementate funcţiile respective. Meniul va oferi ca principale opţiuni crearea listei, listarea de la stanga la dreapta, listarea de la dreapta la stanga, inserarea unui nod in interiorul listei, inserarea unui nod pe prima poziţie, inserarea unui nod pe ultima poziţie, ştergerea unui nod din interiorul listei, ştergerea primului nod, ştergerea ultimului nod şi salvarea listei. Codul corespunzător este: #include <iostream.h> #include <conio.h> #include <stdlib.h> void main(){ int rasp; clrscr(); cout<<"operatii CU LISTE :"<<endl<<endl; cout<< " 1: creare"<<endl<< " 2: listare de la stanga la dreapta"<<endl<< " 3: listare de la dreapta la stanga"<<endl<< " 4: inserare nod in interiorul listei"<<endl<< " 5: inserare nod pe prima pozitie"<<endl<< " 6: inserare nod pe ultima pozitie"<<endl<< 76

77 " 7: stergerea unui nod din interiorul listei"<<endl<< " 8: stergerea primului nod"<<endl<< " 9: stergerea ultimului nod"<<endl<< "10: salvez lista"<<endl; cin>>rasp; switch (rasp){ case 1: cout<<"voi crea o lista";break; case 2: cout<<"voi lista de la stanga la dreapta";break; case 3: cout<<"voi lista de la dreapta la stanga";break; case 4: cout<<" voi insera un nod in interiorul listei";break; case 5: cout<<" voi insera un nod inaintea primului nod";break; case 6: cout<<" voi insera un nod dupa ultimul nod";break; case 7: cout<<" voi sterge un nod din interiorul listei";break; case 8: cout<<" voi sterge primul nod";break; case 9: cout<<" voi sterge ultimul nod";break; case 10: cout<<" voi salva lista";break; default: exit(1); getch(); 77

78 SUGESTII TEME DE LABORATOR A. Să se verifice dacă un număr întreg n, citit de la tastatură, este par. B. Valorile a şi b (citite de la tastatură) sunt capetele unui interval. Să se stabilească dacă valoarea x (citită de la tastatură) se găseşte în interiorul intervalului. C. Să se calculeze valoarea expresiei E ( x) = x 1 x x + 1 pentru pentru pentru x < 0 x = 0 x > 0 pentru patru valori ale parametrului x, citite de la tastatură D. Se citesc de la tastatură valorile pentru variabilele întregi a, b şi c. Se va afişa pe monitor valoarea maximului dintre a, b şi c. E. Aceeaşi cerinţă, pentru patru valori reale a, b, c şi d. F. Să se afişeze în ordine crescătoare valorile de la problema A. G. Se citesc trei numere reale, în variabilele a, b, c. Dacă cele trei valori pot forma unghiurile unui triunghi, să se verifice dacă toate unghiurile sunt ascuţite; în caz contrar, verificati dacă există un unghi obtuz sau un unghi drept. Scrieti un mesaj corespunzator pentru fiecare caz. H. Să se rezolve sistemul liniar de trei ecuaţii liniare cu trei necunoscute reale. I. Se citeşte de la tastatură un număr întreg n, de exact patru cifre. a. Să se calculeze suma dintre cifra sutelor şi cifra zecilor b. Să se afişeze numărul n inversat c. Să se verifice dacă numărul n este palindrom 78

79 7. CICLUL FOR ŞI INSTRUCŢIUNILE REPETITIVE DE TIP WHILE ŞI DO-WHILE Instrucţiunea for este o structură ciclică cu test iniţial şi implementează structura ciclică cu număr cunoscut de paşi Sintaxa: for (expresie1; expresie2; expresie3) instructiune; Funcţionarea: evaluare expresie1 ATÂTA TIMP CÂT expresie2 este TRUE REPETĂ begin instrucţiune evaluare expresie3 end Nu este obligatorie prezenţa expresiilor, ci doar a instrucţiunilor vide Instrucţiunea while este o structura ciclică cu test iniţial Sintaxa: while(<expresie>) instr1; La întâlnirea acestei instrucţiuni, se evaluează expresie. Dacă aceasta are valoarea TRUE (diferită de ZERO), se execută instrucţiunea instr1. Se reevaluează valoarea expresiei. Dacă ea este tot 1, se repetă instrucţiune, etc. Astfel, instrucţiunea (corpul ciclului) se repetă atât timp cât expresie are valoarea de adevăr TRUE. În momentul în care <expresie> are valoarea de adevăr FALSE (egală cu ZERO), se iese din ciclu şi se trece la următoarea instrucţiune din afara buclei while. În cazul în care la prima evaluare a expresiei, aceasta are valoarea de adevăr FALSE, corpul instrucţiunii while nu va fi executat niciodată. instr1 din corpul ciclului while poate fi compusă (un bloc). 79

80 Instrucţiunea/instrucţiunile din corpul ciclului while trebuie să modifice valoarea expresiei, altfel va fi un ciclu infinit Instrucţiunea do while Sintaxa: do instr1; while(<expresie>) Funcţionarea: Se execută instrucţiunea instr1 sau blocul de instrucţiuni. Se evaluează apoi <expresie>. Dacă aceasta are valoarea TRUE, se execută din nou instr1, altfel se iese din buclă. Se testează din nou valoarea expresiei. Se repetă execuţia instrucţiunii instr1 atâta cât timp valoarea expresiei este TRUE. În cazul instrucţiunii do while, corpul ciclului se execută cel puţin o dată. Instrucţiunea break forţează ieşirea din interiorul unei bucle, fără a se mai ţine seama de condiţia de menţinere în buclă. Instrucţiunile situate în corpul buclei după instrucţiunea break nu vor mai fi executate. Intrucţiunea continue duce la ignorarea instrucţiunilor din buclă, situate după aceasta, şi testarea din nou a expresiei de menţinere în buclă. În cazul buclelor for, se realizează şi evaluarea celei de a treia expresii, responsabilă cu incrementarea contorilor. EXEMPLE A. Determinarea faptului dacă un număr este sau nu prim #include <conio.h> #include <iostream.h> #include <math.h> void main() { clrscr(); unsigned long n, d; int prim=1; cout<<"n=?";cin>>n; for(d=2;d<=sqrt(n);d++) if(n%d==0) prim=0; if(prim) cout<<n<<" este prim"; 80

81 else cout<<n<<" nu este prim"; getch(); B. Calculul cmmdc al două numere, utilizând algoritmul lui Euclid #include<iostream.h> #include<conio.h> void main(){ clrscr(); int a, b, p=0; cout<<"a=";cin>>a; cout<<"b=";cin>>b; if(a==b)cout<<"cmmdc="<<a; else while(a!=b){if(a>b)a=a-b;else b=b-a;p++; cout<<"cmmdc="<<a<<" in "<<p<<" pasi"; getch(); #include<iostream.h> #include<conio.h> void main(){ clrscr(); int a, b, r, p; cout<<"a=";cin>>a; cout<<"b=";cin>>b; while(b){ r=a%b; a=b; b=r; p++; cout<<"cmmdc="<<a<<" in "<<p<<" pasi"; getch(); 81

82 SUGESTII TEME DE LABORATOR A. Se citeşte de la tastatură o valoare naturală n. Să se afişeze numărul divizorilor numarului citit. B. Scrieţi un program care afişează numerele divizibile cu 3 din intervalul [a,b]. Valorile a şi b se citesc de la tastatură. C. Se citeşte un număr natural n. Să se afişeze suma cifrelor lui n. D. Scrieti un program care afişează numerele prime până la n. Valoarea lui n se citeşte de la tastatură. E. De câte ori apare o cifră dată c, în numarul n? F. Să se determine dacă un număr n este palindrom G. Să se calculeze suma cifrelor unui număr întreg H. Se citeşte un număr întreg n şi n valori pentru parametrul real x. Să se afişeze maximul şi minimul valorilor introduse. I. Scrieţi un program care determină perimetrul şi aria unui triunghi. Există 4 situaţii posibile. Un triunghi poate fi: 1. isoscel 2. echilateral 3. dreptunghic 4. oarecare. În funcţie de cifra introdusă de la tastatură (1, 2, 3 sau 4) se va cere utilizatorului numărul minim de informaţii care trebuie să se citească pentru fiecare tip de triunghi datele necesare, astfel încât să se poată calcula perimetrul şi aria triunghiului. 82

83 8. TABLOURI UNIDIMENSIONALE PROBLEME DE ORDONARE Tablourile sunt colecţii de date de acelaşi tip reunite sub un singur nume, care ne permit să programăm mai uşor operaţii asupra grupurilor de valori de acelaşi tip. Declararea tabloului este similară cu declaraţia unei variabile simple, cu o singură excepţie: trebuie declarată şi dimensiunea tabloului. Numărul de componente se declară între [ ]. Declaraţia float date[50]; creează un tablou cu 50 de elemente tip float. Primul element are indicele 0, al doilea are indicele 1,, iar ultimul are indicele 49. Un tablou unidimensional (numit de foarte multe ori vector) este deci o colecţie structurată de elemente care pot fi accesate individual, specificând poziţia componentei printr-un indice (variabilă de tip întreg). Sintaxa unei declaraţii de tablou unidimensional (vector): TipDată NumeTablou[ExpresieConstInt]; Elementele unui tablou pot avea aproape orice tip de dată. Expresia dintre parantezele drepte este o constantă întreagă, ce trebuie să fie strict mai mare decât 0 şi determină numărul de componente ale tabloului. Dacă valoarea este n, domeniul indicilor va fi între 0 şi n-1, deci vectorul are n elemente. Pentru a avea acces la componentele individuale ale unui vector, scriem numele vectorului urmat de o expresie indice între [ ]. Expresia specifică numărul componentei accesate şi poate fi o constantă întreagă, o variabilă întreagă, sau o expresie care este evaluată la o valoare întreagă. Oricare ar fi, însă, forma indicelui, acesta trebuie să fie o valoare întreagă. Fiecare componentă a unui tablou poate fi tratată exact ca o variabilă simplă. Elementele unui tablou pot fi iniţializate în instrucţiunea de declarare prin adăugarea unei liste de valori separate prin virgulă, plasate între acolade. Exemplu #include <iostream.h> #include <conio.h> void main( ){ float x[5] = {11.2, 3.172, 12.1, -27.3, 12; int i ; for(i = 0 ; i <5 ; i++) cout << "x[" << i << "]= " << x[i] << endl ; 83

84 Dacă se înscriu mai multe valori, compilatorul semnalează o eroare. Dacă sunt mai puţine valori în listă, restul sunt iniţializate cu valoarea 0. Tablourile sunt transmise funcţiilor prin referinţă. În lista parametrilor formali, declararea unui tablou nu include şi dimensiunea sa între [ ]. Dacă se include dimensiunea, compilatorul o ignoră, deoarece compilatorului îi este necesară doar informaţia referitoare la natura parametrului, adică faptul că este vorba despre un tablou, şi la tipul componentelor sale. Acesta este motivul pentru care trebuie adăugat un al doilea parametru al funcţiei prin care se precizează numărul de componente. În prototipul unei funcţii care are parametri de tip tablou nu este necesară prezenţa numelor parametrilor formali. EXEMPLE A. Aflarea valorilor maxime şi minime şi a poziţiilor pe care acestea le ocupă într-un vector #include <conio.h> #include <iostream.h> void main() { clrscr(); int v[50], i, n, max, pozmax, min, pozmin; cout<<"n=?"; cin>>n; for(i=1;i<=n;i++){ cout<<"v["<<i<<"]=?"; cin>>v[i]; max=v[1];pozmax=1; min=v[1];pozmin=1; for(i=2;i<=n;i++){ if(v[i]>max){ max=v[i];pozmax=i; if(v[i]<min){ min=v[i];pozmin=i; cout<<"maximul este "<<max<<" si ocupa pozitia "<<pozmax<<endl; cout<<"minimul este "<<min<<" si ocupa pozitia "<<pozmin; getch(); 84

85 B. Ordonarea crescătoare a elementelor unui vector #include <conio.h> #include <iostream.h> void main() { clrscr(); int v[50], i, j, n, aux; cout<<"n=?"; cin>>n; for(i=1;i<=n;i++){ cout<<"v["<<i<<"]=?"; cin>>v[i]; for(j=1;j<=n-1;j++){ for(i=1;i<=n-1;i++) if(v[i]>v[i+1]){ aux=v[i]; v[i]=v[i+1]; v[i+1]=aux; for(i=1;i<=n;i++) cout<<"v[i"<<"]="<<v[i]<<endl; getch(); C. ordonarea descrescătoare a elementelor unui vector #include <conio.h> #include <iostream.h> void main() { clrscr(); int v[50], i, j, n, aux; cout<<"n=?"; cin>>n; for(i=1;i<=n;i++){ cout<<"v["<<i<<"]=?"; cin>>v[i]; for(j=1;j<=n-1;j++){ for(i=1;i<=n-1;i++) if(v[i]<v[i+1]){ aux=v[i]; v[i]=v[i+1]; v[i+1]=aux; 85

86 for(i=1;i<=n;i++) cout<<"v[i"<<"]="<<v[i]<<endl; getch(); C. Numere Fibonacci #include <conio.h> #include <iostream.h> void main(){ clrscr(); unsigned long n, a, b, f[50], j; int i, fv[50]; //afisarea numerelor fibonacci f[1]=1; f[2]=2; for(i=3; i<=46; i++) f[i]=f[i-2]+f[i-1]; for(i=1; i<=46; i++) cout<<i<<" "<<f[i]<<endl; //descompunerea unui numar n in suma de numere fibonacci getch(); cout<<"n=?"; cin>>n; for(i=1; i<=46; i++) fv[i]=0; for(i=46; i>=1;i--) if(f[i]<=n){ n=n-f[i]; cout<<f[i]<<" "; cout<<endl; getch(); //vizualizarea numerelor de la a la b prin componentele fibonacci cout<<"a=";cin>>a; cout<<"b=";cin>>b; for(j=a; j<=b; j++){ n=j; for(i=1; i<=46; i++) fv[i]=0; for(i=46; i>=1;i--) if(f[i]<=n){ n=n-f[i]; fv[i]=1; 86

87 for(i=46; i>=1;i--) cout<<fv[i]; cout<<endl; getch(); 87

88 SUGESTII TEME DE LABORATOR A. Se introduce o valoare întregă n, un vector v cu n elemente întregi, o valoare întreagă k şi un caracter c. Să se rotească circular spre stânga sau spre dreapta (în funcţie de valoarea caracterului c) cu exact k poziţii. B. Să se construiască vectorul w, având ca elemente numerele prime dintr-un vector v dat. C. Să se rearanjeze elementele unui vector v, astfel încât la început să fie numerele impare, în ordine crescătoare, apoi cele pare, în ordine descrescătoare. D. Să se introducă între fiecare dintre elementele succesive ale unui vector media lor aritmetică. E. Să se descompună în factori primi un număr întreg n, afişându-se doi vectori: vectorul b al bazelor şi vectorul e al exponenţilor corespunzători. 88

89 9. TABLOURI BIDIMENSIONALE Tablourile bidimensionale sunt denumite si matrici. La declararea unui tablou bidimensional, se specifică numărul de elemente al fiecărei dimensiuni, incluzând fiecare dintre aceste numere între paranteze drepte. Indexul inferior al fiecarei dimensiuni este 0. Sintaxa pentru declararea unei matrice este urmatoarea: tipul_datelor nume_matrice[nr_linii][nr_coloane]; Exemplu: o matrice de numere intregi, care are 5 linii a câte 4 componente pe linie : int a[5][4]; Rămân valabile cele menţionate la capitolul referitor la tablorile unidimensionale. EXEMPLE A. Suma a două matrice #include <stdio.h> #include <conio.h> void main() /* Suma a doua matrici cu m linii si n coloane */ { int a[10][10],b[10][10],c[10][10]; int n,m,i,j,k; printf("\nintroduceti numarul de linii : "); scanf("%d",&m); printf("\nintroduceti numarul de coloane : "); scanf("%d",&n); printf("\nintroduceti elementele matricii A\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) { printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]); ; printf("\nintroduceti elementele matricii B\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) { printf("b[%d][%d]=",i,j); scanf("%d",&b[i][j]); ; 89

90 for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) c[i][j]=a[i][j]+b[i][j]; printf("\nelementele matricei C sunt :\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) printf("c[%d][%d]=%d\n",i,j,c[i][j]); getch(); B. Produsul a două matrice #include <stdio.h> #include <conio.h> void main() /* Produsul a doua matrici cu A(mxn) si B(nxp) */ { int a[10][10],b[10][10],c[10][10]; int n,m,p,i,j,k,s; printf("\nintroduceti numarul de linii al primei matrici : "); scanf("%d",&m); printf("introduceti numarul de coloane al primei matrici : "); scanf("%d",&n); printf("introduceti numarul de coloane al celei de a doua matrici : "); scanf("%d",&p); printf("\nintroduceti elementele matricii A\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) { printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]); ; printf("\nintroduceti elementele matricii B\n"); for (i=0;i<=n-1;i++) for (j=0;j<=p-1;j++) { printf("b[%d][%d]=",i,j); scanf("%d",&b[i][j]); ; for (i=0;i<=m-1;i++) for (j=0;j<=p-1;j++) { c[i][j]=0; for (k=0;k<=n-1;k++) c[i][j]=c[i][j]+a[i][k]*b[k][j]; printf("\nelementele matricii C sunt :\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) 90

91 printf("c[%d][%d]=%d\n",i,j,c[i][j]); getch(); C. Transpusa unei matrice #include <stdio.h> #include <conio.h> void main() /* Transpusa unei matrici A(mxn) */ { int a[10][10],b[10][10]; int n,m,i,j; printf("\nintroduceti numarul de linii : "); scanf("%d",&m); printf("introduceti numarul de coloane : "); scanf("%d",&n); printf("\nintroduceti elementele matricii A\n"); for (i=0;i<=m-1;i++) for (j=0;j<=n-1;j++) { printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]); ; for (i=0;i<=n-1;i++) for (j=0;j<=m-1;j++) b[i][j]=a[j][i]; printf("\nelementele matricii transpuse sunt :\n"); for (i=0;i<=n-1;i++) for (j=0;j<=m-1;j++) printf("b[%d][%d]=%d\n",i,j,b[i][j]); getch(); 91

92 SUGESTII TEME DE LABORATOR A. Să se afişeze elementele de pe bordura unei matrici B. Să se afişeze elementele de sub diagonala principală a unei matrici pătrate C. Să se afişeze elementele de deasupra diagonalei secundare a unei matrici pătrate D. Să se interclaseze coloanele unei matrici, astfel încât elementele de pe linia k să fie ordonate crescător E. Determinaţi elementele şa ale unei matrici (elementele minime pe linie şi maxime pe coloane, sau invers) 92

93 10. FUNCŢII DEFINITE DE UTILIZATOR bază: Pentru utilizarea funcţiilor în C++, este necesară cunoaşterea următoarelor aspecte de a) Funcţiile grupează setul de operatori pentru îndeplinirea unei sarcini concrete. b) Programul principal apelează la funcţie, adresîndu-se la numele ei, după care urmează paranteze rotunde. c) După terminarea prelucrării informaţiei, majoritatea funcţiilor întorc programului principal valori de tipuri concrete, care pot fi olosite în calcule. d) Programul principal transmite funcţiilor parametrii (informaţia iniţială), inclusă în paranteze rotunde, care urmează după numele funcţiei. e) Limbajul C++ foloseşte prototipuri de funcţie pentru determinarea tipului valorii returnate de câtre funcţie, a cantităţii si tipurilor parametrilor transmişi funcţiei. În timpul creării programului, e necesar să se rezerve fiecare funcţie pentru rezolvarea unei sarcini. Fiecare funcţie creată trebuie să primeascăun nume unic. Ca şi în cazul variabilelor, numele unei funcţii este un identificator şi e de dorit să corespundă cu sensul logic al sarcinei pe care o îndeplineşte. Funcţiile din C++ se aseamănă structural cu funcţia principală main(). În faţa numelui funcţiei se indică tipul ei, iar după numele funcţiei urmează lista de parametri descrişi înăuntrul parantezelor rotunde. Corpul funcţiei (compus din operatori) este amplasat după descrierea parametrilor, între acolade. unde Sintaxa descrierii unei funcţii: tip_f nume_f (lista parametri) {declarare de variabile; operatori; tip_f nume_f - tipul funcţiei sau tipul valorii returnate de funcţie, - numele funcţiei. Dacă funcţia nu întoarce valori, tipul ei este void. 1. Transmiterea parametrilor în funcţie. Dacă funcţia foloseşte parametri, ei trebuie descrişi în cadrul descrierii funcţiei. În timpul descrierii parametrelor funcţiei se indică numeleşi tipul fiecărui parametru. tip_parametru nume_parametru; 93

94 Dacă funcţia conţine mai mulţi parametri, ei vor fi descrişi împreună între parantezele rotunde după numele funcţiei, despărţiţi prin virgulă tip_funcţie nume_funcţie (tip_parametru1 nume_parametru1, tip_parametru2 nume_parametru2. tip_parametrun nume_parametrun ); În unele surse de descriere a limbajului de programare C/C++, parametrii ce se transmit din program în funcţie se numesc actuali, iar parametrii ce sunt declaraţi în antetul funcţiei şi cărora li se atribuie valorile parametrilor actuali, se numesc parametri formali. În momentul folosirii parametrilor în funcţie, este necesară cunoaşterea următoarelor aspecte: - Dacă funcţia foloseşte parametri, ea trebuie să indice numele unic şi tipul fiecărui parametru. - Când programul apelează funcţia, compilatorul atribuie valoarea parametrilor de la stânga la dreapta - Valorile transmise din program în funcţie, trebuie să coincidă ca număr, loc şi tip cu parametrii din funcţie. 2. Întoarcerea valorilor din funcţie. Obiectivul oricărei funcţii este îndeplinirea unei sarcini concrete. În majoritatea cazurilor, funcţiile vor efectua calcule. După aceasta, funcţia va întoarce rezultatul fie funcţiei din care a fost apelată, fie funcţiei principale main. În momentul când funcţia întoarce o valoare, trebuie să fie cunoscut tipul ei. Tipul valorii returnate de funcţie se indică în momentul descrierii funcţiei, înainte de numele ei. Tipul valorii returnate se mai numeşte şi tipul funcţiei. Funcţiile folosesc operatorul return pentru a întoarce valori funcţiilor din care au fost apelate. Când compilatorul întâlneşte operatorul return, el întoarce valoarea dată şi încheie executarea funcţiei curente, controlul executării programului fiind cedat funcţiei din care a fost chemată funcţia curentă. Dacă după operatorul return, în funcţie mai există şi alţi operatori, ei vor fi ignoraţi, funcţia terminîndu-se odată cu îndeplinirea operatorului return. Valoarea întoarsă de funcţie poate fi folosită în orice loc al programului, unde e posibilă folosirea unei valori de tip identic cu valoarea returnată. Când funcţia întoarce o valoare, această valoare poate fi atribuită unei variabile de acelaşi tip, folosind operatorul de atribuire. Valoarea mai poate fi folosită în cadrul instrucţiunilor de afişare, în cadrul instrucţiunilor de decizie sau a instrucţiunulor de ciclare. De asemenea, ea poate fi folosită ca parametru în cadrl apelului altei funcţii. 3. Prototipul funcţiei. Înainte de apelul unei funcţii, compilatorul C++ trebuie să cunoască tipul valorii returnate, cantitatea şi tipul parametrilor folosiţi de funcţie. Există însă situaţii cînd unele funcţii în program sînt apelate reciproc. În aceste cazuri, este posibilă situaţia cînd o funcţie va fi apelată înaintea descrierii sale. 94

95 În acest caz, se folosesc prototipuri ale funcţiilor. Prototipul unei funcţii este amplasat la începutul programului şi conţine informaţia despre tipul valorii returnate, cantitatea şi tipul parametrilor folosiţi de funcţie. Odată declarat prototipul unei funcţii, înainte de a fi început corpul programului, descrierea funcţiei poate fi făcută după acolada de închidere a programului principal. 4. Variabile localeşi domeniul de vizibilitate. Apare adeseori necesitatea folosirii în funcţii a variabilelor proprii.variabilele declarate în cadrul funcţiei e numesc variabile locale. Numele şi valoarea unei variabile locale sunt cunoscute numai funcţiei în care ea a fost declarată. Chiar faptul că variabila locală există este cunoscut numai de către funcţia în are ea a fostd eclarată. Declararea variabilelor are loc la începutul funcţiei, imediat după acolada care deschide corpul acesteia. Numele variabilei locale trebuie să fie unic în funcţia în care a fost declarată. O variabilăse numeşte locală, din cauză că este văzută numai din funcţia în care a fost descrisă. unde: Sintaxa de declarare a unei variabile locale: tip_f numele_f (lista parametrilor) {tip_vl numele_vl; tip_f nume_f tip_vl numele_vl - tipul funcţiei; - numele funcţiei; - tipul variabilei; - numele variabilei; Principiile de declarare şi folosire a unei variabile locale oricărei funcţii sunt identice cu principiile de declarare şi utilizare a unei variabile declarate în corpul funcţiei principalemain( ); O variabilă declarată în corpul funcţiei main() este şi ea locală acestei funcţii. În general, tot ceea ce este valabil pentru a fost spus despre variabilele declarate în funcţia main( ) - tipurile, numele, principiile de utilizare ş.a.- rămâne valabil şi pentru o variabilă locală, din orice altă funcţie. 5. Variabile globale Numim variabilă globală o variabilă pentru care numele şi valoarea sunt cunoscute pe parcursul întregului program, orice funcţie din acest program. Pentru a crea o variabilă globală, se foloseşte declararea ei la începutul programului, în afara oricărei funcţii. Orice funcţie (inclusiv funcţia main), care va urma după această declarare, poate folosi această variabilă globală. Declararea unei variabile globale: # include< > # include< > # include< > 95

96 tip_vg nume_vg; eventuale declaraţii de funcţii void main (void){ unde tip_vg este tipul variabilei globale, iar nume_vg numele variabilei globale. Fiind declarată o variabilă globală, valoarea ei nu numai că e cunoscută oricărei funcţii din program, dar şi poate fi şi schimbată de către oricare dintre funcţiile prezente în program. Cu toate că prezenţa variabilelor globale în program adaogă noi posibilităţi, este de dorit să nu se facă abuz de folosirea lor. Din cauză că orice funcţie din program poate schimba valoarea variabilei globale, este dificil de urmărit toate funcţiile care ar putea schimba această valoare, ceea ce conduce la un control dificil asupra execuţiei programului 6. Conflicte dintre variabile localeşi globale În cazul în care un program trebuie să folosească o variabilă globală, poate apărea o situaţie de conflict între numele variabilei globale şi numele unei variabile locale. În aceste cazuri, limbajul C++ oferă prioritate variabilei locale. Dacă există o variabilă globală cu acelaşi nume ca o variabila locală, compilatorul consideră, că orice apel al variabilei cu acest nume este un apel al variabilei locale. Există situaţii, când apare necesitatea de a se adresa o variabilă globală care se află în conflict cu o variabilă locală. În acest caz, se poate folosi operatorul global de acces ::. EXEMPLE A. Transmiterea prin valoara şi prin referinţă #include <stdio.h> #include <conio.h> #include <math.h> float f1(int a,int b,int c) { a=a*a; b=b*b; c=c*c; return sqrt(a+b+c); 96

97 float f2(int *a,int *b,int *c) { *a=*a**a; *b=*b**b; *c=*c**c; return sqrt(*a+*b+*c); void main() { int x,y,z; printf("\nintroduceti pe x : "); scanf("%d",&x); printf("introduceti pe y : "); scanf("%d",&y); printf("introduceti pe z : "); scanf("%d",&z); printf("rezultatul aplicarii lui f1 : %g\n",f1(x,y,z)); printf("x=%d\n",x); printf("y=%d\n",y); printf("z=%d\n",z); printf("rezultatul aplicarii lui f2 : %g\n",f2(&x,&y,&z)); printf("x=%d\n",x); printf("y=%d\n",y); printf("z=%d\n",z); getch(); B. Suma cifrelor unui număr #include <fstream.h> #include <conio.h> void main(){ clrscr(); int x, y, z, rasp, gasit=0; char fis[20]; cout<<"numele fisierului de intrare : ";cin>>fis; ifstream f(fis); f>>x>>y; cout<<x<<" "<<y<<endl; while((!gasit)&&(x<=y)){ z=(x+y)/2; f>>rasp; if(rasp) gasit=1; else{ f>>rasp; 97

98 if(rasp)y=z-1; else x=z+1; if(gasit)cout<<z; else cout<<"0"; getch(); f.close; C. Factorialul primelor 170 de numere double factorial(int); #include <stdio.h> #include <conio.h> void main() /* Afiseaza pe n! pentru m=0,1,2,...,170 */ { int m; for (m=0;m<171;m++) { printf("m=%d\tm!=%g\n",m,factorial(m)); if ((m+1)%23==0) { printf("apasati o tasta pt.a continua\n"); getch(); getch(); double factorial(int n) /* Calculeaza pe n! pentru n din intervalul [0,170]; pentru alte valori returneaza -1 */ { double f; int i; if (n<0 n>170) return -1.0; for (i=2,f=1.0;i<+n;i++) f*=i; return f; 98

99 D. Aflarea unei rădăcini unice dintr-un interval dat double f(double); double radac(double ls,double ld); #include <conio.h> #include <stdio.h> #include <math.h> void main() /* Calculeaza o radacina unica din intervalul [a,b] */ { double a,b,x,fx; printf("\n\nintroduceti limita din stanga "); scanf("%lf",&a); printf("introduceti limita din dreapta "); scanf("%lf",&b); if (fabs(f(a))<1e-30) printf("radacina este chiar limita din stanga\n"); else if (fabs(f(b))<1e-30) printf("radacina este chiar limita din dreapta\n"); else if (f(a)*f(b)>0) printf("varianta nepermisa\n"); else printf("radacina este x=%g\tf(x)=%g\n",radac(a,b),f(radac(a,b))); getch(); double f(double x) { double val; val=x*x-3.0*x+2.0; return val; double radac(double ls,double ld) /* Numarul de simboluri * arata de cate ori a fost apelata functia */ { double jum,val; jum=(ls+ld)/2; if (f(ls)*f(jum)<0) ld=jum; else ls=jum; if (fabs(f(jum))<1e-300) val=jum; else {val=radac(ls,ld);printf("*"); return val; 99

100 E. Maxime din minime pe linii şi coloane #include <stdio.h> #include <conio.h> void maxmin(int a[10],int n,int& maxim,int& minim) { int i; maxim=a[1]; minim=a[1]; for (i=2;i<=n;i++) { if (maxim<a[i]) maxim=a[i]; if (minim>a[i]) minim=a[i]; ; ; void main() /* Maxime si minime in matrice */ { int a[10][10],ajut[10],mxln[10],mnln[10],mxcl[10],mncl[10]; int n,m,i,j,k,mxmxln,mxmnln,mnmxln,mnmnln,mxmxcl,mxmncl,mnmxcl,mn mncl; printf("\nintroduceti numarul de linii : "); scanf("%d",&m); printf("\nintroduceti numarul de coloane : "); scanf("%d",&n); printf("\nintroduceti elementele matricii\n\n"); for (i=1;i<=m;i++) for (j=1;j<=n;j++) { printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]); ; printf("\n"); for (i=1;i<=m;i++) { for (j=1;j<=n;j++) ajut[j]=a[i][j]; maxmin(ajut,n,mxln[i],mnln[i]); printf("linia %d\t\tmax=%d\tmin=%d\n",i,mxln[i],mnln[i]); maxmin(mxln,m,mxmxln,mnmxln); printf("\nmaximumul din maximele pe linii este %d",mxmxln); printf("\nminimumul din maximele pe linii este %d",mnmxln); maxmin(mnln,m,mxmnln,mnmnln); printf("\nmaximumul din minimele pe linii este %d",mxmnln); printf("\nminimumul din minimele pe linii este %d\n\n",mnmnln); getch(); for (j=1;j<=n;j++) { 100

101 for (i=1;i<=m;i++) ajut[i]=a[i][j]; maxmin(ajut,m,mxcl[j],mncl[j]); printf("coloana %d\tmax=%d\tmin=%d\n",j,mxcl[j],mncl[j]); maxmin(mxcl,n,mxmxcl,mnmxcl); printf("\nmaximumul din maximele pe coloane este %d",mxmxcl); printf("\nminimumul din maximele pe coloane este %d",mnmxcl); maxmin(mncl,n,mxmncl,mnmncl); printf("\nmaximumul din minimele pe coloane este %d",mxmncl); printf("\nminimumul din minimele pe coloane este %d\n\n",mnmncl); getch(); 101

102 SUGESTII TEME DE LABORATOR A. Să se scrie funcţia citvect, care citeşte un vector de n elemente B. Să se scrie funcţia scrvect, care afişează un vector de n elemente C. Să se scrie funcţia citvmat, care citeşte o matrice cu nl linii şi nc coloane D. Să se scrie funcţia scrvmat, care afişează o matrice cu nl linii şi nc coloane E. Să se scrie funcţia perlin care permută liniile l1 şi l2 ale unei matrice F. Să se scrie funcţia intercl care interclasează doi vectori ordonaţi crescător G. Cunoscând vectorul de numere întregi v, să se creeze vectorul w, care conţine elementele prime din v, utilizând o funcţie care determină dacă un număr este prim H. Să se scrie câte o funcţie care primeşte ca parametrii numerele întregi n şi b şi înscrie într-un vector v cifrele numărului n scris în baza b I. Să se scrie o funcţie pentru extragerea elementelor comune din doi vectori (neordona) într-un al treilea vector. J. Să se scrie o funcţie care caculează aria intersecţiei a două dreptunghiuri, date prin coordonatele colţurilor stânga-sus şi dreapta-jos. Coordonatele sunt numere întregi pozitive. K. Să se scrie o funcţie care determină aria reuniunii a două dreptunghiuri date prin coordonatele întregi ale colţurile stânga-sus şi dreapta-jos. 102

103 11. POINTERI Pointerii au fost introdusi in limbajele de programare pentru a putea rezolva mai eficient anumite probleme. Pointerul este o variabila ce contine adresa unui obiect. Obiectul a carei adresa este conţinută de pointer poate fi variabilă sau funcţie. Ex: int a; int *b; Variabila a este de tip întreg, iar variabila b este de tip pointer; ea conţine adresa unei variabile de tip întreg (adresa la care se află o valoare de tip întreg). În cazul declarării variabilei, semnul * din stânga acesteia semnifică faptul ca acesta conţine o adresă (variabila este de tip pointer) şi nu o valoare. În momentul utilizării variabilei semnul * din stânga acesteia are altă semnificaţie, acesta semnifică faptul că se preia valoarea variabilei de tip pointer. Ex: a=*b; variabila a preia valoarea de la adresa lui b (valoarea la care pointează b) Operatorul unar & este utilizat pentru obţinerea adresei. Ex: b=&a; Alocarea dinamică a memoriei Utilizatorul poate solicita în timpul execuţiei programului alocarea unei zone de memorie. Această zonă de memorie poate fi eliberată, în momentul în care nu mai este necesară. Alocarea memoriei se poate realiza cu funcţiile din biblioteca având prototipul (declaraţiile) în <alloc.h> sau prin utilizarea operatorului new. void *malloc (unsigned n); Funcţia alocă un bloc de memorie de n octeţi. Funcţia întoarce un pointer la începutul zonei de memorie alocată. În cazul în care nu este posibilă alocarea unei zone compacte de n octeţi funcţia returnează NULL(0x0000). Memoria alocată NU este iniţializată. La sfârţitul operaţiilor memoria trebuie eliberată. În cazul alocării cu funcţia malloc dealocarea memoriei se face cu funcţia: 103

104 void free(void *p); Funcţia eliberează o zonă de memorie indicată de p, alocată în prealabil prin malloc(). Funcţiile de alocare întorc pointeri generici (void*) la zone de memorie, în timp ce utilizatorul alocă memorie ce păstrează informaţii de un anumit tip. Pentru a putea accesa memoria alocată, indirect, prin intermediul pointerului, acesta va trebui să fie un pointer cu tip, ceea ce impune conversia explicită (prin cast) a pointerului întors de funcţia de alocare într-un pointer cu tip. int *p; p=(int*)malloc(n*sizeof(int)) if(p==null) { printf( Memorie insuficienta! );... if(p) // identic cu if(p!=null) free(p); sau int *p; p=new int[n]; if(p==null) { printf( Memorie insuficienta! );... if(p) delete[] p; Exemplu de alocare dinamică a unei matrici si de eliberare a zonei alocate. #include <stdio.h> #include <conio.h> #include <alloc.h> //aloca dinamic o matrice cu m linii si n coloane double **aloca2double(int m,int n) {double **A; int k,i; A=(double**) malloc(m*sizeof(double*)); if(!a) return NULL; for(k=0;k<m;k++) {A[k]=(double*) malloc(n*sizeof(double)); if(!a) //alocare esuata, elibereaza mem. deja alocată { for(i=0;i<k;i++) free(a[i]); free(a); return NULL; //endif //endfor for(k=0;k<m;k++) for(i=0;i<n;i++) A[k][i]=0; return A; 104

105 // //elibereaza zona de memorie alocata void elib2double(double**a, int m) {int k; for(k=0;k<m;k++) if(a[k]) free(a[k]); if(a) free(a); // void main(void) { double **x; x=aloca2double(100,50); if(x==null) printf("memorie insuficienta"); //... operatii cu matricea x... elib2double(x,100); ARITMETICA POINTERILOR Datorită faptului că adresele de memorie a elementelor dintr-un tablou sunt consecutive se pot efectua operaţii cu aceste adrese în cadrul tabloului. La incrementarea unei variabile pointer, C++ incrementează automat adresa cu o valoare adecvată (1 octet dacă tipul variabilei la care punctează este char, 2 octeţi pentru tipul de date short, patru octeţi pentru long sau float, etc.), astfel încât pointerul să indice următoarea valoare pe care o are tipul pointerului (tipul datei la care punctează). Pentru tipuri de date complexe (structuri, clase) se incrementează cu dimensiunea structurii sau clasei la care punctează. Ex: #include <stdio.h> //biblioteca pentru functia printf -- afisare #include <conio.h> //biblioteca pentru functia getch asteapta //apasarea unei taste DOS void main(void) { int t[4]={0, 1, 2, 3; int *p; p=&t[2]; p-=2;printf("%d\n", *p); /* afiseaza valoarea lui t[0] */ p+=1;printf("%d\n", *p); /* afiseaza valoarea lui t[1] */ p++;printf("%d\n", *p); /* afiseaza valoarea lui t[2] */ (*p)+=5;printf("%d\n", *p); /* afiseaza valoarea lui t[2]+5 */ getch(); 105

106 Ex: int a01,a02,*a1,b1[3][4] a3[10]; a1=b1[0];implica a1+2=b1[2]; b1[0]=&b1[0][0];implica b1[0]+5=&b1[1][0]; a3=&a3[0]; b1=&b1[0];b1=&b1[2]-2; b1[2][1]=*(&b1[2][1]); b1[2][1]=*(b1[2]+1); b1[2][1]=*(*(b1+2)+1); b1[2][3]=*(*(b1+2)+3) b1[2][3]=*(&b1[2]+3) EXEMPLE A. Pointeri şi adrese #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <iostream.h> void main(void){ int x, y, *adr; clrscr(); //variabila "x" (de tip int) ia o valoare cout<<"x=";cin>>x; //variabila "adr" (de tip pointer) ia ca valoare adresa variabilei x adr=&x; cout<<"valoarea lui x = "<<x<< " (valoare tiparita direct)"<<endl; cout<<"ceea ce e totuna cu "<<*adr<< " (valoare luata de la adresa lui x)"<<endl; cout<<"adresa lui x = "<<adr<< " (am tiparit valoarea variabilei adresa)"<<endl; cout<<"sau, altfel zis "<<&x<< " (am tiparit adresa variabilei a)"<<endl<<endl; //dar si variabila "adr" (de tip pointer) are o adresa cout<<"adresa variabilei x este tinuta la adresa "<<&adr; getch(); 106

107 B. Aceeaşi funcţie utilizator, definită cu şi fără pointeri #include <iostream.h> #include <conio.h> #include <stdio.h> #include <string.h> int cresc1(int &a,int k) {a+=k;return a; int cresc2(int * a,int k) {*a+=k;return *a; void main(void){ int x,y,d; clrscr(); cout<<"functie definita fara pointeri\n"; cout<<"pe cine cresc?";cin>>x; cout<<"cu cat cresc?";cin>>d; cout<<"obtin "<<cresc1(x,d)<<"\n\n"; cout<<"functie definita cu pointeri\n"; cout<<"pe cine cresc?";cin>>y; cout<<"cu cat cresc?";cin>>d; cout<<"obtin "<<cresc1(y,d)<<endl; getch(); C. Legătura dintre pointeri şi tablouri #include <conio.h> #include <iostream.h> void main(){ int a, b, * pa, * pb, v[100], i, n; float x[100], * px; clrscr(); cout<<"a=?";cin>>a; cout<<"b=?";cin>>b; pa=&a; pb=&b; cout<<a<<" "<<pa<<" "<<*pa<<endl; 107

108 cout<<b<<" "<<pb<<" "<<*pb<<endl; getch(); /* cout<<"cate elemente are vectorul v? ";cin>>n; for(i=0;i<n;i++){ cout<<"introduceti pe v["<<i<<"] ";cin>>v[i]; for(i=0;i<n;i++){ cout<<"v["<<i<<"]= "<<v[i]<<endl; pa=v; cout<<*pa<<endl; pa=pa+3; cout<<*pa<<endl; */ cout<<"cate elemente are vectorul x? ";cin>>n; for(i=0;i<n;i++){ cout<<"introduceti pe x["<<i<<"] ";cin>>x[i]; for(i=0;i<n;i++){ cout<<"x["<<i<<"]= "<<x[i]<<endl; px=x; cout<<*px<<endl; px=px+3; cout<<*px<<endl; getch(); D. Aritmetica pointerilor #include <stdio.h> #include <conio.h> void main() { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8; unsigned long int adr0, adr1, adr2; int *p1, *p2; clrscr(); printf("a = %p\na + 1 = %p\na + 3 = %p\n\n", a, a + 1, a + 3); printf("sizeof(a) = %d\n", sizeof(a)); 108

109 printf("sizeof(a + 1) = %d\n", sizeof(a + 1)); printf("sizeof(a + 3) = %d\n\n", sizeof(a + 3)); adr0 = (unsigned long int) a; adr1 = (unsigned long int) (a + 1); adr2 = (unsigned long int) a + 1; printf("adr0 = %lu\nadr1 = %lu\nadr2 = %lu\n\n", adr0, adr1, adr2); p1 = a + 4; p2 = &(a[4]); printf("p1 = %p \t *p1 = %d\n", p1, *p1); printf("p2 = %p \t *p2 = %d\n", p2, *p2); printf("a + 4 = %p \t a[4] = %d\n", a + 4, a[4]); *p1 = *p1 + 1; printf("\na[4] = %d\n", a[4]); getch(); 109

110 SUGESTII TEME DE LABORATOR A. Să se scrie un program care afişează ca întreg în baza 10 conţinutul primului octet al unei variabile de tip float B. Să se scrie o funcţie pentru incrementarea unui moment de timp, dat ca oră, minut şi secundă și perioada zilei (AM sau PM). Funcția va trebui să modifice 3 numere întregi şi un vector de caractere şi va primi 3 argumente pointer şi un argument vector. C. Să se scrie o funcţie care calculează panta şi ordonata pentru o dreaptă dată prin 2 puncte. Ecuaţia dreptei dată prin pantă şi ordonată este y = m * x + n. Funcţia va avea antetul: void panta(int x1, int y1, int x2, int y2, float *m, float *n); 110

111 12. ŞIRURI DE CARACTERE În limbajul C/C++, şirurile de caractere sunt vectori având tipul de bază char. Un şir de caractere se termina prin marcatorul \0, sau caracterul nul. De exemplu, şirul "x2a" este memorat pe 4 caractere, ultimul fiind \0, numărul de elemente al şirului fiind, deci, 3, iar dimensiunea şirului 4. Un caracter dintr-un şir (vector) de caractere "a" poate fi accesat folosind indexul şirului (a[i], de exemplu) sau folosind pointeri la caracter. Iniţializarea (citirea) unui şir de caractere se poate face în mai multe moduri: a. Iniţializarea fiecărui element cu câte un character (ca la orice vector): a[0] = 'x'; a[1] = '2'; a[2] = 'A'; a[3] = '\0'; b. Folosind funcţia "scanf( )": scanf("%s", a); Formatul "%s" este folosit pentru citirea unui sir de caractere. Se efectuează trei pasi: - poziţionarea pe primul caracter al şirului; - citirea tuturor caracterelor diferite de <Enter> şi introducerea lor în vectorul "a"; - citirea se face până la întâlnirea EOF, după care se plasează '\0' la sfârşitul şirului. Deoarece numele unui şir (ca la orice vector) este un pointer la adresa de bază a şirului, expresia "a" este echivalentă cu "&a[0]". Dacă şirul citit are mai multe caractere decat cele rezervate, se va obţine o eroare. Este important de reţinut că 'b' şi "b" sunt două lucruri diferite, prima fiind o constantă caracter, în timp ce a doua este o constantă şir de caractere, care conţine pe prima poziţie constanta caracter 'b' şi pe a doua poziţie caracterul '\0' 3. Şirurile se pot iniţializa la fel ca şi caracterele sau, echivalent char a[] = "x2a"; char a[] = {'x', '2', 'c', '\0'; 4. Putem folosi un pointer către un şir constant, dar interpretarea este diferită: char *p = "x2a"; 111

112 Numele unui şir (ca la orice vector) poate fi tratat ca un pointer către adresa de bază a şirului din memorie. Constanta "x2a" este memorată de către compilator. În acelaşi timp, aceasta este "un nume de şir". Diferenţa dintre un şir iniţializat cu o constantă şir şi un pointer iniţializat tot cu o constantă şir este că şirul conţine caractere individuale urmate de caracterul "\0", în timp ce pointerul este asignat cu adresa şirului constant din memorie. #include <stdio.h> #include <ctype.h> main() { char c, nume[200]; int i, sum = 0; printf("\nintroduceti numele "); for (i = 0; (c = getchar())!= '\n'; ++i) { nume[i] = c; if (isalpha(c)) sum += c; nume[i] = '\0'; printf("\n%s%s%s\n%s", "Buna ziua ",nume,".", "Numele tau scris invers este "); for (--i; i >= 0; --i) putchar(nume[i]); printf("\n%s%d%s\n\n%s\n", "si numele tau are ", sum," litere.", "La revedere. "); FUNCŢII PENTRU OPERAŢII CU ŞIRURI DE CARACTERE Funcţiile pentru operaţii cu şiruri de caractere se găsesc în header-ul <string.h>. A. Functia strlen int strlen(nume_şir); returnează lungimea efectivă a unui şir (fără a număra terminatorul de şir). Exemplu: char s[20]= Buna ziua! ; strlen(s) =

113 B. Funcţia strcpy strcpy(şir_destinaţie, şir_sursă); copiază şirul şir_ sursa în şir_destinaţie (se simulează atribuirea şir_destinaţie = şir_sursă). Exemplu: char x[20]= Ion, y[30]= Vasile ; strcpy(x,y); x = Vasile ; y= Vasile ; C. Funcţia strcat strcat(dest,sursa); adauga şirului dest şirul sursa. Sirul sursa rămâne nemodificat. Operatia se numeste concatenare şi NU este comutativă. Exemplu: char *x= Buna,*y= ziua! ; strcat(x,y); x = Buna ziua! D. Funcţia strncat strncat(dest,sursa,nr); adaugă la dest primele nr caractere din şirul sursa. Şirul sursa ramane nemodificat. Exemplu: char *x= Buna,*y= ziua!? ; strncat(x,y,2); a = Buna zi ; E. Funcţia strchr strchr(sir,c); are rolul de a căuta caracterul c in şirul sir. Căutarea se face de la stânga la dreapta, iar funcţia întoarce adresa subşirului care începe cu prima apariţie a caracterului c. Dacă nu este găsit caracterul, funcţia returnează 0. Diferenţa dintre adresa şirului iniţial şi cea a subşirului returnat reprezintă chiar poziţia caracterului căutat în şirul dat. Exemplu: char *a= acesta este un sir,b= t,c= x,d; cout<<strchr(a,b); se tipăreşte ta este un sir ; cout<<strchr(a,c); nu se tipăreşte nimic (sau se tipăreşte 0, dacă se face o conversie la int a lui strchr(a,c) ; d= strchr(a,b); cout<< Caracterul apare prima data la pozitia <<d-a; 113

114 F. Funcţia strrchr strrchr(sir,c); are acelaşi rol cu strchr, cu deosebirea că returneaza adresa ultimei aparitii a caracterului (căutarea se face de la dreapta spre stânga; r = right) G. Funcţia strcmp int strcmp(sir1,sir2); are rolul de a compara două şiruri de caractere. Valoarea returnată este <0 (daca sir1<sir2) =0 (daca sir1=sir2) >0 (daca sir1>sir2). Funcţia strcmp face distincţie între literele mari şi cele mici ale alfabetului. Funcţia strcmp returnează diferenţa dintre codurile ASCII ale primelor caractere care nu coincid. H. Functia stricmp int stricmp(sir1,sir2); are acelaşi rol cu strcmp, cu deosebirea că nu face distincţie între literele mari şi cele mici ale alfabetului (i = ignore). I. Funcţia strstr strstr(sir1,sir2); are rolul de a identifica dacă şirul sir2 este subşir al sirului sir1. Dacă este, funcţia returnează adresa de început a subşirului sir2 în şirul sir1, altfel returnează adresa 0. În cazul în care sir2 apare de mai multe ori în sir1, se returnează adresa de început a primei apariţii. Căutarea se face de la stânga la dreapta J. Functia strtok strtok(sir1,sir2); are rolul de a separa şirul sir1 în mai multe şiruri (cuvinte) separate între ele prin unul sau mai multe caractere cu rol de separator. Şirul sir2 este alcătuit din unul sau mai multe caractere cu rol de separator. Funcţia strtok acţionează în felul următor: - Primul apel trebuie să fie de forma strtok(sir1,sir2); Funcţia întoarce adresa primului caracter al primei entităţi. După prima entitate, separatorul este înlocuit automat prin caracterul nul. - Urmatoarele apeluri sunt de forma strtok(null,sir2); De fiecare dată, funcţia întoarce adresa de început a următoarei entităţi, adăugând automat după ea caracterul nul. - Când şirul nu mai conţine entităţi, funcţia returnează adresa nula. 114

115 K. Functia strspn int strspn(sir1,sir2); are rolul de a returna numărul de caractere ale şirului sir1 (caractere consecutive care încep obligatoriu cu primul caracter) care se găsesc în şirul sir2. L. Funcţia strcspn int strspn(sir1,sir2); are rolul de a returna numărul de caractere ale şirului sir1 (caractere consecutive care încep obligatoriu cu primul caracter) care NU se găsesc în şirul sir2. M. Funcţia strlwr strlwr(sir); are rolul de a converti toate literele mari din şir în litere mici. Restul caracterelor rămân neschimbate. N. Funcţia strupr strupr(sir); are rolul de a converti toate literele mici din şir în litere mari. Restul caracterelor raman neschimbate O. Funcţia strbrk strpbrk(sir1,sir2); acţioneaza în felul următor: - Caută primul caracter al şirului sir1 în sir2. Dacă este găsit, returnează adresa sa din cadrul şirului sir1 şi execuţia se termină. Altfel, se trece la pasul următor. - Caută al doilea caracter al şirului sir1 în sir2. Dacă este găsit, returnează adresa sa din cadrul şirului sir1 şi execuţia se termină. Altfel, se trece la pasul următor. - - Dacă nici un caracter al şirului sir1 nu aparţine şirului sir2, funcţia returnează adresa nulă. P. Funcţia atof double atof(sir); converteşte un şir către tipul double. Dacă această conversie eşuează (se întâlneşte un caracter nenumeric), valoarea întoarsă este 0. Această funcţie (ca şi cele similare) necesită includerea bibliotecii stdlib.h. Q. Funcţia _atold long double _atold(sir); converteşte un şir către tipul long double. Dacă această conversie eşuează, valoarea întoarsa este 0. P. Funcţia atoi 115

116 int atoi(sir); converteşte un şir către tipul int. Dacă această conversie eşuează (se întâlneşte un caracter nenumeric), valoarea întoarsă este 0. R. Funcţia atoll long atol(sir); converteşte un şir către tipul long. Dacă această conversie eşuează, valoarea întoarsa este 0. S. Functia itoa itoa(int valoare,sir,int baza); converteşte o valoare de tip int în şir, care este memorat în variabila sir. Baza reţine baza de numeraţie către care să se facă conversia. În cazul bazei 10, şirul reţine şi eventualul semn -. T. Funcţia ltoa ltoa(long valoare,sir,int baza); converteşte o valoare de tip long int în şir, care este memorat în variabila sir. U. Funcţia ultoa ultoa(unsigned long valoare,sir,int baza); converteşte o valoare de tip unsigned long în şir, care este memorat în variabila sir. EXEMPLE A. Afişarea tuturor poziţiilor unui caracter într-un şir #include <iostream.h> #include <string.h> void main( ){ char a[100],*p,c; cin.get(a,100); cin>>c; p=strchr(a,c); while (p){ cout<<"pozitia "<<p-a<<endl; p++; p=strchr(p,c); 116

117 B. Separarea cuvintelor dintr-un text #include <iostream.h> #include <conio.h> #include <string.h> void main(){ char text[100],cuv[10][10],*p,*r,separator[]=",.!?";int i=0,nr=0; clrscr(); cout<<"dati sirul:";cin.get(text,100); strcpy(p,text); p=strtok(p,separator); while (p) {strcpy(cuv[++nr],p); p=strtok(null,separator); cout<<"sunt "<<nr<<" cuvinte:"<<endl; for (i=1;i<=nr;i++) cout<<cuv[i]<<endl; getch(); C. Sirul este alcatuit exclusiv din caractere numerice? #include <iostream.h> #include <conio.h> #include <string.h> void main(){ char text[100],cifre[]=" "; clrscr(); cout<<"dati sirul:";cin.get(text,100); if (strcspn(cifre,text)==strlen(text)) cout<<"exclusiv numeric"; else cout<< nenumeric ; getch(); 117

118 SUGESTII TEME DE LABORATOR 1. Să se transforme un şir din litere mici în litere mari. 2. Să se transforme un şir din litere mari în litere mici. 3. Se citeşte un text dintr-un fişier şi un caracter c. Să se determine de câte ori se găseşte caracterul în text. 4. Să se sorteze alfabetic un şir de cuvinte 5. Se citesc n cuvinte. Să se afişeseze grupurile de cuvinte care au ultimele 2 caractere identice 6. Să se despartă un text în cuvinte şi să se afişeze cuvintele separate. Să se afişeze cuvântul de lungime maximă. 7. În directorul curent se află fişierul cuvinte.txt, care conţine mai multe linii de text formate din cuvinte separate de câte un spaţiu. Să se afişeze cuvintele care au cel puţin 3 consoane sau 3 vocale consecutive.. Se citeşte un şir de caractere. Să se afişeze şirul oglindit, din care lipsesc vocalele. 9. Se citeşte un text. Textul conţine cuvinte separate printr-un spaţiu. Să se determine câte cuvinte conţine textul. 10. Dintr-un fişier se citeşte un text. Textul conţine cuvinte separate printr-un spaţiu sau mai multe. Se va genera un nou fişier, care va conţine textul iniţial, având spaţiile de prisos eliminate (între cuvinte va rămâne numai câte un spaţiu). 11. Simulaţi comanda REPLACE, astfel încât într-un text veţi înlocui un caracter x, citit de la tastatură, cu un alt caracter y, citit de la tastatură. 12. Se citeşte de la tastatură un cuvânt. Să se stabilească dacă el conţine două litere alăturate identice, afişându-se un mesaj corespunzator. 13. Dintr-un fişier se citesc numele a n persoane. Să se modifice conţinutul fişierului astfel încaât toate numele să fie scrise astfel: prima litera mare şi restul litere mici. 14. Într-un fişier sunt scrise cuvinte pe linii separate. Să se afişeze cuvintele care conţin majuscule. 15. Să se afişeze vocalele unui cuvânt. 118

119 13. STRUCTURI Structura este un grup de variabile de tipuri diferite reunite sub acelaşi nume, ce pune la dispoziţia utilizatorului un mod convenabil de pastrare a informaţiilor legate între ele. Declararea unei structuri creează un nou tip de date, ce poate fi folosit pentru a crea variabile de acel tip, sau pentru a crea direct variabile de acel tip. Variabilele care fac parte din structură se numesc membri, elemente sau câmpuri ale structurii. Între membrii structurii exista de obicei o legatură logică. Spre deosebire de tablouri, fiecare element al unei structuri poate avea propriul său tip, care poate diferi de tipul oricărui alt element. Forma generala a declararii unei structuri este: struct nume_generic { tip nume_membrul_l; tip nume_membrul_2; unde: tip nume_membrul_n; lista_variabile; struct tip nume_generic lista_variabile nume_membru_i - este cuvânt rezervat, numele tipului de date; - este orice tip de dată admis de C; nu trebuie sa fie acelaşi pentru toate câmpurile; - numele dat noului tip de date ; opţional; - este o listă de variabile de tip nume_generic (dacă apare) sau anonim (daca nu apare) ; este opţională; - este numele câmpului (membrului) i al structurii. Nume_generic şi lista_variabile sunt opţionale, dar cel puţin una trebuie să apară; dacă nume_generic apare, înseamnă că s-a creat un nou tip de date; dacă apare numai lista_variabile, înseamnă că s-au declarat variabile de tip structură, fără ca structura să aibă tip (tipul structurii create este anonim). Pentru a accesa un câmp al unei structuri, trebuie specificate numele variabilelor de tip structură şi numele câmpului, separate printr-un punct. Forma generală de acces la un membru: nume_variabilă. nume_membru unde nume_variabilă - numele variabilei de tip structură 119

120 nume membru - numele câmpului ce se doreşte a fi accesat. Structurile pot fi aranjate în tablouri. Pentru a accesa un camp al unei anumite structuri din tablou, indexul trebuie urmat de punct şi de numele câmpului ce trebuie accesat. Un membru al unei structuri poate fi un tip simplu - unul din tipurile de bază, sau un tip compus, cum ar fi un tablou de caractere, sau tablourile uni şi multidimensionale. EXEMPLE A. Numere complexe #include<stdio.h> #include<math.h> typedef struct{ float a; //partea reala float b; //partea imaginara complex; //numele structurii //citirea unui nr. Complex void citire(complex* z,char s[]) //s retine numele nr. complex { printf("introducem nr. complex %s:\n",s); printf("\tpartea reala: "); scanf("%f",&(*z).a); printf("\tpartea imaginara: "); scanf("%f",&z->b); //alt mod de scriere //afisarea unui nr. Complex void afisare(complex z,char s[]) { printf("nr. complex %s: ",s); if(z.b>=0) printf("%.2f+%.2fi\n",z.a,z.b); else printf("%.2f%.2fi\n",z.a,z.b); 120

121 //modulul unui nr. Complex float modul(complex z) { return sqrt(pow(z.a,2)+pow(z.b,2)); //conjugatul unui numar complex complex conjugat(complex z) { complex t; t.a=z.a; t.b=-z.b; return t; //suma a doua nr. complexe (varianta cu transfer prin tipul rezultat) complex suma1(complex x,complex y) { complex z; z.a=x.a+y.a; z.b=x.b+y.b; return z; //suma a doua nr. complexe (varianta cu transfer prin linia de parametri) void suma2(complex x,complex y,complex* z) { z->a=x.a+y.a; //(*z).a=x.a+y.a; z->b=x.b+y.b; //produsul a doua nr. Complexe complex produs(complex x,complex y) { complex z; z.a=x.a*y.a-x.b*y.b; z.b=x.a*y.b+x.b*y.a; return z; //functia principala in rulare 121

122 void main() { complex z1,z2; //citirea celor doua nr. complexe citire(&z1,"z1"); citire(&z2,"z2"); printf("\n"); //afisarea celor doua nr. complexe afisare(z1,"z1"); afisare(z2,"z2"); printf("\n"); //modulele celor doua nr. complexe printf("modulul lui z1: %.2f\n",modul(z1)); printf("modulul lui z2: %.2f\n",modul(z2)); printf("\n"); //conjugatele celor doua numere complexe afisare(conjugat(z1),"conjugat z1"); afisare(conjugat(z2),"conjugat z2"); //suma a doua nr. complexe - varianta 1 complex s1; s1=suma1(z1,z2); afisare(s1,"z1+z2"); //suma a doua nr. complexe - varianta 2 complex s2; suma2(z1,z2,&s2); afisare(s2,"z1+z2"); //produsul a doua nr. complexe complex p; p=produs(z1,z2); afisare(p,"z1*z2"); getchar(); int k; scanf("%d", &k); 122

123 SUGESTII TEME DE LABORATOR A. Se reţine un număr complex z = a + bi ca structura struct complex { float a; float b; ; Să se scrie funcţiile pentru adunarea, scăderea, înmulţirea şi împărţirea a două numere complexe. B. Se reţine un număr raţional r = a/b ( a, b Z, b 0 ) ca structura struct rational { long int a; long int b; ; Să se scrie funcţiile pentru adunarea, scăderea, înmulţirea şi împărţirea a două numere raţionale. C. Se reţine un punct din plan ca structura struct punct { float a; float b; ; Să se scrie funcţiile pentru calculul distanţei dintre două puncte, calculul pantei şi ordonatei pentru dreapta care trece prin două puncte, determinarea faptului dacă un punct se găseşte pe dreapta care uneşte două puncte, calculul ariei şi perimetrului unui triunghi determinat de trei puncte. 123

124 14. LISTE Lista este o colectie de elemente (noduri, celule) înlănţuite, care formează o structură dinamică, situată in memoria dinamică, în care toate elementele sunt de acelaşi tip (oricât de complex). Numărul de elemente este variabil, eventual chiar nul. O listă este deci o secvenţă de zero, una, sau mai multe elemente, numite noduri, toate fiind de acelaşi tip. Spre deosebire de listă, tabloul este o structură statică, situata in memoria dinamică, în care toate elementele sunt de acelaşi tip, numărul de elemente fiind constant. Un nod al unei liste liniare apare ca o structura recursivă, având o componentă de tip pointer la structură, care reprezintă legatura (înlănţuirea) spre nodul următor. Fiecare element (celulă/nod) din cadrul listei înlanţuite are o structură de tipul: Informaţie utilă; Informaţie de înlanţuire către elemental (nodul) următor; //pentru listele dublu înlănţuite Informaţie de înlanţuire către elemental (nodul) anterior; Dacă în cadrul elementului/celulei/nodului se face referire doar la elementul /celula/nodul următor, atunci avem liste simplu înlănţuite. Dacă se face şi referire la nodul anterior, atunci avem liste dublu înlănţuite. Structura unui element / celule / nod: ADRESA NODULUI ANTERIOR DATE NOD ADRESA NODULUI URMĂTOR CAP LISTĂ Pentru lucrul cu liste simplu înlănţuite, este suficient să se cunoască adresa capului listei, iar pentru listele dublu înlantuite se poate ajunge la orice nod, dacă se cunoaşte adresa unui singur nod din listă, oricare ar fi el. Dacă ultimul nod din listă se pune în legătură cu primul nod, avem de-a face cu o listă circulară (simplu sau dublu înlănţuită, după cum lista originală era simplu sau dublu înlănţuită. 124

125 EXEMPLE A. Operaţii cu liste liniare dublu înlănţuite #include <fstream.h> #include <conio.h> #include <stdlib.h> struct nod{ nod * ante; int val; nod * post; ; nod * curent, * prim, * ultim, * ajut; void creare(){ clrscr(); curent = new nod; prim=curent; ultim=curent; curent->ante=0; curent->post=0; cout<<"introduceti valoarea:";cin>>curent->val; void listarestdr(){ clrscr(); curent=prim; while(curent->post){ cout<<curent->val<<" "; curent=curent->post; cout<<curent->val; getch(); void listaredrst(){ clrscr(); curent=ultim; while(curent->ante){ cout<<curent->val<<" "; curent=curent->ante; cout<<curent->val; getch(); 125

126 void insmijloc(){ clrscr(); cout<<"in constructie. Voi insera un nod in interior"; getch(); void insinaint(){ clrscr(); cout<<"in constructie. Voi insera un nod in prima pozitie"; getch(); void inscoada(){ clrscr(); curent=new nod; cout<<"introduceti valoarea:";cin>>curent->val; ultim->post=curent; curent->ante=ultim; curent->post=0; ultim=curent; void stergint(){ clrscr(); cout<<"in constructie. Voi sterge un nod din interior"; getch(); void stergprim(){ clrscr(); cout<<"in constructie. Voi sterge primul nod"; getch(); void stergult(){ clrscr(); cout<<"in constructie. Voi sterge ultimul nod"; getch(); void salvez(){ int i,n; clrscr(); cout<<"in constructie. Voi salva lista in fisier"; ofstream f("lista.dat"); curent=prim;n=1; while(curent->post){ 126

127 curent=curent->post; n++; cout<<"lista are "<<n<<" noduri"<<endl; f<<n<<endl; curent=prim; for(i=1;i<=n;i++){ f<<curent->val<<endl; curent=curent->post; getch(); void meniu2(){ int rasp; clrscr(); cout<<"operatii CU LISTE :"<<endl<<endl; cout<<" 1: creare"<<endl<< " 2: listare de la stanga la dreapta"<<endl<< " 3: listare de la dreapta la stanga"<<endl<< " 4: inserare nod in interiorul listei"<<endl<< " 5: inserare nod pe prima pozitie"<<endl<< " 6: inserare nod pe ultima pozitie"<<endl<< " 7: stergerea unui nos din interiorul listei"<<endl<< " 8: stergerea primului nod"<<endl<< " 9: stergerea ultimului nod"<<endl<< "10: salvez lista"<<endl; cin>>rasp; switch (rasp){ case 1: creare();break; case 2: listarestdr();break; case 3: listaredrst();break; case 4: insmijloc();break; case 5: insinaint();break; case 6: inscoada();break; case 7: stergint();break; case 8: stergprim();break; case 9: stergult();break; case 10: salvez();break; default: exit(1); meniu2(); int citire(){ int i,n; clrscr(); 127

128 cout<<"in constructie. Voi citi lista din fisier"; ifstream f("lista.dat"); f>>n; curent=new(nod); prim=curent; ultim=curent; f>>(curent->val); for(i=2;i<=n;i++){ curent=new(nod); f>>(curent->val); ultim->post=curent; curent->ante=ultim; curent->post=0; ultim=curent; getch(); return 0; void meniu1(){ int rasp; clrscr(); cout<<"exploatarea LISTELOR INLANTUITE"<<endl<<endl; cout<<"1 Citire lista din fisier"<<endl; cout<<"2 Lista noua"<<endl; cin>>rasp; switch (rasp){ case 1: citire();meniu2();break; case 2: meniu2();break; default: exit(1); void main(){ clrscr(); meniu1(); 128

129 SUGESTII TEME DE LABORATOR A. Rescrieţi funcţiile din programul de mai sus pentru cazul listelor liniare simplu înlănţuite B. Rescrieţi funcţiile din programul de mai sus pentru cazul listelor circulare dublu înlănţuite 129

130 15. RECURSIVITATE Recursivitatea este un mecanism general de elaborare a algoritmilor. O funcţie se numeşte recursivă dacă ea se autoapelează, fie direct (în definiţia ei se face apel la ea însăşi), fie indirect (funcţia X apelează funcţia Y, care apelează funcţia X). Recursivitatea a apărut din necesitati practice, date de transcrierea directă a formulelor matematice recursive. Apoi, acest mecanism a fost extins, fiind utilizat în elaborarea multor algoritmi. De exemplu, definiţia recursivă a lui n! este : n *( n 1)! daca n > 0 n! = 1 altfel Functia recursivă se va scrie astfel: long factorial(int n) {if(n==0) return 1; else return factorial(n-1)*n; void main() {cout<<factorial(5) ; Se observă ca funcţia factorial se autoapelează. Autoapelul se realizează prin instrucţiunea return factorial(n-1)*n. Recursivitatea utilizează segmentul de stivă pentru a memora datele programului apelant, câtă vreme calculatorul rulează programul apelat. De fiecare dată când o funcţie se autoapelează, se creează un nou nivel în segmentul de stivă. Funcţionarea poate fi urmărită în figura de mai jos: 130

131 Fiecare apel de funcţie lucrează cu datele aflate pe nivelul corespunzator acelui apel. La ieşirea din apelul unei funcţii, nivelul respectiv se eliberează şi datele aflate acolo se pierd. Există posibilitatea ca subprogramul să lucreze direct cu variabilele globale, dar în acest caz, subprogramul işi pierde independenţa. Observaţii : - în cazul unui număr mare de autoapelări, există posibilitatea ca segmentul de stivă sa se ocupe total, caz în care programul se va termina cu eroarea STACK OVERFLOW. Aceasta se întamplă mai ales atunci când condiţia de terminare este pusă greşit şi subprogramul se apelează la nesfârşit. - pentru orice algoritm recursiv există unul iterativ, care rezolvă aceeaşi problemă. - mecanismul recursivităţii înlocuieste instrucţiunile repetitive. - datorită faptului că la fiecare autoapel se ocupă o zonă de memorie, recursivitatea este eficientă numai dacă numărul de autoapelări nu este prea mare, pentru a nu se ajunge la umplerea zonei de memorie alocată. - recursivitatea oferă avantajul unor soluţii mai clare pentru probleme şi a unei lungimi mai mici a programului. Ea prezintă însă dezavantajul unui timp mai mare de execuţie şi a unui spaţiu de memorie alocată mai mare. Este de preferat ca, atunci când programul recursiv poate fi transformat cu uşurinţă într-unul iterativ, să se facă apel la cel din urmă. EXEMPLE A. factorial recursiv #include <conio.h> #include <iostream.h> unsigned long fact(int n){ if(n==1) return 1; else return n*fact(n-1); 131

132 void main(){ int n; clrscr(); cout<<"n=";cin>>n; cout<<n<<"!="<<fact(n); getch(); B. Euclid recursiv #include<iostream.h> #include<conio.h> int euclid(int a, int b){ if(b==0) return a; else euclid(b, a%b); void main(){ clrscr(); int a, b, c; cout<<"a=";cin>>a; cout<<"b=";cin>>b; c=euclid(a,b); cout<<"cmmdc="<<c; getch(); C. Umplerea cu 1 a unei zone închise de valori de 0, delimitate de valori de 1 #include <conio.h> #include <stdlib.h> #include <iostream.h> int nl,nc,i,j,l,c,a[100][100]; char r; void umplu(int l,int c) { a[l][c]=1; if ((l>1)&&(a[l-1][c]==0)) umplu(l-1,c); 132

133 if ((c>1)&&(a[l][c-1]==0)) umplu(l,c-1); if ((c<nc)&&(a[l][c+1]==0)) umplu(l,c+1); if ((l<nl)&&(a[l+1][c]==0)) umplu(l+1,c); void main(void){ r='d'; clrscr(); cout<<'\333'; cout<<"linii=";cin>>nl; cout<<"coloane=";cin>>nc; randomize(); for (i=1;i<=nl;i++) for (j=1;j<=nc;j++) a[i][j]=random(2); clrscr(); cout<<" "; for (j=1;j<=nc;j++) cout<<j%10;cout<<endl<<endl; for (i=1;i<=nl;i++) { cout<<i%10<<" "; for (j=1;j<=nc;j++) cout<<a[i][j]; cout<<endl; cout<<endl; while (r=='d') { cout<<"linia=";cin>>l; cout<<"coloana=";cin>>c; umplu(l,c); clrscr(); cout<<" "; for (j=1;j<=nc;j++) cout<<j%10;cout<<endl<<endl; for (i=1;i<=nl;i++) { cout<<i%10<<" "; for (j=1;j<=nc;j++) cout<<a[i][j]; cout<<endl; cout<<endl; cout<<"continuati?";r=getch(); cout<<endl; 133

134 SUGESTII TEME DE LABORATOR A. Să se calculeze recursiv funcţia Ackerman, definită n 1 A( m, n) = A( m 1,1) A( m 1, A( m, n 1)) m = 0 n = 0 altfel B. Să se calculeze recursiv primele 44 de numere din şirul lui Fibonacci C. Să se scrie o funcţie recursivă pentru calculul sumei unui număr natural D. Să se genereze recursiv produsul cartezian a două mulţimi E. Să se scrie o funcţie pentru generea recursivă a permutărilor unei mulţimi F. Să se scrie o funcţie pentru generea recursivă a aranjamentelor de n elemente luate câte k G. Să se scrie o funcţie pentru generea recursivă a combinărilor de n elemente luate câte k 134

135 16. METODA DIVIDE ET IMPERA Metoda Divide et Impera (Imparte şi Stăpâneste) este o metodă de programare care se aplică problemelor care pot fi descompuse în subprobleme independente, similare problemei iniţiale, de dimensiuni mai mici, şi care pot fi rezolvate foarte uşor. Procesul se reia până când (în urma descompunerilor repetate) se ajunge la probleme care admit rezolvare imediată. Nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici. Numărul celor rezolvabile prin "divide et impera" este relativ mic, tocmai datorită cerinței ca problema să admită o descompunere repetată. Divide et impera este o tehnică ce admite o implementare recursivă. Principiul general prin care se elaborează algoritmi recursivi este: "ce se întâmplă la un nivel, se întâmplă la orice nivel" (având grijă să asigurăm condiţiile de terminare). Un algoritm prin divide et impera se elaborează astfel: la un anumit nivel avem două posibilităţi: 1. s-a ajuns la o problemă care admite o rezolvare imediată (condiţia de terminare), caz în care se rezolvă şi se revine din apel; 2. nu s-a ajuns în situaţia de la punctul 1, caz în care problema curentă este descompusă în (două sau mai multe) subprobleme, pentru fiecare din ele urmând un apel recursiv al funcţiei, după care combinarea rezultatelor are loc fie pentru fiecare subproblemă, fie la final, înaintea revenirii din apel. Aceasta metodă (tehnică) se poate implementa atât iterativ cât şi recursiv. Dat fiind că problemele se împart în subprobleme în mod recursiv, de obicei împărţirea se realizează până când şirul obţinut este de lungime 1, caz în care rezolvarea subproblemei este foarte uşoară. De exemplu, fie un vector X=[x 1, x 2, x 3, x i x p x j, x n ] asupra căruia se aplică o prelucrare. Pentru orice secvenţă din vector delimitată de indecşii i si j, i<j există o valoare p, astfel încât prin prelucrarea secvenţelor : x i, x i+1, x i+2, x i+3, x p si x p+1, x p+2, x p+3, x j se obţin soluţiile corespunzatoare celor două subşiruri care, prin compunere, conduc la obţinerea soluţiei prelucrării secvenţei: x i, x i+1, x i+2, x i+3, x j Un exemplu îl constituie căutarea binară: Se consideră un vector ordonat crescator cu N elemente şi o valoare K. Se cere să se scrie o funcţie care returnează poziţia elementului K în vectorul dat. În cazul în care K nu există în vector, se returnează -1. O soluţie ar fi căutarea secvenţială: se parcurge vectorul în mod normal, şi se localizează elementul K. Această soluţie are complexitatea O(N). Metoda optimă de rezolvare este cautarea binară. Aceasta se foloseşte de metoda divide et impera. Se împarte vectorul în jumătate, după care se continuă căutarea, în mod similar, în acea parte a vectorului unde se afla elementul K. Condiţia ca vectorul să fie sortat este esenţială. Complexitatea acestui algoritm este O(logN). #include<iostream.h> #include<conio.h> 135

136 int V[MAX_N], N, K; int binarysearch( int st, int dr) { if( dr > st ) return -1; int m = (st + dr) >> 1; if( V[m] == K ) return m; if( V[m] >= K ) return binarysearch(st, m-1); return binarysearch( dr, m+1); int main() { // se citeste vectorul si valoarile N si K cout << binarysearch( 1, N ); EXEMPLE A. Ghicirea unui număr #include <fstream.h> #include <conio.h> void main(){ clrscr(); int x, y, z, rasp, gasit=0; char fis[20]; cout<<"numele fisierului de intrare : ";cin>>fis; ifstream f(fis); f>>x>>y; cout<<x<<" "<<y<<endl; while((!gasit)&&(x<=y)){ z=(x+y)/2; f>>rasp; if(rasp) gasit=1; else{ f>>rasp; if(rasp)y=z-1; else x=z+1; if(gasit)cout<<z; else cout<<"0"; getch(); 136

137 f.close; B. Algoritmi de sortare-merge sort Dată fiind o listă neordonată, o împărţim în două liste, de dimensiuni egale sau foarte apropriate, ordonăm cele două liste (folosind acelaşi algoritm) şi apoi efectuăm operaţia "merge", adică vom combina cele două liste ordonate într-una singură, obţinând astfel lista originală ordonată. Operaţia principală care se efectuează este comparaţia dintre elementele listei. #include<iostream.h> #include<conio.h> int a[1000],n; void interclas(int i,int m,int j) {int b[1000]; int x=i; int k=1; int y=m+1; while(x<=m && y<=j) if(a[x]<a[y]) b[k++]=a[x++]; else b[k++]=a[y++]; while(x<=m) b[k++]=a[x++]; while(y<=j) b[k++]=a[y++]; int t=i; for(k=1;k<=(j-i)+1;k++) a[t++]=b[k]; int divimp(int i, int j) {if(i<j) {int m=(i+j)/2; divimp(i,m); divimp(m+1,j); interclas(i,m,j); void main() {clrscr(); cout<< n= ; cin>>n; for(int i=1;i<=n;i++) {cout<< a[ <<i<< ]= ; cin>>a[i]; divimp(1,n); for(i=1;i<=n;i++) cout<<a[i]<< ; getch(); 137

138 C. Turnurile din Hanoi Se dau trei tije verticale A, B şi C. Pe tija A se găsesc un număr n de discuri de diametre diferite, perforate la mijloc, aranjate în ordine descrescătoare a diametrelor discurilor, de la bază spre vârf. Celelalte tije sunt goale. Se cere să se găsească o strategie de mutare a discurilor de pe tija A pe tija B, respectând următoarele reguli: - La un moment dat se va muta un singur disc (cel care se aflădeasupra celorlalte discuri pe o tijă). - Un disc oate fi aşezat doar peste un alt disc având diametru mai mare decât al său, sau pe o tijăgoală. #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <iostream.h> void hanoi(int n,int a, int b, int c){ if (n==1) {cout<<"se muta discul 1 de pe tija "<<a<<" pe tija "<<b<<endl; getch();return; hanoi(n-1,a,c,b); cout<<"se muta discul "<<n<<" de pe tija "<<a<<" pe tija "<<b<<endl; getch(); hanoi(n-1,c,b,a); void main(void){ int n; cout<<"n=";cin>>n; hanoi(n,1,2,3); 138

III. Reprezentarea informaţiei în sistemele de calcul

III. Reprezentarea informaţiei în sistemele de calcul Metode Numerice Curs 3 III. Reprezentarea informaţiei în sistemele de calcul III.1. Reprezentarea internă a numerelor întregi III. 1.1. Reprezentarea internă a numerelor întregi fără semn (pozitive) Reprezentarea

Διαβάστε περισσότερα

Metode iterative pentru probleme neliniare - contractii

Metode iterative pentru probleme neliniare - contractii Metode iterative pentru probleme neliniare - contractii Problemele neliniare sunt in general rezolvate prin metode iterative si analiza convergentei acestor metode este o problema importanta. 1 Contractii

Διαβάστε περισσότερα

Curs 4 Serii de numere reale

Curs 4 Serii de numere reale Curs 4 Serii de numere reale Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi" Iaşi 2014 Criteriul rădăcinii sau Criteriul lui Cauchy Teoremă (Criteriul rădăcinii) Fie x n o serie cu termeni

Διαβάστε περισσότερα

Curs 10 Funcţii reale de mai multe variabile reale. Limite şi continuitate.

Curs 10 Funcţii reale de mai multe variabile reale. Limite şi continuitate. Curs 10 Funcţii reale de mai multe variabile reale. Limite şi continuitate. Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi" Iaşi 2014 Fie p, q N. Fie funcţia f : D R p R q. Avem următoarele

Διαβάστε περισσότερα

Curs 14 Funcţii implicite. Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi"

Curs 14 Funcţii implicite. Facultatea de Hidrotehnică Universitatea Tehnică Gh. Asachi Curs 14 Funcţii implicite Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi" Iaşi 2014 Fie F : D R 2 R o funcţie de două variabile şi fie ecuaţia F (x, y) = 0. (1) Problemă În ce condiţii ecuaţia

Διαβάστε περισσότερα

MARCAREA REZISTOARELOR

MARCAREA REZISTOARELOR 1.2. MARCAREA REZISTOARELOR 1.2.1 MARCARE DIRECTĂ PRIN COD ALFANUMERIC. Acest cod este format din una sau mai multe cifre şi o literă. Litera poate fi plasată după grupul de cifre (situaţie în care valoarea

Διαβάστε περισσότερα

(a) se numeşte derivata parţială a funcţiei f în raport cu variabila x i în punctul a.

(a) se numeşte derivata parţială a funcţiei f în raport cu variabila x i în punctul a. Definiţie Spunem că: i) funcţia f are derivată parţială în punctul a în raport cu variabila i dacă funcţia de o variabilă ( ) are derivată în punctul a în sens obişnuit (ca funcţie reală de o variabilă

Διαβάστε περισσότερα

5. FUNCŢII IMPLICITE. EXTREME CONDIŢIONATE.

5. FUNCŢII IMPLICITE. EXTREME CONDIŢIONATE. 5 Eerciţii reolvate 5 UNCŢII IMPLICITE EXTREME CONDIŢIONATE Eerciţiul 5 Să se determine şi dacă () este o funcţie definită implicit de ecuaţia ( + ) ( + ) + Soluţie ie ( ) ( + ) ( + ) + ( )R Evident este

Διαβάστε περισσότερα

Asupra unei inegalităţi date la barajul OBMJ 2006

Asupra unei inegalităţi date la barajul OBMJ 2006 Asupra unei inegalităţi date la barajul OBMJ 006 Mircea Lascu şi Cezar Lupu La cel de-al cincilea baraj de Juniori din data de 0 mai 006 a fost dată următoarea inegalitate: Fie x, y, z trei numere reale

Διαβάστε περισσότερα

a n (ζ z 0 ) n. n=1 se numeste partea principala iar seria a n (z z 0 ) n se numeste partea

a n (ζ z 0 ) n. n=1 se numeste partea principala iar seria a n (z z 0 ) n se numeste partea Serii Laurent Definitie. Se numeste serie Laurent o serie de forma Seria n= (z z 0 ) n regulata (tayloriana) = (z z n= 0 ) + n se numeste partea principala iar seria se numeste partea Sa presupunem ca,

Διαβάστε περισσότερα

III. Serii absolut convergente. Serii semiconvergente. ii) semiconvergentă dacă este convergentă iar seria modulelor divergentă.

III. Serii absolut convergente. Serii semiconvergente. ii) semiconvergentă dacă este convergentă iar seria modulelor divergentă. III. Serii absolut convergente. Serii semiconvergente. Definiţie. O serie a n se numeşte: i) absolut convergentă dacă seria modulelor a n este convergentă; ii) semiconvergentă dacă este convergentă iar

Διαβάστε περισσότερα

Seminar 5 Analiza stabilității sistemelor liniare

Seminar 5 Analiza stabilității sistemelor liniare Seminar 5 Analiza stabilității sistemelor liniare Noțiuni teoretice Criteriul Hurwitz de analiză a stabilității sistemelor liniare În cazul sistemelor liniare, stabilitatea este o condiție de localizare

Διαβάστε περισσότερα

DISTANŢA DINTRE DOUĂ DREPTE NECOPLANARE

DISTANŢA DINTRE DOUĂ DREPTE NECOPLANARE DISTANŢA DINTRE DOUĂ DREPTE NECOPLANARE ABSTRACT. Materialul prezintă o modalitate de a afla distanţa dintre două drepte necoplanare folosind volumul tetraedrului. Lecţia se adresează clasei a VIII-a Data:

Διαβάστε περισσότερα

V.7. Condiţii necesare de optimalitate cazul funcţiilor diferenţiabile

V.7. Condiţii necesare de optimalitate cazul funcţiilor diferenţiabile Metode de Optimizare Curs V.7. Condiţii necesare de optimalitate cazul funcţiilor diferenţiabile Propoziţie 7. (Fritz-John). Fie X o submulţime deschisă a lui R n, f:x R o funcţie de clasă C şi ϕ = (ϕ,ϕ

Διαβάστε περισσότερα

Subiecte Clasa a VIII-a

Subiecte Clasa a VIII-a Subiecte lasa a VIII-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate pe foaia de raspuns in dreptul

Διαβάστε περισσότερα

Metode de interpolare bazate pe diferenţe divizate

Metode de interpolare bazate pe diferenţe divizate Metode de interpolare bazate pe diferenţe divizate Radu Trîmbiţaş 4 octombrie 2005 1 Forma Newton a polinomului de interpolare Lagrange Algoritmul nostru se bazează pe forma Newton a polinomului de interpolare

Διαβάστε περισσότερα

Analiza în curent continuu a schemelor electronice Eugenie Posdărăscu - DCE SEM 1 electronica.geniu.ro

Analiza în curent continuu a schemelor electronice Eugenie Posdărăscu - DCE SEM 1 electronica.geniu.ro Analiza în curent continuu a schemelor electronice Eugenie Posdărăscu - DCE SEM Seminar S ANALA ÎN CUENT CONTNUU A SCHEMELO ELECTONCE S. ntroducere Pentru a analiza în curent continuu o schemă electronică,

Διαβάστε περισσότερα

Subiecte Clasa a VII-a

Subiecte Clasa a VII-a lasa a VII Lumina Math Intrebari Subiecte lasa a VII-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate

Διαβάστε περισσότερα

Curs 1 Şiruri de numere reale

Curs 1 Şiruri de numere reale Bibliografie G. Chiorescu, Analiză matematică. Teorie şi probleme. Calcul diferenţial, Editura PIM, Iaşi, 2006. R. Luca-Tudorache, Analiză matematică, Editura Tehnopress, Iaşi, 2005. M. Nicolescu, N. Roşculeţ,

Διαβάστε περισσότερα

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor X) functia f 1

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor X) functia f 1 Functii definitie proprietati grafic functii elementare A. Definitii proprietatile functiilor. Fiind date doua multimi X si Y spunem ca am definit o functie (aplicatie) pe X cu valori in Y daca fiecarui

Διαβάστε περισσότερα

Aplicaţii ale principiului I al termodinamicii la gazul ideal

Aplicaţii ale principiului I al termodinamicii la gazul ideal Aplicaţii ale principiului I al termodinamicii la gazul ideal Principiul I al termodinamicii exprimă legea conservării şi energiei dintr-o formă în alta şi se exprimă prin relaţia: ΔUQ-L, unde: ΔU-variaţia

Διαβάστε περισσότερα

R R, f ( x) = x 7x+ 6. Determinați distanța dintre punctele de. B=, unde x și y sunt numere reale.

R R, f ( x) = x 7x+ 6. Determinați distanța dintre punctele de. B=, unde x și y sunt numere reale. 5p Determinați primul termen al progresiei geometrice ( b n ) n, știind că b 5 = 48 și b 8 = 84 5p Se consideră funcția f : intersecție a graficului funcției f cu aa O R R, f ( ) = 7+ 6 Determinați distanța

Διαβάστε περισσότερα

SEMINAR 14. Funcţii de mai multe variabile (continuare) ( = 1 z(x,y) x = 0. x = f. x + f. y = f. = x. = 1 y. y = x ( y = = 0

SEMINAR 14. Funcţii de mai multe variabile (continuare) ( = 1 z(x,y) x = 0. x = f. x + f. y = f. = x. = 1 y. y = x ( y = = 0 Facultatea de Hidrotehnică, Geodezie şi Ingineria Mediului Matematici Superioare, Semestrul I, Lector dr. Lucian MATICIUC SEMINAR 4 Funcţii de mai multe variabile continuare). Să se arate că funcţia z,

Διαβάστε περισσότερα

SERII NUMERICE. Definiţia 3.1. Fie (a n ) n n0 (n 0 IN) un şir de numere reale şi (s n ) n n0

SERII NUMERICE. Definiţia 3.1. Fie (a n ) n n0 (n 0 IN) un şir de numere reale şi (s n ) n n0 SERII NUMERICE Definiţia 3.1. Fie ( ) n n0 (n 0 IN) un şir de numere reale şi (s n ) n n0 şirul definit prin: s n0 = 0, s n0 +1 = 0 + 0 +1, s n0 +2 = 0 + 0 +1 + 0 +2,.......................................

Διαβάστε περισσότερα

Planul determinat de normală şi un punct Ecuaţia generală Plane paralele Unghi diedru Planul determinat de 3 puncte necoliniare

Planul determinat de normală şi un punct Ecuaţia generală Plane paralele Unghi diedru Planul determinat de 3 puncte necoliniare 1 Planul în spaţiu Ecuaţia generală Plane paralele Unghi diedru 2 Ecuaţia generală Plane paralele Unghi diedru Fie reperul R(O, i, j, k ) în spaţiu. Numim normala a unui plan, un vector perpendicular pe

Διαβάστε περισσότερα

Subiecte Clasa a V-a

Subiecte Clasa a V-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate pe foaia de raspuns in dreptul numarului intrebarii

Διαβάστε περισσότερα

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor. Fiind date doua multimi si spunem ca am definit o functie (aplicatie) pe cu valori in daca fiecarui element

Διαβάστε περισσότερα

Criptosisteme cu cheie publică III

Criptosisteme cu cheie publică III Criptosisteme cu cheie publică III Anul II Aprilie 2017 Problema rucsacului ( knapsack problem ) Considerăm un număr natural V > 0 şi o mulţime finită de numere naturale pozitive {v 0, v 1,..., v k 1 }.

Διαβάστε περισσότερα

Esalonul Redus pe Linii (ERL). Subspatii.

Esalonul Redus pe Linii (ERL). Subspatii. Seminarul 1 Esalonul Redus pe Linii (ERL). Subspatii. 1.1 Breviar teoretic 1.1.1 Esalonul Redus pe Linii (ERL) Definitia 1. O matrice A L R mxn este in forma de Esalon Redus pe Linii (ERL), daca indeplineste

Διαβάστε περισσότερα

1.3 Baza a unui spaţiu vectorial. Dimensiune

1.3 Baza a unui spaţiu vectorial. Dimensiune .3 Baza a unui spaţiu vectorial. Dimensiune Definiţia.3. Se numeşte bază a spaţiului vectorial V o familie de vectori B care îndeplineşte condiţiile de mai jos: a) B este liniar independentă; b) B este

Διαβάστε περισσότερα

Sisteme de numeraţie

Sisteme de numeraţie Sisteme de numeraţie F.Boian, Bazele matematice ale calculatoarelor, UBB Cluj-Napoca, 2002 Sistem de numeraţie - totalitatea regulilor folosite pentru scrierea numerelor cu ajutorul unor simboluri (cifre).

Διαβάστε περισσότερα

Integrala nedefinită (primitive)

Integrala nedefinită (primitive) nedefinita nedefinită (primitive) nedefinita 2 nedefinita februarie 20 nedefinita.tabelul primitivelor Definiţia Fie f : J R, J R un interval. Funcţia F : J R se numeşte primitivă sau antiderivată a funcţiei

Διαβάστε περισσότερα

Curs 2 Şiruri de numere reale

Curs 2 Şiruri de numere reale Curs 2 Şiruri de numere reale Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi" Iaşi 2014 Convergenţă şi mărginire Teoremă Orice şir convergent este mărginit. Demonstraţie Fie (x n ) n 0 un

Διαβάστε περισσότερα

Seminariile Capitolul X. Integrale Curbilinii: Serii Laurent şi Teorema Reziduurilor

Seminariile Capitolul X. Integrale Curbilinii: Serii Laurent şi Teorema Reziduurilor Facultatea de Matematică Calcul Integral şi Elemente de Analiă Complexă, Semestrul I Lector dr. Lucian MATICIUC Seminariile 9 20 Capitolul X. Integrale Curbilinii: Serii Laurent şi Teorema Reiduurilor.

Διαβάστε περισσότερα

COLEGIUL NATIONAL CONSTANTIN CARABELLA TARGOVISTE. CONCURSUL JUDETEAN DE MATEMATICA CEZAR IVANESCU Editia a VI-a 26 februarie 2005.

COLEGIUL NATIONAL CONSTANTIN CARABELLA TARGOVISTE. CONCURSUL JUDETEAN DE MATEMATICA CEZAR IVANESCU Editia a VI-a 26 februarie 2005. SUBIECTUL Editia a VI-a 6 februarie 005 CLASA a V-a Fie A = x N 005 x 007 si B = y N y 003 005 3 3 a) Specificati cel mai mic element al multimii A si cel mai mare element al multimii B. b)stabiliti care

Διαβάστε περισσότερα

Lucrare. Varianta aprilie I 1 Definiţi noţiunile de număr prim şi număr ireductibil. Soluţie. Vezi Curs 6 Definiţiile 1 şi 2. sau p b.

Lucrare. Varianta aprilie I 1 Definiţi noţiunile de număr prim şi număr ireductibil. Soluţie. Vezi Curs 6 Definiţiile 1 şi 2. sau p b. Lucrare Soluţii 28 aprilie 2015 Varianta 1 I 1 Definiţi noţiunile de număr prim şi număr ireductibil. Soluţie. Vezi Curs 6 Definiţiile 1 şi 2 Definiţie. Numărul întreg p se numeşte număr prim dacă p 0,

Διαβάστε περισσότερα

Lectia VI Structura de spatiu an E 3. Dreapta si planul ca subspatii ane

Lectia VI Structura de spatiu an E 3. Dreapta si planul ca subspatii ane Subspatii ane Lectia VI Structura de spatiu an E 3. Dreapta si planul ca subspatii ane Oana Constantinescu Oana Constantinescu Lectia VI Subspatii ane Table of Contents 1 Structura de spatiu an E 3 2 Subspatii

Διαβάστε περισσότερα

a. 11 % b. 12 % c. 13 % d. 14 %

a. 11 % b. 12 % c. 13 % d. 14 % 1. Un motor termic funcţionează după ciclul termodinamic reprezentat în sistemul de coordonate V-T în figura alăturată. Motorul termic utilizează ca substanţă de lucru un mol de gaz ideal având exponentul

Διαβάστε περισσότερα

5.5. REZOLVAREA CIRCUITELOR CU TRANZISTOARE BIPOLARE

5.5. REZOLVAREA CIRCUITELOR CU TRANZISTOARE BIPOLARE 5.5. A CIRCUITELOR CU TRANZISTOARE BIPOLARE PROBLEMA 1. În circuitul din figura 5.54 se cunosc valorile: μa a. Valoarea intensității curentului de colector I C. b. Valoarea tensiunii bază-emitor U BE.

Διαβάστε περισσότερα

Sisteme diferenţiale liniare de ordinul 1

Sisteme diferenţiale liniare de ordinul 1 1 Metoda eliminării 2 Cazul valorilor proprii reale Cazul valorilor proprii nereale 3 Catedra de Matematică 2011 Forma generală a unui sistem liniar Considerăm sistemul y 1 (x) = a 11y 1 (x) + a 12 y 2

Διαβάστε περισσότερα

Principiul Inductiei Matematice.

Principiul Inductiei Matematice. Principiul Inductiei Matematice. Principiul inductiei matematice constituie un mijloc important de demonstratie in matematica a propozitiilor (afirmatiilor) ce depind de argument natural. Metoda inductiei

Διαβάστε περισσότερα

1. Reprezentarea numerelor şi operaţii aritmetice în sisteme de calcul.

1. Reprezentarea numerelor şi operaţii aritmetice în sisteme de calcul. 1. Reprezentarea numerelor şi operaţii aritmetice în sisteme de calcul. 1.1. Sisteme de reprezentare ale numerelor: a) Sistemul zecimal: baza sistemului este 10 simbolii (digiţi) sistemului sunt cifrele

Διαβάστε περισσότερα

Capitolul 4. Integrale improprii Integrale cu limite de integrare infinite

Capitolul 4. Integrale improprii Integrale cu limite de integrare infinite Capitolul 4 Integrale improprii 7-8 În cadrul studiului integrabilităţii iemann a unei funcţii s-au evidenţiat douăcondiţii esenţiale:. funcţia :[ ] este definită peintervalînchis şi mărginit (interval

Διαβάστε περισσότερα

5.4. MULTIPLEXOARE A 0 A 1 A 2

5.4. MULTIPLEXOARE A 0 A 1 A 2 5.4. MULTIPLEXOARE Multiplexoarele (MUX) sunt circuite logice combinaţionale cu m intrări şi o singură ieşire, care permit transferul datelor de la una din intrări spre ieşirea unică. Selecţia intrării

Διαβάστε περισσότερα

2. Circuite logice 2.5. Sumatoare şi multiplicatoare. Copyright Paul GASNER

2. Circuite logice 2.5. Sumatoare şi multiplicatoare. Copyright Paul GASNER 2. Circuite logice 2.5. Sumatoare şi multiplicatoare Copyright Paul GASNER Adunarea în sistemul binar Adunarea se poate efectua în mod identic ca la adunarea obişnuită cu cifre arabe în sistemul zecimal

Διαβάστε περισσότερα

Ecuatii exponentiale. Ecuatia ce contine variabila necunoscuta la exponentul puterii se numeste ecuatie exponentiala. a x = b, (1)

Ecuatii exponentiale. Ecuatia ce contine variabila necunoscuta la exponentul puterii se numeste ecuatie exponentiala. a x = b, (1) Ecuatii exponentiale Ecuatia ce contine variabila necunoscuta la exponentul puterii se numeste ecuatie exponentiala. Cea mai simpla ecuatie exponentiala este de forma a x = b, () unde a >, a. Afirmatia.

Διαβάστε περισσότερα

Laborator 1: INTRODUCERE ÎN ALGORITMI. Întocmit de: Claudia Pârloagă. Îndrumător: Asist. Drd. Gabriel Danciu

Laborator 1: INTRODUCERE ÎN ALGORITMI. Întocmit de: Claudia Pârloagă. Îndrumător: Asist. Drd. Gabriel Danciu INTRODUCERE Laborator 1: ÎN ALGORITMI Întocmit de: Claudia Pârloagă Îndrumător: Asist. Drd. Gabriel Danciu I. NOŢIUNI TEORETICE A. Sortarea prin selecţie Date de intrare: un şir A, de date Date de ieşire:

Διαβάστε περισσότερα

riptografie şi Securitate

riptografie şi Securitate riptografie şi Securitate - Prelegerea 12 - Scheme de criptare CCA sigure Adela Georgescu, Ruxandra F. Olimid Facultatea de Matematică şi Informatică Universitatea din Bucureşti Cuprins 1. Schemă de criptare

Διαβάστε περισσότερα

Al cincilea baraj de selecţie pentru OBMJ Bucureşti, 28 mai 2015

Al cincilea baraj de selecţie pentru OBMJ Bucureşti, 28 mai 2015 Societatea de Ştiinţe Matematice din România Ministerul Educaţiei Naţionale Al cincilea baraj de selecţie pentru OBMJ Bucureşti, 28 mai 2015 Problema 1. Arătaţi că numărul 1 se poate reprezenta ca suma

Διαβάστε περισσότερα

Laborator 11. Mulţimi Julia. Temă

Laborator 11. Mulţimi Julia. Temă Laborator 11 Mulţimi Julia. Temă 1. Clasa JuliaGreen. Să considerăm clasa JuliaGreen dată de exemplu la curs pentru metoda locului final şi să schimbăm numărul de iteraţii nriter = 100 în nriter = 101.

Διαβάστε περισσότερα

Functii Breviar teoretic 8 ianuarie ianuarie 2011

Functii Breviar teoretic 8 ianuarie ianuarie 2011 Functii Breviar teoretic 8 ianuarie 011 15 ianuarie 011 I Fie I, interval si f : I 1) a) functia f este (strict) crescatoare pe I daca x, y I, x< y ( f( x) < f( y)), f( x) f( y) b) functia f este (strict)

Διαβάστε περισσότερα

10 REPREZENTAREA DIGITALĂ

10 REPREZENTAREA DIGITALĂ 10 REPREZENTAREA DIGITALĂ 10.1 Niveluri logice În reprezentarea digitală pentru exprimarea cantitativă a informaţiei se folosesc semnale electrice care pot avea doar două niveluri de tensiune: un nivel

Διαβάστε περισσότερα

Definiţia generală Cazul 1. Elipsa şi hiperbola Cercul Cazul 2. Parabola Reprezentari parametrice ale conicelor Tangente la conice

Definiţia generală Cazul 1. Elipsa şi hiperbola Cercul Cazul 2. Parabola Reprezentari parametrice ale conicelor Tangente la conice 1 Conice pe ecuaţii reduse 2 Conice pe ecuaţii reduse Definiţie Numim conica locul geometric al punctelor din plan pentru care raportul distantelor la un punct fix F şi la o dreaptă fixă (D) este o constantă

Διαβάστε περισσότερα

Progresii aritmetice si geometrice. Progresia aritmetica.

Progresii aritmetice si geometrice. Progresia aritmetica. Progresii aritmetice si geometrice Progresia aritmetica. Definitia 1. Sirul numeric (a n ) n N se numeste progresie aritmetica, daca exista un numar real d, numit ratia progresia, astfel incat a n+1 a

Διαβάστε περισσότερα

Capitolul 4 PROPRIETĂŢI TOPOLOGICE ŞI DE NUMĂRARE ALE LUI R. 4.1 Proprietăţi topologice ale lui R Puncte de acumulare

Capitolul 4 PROPRIETĂŢI TOPOLOGICE ŞI DE NUMĂRARE ALE LUI R. 4.1 Proprietăţi topologice ale lui R Puncte de acumulare Capitolul 4 PROPRIETĂŢI TOPOLOGICE ŞI DE NUMĂRARE ALE LUI R În cele ce urmează, vom studia unele proprietăţi ale mulţimilor din R. Astfel, vom caracteriza locul" unui punct în cadrul unei mulţimi (în limba

Διαβάστε περισσότερα

Spatii liniare. Exemple Subspaţiu liniar Acoperire (înfăşurătoare) liniară. Mulţime infinită liniar independentă

Spatii liniare. Exemple Subspaţiu liniar Acoperire (înfăşurătoare) liniară. Mulţime infinită liniar independentă Noţiunea de spaţiu liniar 1 Noţiunea de spaţiu liniar Exemple Subspaţiu liniar Acoperire (înfăşurătoare) liniară 2 Mulţime infinită liniar independentă 3 Schimbarea coordonatelor unui vector la o schimbare

Διαβάστε περισσότερα

BARAJ DE JUNIORI,,Euclid Cipru, 28 mai 2012 (barajul 3)

BARAJ DE JUNIORI,,Euclid Cipru, 28 mai 2012 (barajul 3) BARAJ DE JUNIORI,,Euclid Cipru, 8 mi 0 (brjul ) Problem Arătţi că dcă, b, c sunt numere rele cre verifică + b + c =, tunci re loc ineglitte xy + yz + zx Problem Fie şi b numere nturle nenule Dcă numărul

Διαβάστε περισσότερα

Cursul Măsuri reale. D.Rusu, Teoria măsurii şi integrala Lebesgue 15

Cursul Măsuri reale. D.Rusu, Teoria măsurii şi integrala Lebesgue 15 MĂSURI RELE Cursul 13 15 Măsuri reale Fie (,, µ) un spaţiu cu măsură completă şi f : R o funcţie -măsurabilă. Cum am văzut în Teorema 11.29, dacă f are integrală pe, atunci funcţia de mulţime ν : R, ν()

Διαβάστε περισσότερα

III.2.2. Reprezentarea în virgulă mobilă

III.2.2. Reprezentarea în virgulă mobilă III... Reprezentarea în virgulă mobilă Una dintre cele mai răspândite reprezentări internă (în PC-uri) a numerelor reale este reprezentarea în virgulă mobilă. Reprezentarea în virgulă mobilă presupune

Διαβάστε περισσότερα

4. CIRCUITE LOGICE ELEMENTRE 4.. CIRCUITE LOGICE CU COMPONENTE DISCRETE 4.. PORŢI LOGICE ELEMENTRE CU COMPONENTE PSIVE Componente electronice pasive sunt componente care nu au capacitatea de a amplifica

Διαβάστε περισσότερα

2. Sisteme de forţe concurente...1 Cuprins...1 Introducere Aspecte teoretice Aplicaţii rezolvate...3

2. Sisteme de forţe concurente...1 Cuprins...1 Introducere Aspecte teoretice Aplicaţii rezolvate...3 SEMINAR 2 SISTEME DE FRŢE CNCURENTE CUPRINS 2. Sisteme de forţe concurente...1 Cuprins...1 Introducere...1 2.1. Aspecte teoretice...2 2.2. Aplicaţii rezolvate...3 2. Sisteme de forţe concurente În acest

Διαβάστε περισσότερα

Matrice. Determinanti. Sisteme liniare

Matrice. Determinanti. Sisteme liniare Matrice 1 Matrice Adunarea matricelor Înmulţirea cu scalar. Produsul 2 Proprietăţi ale determinanţilor Rangul unei matrice 3 neomogene omogene Metoda lui Gauss (Metoda eliminării) Notiunea de matrice Matrice

Διαβάστε περισσότερα

Concurs MATE-INFO UBB, 1 aprilie 2017 Proba scrisă la MATEMATICĂ

Concurs MATE-INFO UBB, 1 aprilie 2017 Proba scrisă la MATEMATICĂ UNIVERSITATEA BABEŞ-BOLYAI CLUJ-NAPOCA FACULTATEA DE MATEMATICĂ ŞI INFORMATICĂ Concurs MATE-INFO UBB, aprilie 7 Proba scrisă la MATEMATICĂ SUBIECTUL I (3 puncte) ) (5 puncte) Fie matricele A = 3 4 9 8

Διαβάστε περισσότερα

Ecuatii trigonometrice

Ecuatii trigonometrice Ecuatii trigonometrice Ecuatiile ce contin necunoscute sub semnul functiilor trigonometrice se numesc ecuatii trigonometrice. Cele mai simple ecuatii trigonometrice sunt ecuatiile de tipul sin x = a, cos

Διαβάστε περισσότερα

Să se arate că n este număr par. Dan Nedeianu

Să se arate că n este număr par. Dan Nedeianu Primul test de selecție pentru juniori I. Să se determine numerele prime p, q, r cu proprietatea că 1 p + 1 q + 1 r 1. Fie ABCD un patrulater convex cu m( BCD) = 10, m( CBA) = 45, m( CBD) = 15 și m( CAB)

Διαβάστε περισσότερα

MULTIMEA NUMERELOR REALE

MULTIMEA NUMERELOR REALE www.webmteinfo.com cu noi totul pre mi usor MULTIMEA NUMERELOR REALE office@ webmteinfo.com 1.1 Rdcin ptrt unui numr nturl ptrt perfect Ptrtul unui numr rtionl este totdeun pozitiv su zero (dic nenegtiv).

Διαβάστε περισσότερα

2.1 Sfera. (EGS) ecuaţie care poartă denumirea de ecuaţia generală asferei. (EGS) reprezintă osferă cu centrul în punctul. 2 + p 2

2.1 Sfera. (EGS) ecuaţie care poartă denumirea de ecuaţia generală asferei. (EGS) reprezintă osferă cu centrul în punctul. 2 + p 2 .1 Sfera Definitia 1.1 Se numeşte sferă mulţimea tuturor punctelor din spaţiu pentru care distanţa la u punct fi numit centrul sferei este egalăcuunnumăr numit raza sferei. Fie centrul sferei C (a, b,

Διαβάστε περισσότερα

1.7. AMPLIFICATOARE DE PUTERE ÎN CLASA A ŞI AB

1.7. AMPLIFICATOARE DE PUTERE ÎN CLASA A ŞI AB 1.7. AMLFCATOARE DE UTERE ÎN CLASA A Ş AB 1.7.1 Amplificatoare în clasa A La amplificatoarele din clasa A, forma de undă a tensiunii de ieşire este aceeaşi ca a tensiunii de intrare, deci întreg semnalul

Διαβάστε περισσότερα

Fig Impedanţa condensatoarelor electrolitice SMD cu Al cu electrolit semiuscat în funcţie de frecvenţă [36].

Fig Impedanţa condensatoarelor electrolitice SMD cu Al cu electrolit semiuscat în funcţie de frecvenţă [36]. Componente şi circuite pasive Fig.3.85. Impedanţa condensatoarelor electrolitice SMD cu Al cu electrolit semiuscat în funcţie de frecvenţă [36]. Fig.3.86. Rezistenţa serie echivalentă pierderilor în funcţie

Διαβάστε περισσότερα

Seminar Algebra. det(a λi 3 ) = 0

Seminar Algebra. det(a λi 3 ) = 0 Rezolvari ale unor probleme propuse "Matematica const în a dovedi ceea ce este evident în cel mai puµin evident mod." George Polya P/Seminar Valori si vectori proprii : Solutie: ( ) a) A = Valorile proprii:

Διαβάστε περισσότερα

Ovidiu Gabriel Avădănei, Florin Mihai Tufescu,

Ovidiu Gabriel Avădănei, Florin Mihai Tufescu, vidiu Gabriel Avădănei, Florin Mihai Tufescu, Capitolul 6 Amplificatoare operaţionale 58. Să se calculeze coeficientul de amplificare în tensiune pentru amplficatorul inversor din fig.58, pentru care se

Διαβάστε περισσότερα

Valori limită privind SO2, NOx şi emisiile de praf rezultate din operarea LPC în funcţie de diferite tipuri de combustibili

Valori limită privind SO2, NOx şi emisiile de praf rezultate din operarea LPC în funcţie de diferite tipuri de combustibili Anexa 2.6.2-1 SO2, NOx şi de praf rezultate din operarea LPC în funcţie de diferite tipuri de combustibili de bioxid de sulf combustibil solid (mg/nm 3 ), conţinut de O 2 de 6% în gazele de ardere, pentru

Διαβάστε περισσότερα

Problema a II - a (10 puncte) Diferite circuite electrice

Problema a II - a (10 puncte) Diferite circuite electrice Olimpiada de Fizică - Etapa pe judeţ 15 ianuarie 211 XI Problema a II - a (1 puncte) Diferite circuite electrice A. Un elev utilizează o sursă de tensiune (1), o cutie cu rezistenţe (2), un întrerupător

Διαβάστε περισσότερα

Examen AG. Student:... Grupa:... ianuarie 2011

Examen AG. Student:... Grupa:... ianuarie 2011 Problema 1. Pentru ce valori ale lui n,m N (n,m 1) graful K n,m este eulerian? Problema 2. Să se construiască o funcţie care să recunoască un graf P 3 -free. La intrare aceasta va primi un graf G = ({1,...,n},E)

Διαβάστε περισσότερα

Conice. Lect. dr. Constantin-Cosmin Todea. U.T. Cluj-Napoca

Conice. Lect. dr. Constantin-Cosmin Todea. U.T. Cluj-Napoca Conice Lect. dr. Constantin-Cosmin Todea U.T. Cluj-Napoca Definiţie: Se numeşte curbă algebrică plană mulţimea punctelor din plan de ecuaţie implicită de forma (C) : F (x, y) = 0 în care funcţia F este

Διαβάστε περισσότερα

4. Măsurarea tensiunilor şi a curenţilor electrici. Voltmetre electronice analogice

4. Măsurarea tensiunilor şi a curenţilor electrici. Voltmetre electronice analogice 4. Măsurarea tensiunilor şi a curenţilor electrici oltmetre electronice analogice oltmetre de curent continuu Ampl.c.c. x FTJ Protectie Atenuator calibrat Atenuatorul calibrat divizor rezistiv R in const.

Διαβάστε περισσότερα

Conice - Câteva proprietǎţi elementare

Conice - Câteva proprietǎţi elementare Conice - Câteva proprietǎţi elementare lect.dr. Mihai Chiş Facultatea de Matematicǎ şi Informaticǎ Universitatea de Vest din Timişoara Viitori Olimpici ediţia a 5-a, etapa I, clasa a XII-a 1 Definiţii

Διαβάστε περισσότερα

10. STABILIZATOAE DE TENSIUNE 10.1 STABILIZATOAE DE TENSIUNE CU TANZISTOAE BIPOLAE Stabilizatorul de tensiune cu tranzistor compară în permanenţă valoare tensiunii de ieşire (stabilizate) cu tensiunea

Διαβάστε περισσότερα

Principiul incluziunii si excluziunii. Generarea şi ordonarea permutărilor. Principiul porumbeilor. Pri

Principiul incluziunii si excluziunii. Generarea şi ordonarea permutărilor. Principiul porumbeilor. Pri Generarea şi ordonarea permutărilor. Principiul porumbeilor. Principiul incluziunii si excluziunii Recapitulare din cursul trecut Presupunem că A este o mulţime cu n elemente. Recapitulare din cursul trecut

Διαβάστε περισσότερα

Examen AG. Student:... Grupa: ianuarie 2016

Examen AG. Student:... Grupa: ianuarie 2016 16-17 ianuarie 2016 Problema 1. Se consideră graful G = pk n (p, n N, p 2, n 3). Unul din vârfurile lui G se uneşte cu câte un vârf din fiecare graf complet care nu-l conţine, obţinându-se un graf conex

Διαβάστε περισσότερα

Subiecte Clasa a VIII-a

Subiecte Clasa a VIII-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate pe foaia de raspuns in dreptul numarului intrebarii

Διαβάστε περισσότερα

Lucrarea de laborator nr. 2

Lucrarea de laborator nr. 2 Metode Numerice Lucrarea de laborator nr. I. Scopul lucrării Reprezentarea numerelor reale în calculator. Erori de rotunjire. II. III. Conţinutul lucrării. Reprezentarea numerelor reale sub formă normalizată..

Διαβάστε περισσότερα

RĂSPUNS Modulul de rezistenţă este o caracteristică geometrică a secţiunii transversale, scrisă faţă de una dintre axele de inerţie principale:,

RĂSPUNS Modulul de rezistenţă este o caracteristică geometrică a secţiunii transversale, scrisă faţă de una dintre axele de inerţie principale:, REZISTENTA MATERIALELOR 1. Ce este modulul de rezistenţă? Exemplificaţi pentru o secţiune dreptunghiulară, respectiv dublu T. RĂSPUNS Modulul de rezistenţă este o caracteristică geometrică a secţiunii

Διαβάστε περισσότερα

CURS XI XII SINTEZĂ. 1 Algebra vectorială a vectorilor liberi

CURS XI XII SINTEZĂ. 1 Algebra vectorială a vectorilor liberi Lect. dr. Facultatea de Electronică, Telecomunicaţii şi Tehnologia Informaţiei Algebră, Semestrul I, Lector dr. Lucian MATICIUC http://math.etti.tuiasi.ro/maticiuc/ CURS XI XII SINTEZĂ 1 Algebra vectorială

Διαβάστε περισσότερα

Orice izometrie f : (X, d 1 ) (Y, d 2 ) este un homeomorfism. (Y = f(x)).

Orice izometrie f : (X, d 1 ) (Y, d 2 ) este un homeomorfism. (Y = f(x)). Teoremă. (Y = f(x)). Orice izometrie f : (X, d 1 ) (Y, d 2 ) este un homeomorfism Demonstraţie. f este continuă pe X: x 0 X, S Y (f(x 0 ), ε), S X (x 0, ε) aşa ca f(s X (x 0, ε)) = S Y (f(x 0 ), ε) : y

Διαβάστε περισσότερα

8 Intervale de încredere

8 Intervale de încredere 8 Intervale de încredere În cursul anterior am determinat diverse estimări ˆ ale parametrului necunoscut al densităţii unei populaţii, folosind o selecţie 1 a acestei populaţii. În practică, valoarea calculată

Διαβάστε περισσότερα

Tranzistoare bipolare şi cu efect de câmp

Tranzistoare bipolare şi cu efect de câmp apitolul 3 apitolul 3 26. Pentru circuitul de polarizare din fig. 26 se cunosc: = 5, = 5, = 2KΩ, = 5KΩ, iar pentru tranzistor se cunosc următorii parametrii: β = 200, 0 = 0, μa, = 0,6. a) ă se determine

Διαβάστε περισσότερα

Limbaje de Programare Curs 3 Iteraţia. Reprezentare internă. Operatori pe biţi

Limbaje de Programare Curs 3 Iteraţia. Reprezentare internă. Operatori pe biţi Limbaje de Programare Curs 3 Iteraţia. Reprezentare internă. Operatori pe biţi Dr. Casandra Holotescu Universitatea Politehnica Timişoara Ce discutăm azi... 1 Iteraţia 2 Reprezentare internă 3 Operaţii

Διαβάστε περισσότερα

z a + c 0 + c 1 (z a)

z a + c 0 + c 1 (z a) 1 Serii Laurent (continuare) Teorema 1.1 Fie D C un domeniu, a D şi f : D \ {a} C o funcţie olomorfă. Punctul a este pol multiplu de ordin p al lui f dacă şi numai dacă dezvoltarea în serie Laurent a funcţiei

Διαβάστε περισσότερα

V O. = v I v stabilizator

V O. = v I v stabilizator Stabilizatoare de tensiune continuă Un stabilizator de tensiune este un circuit electronic care păstrează (aproape) constantă tensiunea de ieșire la variaţia între anumite limite a tensiunii de intrare,

Διαβάστε περισσότερα

a) (3p) Sa se calculeze XY A. b) (4p) Sa se calculeze determinantul si rangul matricei A. c) (3p) Sa se calculeze A.

a) (3p) Sa se calculeze XY A. b) (4p) Sa se calculeze determinantul si rangul matricei A. c) (3p) Sa se calculeze A. Bac Variata Proil: mate-izica, iormatica, metrologie Subiectul I (3 p) Se cosidera matricele: X =, Y = ( ) si A= a) (3p) Sa se calculeze XY A b) (4p) Sa se calculeze determiatul si ragul matricei A c)

Διαβάστε περισσότερα

VII.2. PROBLEME REZOLVATE

VII.2. PROBLEME REZOLVATE Teoria Circuitelor Electrice Aplicaţii V PROBEME REOVATE R7 În circuitul din fiura 7R se cunosc: R e t 0 sint [V] C C t 0 sint [A] Se cer: a rezolvarea circuitului cu metoda teoremelor Kirchhoff; rezolvarea

Διαβάστε περισσότερα

2 Transformări liniare între spaţii finit dimensionale

2 Transformări liniare între spaţii finit dimensionale Transformări 1 Noţiunea de transformare liniară Proprietăţi. Operaţii Nucleul şi imagine Rangul şi defectul unei transformări 2 Matricea unei transformări Relaţia dintre rang şi defect Schimbarea matricei

Διαβάστε περισσότερα

Capitolul 3. Serii Fourier. a unei funcţii periodice de perioadă Dezvoltarea în serie Fourier

Capitolul 3. Serii Fourier. a unei funcţii periodice de perioadă Dezvoltarea în serie Fourier Capitolul Serii Fourier 7-8. Dezvoltarea în serie Fourier a unei funcţii periodice de perioadă Pornind de la discuţia asupra coardei vibrante începută în anii 75 între Euler şi d Alembert, se ajunge la

Διαβάστε περισσότερα

6 n=1. cos 2n. 6 n=1. n=1. este CONV (fiind seria armonică pentru α = 6 > 1), rezultă

6 n=1. cos 2n. 6 n=1. n=1. este CONV (fiind seria armonică pentru α = 6 > 1), rezultă Semiar 5 Serii cu termei oarecare Probleme rezolvate Problema 5 Să se determie atura seriei cos 5 cos Soluţie 5 Şirul a 5 este cu termei oarecare Studiem absolut covergeţa seriei Petru că cos a 5 5 5 şi

Διαβάστε περισσότερα

O generalizare a unei probleme de algebră dată la Olimpiada de Matematică, faza judeţeană, 2013

O generalizare a unei probleme de algebră dată la Olimpiada de Matematică, faza judeţeană, 2013 O generalizare a unei probleme de algebră dată la Olimpiada de Matematică, faza judeţeană, 2013 Marius Tărnăuceanu 1 Aprilie 2013 Abstract În această lucrare vom prezenta un rezultat ce extinde Problema

Διαβάστε περισσότερα

Sisteme liniare - metode directe

Sisteme liniare - metode directe Sisteme liniare - metode directe Radu T. Trîmbiţaş 27 martie 2016 1 Eliminare gaussiană Să considerăm sistemul liniar cu n ecuaţii şi n necunoscute Ax = b, (1) unde A K n n, b K n 1 sunt date, iar x K

Διαβάστε περισσότερα

Codificatorul SN74148 este un codificator zecimal-bcd de trei biţi (fig ). Figura Codificatorul integrat SN74148

Codificatorul SN74148 este un codificator zecimal-bcd de trei biţi (fig ). Figura Codificatorul integrat SN74148 5.2. CODIFICATOAE Codificatoarele (CD) sunt circuite logice combinaţionale cu n intrări şi m ieşiri care furnizează la ieşire un cod de m biţi atunci când numai una din cele n intrări este activă. De regulă

Διαβάστε περισσότερα

Concurs MATE-INFO UBB, 25 martie 2018 Proba scrisă la MATEMATICĂ

Concurs MATE-INFO UBB, 25 martie 2018 Proba scrisă la MATEMATICĂ UNIVERSITATEA BABEŞ-BOLYAI CLUJ-NAPOCA FACULTATEA DE MATEMATICĂ ŞI INFORMATICĂ Concurs MATE-INFO UBB, 5 martie 18 Proba scrisă la MATEMATICĂ NOTĂ IMPORTANTĂ: 1 Problemele tip grilă (Partea A pot avea unul

Διαβάστε περισσότερα

Curs 2 DIODE. CIRCUITE DR

Curs 2 DIODE. CIRCUITE DR Curs 2 OE. CRCUTE R E CUPRN tructură. imbol Relația curent-tensiune Regimuri de funcționare Punct static de funcționare Parametrii diodei Modelul cu cădere de tensiune constantă Analiza circuitelor cu

Διαβάστε περισσότερα