Laborator PC UMC
-
Upload
martin-cezar -
Category
Documents
-
view
57 -
download
1
description
Transcript of Laborator PC UMC
Programarea Calculatoarelor
1
Laborator I
1. REPREZENTAREA INFORMAŢIEI ÎN CALCULATOR.
CODIFICĂRI
Pentru a putea fi prelucrate cu ajutorul calculatorului, informaţiile utilizate în viaţa
cotidiană (imagini, numere, litere, desene, sunete) şi instrucţiunile pe care trebuie să le execute
procesorul calculatorului trebuie să fie reprezentate (codificate) într-un anumit format, acceptat
de calculator. Transformarea informaţiei, din forma de reprezentare externă, ușor de înțeles, în
forma de reprezentare internă pe care o înţelege calculatorul, sub formă de cifre binare, se
numeşte codificare internă a informaţiei. Codificarea informaţiei presupune ca fiecărei entităţi
informaţionale să i se atribuie o secvenţă unică de cifre binare.
Unitatea elementară de reprezentare a informaţiei în calculator este bit-ul (binary digit -
cifră binară), rezultând din faptul că unitățile de stocare elementare într-un calculator sunt
comutatoarele electronice, fiecare comutator având una dintre cele două stări: on (reprezentată de
obicei de 1), sau off (0). Data este deci termenul utilizat pentru a descrie informația reprezentată
de grupurile de comutatoare on/off.
Chiar dacă datele și informațiile sunt cuvinte adesea folosite alternativ, există o distincție
importantă între ele. Datele reprezintă materia primă pe care o prelucrează calculatorul şi
organizează pentru a produce informații.
Datele
- materia primă pentru informaţii.
- atunci când sunt prelucrate, organizate, structurate sau prezentate într-un anumit context,
pentru a le face utile, acestea devin informații.
Informaţii Date
Un grup de 8 biți formează un octet sau byte. Deoarece cifrele binare pot fi combinate în
diverse moduri, cu un octet calculatorul poate reprezenta 256 de simboluri sau caractere diferite.
Byte-ul este extrem de important, deoarece există combinații suficiente de 8-biți pentru a
reprezenta toate caracterele de pe o tastatură. Această reprezentare prin care fiecărei entităţi
informaţionale i se asociază o secvenţă de cifre binare se numește codificare.
caracter pur sintactic
comunicare
(transmitere) Prelucrare: -înregistrare
-filtrare
-sortare
-combinare
-calculare
culegere
codificare
transmitere
Informaţii
elaborate Date
elementare Date
de bază
Informaţii
pertinente
dispun de caracteristici semantice, orientate spre conţinutul şi sensul atribuit reprezentării realităţii.
Programarea Calculatoarelor
2
În funcţie de natura caracterelor pe care le pot reprezenta, sistemele de codificare se pot
grupa în:
- sisteme de codificare numerice;
- sisteme de codificare alfanumerice.
a. Coduri numerice – prin intermediul cărora se pot reprezenta în memoria calculatorului
datele numerice.
b. Coduri alfanumerice – prin intermediul cărora se pot reprezenta în memoria calculatorului
datele alfanumerice. În practică se utilizează trei sisteme de codificarea a caracterelor alfa-
numerice: ASCII ( American Standard Code for Information Interchange), EBCDIC (Extended
Binary Coded Decimal Interchange Code) şi Unicode.
a) Coduri numerice
Pentru a reprezenta datele în calculator și pentru a le putea transmite convenabil între
sistemele de calcul au fost dezvoltate diferite scheme de codificare. Codurile numerice reprezintă
cele 10 cifre zecimale, cu sau fără semn algebric. Acestea pot fi:
► coduri ponderate: fiecare cifră a numărului zecimal este reprezentată printr-un cod binar cu
patru biţi, fiecare rang al secvenţei având asociată o pondere.
Pentru fiecare grup de patru biți, suma ponderilor acelor poziții unde cifra binară este 1
este egală cu cifra zecimală pe care o reprezintă grupul. Deci o cifră zecimală se exprimă
conform formulei:
i
i
i waN
3
1
,
unde ai ∊{0.1} iar reprezintă ponderea asociată poziţiei, conform codului respectiv.
Cele mai cunoscute coduri ponderate sunt:
Codul BCD sau codul 8-4-2-1
Este utilizat pentru reprezentarea numerelor întregi zecimale codificate binar şi are ca
pondere puterile lui 2: 23, 2
2, 2
1, 2
0. Marele său avantaj este uşurinţa conversiei către zecimal.
Reprezentarea unui întreg zecimal se face cu fiecare cifră reprezentată individual,
conform tabelului de mai jos:
cifră zecimală cod BCD
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
Programarea Calculatoarelor
3
Reprezentarea cifrelor zecimale se realizează câte 2 cifre pe un octet - forma împachetată
(cifra zecimală mai puţin semnificativă pe biţii 0 - 3 şi cifra zecimală mai semnificativă pe biţii 4
- 7) sau individual pe câte un octet - forma despachetată (în acest caz, cifra zecimală va fi
reprezentată în biții 0-3, iar primii 4-7 vor fi 0).
De exemplu, se cere reprezentarea în cod BCD a numărului zecimal 5463:
- în format împachetat: 0101 0100 0110 0011
5 4 6 3
16 biţi
- în format despachetat: 00000101 00000100 00000110 00000011
5 4 6 3
32 biţi
Acest cod este mai puţin eficient decât reprezentarea pur binară, în sensul că necesită mai
mulţi biţi în reprezentare. De exemplu, numărul zecimal 21 poate fi reprezentat ca 10101 în binar,
dar în codul 8-4-2-1 se reprezintă ca 00100001.
Obs: pentru reprezentarea în BCD a numerelor cu semn se utilizează un bit suplimentar pentru
semn (primul bit din stânga).
Codul 2-4-2-1
Utilizează ponderile 2, 4, 2 şi 1 în codificare. Codurile pentru cifrele de la 0 la 4 încep cu 0, iar
codurile pentru ultimele cinci cifre, 5 – 9 încep cu 1, conform tabelului de mai jos:
cifră zecimală cod 2-4-2-1
0 0000
1 0001
2 0010
3 0011
4 0100
5 1011
6 1100
7 1101
8 1110
9 1111
► coduri neponderate: biţilor nu li se mai asociază ponderi, trecerea de la o cifră zecimală la
următoarea se face prin modificarea unui singur rang binar.
Cele mai cunoscute coduri neponderate sunt:
Codul EXCESS 3 (XS-3): reprezentarea în acest cod se obţine din reprezentarea în codul 8-4-2-
1 prin adunarea la fiecare grup de patru cifre binare a cifrei 3 reprezentată în binar: 0011,
conform tabelului de mai jos:
Programarea Calculatoarelor
4
cifră zecimală cod XS-3
0 0011
1 0100
2 0101
3 0110
4 0111
5 1000
6 1001
7 1010
8 1011
9 1100
Codul Gray: reprezentarea în acest cod se caracterizează prin faptul că două cifre alăturate au
reprezentări binare ce diferă printr-un singur bit. Secvenţa este circulară:
00 → 01 → 11 → 10 → 00
şi această proprietate face ca acest cod să fie utilizat în aplicaţii pentru detectarea erorilor. De
asemenea, această reprezentare este utilă pentru mărimile care cresc sau descresc succesiv.
Tabelul de mai jos cuprinde reprezentarea cifrelor zecimale în cod Gray:
cifră zecimală cod Gray
0 0000
1 0001
2 0011
3 0010
4 0110
5 0111
6 0101
7 0100
8 1100
9 1101
Mai jos sunt prezentaţi algoritmii pentru conversia cod binar–cod Gray:
(b1,...,bm)→(g1,...,gm), şi respectiv pentru decodificarea cod Gray - cod binar: (g1,...,gm)
→(b1,...,bm):
begin begin
g1= b1; b1=valoare=g1;
for i=2,..,m for i=2,…, m
gi = bi-1 XOR bi if gi=1 then
repeat valoare=NOTvaloare
end endif
bi=valoare
repeat
end
Programarea Calculatoarelor
5
Coduri pentru detecţia şi corecţia erorilor
În cazul transmisiei pe canalele de comunicaţie a mesajelor prezentate sub formă binară,
detectarea şi corectarea erorilor apărute reprezintă etape importante. În esenţă presupun
detectarea poziţiei simbolurilor alterate şi corectarea acestora, adică schimbarea în valoarea
binară opusă.
În acest sens, alături de cei n biţi de date ai mesajului de transmis se introduc k biţi
suplimentari de informaţie neesenţială, informaţie de control. Vectorul format din cei k+n biţi
formează un cuvânt de cod.
Cele mai utilizate coduri detectoare şi corectoare sunt:
Coduri de control a parităţii
Pentru fiecare succesiune de cifre binare a1,…,an se adaugă un bit de paritate an+1 care
face ca numărul de biţi cu valoarea 1 din mesajul transmis să fie par sau impar, în funcţie de
convenţia de paritate stabilită. În momentul în care un bit se modifică, acesta va schimba
paritatea: de la pară la impară sau invers. Acest cod are o eficienţă scăzută deoarece nu poate
detecta decât un număr impar de biţi eronaţi.
Coduri bazate pe distanţa Hamming
Distanţa Hamming între două cuvinte de cod cu acelaşi număr de biţi în reprezentare este
egală cu numărul poziţiilor în care cele două cuvinte diferă, adică numărul de erori care
transformă un vector de informaţie în alt vector.
De exemplu, distanţa Hamming între cuvintele de cod:
10001001
10110001 este egală cu 3.
Distanţa Hamming minimă Dmin pentru un cod este cea mai mică distanţă Hamming
dintre toate perechile de cuvinte din cod. Codurile Hamming pot detecta Dmin-1 erori şi pot
corecta (Dmin-1)/2 erori.
De exemplu, pentru cuvintele de cod:
11101
10110
00000
01011
Dmin este 3 şi atunci codul Hamming poate detecta maxim 2 erori şi poate corecta o singură
eroare (un singur bit alterat).
Coduri polinomiale cu redundanţă ciclică – CRC („Cyclic Redundancy Code”)
Aceste coduri se bazează pe un polinom generator de grad k-1, k fiind lungimea şirului
de biţi transmişi: ultimul bit din şir este coeficientul lui x0 din polinom, iar bitul cel mai
semnificativ este coeficientul lui xk-1
.
De exemplu, şirul de biţi 101011 are polinomul asociat:
p(x)=x5⊕x
3⊕x⊕1
Aritmetica polinomială este de tip modulo 2, folosind operatorul logic XOR.
Se calculează restul împărţirii polinomului recepţionat la polinomul generator. Dacă
restul este zero, atunci transmisia secvenţei a fost corectă, fără erori.
Programarea Calculatoarelor
6
b) Coduri alfanumerice
În afară de valori numerice, într-un calculator trebuie reprezentate, de asemenea, date de
tip text care conțin caractere. Setul de caractere conține litere ale alfabetului ("A" ... "Z", "o" ...
"Z"), cifre ('0 '... '9'), simboluri speciale ('+', '$', '. ",", "," @ "," * ", etc.), și caractere non-
imprimabile (ex. CR, etc.).
Reprezentarea caracterelor alfanumerice în biți 0 și 1 se face prin coduri de caractere.
Există trei coduri de caractere utilizate pe scară largă:
- American standard Code for Information Interchange (ASCII): este un cod de 7
biți care permite reprezentarea a 27 = 128 caractere distincte. Versiunea ASCII-8 sau ASCII
extins este un cod de 8 biți care permite reprezentarea a 28 = 256 caractere distincte. Primele 128
de caractere sunt la fel în ambele coduri. Cele 128 de combinații suplimentare ale ASCII extins
sunt utilizate pentru simboluri cum ar fi: Ç ü è ©, ®, Æ, etc.
- Extended Binary Coded Decimal Interchange Code(EBCDIC): a fost unul dintre
primele coduri informatice utilizat pe scara largă care au permis reprezentarea caracterelor
alfabetice litere mari și mici, în plus față de caracterele speciale, cum ar fi semne de punctuație și
caractere de control. Este un cod de 8 biți care permite reprezentarea a 28 = 256 caractere.
Reprezentarea se face în două grupuri de 4 cifre, fiecare grup reprezentând un număr
hexazecimal.
- UNICODE: este un cod alfanumeric pe 16 biţi care permite 65536 de combinaţii
diferite. Este sistemul de codificare standard universal, conceput pentru a reprezenta date bazate
pe text scrise în orice limbă.
Programarea Calculatoarelor
7
Laborator 2
2. SISTEME DE NUMERAŢIE
Toate națiunile diferitelor civilizaţii au stabilit propriul sistem de numerotare pe care să-l
folosească în viața de zi cu zi și în alte activități, cum ar fi comerțul și toate celelalte aspecte ale
vieții care necesită numărarea.
Un sistem de numeraţie este format din totalitatea regulilor şi a notaţiilor matematice
utilizate pentru reprezentarea numerelor cu ajutorul cifrelor sau a altor simboluri.
Sistemul de numeraţie roman este cunoscut ca un sistem non-poziţional deoarece fiecare
simbol reprezintă o valoare specifică independentă de poziția sa.
De exemplu: I semnifică întotdeauna 1
V semnifică întotdeauna 5
X semnifică întotdeauna 10
Dar combinaţiile de simboluri au semnificaţii diferite.
De exemplu: IV semnifică 4
VI semnifică 6
Sistemul zecimal este un sistem poziţional deoarece valoarea fiecărui simbol depinde de
poziția sa.
Un sistem de numeraţie se numeşte deci poziţional, dacă valoarea unei cifre este dată de
poziţia pe care aceasta o ocupă în cadrul numărului. Fiecare sistem de numeraţie poziţional
constă dintr-o bază, simboluri și o relație care asociază caracterele cu baza.
Ideea generală în sistemele de numerotare poziţionale este aceea că o valoare numerică
este reprezentata prin puterile crescătoare ale unei baze. Fiecare cifră este înmulţită cu puterea
bazei:
cifra * baza(poziţie -1)
Sistem Baza Cifre
de numeraţie corespunzătoare
---------------------------------------------------------------------
Decimal 10 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Binary 2 0, 1
Octal 8 0, 1, 2, 3, 4, 5, 6, 7
Hexadecimal 16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
În general, un număr r este reprezentat într-o bază b printr-o secvenţă de simboluri an, an-
1,…,a0, f1, f2,…,fm:
(an bn) + (an-1 b
n-1) +…+ (a0 b
0) + (f1 b
-1) + (f2 b
-2) +…+ (fm b
-m)
care verifică următoarele condiţii:
0≤ai<b , i=0,…,n şi 0≤fi<b , i=0,…,m
an≠0
Programarea Calculatoarelor
8
Punctul care separă partea întreagă de partea fracţionară se numeşte punct fracţionar.
Această scriere formează baza pentru conversia unui număr din baza b în zecimal.
Pentru conversia unui întreg din baza b în zecimal se poate utiliza şi regula lui Horner:
(an bn) + (an-1 b
n-1) +…+ (a0 b
0) se poate scrie ca:
(((an b) + an-1) b + …) b + a0.
De exemplu: (1234)5 = (((1 5) + 2) 5 + 3) x 5 + 4 = 194.
Tehnologia digitală utilizează diverse sisteme de numeraţie. Cele mai frecvente sunt
sistemul zecimal, binar, octal și hexazecimal. Sistemul zecimal este în mod clar cel mai familiar
pentru noi, pentru că este un instrument pe care îl folosim în fiecare zi.
În calculator, datele sunt reprezentate numai în sistem binar, octal şi hexazecimal.
Conversii între sisteme de numeraţie
Există două grupuri importante de conversii între baze de numeraţie:
1. Conversia numerelor zecimale în numere reprezentate în bază r
2. Conversia numerelor din bază r în numere zecimale
Conversia zecimal-binar în cazul numerelor întregi
Această conversie implică împărţirea succesivă la 2 (baza conversiei) până când câtul
devine 0. La fiecare împărţire, restul obţinut oferă o nouă cifră a numărului convertit, începând
cu cifra cea mai puţin semnificativă.
De exemplu, să se convertească în binar numărul zecimal 37(10):
37/2 =18 restul 1 (cifra cea mai puţin semnificativă)
18/2 =9 restul 0
9/2 =4 restul 1
4/2 =2 restul 0
2/2 =1 restul 0
1/2 =0 restul 1 (cifra cea mai semnificativă)
Numărul obţinut prin conversia în binar este 100101(2).
Conversia zecimal-binar în cazul numerelor subunitare
Această conversie implică înmulţirea succesivă cu 2 (baza conversiei). La fiecare
înmulţire, partea întreagă a rezultatului obţinut oferă o nouă cifră a numărului convertit, începând
cu cifra cea mai semnificativă. Cifrele sunt plasate deci după punctul zecimal, în ordinea
obţinerii. Procedeul se poate opri oricând, după atingerea preciziei dorite.
De exemplu, să se convertească în binar cu gradul de precizie 8 numărul fracţionar 0.37(10):
0.37*2 = 0.74 se reţine 0
0.74*2 = 1.48 se reţine 1
0.48*2 = 0.96 se reţine 0
0.96*2 = 1.92 se reţine 1
0.92*2 = 1.84 se reţine 1
0.84*2 = 1.68 se reţine 1
0.68*2 = 1.36 se reţine 1
0.36*2 = 0.72 se reţine 0
Numărul obţinut prin conversia în binar este 0.01011110(2).
Programarea Calculatoarelor
9
Conversia zecimal-binar în cazul numerelor reale
Deoarece un număr real x se poate scrie sub forma: x = [x] + {x}, parte întreagă plus
parte fracţionară, se realizează conversia separat pentru numărul întreg şi separat pentru numărul
subunitar (ca în exemplele anterioare), iar apoi se concatenează cele două rezultate, plasând
virgula între ele.
De exemplu, să se convertească în binar cu gradul de precizie 8 numărul real 147.37(10):
147(10) 10010011(2)
0.37(10) 0.01011110(2)
------------------------------------------
147.37(10) 10010011. 01011110(2)
Conversia binar – zecimal
Se adună termenii obţinuţi din produsul dintre fiecare cifră binară care intră în
componenţa numărului şi puterea bazei 2 care corespunde ponderii cifrei. Bitul situat pe poziţia
cea mai din dreapta va avea ponderea 20, iar celelalte cifre binare, spre stânga vor avea ponderile
21, 2
2, etc.
Pentru numerele fracţionare, ponderile alocate cifrelor aflate la dreapta virgulei de
separaţie vor fi 2-1
, 2-2
, etc.
De exemplu, să se convertească în zecimal numărul binar 10100101.101(2):
27+2
5+2
2+2
0+2
-1+2
-3 = 165.75
Conversia binar – octal
În acest caz conversia se face prin împărţirea numărul binar în grupuri de câte 3 cifre
binare, începând de la ultima, cea mai din dreapta cifră binară. Dacă numărul de cifre binare nu
este un multiplu de 3, atunci se prefixează numărul cu zerouri, astfel încât fiecare grup să conţină
3 cifre binare. Pentru fiecare grup de cifre binare se converteşte numărul binar de 3 cifre într-o
cifră hexazecimală echivalentă, conform tabelului de corespondenţă următor:
cifre octale echivalent binar
---------------------------------------------------------------------
0..............0 000
1..............1 001
2..............2 010
3..............3 011
4..............4 100
5..............5 101
6..............6 110
7..............7 111
De exemplu, să se convertească numărul 1100010101(2) în octal:
- se divide numărul în grupuri de câte 3 cifre: 011 100 010 101
- se converteşte fiecare grup într-o cifră octală: 3 4 2 5
Numărul convertit rezultat va fi deci 3425(8).
Programarea Calculatoarelor
10
Obs: În cazul numerelor fracţionare, cifrele de la partea fracţionară se împart în grupe de câte 3
de la stânga la dreapta (ultima grupă se completează în spate, cu unul sau două zerouri) şi apoi
fiecare grupă se înlocuieşte cu cifra octală corespunzătoare ei.
Operaţii aritmetice în binar
Tabela adunării în binar: Tabela scăderii în binar:
+ 0 1
0 0 1
1 1 10
Obs:
1) Rezultatul adunării de pe ultima linie: 1+1 = 2 (10(2)).
2) La scăderea 0-1 se trece 1 şi se împrumută o unitate din stânga.
3) Operaţiile de înmulţire şi împărţire în binar se efectuează identic cu cele din baza 10, ţinând
cont de regulile:
0x0=0 0x1=0 1x0=0 1x1=1
0:0=0 0:1=0 1:0=imposibil 1:1=1
De exemplu: 1101101 x
101
1101101
1101101
1000100001
Verificare: 1101101(2) = 109 ; 101(2) = 5 ; 1000100001(2)= 545
109 x 5 = 545
Alt exemplu: 11010111 101
101 101011
00110
101
00111
101
101
101
===
Verificare: 11010111(2) = 215 ; 101(2) = 5 ; 101011(2) = 43
215 : 5 = 43 rest 0.
Conversia binar-hexazecimal
Se împarte numărul binar în grupuri de câte 4 cifre binare, începând de la ultima, cea mai
din dreapta cifră binară. Dacă numărul de cifre binare nu este un multiplu de 4, atunci se
prefixează numărul cu zerouri, astfel încât fiecare grup să conţină 4 cifre binare. Pentru fiecare
- 0 1
0 0 1 împrumut 1
1 1 0
Programarea Calculatoarelor
11
grup de cifre binare se converteşte numărul binar de 4 cifre într-o cifră hexazecimală echivalentă,
conform tabelului de corespondenţă următor:
cifre hexazecimale echivalent binar
---------------------------------------------------------------------
0..............0 0000
1..............1 0001
2..............2 0010
3..............3 0011
4..............4 0100
cifre hexazecimale echivalent binar
---------------------------------------------------------------------
5..............5 0101
6..............6 0110
7..............7 0111
8..............8 1000
9..............9 1001
10............A 1010
11............B 1011
12............C 1100
13............D 1101
14............E 1110
15............F 1111
De exemplu, să se convertească numărul binar 11000110(2) într-un număr hexazecimal:
- se divide numărul în grupuri de câte 4 cifre: 1100 0110
- se converteşte fiecare grup într-o cifră hexazecimală: C 6
Numărul convertit rezultat va fi deci C6(16).
Conversia hexazecimal-binar
Se converteşte fiecare cifră hexazecimală într-un grup de 4 cifre binare, conform
tabelului anterior.
De exemplu, să se convertească numărul 264E în binar:
Se converteşte fiecare cifră în binar: 2 6 4 E
0010 0110 0100 1110
Numărul convertit rezultat va fi deci: 0010011001001110(2)
Reprezentarea în simplă precizie. Depăşiri
În mod obişnuit, numerele sunt reprezentate în calculator utilizând un număr fix de biţi:
8, 16, 32, 64 şi 80. Aceste dimensiuni sunt multiplii de 8, după cum organizarea calculatoarelor
are la bază dimensiunea de un octet.
Reprezentarea în care sunt utilizaţi un anumit număr de biţi pentru o valoare numerică se
numeşte reprezentare în precizie simplă. Atunci când se utilizează un anumit număr de biţi
pentru a reprezenta un număr, există un anumit interval de valori posibile care pot fi
Programarea Calculatoarelor
12
reprezentate. De exemplu, sunt 28=256 de combinaţii posibile de 8 biţi, domeniul de valori
posibile pentru a fi reprezentate fiind 0 – 255. Un număr mai mare decât 255 nu poate fi
reprezentat utilizând 8 biţi. În mod asemănător, 16 biţi permit ca domeniu de reprezentare 0 –
65535.
Atunci când rezultatul unui calcul nu poate fi reprezentat cu numărul de biţi disponibili,
apare o depăşire.
De exemplu, la adunarea pe 8 biţi a numerelor 150 şi 140, rezultatul este 290, care este în
afara intervalului 0 – 255 şi nu poate fi reprezentat pe 8 biţi.
În situaţia în care apare o depăşire, biţii cei mai puţini semnificativi se păstrează, dar biţii
cei mai semnificativi se vor pierde, ceea ce va conduce la o valoare semnificativ mai mică decât
rezultatul corect.
De exemplu, 64(10) + 250(10):
64(10) 01000000(2)
250(10) 11111010(2)
---------------------------------------------------------------------
314(10) (1)00111010(2) - depăşire
se vor reţine cei mai puţin semnificativi 8
biţi pentru a limita rezultatul la valoarea
maximă a domeniului
58(10) 00111010(2)
Reprezentarea numerelor cu semn
Am văzut că în cazul reprezentării numerelor fără semn (valori pozitive), intervalul de
valori pozitive care poate fi reprezentat este [0 , 2n-1], unde n este numărul de biţi utilizaţi în
reprezentare:
n domeniu de valori
----------------------------------------------
8 biţi 0 – 255
16 biţi 0 – 65535
32 biţi 0 - 2147483647
În binar există posibilitatea reprezentării numerelor cu semn, pozitive şi negative. Cea
mai uzuală modalitate de a reprezenta astfel de numere este reprezentarea în cod complementar
faţă de 2 (sau cod complementar). Această reprezentare este utilizată deoarece reduce
complexitatea hardware din unitatea aritmetico-logică a procesorului unui calculator: toate
operaţiile aritmetice pot fi efectuate de către aceleaşi circuite, indiferent dacă numerele sunt
considerate a fi cu semn sau fără semn. Operaţiile efectuate pe biţi sunt identice, diferenţa
provenind din interpretarea biţilor.
Pentru a obţine complementul faţă de 2 a unui număr binar, se inversează valoarea biţilor
numărului şi apoi se adună valoarea 1.
Programarea Calculatoarelor
13
De exemplu, complementul faţă de 2 a numărului binar 00101001(2) se obţine astfel:
00101001(2)
se inversează valoarea biţilor
11010110(2) +
00000001(2) se adaugă valoarea 1
-----------------
11010111(2)
Prin această metodă se pot reprezenta numere întregi din intervalul de valori [-2n-1
, 2n-1
-
1], unde n este numărul de biţi utilizaţi în reprezentare.
Primul bit din stânga, bitul cel mai semnificativ, este bitul de semn şi are valoarea 0
pentru numere pozitive şi valoarea 1 pentru numere negative.
De exemplu, considerăm n=8. Intervalul de valori reprezentabile este [-128 , 127] şi
reprezentăm numărul -72 în cod complementar:
-72(10) 11001000(2)
inversare
10110111(2) +
00000001(2) se adaugă valoarea 1
--------------
10111000(2)
Obs:
1) În cazul numerelor cu semn reprezentate în cod complementar semnul se păstrează,
adică primul bit din stânga nu intră în complementaritate.
2) Valoarea numerică a unui număr negativ x reprezentat pe n biţi în cod complementar
se calculează cu formula:
C2(x) = 2n-|x|
De exemplu, valoarea numerică a numărului -72 pe 8 biţi în cod complementar este:
C2(x) = 2n-72 = 256-72 = 184
Verificare: 10111000(2) = 0*20+0*2
1+0*2
2+1*2
3+1*2
4+1*2
5+0*2
6+1*2
7 = 8 + 16 + 32 + 128 =
184
3) Prin adunarea numărului cu complementul său faţă de 2 se obţine rezultatul 0.
De exemplu, 72(10) + (-72)10 = 0
Verificare: 01001000(2) + 10111000(2) = 000000000(2)
4) Şi în cazul reprezentării numerelor cu semn poate să apară depăşirea. De exemplu,
dacă se efectuează -100 – 30:
-100(10) 11100100(2)
inversare
10011011(2) +
00000001(2) se adaugă valoarea 1
--------------
10011100(2)
Programarea Calculatoarelor
14
-30(10) 10011110(2)
inversare
11100001(2) +
00000001(2) se adaugă valoarea 1
--------------
11100010(2)
-100 (10) -30(10) 10011100(2) +
11100010(2)
--------------
101111110(2) depăşire: rezultat pozitiv,
Incorect
Reprezentarea în virgulă mobilă
Se bazează pe notaţia exponenţială (sau ştiinţifică), conform căreia un număr real
nenegativ a se exprimă sub forma:
a = ± m x 10E, unde: 1≤ m < 10
E ∊ Z - exponent
m – mantisă
De exemplu, notaţia exponenţială a numărului 264.39 = 2.6439 x 102, iar reprezentarea
numărului 0.00026439 este 2.6439 x 10-4
.
Obs: condiţia ca 1≤ m < 10 poate fi îndeplinită prin înmulţiri sau împărţiri repetate ale numărului
x la 10, micşorând sau mărind corespunzător exponentul E.
Pentru reprezentarea în calculator se preferă baza 2, astfel încât numărul se va scrie:
a = ± m x 2E, unde: 1≤ m < 2
m = (b0.b1b2b3……)(2) cu b0 = 1
Această formă a numărului se numeşte formă normalizată. De exemplu, numărul 9/2 poate fi
scris ca:
9/2 = 100.1 = (1.001)(2) x 22
Biţii care urmează după punct formează partea fracţionară a mantisei.
Obs: reprezentarea în virgulă mobilă a unui număr nenul este unică atâta timp cât este respectată
condiţia ca 1≤ m < 2.
De exemplu, nerespectând această cerinţă, numărul 9/2 poate fi scris de asemenea:
9/2 = (0.01001)(2) x 24
Conform standardului de reprezentare IEEE754, reprezentarea numerelor reale în virgulă
mobilă pe lungime (precizie) simplă (32 biţi) se realizează astfel:
Programarea Calculatoarelor
15
31 30 23 22 0
s E1……….E………E8 b1………………m……….……..b23
Reprezentarea numerelor reale în virgulă mobilă pe lungime (precizie) dublă (64 biţi) se
realizează astfel:
63 62 52 51 0
s E1……….E………E11 b1………………m……….……..b52
Pentru reprezentarea în precizie simplă exponentul este reprezentat pe 8 biţi, ceea ce
implică un domeniu de valori [-127 , 127]. Pentru a nu folosi exponenţi negativi s-a introdus
noţiunea de caracteristică:
caracteristica = exponent + 2nr. biţi exponent -1
-1
Se adaugă astfel la exponent o valoare de exces egală cu 127. Pentru reprezentarea
exponentului în dublă precizie, pe 11 biţi, se va adăuga valoarea 1023.
De exemplu, să se reprezinte numărul 135.74356 în virgulă mobilă, simplă precizie:
- se converteşte numărul în binar:
135 = 10000111(2)
.74356 = .1011(2)
deci 135.74356 = 10000111.1011(2)
- se scrie numărul în formă normalizată:
135.74356 = 1,00001111011 x 27
- se calculează şi se reprezintă caracteristica:
7 + 127 = 134 = 10000110(2)
- se finalizează reprezentarea:
31 30 23 22 0
0 10000110 00001111011000000000000
Exemplul următor realizează conversia din formatul de reprezentare virgulă mobilă
simplă precizie în zecimal a numărului:
31 30 23 22 0
0 10000110 11010110000000000000000
- se transformă exponentul în zecimal:
10000110(2) = 134
- se scrie numărul în forma ± 1.m x 2E-127
:
1.1101011 x 2134-127
- se normalizează şi se converteşte în zecimal:
1.1101011 x 27 = 11101011(2) = 1 +2 +8+ 32 +64 + 128 = 235
Programarea Calculatoarelor
16
Teste grilă rezolvate
1. Câte numere cu o singură cifră sau simboluri, excluzând zero, sunt necesare
reprezentării într-un sistem de numeraţie în bază 60?
a) 60 b) 59 c) 61
2. Care este reprezentarea în cod BCD (format împachetat) a numărului zecimal 746 ?
a) 010010111 b)011101000110 c)011110000101 d)111100001010
3. Care este valoarea binară (8-biți) a numărul zecimal 175?
a) 10101010 b) 10010010 c) 10011111 d) 11100111
4. Care este valoarea octală a numărului binar 100101001001100100011(2) ?
a) 4511443 b) 4312441 c) 3442112 d) 2314322
5. Care este valoarea hexazecimală a numărului binar 11110110010011011001(2) ?
a) A46F9 b) 8Fa64 c) C86DA d) F64D9
6. Care este valoarea zecimală a numărului octal 215?
a) 267 b)141 c) 98 d) 216
7. Care este valoarea zecimală a numărului hexazecimal FF?
a) 156 b) 127 c) 255 d) 256
8. Care este valoarea hexazecimală a numărului zecimal FF?
a) 1C7 b) 4D5 c)2B6 d) 5C4
9. care este rezultatul adunării în binar a numerelor: 10001011(2) şi 01010101(2) ?
a) 10110010 b) 11100000 c)10001000 d)11011011
10. Care este Reprezentarea în cod complementar a numărului 11010000 ?
a) 00111000 b) 00110000 c) 10010000 d) 00101000
Programarea Calculatoarelor
17
Probleme rezolvate
1. Câţi biţi sunt necesari pentru a reprezenta numere întregi din intervalul [0 , 14000]?
Răspuns:
Cu 13 biţi se pot reprezenta numere întregi pozitive din intervalul de valori [0 , 2
13-1] = [0
, 8191].
Cu 14 biţi se pot reprezenta numere întregi pozitive din intervalul de valori [0 , 2
14-1] = [0
,
16383].
Deci 13 biţi nu sunt suficienţi, dar cu 14 biţi se pot reprezenta valori mai mari decât 14000, deci
numărul de biţi necesari este 14.
2. Ce domeniu de numere întregi şi pozitive zecimale se poate reprezenta cu un număr
octal de 4 cifre?
Răspuns:
Un număr octal de 4 cifre poate fi între 0000 și 7777, dacă se iau în considerare numai numere
pozitive.
0000(8) este echivalentul în zecimal pentru 0
7777(8) este echivalentul în zecimal pentru 4095
Deci, domeniul de valori reprezentabile astfel este [0 , 4095].
3. Dacă se adună numerele nouăsprezece și nouă în formă binară, va fi răspunsul diferit
decât în cazul în care se adună aceleaşi numere în formă zecimală? Explicaţie.
Răspuns:
Forma binară, zecimală, etc. utilizată pentru reprezentarea numerelor nu are nici o influență
asupra rezultatului operațiilor matematice.
4. Numărul 10111010(2) este reprezentarea în cod complementar pe 8 biţi a unui număr k.
Care este reprezentarea zecimală a lui k?
Răspuns:
Pentru fiecare număr x reprezentat pe n biți, complement său, y, este calculat ca: y = 2n – x ⟹ x
= 2n – y ⟹x este reprezentarea în cod complementar a lui y. Prin urmare, putem obține numărul
binar original k prin inversarea tuturor biţilor complementului său după care se adună 1.
Obţinem: 10111010(2)
01000101(2) +
00000001(2)
---------------
01000110(2) k= 2 +4 +64 = 70
5. Într-un sistem digital de 8 biți, în care toate numerele sunt reprezentate în cod
complementar, care este cel mai mare număr pozitiv care poate fi reprezentat cu acei 8 biți?
Programarea Calculatoarelor
18
Care este cel mai mic număr negativ care poate fi astfel reprezentat? Exprimaţi
răspunsurile în ambele formate: binar (cod complementar) și zecimal.
Răspuns:
Cel mai mare număr pozitiv este 127(10) = 01111111(2)
Cel mai mic număr negativ este -128(10) = 10000000(2)
6. Cum este posibil să fie identificată o depăşire în momentul efectuării sumei a două
numere binare, fără a face verificarea prin conversia rezultatului în formă zecimală?
Răspuns:
Se va verifica bitul de semn al rezultatului, prin comparare cu biţii de semn ai celor două numere.
7. Asemănător conceptului de cod complementar (faţă de 2) pentru numere binare
reprezentate pe n biţi, definiţi conceptul corespunzător pentru baza 10: cod complementar
faţă de 10 pentru numere zecimale reprezentate pe n biţi. Prezentaţi şi modul de calcul în
acest caz.
Răspuns:
În cazul codului complementar faţă de 2 pentru numere binare, domeniul de reprezentare este: [-
2n-1
, 2n-1
-1], unde n este numărul de biţi utilizaţi în reprezentare.
Asemănător, putem defini domeniul de reprezentare pentru cod complementar faţă de 10 pentru
numere zecimale reprezentate pe n biţi ca fiind [-5 x 10n-1
, 5 x 10n-1
-1]. Dacă luăm de exemplu n
= 2, vom avea două cifre zecimale, iar domeniul de reprezentare va fi [-50 , 49].
Fiecare număr negativ a va fi reprezentat ca 102 – a = 100 –a.
De exemplu, dacă se calculează 20 – 15 = 20 + (-15) = 20 +(102
– 15) = 20+ 85 = 105 = 5
deoarece sunt permise doar două zecimale în reprezentare, iar cifra sutelor este ignorată.
Dacă se calculează 15 – 20 = 15 + (-20) = 15 + (102 -20) = 15 + 80 = 95. 95 este de fapt un
număr negativ deoarece este mai mare decât 49, iar două cifre permit ca domeniu de reprezentare
[-50 , 49]. Valoarea sa efectivă este –(10
2 - 95) = -5.
8. Calculaţi, în cod complementar faţă de 10, cu o reprezentare pe 7 biţi, suma: -a –b, unde
a = 114(10), iar b = 231(10).
Răspuns:
-a = 107 – 114 = 9999886
-b = 107 – 231 = 9999769
-a –b = 9999886 + 9999769 = 19999655 = 9999655 deoarece sunt permise doar şapte zecimale
în reprezentare, iar prima cifră este ignorată.
Pentru verificarea calculelor, se poate calcula valoarea în zecimal:
107
- a - b = 107
- 9999655 = 345, care este ceea ce reprezintă valoarea absolută pentru -114-231
în zecimal.
Programarea Calculatoarelor
19
Probleme propuse
1. Care este numărul de biţi necesari pentru a reprezenta numere întregi din intervalele:
[100 , 200] şi [0 , 1000]?
2. Într-un sistem de 6 biți, reprezentare în cod complementar, care este valoarea zecimală
reprezentată de 100100(2)?
3. Realizaţi scăderile următoare folosind reprezentarea în cod complementar pentru
numere negative:
a) 10101(2) – 10001(2) b) 11011(2) -1110(2) c) 100100(2) -100011(2)
4. Completaţi tabelul de mai jos, realizând toate conversiile necesare:
Binar Octal Zecimal Hexazecimal
10001
87
2B
72
1010101
201
989
246
1000010101
5. Realizaţi conversia în cod Gray a următoarelor numere binare:
101110(2) 111010(2) 101011(2) 1010100100(2)
6. Realizaţi conversia următoarelor numere din cod BCD în formă zecimală:
1000 0111 0011 0111 0011 0111 1000 0110 1001
7. Să se reprezinte următoarele numere în virgulă mobilă, simplă precizie:
123.45678 63.2458 546.5479
8. Numărul 10010010(2) este reprezentarea în cod complementar pe 8 biţi a unui număr k.
Care este reprezentarea zecimală a lui k?
Programarea Calculatoarelor
20
Laborator 3
3. ALGORITMI: DEFINIŢIE, PROPRIETĂŢI, REPREZENTĂRI,
VERIFICAREA CORECTITUDINII ŞI
NOŢIUNI DE PROGRAMARE STRUCTURATĂ
Un algoritm este un concept folosit pentru a desemna o procedură de calcul bine
definită, constând dintr-un set finit de instrucțiuni complet ordonat în timp; procedura porneşte
de la o anumită valoare sau un set de valori de intrare și produce într-un timp finit o anumită
valoare sau un set de valori, ca ieșire. Algoritmul exprimă logica completă a soluției de rezolvare
a unei probleme date.
Termenul de "Algoritm" provine din numele matematicianului persan din secolul al IX-
lea Mohammed al-Khowarizmi: Al-Khowarizmi → Algorismus (în latină) → algoritm. Dar,
aceeaşi prezentare a regulilor precise pentru descrierea proceselor de calcul din aritmetică se
întâlneşte şi în celebra lucrare a lui Euclid, „Elementele” - un tratat de geometrie, alcătuit din 13
cărți. Într-o anecdotă scrisă la 800 de ani de la moartea lui Euclid se relatează că regele Ptolemeu
I, în încercarea de a studia această lucrare, l-a întrebat pe Euclid dacă nu ar exista o cale mai
uşoară ca să înţeleagă geometria, la care Euclid sever ar fi răspuns: " În geometrie nu există calea
regală !".
În cartea a VII-a din „Elemente” se regăseşte de altfel primul şi cel mai celebru algoritm
din istorie, Algoritmul lui Euclid pentru determinarea celui mai mare divizor comun a două
numere.
Proprietăţile algoritmilor:
1. Exactitate = un algoritm trebuie să fie descris în mod clar şi precis; la fiecare
pas, operaţia care urmează a fi executată este unic determinată, definită şi
realizabilă, astfel încât să nu existe incertitudine.
2. Generalitate = algoritmul trebuie să rezolve fiecare instanță a problemei
respective; algoritmul obţine date de ieşire pentru orice date de intrare
corespunzătoare problemei.
3. Finitudine = un algoritm trebuie să conțină un număr finit de pași în execuția sa.
4. Eficienţă = un algoritm trebuie să conţină operaţiuni calculabile în mod eficient
şi trebuie să ofere răspunsul corect la problema respectivă. Se poate remarca
faptul că proprietatea de "finitudine" este un caz special de "eficiență". Dacă o
succesiune de etape nu este finită, atunci ea nu poate fi nici eficientă.
Algoritm Date de intrare
Input
Date de ieşire Output
Programarea Calculatoarelor
21
Etapele rezolvării unei probleme:
Vom încerca să detaliem procesul de rezolvare a unei probleme pornind de la aserţiunea
matematicianului George Polya: „O mare descoperire rezolvă o mare problemă, dar există un
grăunte de descoperire în soluţia oricărei probleme”. În cartea sa de referinţă: „How to Solve It”,
Polya a conceptualizat acest proces ca o construcţie ce cuprinde patru etape principale:
► Etapa 1) Înţelegerea problemei: odată formulat enunţul problemei, clar şi precis, trebuie
stabilite:
- datele de intrare şi informaţiile care trebuie obţinute prin rezolvarea problemei;
- care sunt condiţiile concrete de rezolvare: sunt acestea suficiente sau insuficiente? sunt
redundante? sunt contradictorii?
- există informaţii care lipsesc, sau, dimpotrivă, nu sunt necesare?
► Etapa 2) Elaborarea unui plan (model) de rezolvare a problemei, stabilirea unei
conexiuni între datele şi necunoscutele problemei pentru a dezvolta algoritmul corespunzător de
rezolvare, algoritm descris într-una dintre modalităţile de reprezentare algoritmică.
În acest scop se recomandă:
- identificarea unei probleme conexe, asemănătoare (atunci când este posibil) pentru a putea
vedea dacă se poate aplica aceeaşi tehnică de rezolvare;
- împărţirea problemei în subprobleme mai mici şi mai uşor de rezolvat;
- încercarea de a rezolva un caz special al problemei sau o problemă mai generală sau o parte a
problemei.
► Etapa 3) Implementarea planului de rezolvare prin codificarea algoritmului rezultat în
etapa anterioară într-un limbaj de programare. Se recomandă în plus şi:
- efectuarea oricăror acţiuni sau calcule necesare în acest sens;
- verificarea fiecărui pas al algoritmului, intuitiv sau formal.
► Etapa 4) Testarea programului şi corectarea erorilor:
- testarea programului se realizează pe baza mai multor seturi diferite de date de test pentru a
descoperi eventualele erori şi greşeli de concepţie în program; dacă în timpul testării programului
se constată funcţionarea defectuoasă a acestuia, este necesară reluarea ultimelor două sau trei
etape în funcţie de natura erorilor;
- analiza corectitudinii soluţiei în termenii problemei originale: soluţia are sens? este plauzibilă?
- identificarea unei alte metode de găsire a soluţiei; în cazul în care există mai mulţi algoritmi de
rezolvare, trebuie ales algoritmul cel mai eficient din punct de vedere al complexităţii calculului:
algoritmul cu cel mai redus timp de execuţie şi cel mai economic spaţiu de memorie necesar.
Reprezentarea algoritmilor
Reprezentarea algoritmilor şi limbajele de programare s-au influenţat reciproc. Există
astfel diverse modalităţi de reprezentare a algoritmilor, care pot fi utilizate în orice combinaţie:
- în limbaj natural – descriere amănunţită prin cuvinte;
- printr-o schemă logică – reprezentare grafică simplă;
- în pseudocod – descriere formală simplificată intermediară între limbajul natural şi de limbajul
de programare;
- prin convenţii grafice de tip diagrame arborescente;
- prin tabele de decizie de tip condiţii – acţiuni.
Programarea Calculatoarelor
22
(I) Schema logică
Reprezentarea prin schemă logică a unui algoritm utilizează blocuri (operaţii) de bază
şi/sau structuri de control (formate prin gruparea blocurilor de bază).
Blocuri de bază
Blocul de început/sfârşit – orice schemă logică începe cu un bloc de început şi se termină cu un
bloc de sfârşit.
Blocul de intrare – desemnează preluarea datelor (valorilor variabilelor) de la dispozitivul de
intrare (de exemplu de la tastatură).
Blocul de ieşire – desemnează scrierea rezultatelor (valorilor variabilelor) la dispozitivul de
ieşire (de exemplu pe ecranul monitorului).
Blocul de atribuire – este utilizat pentru reprezentarea prelucrărilor asupra datelor.
Blocul decizional – desemnează evaluarea unei condiţii. În funcţie de rezultatul evaluării,
continuarea prelucrărilor poate urmări ramura desemnată cu DA (condiţia din blocul de decizie
este adevărată) sau cea desemnată cu NU (condiţia din blocul de decizie este falsă).
Conectorul logic – este utilizat pentru reunirea ramurilor de execuţie ale algoritmului.
Programarea Calculatoarelor
23
Conectorul de pagină – este utilizat atunci când schema logică trebuie continuată pe o altă
pagină. Conectorul conţine o literă sau un număr care trebuie să fie identic cu cel de pe pagina
unde se continuă prelucrarea.
Structuri de control
Structurile de control sunt grupări de blocuri de bază ce apar frecvent în schemele logice
şi pentru care sunt definite instrucţiuni specifice în limbajele de programare (în situaţia noastră în
C++).
Structura secvenţială (secvenţa) – grupează de obicei mai multe operaţii (instrucţiuni)
elementare (iniţializări de variabile, prelucrări asupra datelor, tipărire a rezultatelor, etc.).
Structura alternativă (decizia) – permite ramificarea simplă a execuţiei în funcţie de valoarea de
adevăr a condiţiei. Cele două ramuri se exclud mutual.
Este posibil ca una dintre ramuri să fie vidă (să nu conţină alte blocuri).
Structura repetitivă condiţionată anterior (bucla/ciclul cu test iniţial) – secvenţa se execută
repetitiv cât timp condiţia este adevărată. Secvenţa se mai numeşte în această situaţie şi corpul
buclei (corpul ciclului). Dacă rezultatul testării iniţiale a condiţiei este fals, secvenţa nu este
executată nici măcar o singură dată.
Programarea Calculatoarelor
24
Obs: Pentru structura repetitivă condiţionată anterior, condiţia testată pentru repetarea
secvenţei se scrie identic în pseudocod şi în C++.
Pentru ca secvenţa să nu se repete la infinit, în cadrul acesteia trebuie modificate
variabilele ce sunt folosite în condiţia testată pentru repetarea buclei astfel încât la un moment
dat să se poată realiza ieşirea din buclă.
În afară de structurile de control menţionate anterior şi care permit descrierea oricărui
algoritm, mai există câteva structuri de control derivate din acestea ce sunt folosite uzual şi
anume:
Structura repetitivă condiţionată posterior (bucla/ciclul cu test final) – secvenţa (corpul buclei)
se execută repetitiv până când condiţia devine adevărată. Spre deosebire de bucla cu test iniţial,
în cazul buclei cu test final secvenţa se execută cel puţin o dată.
Obs: Pentru structura repetitivă condiţionată posterior condiţia testată pentru ieşirea din
buclă trebuie scrisă negat în C++ faţă de pseudocod. În pseudocod secvenţa se repetă până când
condiţia devine adevărată, iar în C++ secvenţa se repetă atâta timp cât condiţia este adevărată.
Pentru ca secvenţa să nu se repete la infinit, în cadrul acesteia trebuie modificate
variabilele ce sunt folosite în condiţia testată pentru repetarea buclei astfel încât la un moment
dat să se poată realiza ieşirea din buclă.
Structura repetitivă (bucla/ciclul) cu contor – este derivată din structura repetitivă condiţionată
anterior. Secvenţa se execută repetitiv de un număr prestabilit de ori controlat de valoarea
variabilei contor. Pentru ca repetarea să nu se facă la infinit, este necesară incrementarea
(decrementarea) variabilei contor cu valoarea pas (care trebuie să fie diferită de zero).
Programarea Calculatoarelor
25
Structura decizională multiplă – este o structură de control derivată din structura alternativă –
permite ramificarea multiplă a execuţiei. Dacă nici una dintre condiţiile testate nu a fost
îndeplinită, execuţia este continuată în <secvenţa alternativă> dacă aceasta a fost specificată.
Observaţie: În C++ structura switch este puţin diferită faţă de celelalte structuri de
control.
Valorile val_1 ... val_n sunt de fapt constante, secvenţele de instrucţiuni nu sunt încadrate
de acolade şi de asemenea pentru fiecare secvenţă în parte de obicei apare în final instrucţiunea
break;
Instrucţiunea switch evaluează variabila/expresia a şi verifică daca aceasta este
echivalentă cu val_1, situaţie în care se execută secvenţa de instrucţiuni imediat următoare până
la instrucţiunea break. Când este întâlnită instrucţiunea break programul sare la sfârşitul
structurii switch. Dacă a nu este egală cu val_1, se trece la evaluarea cu val_2, şi aşa mai departe.
În final, dacă nici una dintre evaluări nu a fost adevărată, se execută instrucţiunile specificate
Programarea Calculatoarelor
26
după default: şi apoi se iese din structura switch. Eticheta default: şi instrucţiunile scrise după
aceasta sunt opţionale.
Dacă instrucţiunea break lipseşte, se trece la execuţia secvenţei pentru val_2 (fără a se
mai verifica egalitatea), apoi la secvenţa pentru val_3 şi aşa mai departe (inclusiv secvenţa
pentru default) până la terminarea structurii sau până la prima instrucţiune break.
Instrucţiunea break poate fi folosită de asemenea în orice altă structură repetitivă pentru a
ieşi din buclă fără a mai fi necesară respectarea condiţiei de ieşire din aceasta.
(II) Limbajul pseudocod
Apariţia limbajelor Pascal şi C au impus limbajul pseudocod în domeniul reprezentării şi
elaborării algoritmilor.
Limbajul pseudocod foloseşte o scriere similară limbajelor de programare moderne. El
permite atât descrierea instrucţiunilor algoritmului, cât şi descrierea exactă a tipului datelor cu
care lucrează algoritmul.
Date Tipul datelor: întreg
real numerice
logic
şir de caractere
Natura datelor: constante
variabile
Organizarea datelor: tablouri unidimensionale-vectori
bidimensionale-matrici
n-dimensionale
liste stive
cozi
ansamble
Operaţii cu date
- date întregi: +, -, *, /, ^ cu rezultatul întreg sau real
< , >, , =, , ≠ , ≤ , ≥ cu rezultatul de tip logic
- date reale: aceleaşi operaţii ca în cazul datelor întregi, cu rezultatul real în cazul operatorilor
aritmetici şi logic în cazul operatorilor relaţionali.
- date logice: disjuncţia (۷ ) , conjuncţia ( ۸) , negaţia (- )
- şiruri de caractere: concatenarea – rezultat de tip şir de caractere, comparaţiile (bazate pe
ordinea lexicografică) – rezultat de tip logic.
- stive, cozi, ansamble: extragerea şi respectiv introducerea unui element într-o stivă, coadă sau
ansamblu (x A, x A) precum şi verificarea dacă o stivă, coadă sau ansamblu este vid
( A = ø )
Cuvinte cheie: cuvinte din limba engleză care identifică un tip de date sau descriu o instrucţiune.
Programarea Calculatoarelor
27
Instrucţiuni: Din punct de vedere al scrierii instrucţiunilor, o instrucţiune poate ocupa mai
multe rânduri, sau pe un rând pot fi scrise mai multe instrucţiuni. Instrucţiunile vor fi separate,
între ele, folosind caracterul ';'.
Instrucţiuni declarative: integer, real, bool, char, array, stack, queue, heap urmat de un şir
de variabile separate între ele prin virgulă, variabile pentru care indicăm că au tipul respectiv.
Exemple: integer a, b, c; array V(n), A(m,n) ; stack S
Instrucţiuni efective, executabile
1) Instrucţiunea de atribuire
v e
unde v este o variabilă, iar e este o expresie de acelaşi tip (integer, real, bool, char)
sau (v1, v2, …., vn) (e1, e2, …., en)
care realizează simultan cele n atribuiri.
2) Instrucţiunile de citire/scriere
read a1, a2, …, an
write a1, a2, …, an
3) Instrucţiunea de selecţie simplă if-then-else
if p then S1
[else] S2
endif
unde p este un predicat, iar S1 şi S2 sunt secvenţe de instrucţiuni.
Se evaluează predicatul p şi în cazul în care valoarea este true, se trece la executarea secvenţei
de instrucţiuni S1. Dacă valoarea este false se trece la execuţia secvenţei S2, iar dacă aceasta nu
apare, se trece la execuţia instrucţiunii următoare instrucţiunii if.
4) Selecţia multiplă
case p1: S1
p2 : S2
...........
pn : Sn
[else] Sn+1
endcase
unde S1, …., Sn sunt secvenţe de instrucţiuni, iar p1, …., pn sunt predicate satisfăcând
condiţiile:
pi ۸ pj = 0 () i ≠ j p1 ۷ p2 ۷ ….. ۷ pn = 1 dacă nu există ramura else.
Dacă p1 este TRUE, se trece la execuţia secvenţei S1după care se trece la instrucţiunea
următoare după endcase. Analog pentru p2, ..., pn. Dacă nici un predicat nu a fost adevărat şi
există ramura else, se trece la execuţia secvenţei corespunzătoare, iar dacă nu există ramura else,
se trece direct la instrucţiunea următoare după endcase.
Programarea Calculatoarelor
28
5) Instrucţiunea repetitivă while (cu test iniţial)
while p
S
repeat
Secvenţa de instrucţiuni S se execută repetat atâta timp cât predicatul p este TRUE.
6) Instrucţiunea repetitivă do (cu test final)
do
S
until p
Spre deosebire de instrucţiunea while, instrucţiunea do începe cu executarea secvenţei S şi nu cu
verificarea predicatului p.
7) Instrucţiunea repetitivă for (cu număr cunoscut de paşi)
for v = e1, e2 [e3]
S
repeat
unde v este o variabilă numerică (contor), iar e1, e2, e3 sunt expresii aritmetice cu e3 ≠ 0. Dacă
e3 lipseşte, se consideră egal cu 1. Efectul este executarea secvenţei S de n ori.
8) Instrucţiunea exit
exit
determină trecerea la execuţia primei instrucţiuni care urmează celui mai interior ciclu do, while,
for, ieşindu-se deci din acel ciclu.
Proceduri
Un program în limbajul algoritmic este o succesiune de una sau mai multe proceduri.
Declararea unei proceduri constă în :
procedure nume [ (listă de parametrii)]
[ declaraţii
[ secvenţă de instrucţiuni
end
Lista de parametrii este un şir de variabile despărţite prin virgulă ce permit transmiterea datelor
între proceduri.
O procedură poate apela o altă procedură:
Fie procedura procedure nume [ (p1, …, pn)]
Adresarea ei se face prin call nume [ (a1, …, an)], unde a1, …, an sunt argumente care păstrează
ordinea, tipul şi dimensiunile listei parametrilor p1, …, pn.
În cazul unei proceduri, lista de parametri conţine atât parametri de intrare, cât şi
parametri de ieşire (în urma apelării procedurii, vor stoca rezultatele calculate de instrucţiunile
procedurii).
Programarea Calculatoarelor
29
Laborator 4
4. ELEMENTE DE BAZĂ ALE LIMBAJULUI C++
VOCABULAR, EXPRESII, OPERATORI
1. Precizaţi care dintre declaraţiile de mai jos reprezintă definiţii valide de variabile:
int x = -20; // validă
unsigned int = 10; // invalidă: lipseşte numele variabilei
unsigned long a = 5, b = 3; // validă
int 3x; // invalidă: 3x nu poate fi un identificator
unsigned double a = 10.0; // invalidă: tipul double nu poate fi unsigned
float a = 10.54F; // validă
2. Expresia: x%10 > 9
a) poate fi falsă sau adevărată, în funcţie de valoarea lui x
b) este adevărată întotdeauna
c) este falsă întotdeauna
d) este incorectă din punct de vedere sintactic
3. Care dintre expresiile de mai jos produc la evaluare valoarea 15:
a) 10/9 + 14
b) 5 * 2+6
c) 30 % 2
d) 3(5)
4. Folosind operatorul condiţional, scrieţi o secvenţă de cod care să testeze dacă trei
numere naturale introduse de la tastatură: a, b, c sunt în ordine crescătoare sau nu.
int a, b, c;
cin>>a>>b>>c;
cout<<(a<=b && b<<c ? ”ordine crescătoare”: ”ordine oarecare”)<<endl;
5. Dacă a este o variabilă de tipul int, care dintre următoarele expresii este întotdeauna
adevărată?
a) (a > 0) && (a == 0)
b) (a >= 0) || (a == 0)
c) (a > 0) && ( a <= 0)
d) (a > 0) || ( a <= 0)
6. Care dintre expresiile de mai jos exprimă formula:
Programarea Calculatoarelor
30
)*ln(
*
yx
dc
ab
a) sqrt(pow(a,b)/(c*d))/log(x*y)
b) pow(pow(a,b)/(c*d), 1/2)/ln(x*y)
c) sqrt(pow(a,b)/(c*d))/ln(x*y)
d) pow(pow(a,b)/(c*d), 1/2)/log(x*y)
7. Instructiunea corectă de definire pentru o variabilă întreagă numită „suma” este:
a) suma : integer;
b) integer suma;
c) int suma;
d) suma int;
8. Care este valoarea expresiei următoare?
(20 - 10) / (30 + 40) + (60 - 50.0) / 70
a) -0.142857 b) 0.142857 c) 0 d) 0.000000
9. Care va fi valoarea variabilelor următoare după iniţializare?
double a = 3 * int(3.14); // a va avea valoarea 9
long b = 2*3.14 - 6; // b va avea valoarea 0
char c = 'a' + 3; // c va avea valoarea ’d’
10. Care dintre expresiile de mai jos nu este echivalentă cu expresia:
if (num != 10):
a) if (num > 10 || num < 10)
b) if ( !(num == 10))
c) if (num – 10)
d) if ( !(num – 10))
11. Expresia:
!(p && q) este echivalentă cu:
a) !p || !q b) !p && !q c) !p && q d) p || q
12. Care dintre expresiile de mai jos exprimă formula:
edc
ba*
, a, b, c, d, e fiind variabile de tip double.
a) a-b / c+d * e;
b) (a-b) / (c+d) * e;
c) (a-b)/c+d * e;
d) a-b / (c+d) * e;
13. Care dintre expresiile de mai jos exprimă o pătrime (număr real):
Programarea Calculatoarelor
31
a) 1/4
b) 1%4
c) 1./4
d) 1.%4
14. Adăugaţi paranteze suplimentare următoarelor expresii pentru a indica în mod explicit
ordinea de evaluare a operatorilor ce compun respectivele expresii:
i) (a > b - c && a <= b + c || a = = 0)
(((a > (b – c)) && (a <= (b + c))) || (a == 0))
ii) (++a * b-- / ++a – b--)
(((++a) * (b--)) / ((++a) – b--))
iii) (a < b ? c < b ? b * c + 5 : b / c - 5 : b + c)
((a < b) ? ((c < b) ? ((b * c) + 5) : ((b / c) - 5)) : (b + c))
15. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
const int x=10; // linia #1
- -x; // linia #2
cout<<x<<endl; // linia #3
a) 10 b) -10 c) Eroare la linia #2 d) Eroare la linia #3
16. Care este valoarea expresiei:
10 / 20 - 10 % 3 * 3 + 3
a) 2 b) 0 c) 3 d) 1
17. În ce condiţii secvenţa de mai jos va afişa “da”?
if (valoare == 10 || 1) cout<<"da";
a) când valoare este 10 b) când valoare este 10 c) întotdeauna d) niciodată
18. Scrieţi câte o expresie pentru :
i) A testa dacă un număr natural a este impar.
n%2 != 0
ii) A testa dacă un caracter c reprezintă o cifră.
c >= '0' && c <= '9'
iii) A testa dacă un caracter c reprezintă o literă.
(c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
iv) A testa dacă un număr a este par şi pozitiv sau dacă este impar şi negativ.
Programarea Calculatoarelor
32
(n%2 == 0 && n >= 0) || (n%2 != 0 && n < 0)
19. Ce va apărea afişat în urma execuţiei instrucţiunii:
cout<<(8 / 2 * 5 % 3 - 10+ (9/5));
a) 1 b) 2 c) -7 d) -9
20. Ce se va afişa în urma execuţiei următoarei instrucţiuni:
cout << ((1+2*(3/2+(40%3*3)*2)-1)+10);
a) 20 b) 24 c) 30 d) 20
21. Care dintre expresiile de mai jos exprimă formula:
1*
1
yx , x şi y fiind variabile de tip double.
a) 1/(xy+1)
b) 1/x*y+1
c) 1/(x*y+1)
d) 1/xy+1
22. Care dintre următoarele expresii este adevărată dacă şi numai dacă valorile
variabilelor x şi y sunt numere naturale consecutive?
a. x-y==1
b. (x==1) && (y==2)
c. (x-y==1) && (y-x==1)
d. y=x±1
e. (x-y==1) || (y-x==1)
Programarea Calculatoarelor
33
Laborator 5
5. INSTRUCŢIUNI
1. Dacă se introduce de la tastatură pentru variabila a valoarea 100, ce se va afişa la
terminarea execuţiei secvenţelor de cod următoare:
i)
if (a >= 0)
if (a < 50)
cout << "valoarea lui a este mica"<<endl;
else
cout << "valoarea lui a este negativa"<<endl;
Răspuns: mesajul afişat va fi: "valoarea lui a este negativa" deoarece compilatorul asociază
cuvântul cheie “else” cu cel mai apropiat “if” care îl precede. Practic, aranjarea corectă a liniilor
de cod în acest caz este:
if (a >= 0)
if (a < 50)
cout << "valoarea lui a este mica"<<endl;
else
cout << "valoarea lui a este negativa"<<endl;
ii)
if (a >= 0)
{
if (a < 50)
cout << "valoarea lui a este mica"<<endl;
}
else
cout << "valoarea lui a este negativa"<<endl;
Răspuns: în acest caz nu va fi afişat nici un mesaj.
2. Ce se va afişa la terminarea execuţiei programului următor:
void main()
{
int a;
// double b;
a= 10;
b=20;
cout<<a+b<<endl;
}
Programarea Calculatoarelor
34
a) Eroare: identificator nedeclarat b) 30 c) 30.00 d) 30.0
3. Care este valoarea variabilei i la terminarea execuţiei următoarei secvenţe de cod:
i = 0;
while(i <=50)
i += 5;
a) 50 b) 55 c) 45 d) 5
4. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a=50, b=10;
while (a > b)
{
a -= 5;
b += 5;
}
cout << a << endl;
a) 20 b) 30 c) 40 d) 50
5. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 10;
if(a = 5)
a ++;
cout << a;
a) 10 b) 6 c) 5 d) 0
6. În secvenţa de mai jos, de câte ori are loc ciclarea?
int a=10, b=10, c=20, contor=0, suma=0;
do
{
if (a>=b) suma++;
cout<<suma;
contor++;
} while (a<c);
a) 0 b) infinit c) 10 d) 1
7. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a=10, b=20;
a *= (20+b)*a;
cout << ”valoarea: ”<<(20+b)*a;
Răspuns: valoarea: 160000
8. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
Programarea Calculatoarelor
35
num = 0;
while (num < 10)
{
cout<<num<<” “;
num = num + 1;
}
a) 0 1 2 3 4 5 6 7 8 9
b) 0 1 2 3 4 5 6 7 8 9 10
c) 1 2 3 4 5 6 7 8 9 10
d) 1 2 3 4 5 6 7 8 9 0
9. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 15, b = 10, c = 5;
if (c >= b && a) b--;
else if (b <= c)
{
a--;
if (a<b)
c--;
}
cout << a*b*c << endl;
a) 700 b)800 c)750 d) 500
10. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 0, b = 20, c;
if(a) c = 15;
else c = 20;
if(b) c = 5;
else c = 10;
cout << c;
a) 15 b) 5 c) 20 d) 10
11. Care dintre următoarele instrucţiuni C++ este corect scrisă din punct de vedere
sintactic?
a) if a==1 cout << ”corect” b) if(a==1) cout << ”corect”;
c) if(a==1) cin << ”corect” d) if(a==1) cout >> ”corect”;
12. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 20, b=85;
while((b - a) % 3)
{
cout<<b<<" ";
Programarea Calculatoarelor
36
b -= 10;
}
a) 85 75 b) 85 75 65 55 c) 80 70 60 d) 80 70 60 50
13. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
float x = 50/8;
int y;
y = x;
cout << y/6 + y/6.0 + ceil(x/6);
a) 7 b)8 c)3 d) 5
14. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int x = 10;
if(x = 5)
if (x == 10) cout << x;
else
cout << “ ”;
cout << 55;
a) 10 55 b) 55 c) 5 d) 10
15. Care dintre secvenţele de atribuiri de mai jos sunt echivalente cu atribuirea:
v *= suma++; ?
a) suma = suma + 1; v = v * suma;
b) v= v * suma;
c) v = v * ++suma;
d) v = v * suma; suma = suma + 1;
16. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int i;
for(i = 1; i<= 1; i++)
cout<<i<<” “;
cout<<i<<endl;
a) 1 0 b) 1 1 c) 1 2 d) 0 0
17. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 10, b = 20, c = 30;
if (a < 5)
if (b < 10) cout << "unu";
else cout << "doi";
else if (c > 20)
Programarea Calculatoarelor
37
cout << "trei";
else
cout << "patru";
a) unu b) trei c) doi d) patru
18. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int x = 10, y = 0;
if (x)
cout<< 4;
cout<< 5;
if (y)
{
cout<< 6;
cout<< 7;
}
a) 45 b) 67 c) 4567 d) 456
19. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int x = 2;
do
{
cout<<x<<" ";
x--;
cout<<endl;
} while(x<0);
a) 2 b) 2 1 0 -1 c) 2 1 d) 2 1 0 -1 -2
20. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int a = 10;
while ( a = 5 )
{
a--;
cout << a << " ";
}
a) 10 b) 4 4 4…………. c) 20 d) 1
21. Ce se va afişa la terminarea execuţiei următoarei instrucţiuni:
if(–10) cout<<"da";
else cout<<”nu”;
a) da b) nu c) da nu d) nu se afişează nimic
Programarea Calculatoarelor
38
22. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int i=0, j=0;
for (i =20 ; i>= 5; i -= 5)
{
cout << i << endl;
for (j=0; j < 1;j++)
{
cout << (i + j) <<" ";
}
}
a) 20 b) 20 c) 20 d) 20
20 15 15 10 20 10 15 10
15 10 10 5 10 5 10 5
10 5 5 5 0
5
23. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
for (int i = 1; i < 10; i++)
{
if( i > 5 ) break;
else continue;
cout << i;
}
a) 1 2 3 4 5 6 7 8 9 b) 5 c) nimic d) 1 2 3 4
24. Care dintre instrucţiunile „for” de mai jos produc acelaşi rezultat ca următoarea
secvenţă de instrucţiuni?
int a = 1;
do
cout << a++;
while ( a <= 10 );
a) for(int a=1; a<10; a++) cout<<a;
b) for(int a=0; a<10; ) cout<<++a;
c) for(int a=0; a<11; a++) cout<<a;
d) for(int a=0; a<11; a++)cout<<++a;
25. Ce se va afişa la terminarea execuţiei următoarei secvenţe de cod:
int i = 1, suma = 0;
for ( ; i <= 10; i *= 2, suma += i);
cout << suma;
a) 0 b) 30 c) 100 d) 20
Programarea Calculatoarelor
39
Laborator 6
6. ALGORITMI CORESPUNZĂTORI UNOR PRELUCRĂRI
ELEMENTARE REPREZENTAŢI ÎNSCHEMĂ LOGICĂ /PSEUDOCOD
Partea întâi
Algoritmi reprezentaţi în schemă logică
1. Se citesc numere până la introducerea valorii 0. Aflaţi suma lor.
2. Aflaţi suma numerelor de trei cifre.
3. Se citesc valorile pentru două variabile întregi (a şi b) şi se afişează care variabilă este
mai mare precum şi valoarea acesteia.
NU
DA
DA NU
n#0
CITEŞTE n
START
s=0
s=s+n
CITEŞTE n
SCRIE s
STOP
NU
START
s=0
i=100
s=s+i
i=i+1 SCRIE s i#1000
STOP
DA
Programarea Calculatoarelor
40
Programul scris în C++
#include<iostream.h> // pentru functiile cin si cout
#include<conio.h> // pentru functiile clrscr si getch
void main()
{
clrscr(); // sterge ecranul
int a, b;
cout << "a="; cin >> a;
cout << "b="; cin >> b;
if(a>b)
{
cout << "a este mai mare" << endl;
cout << "a=" << a << endl;
}
else
if(a==b)
{
cout << "a identic cu b" << endl;
cout << a << endl;
}
else
{
cout << "b este mai mare" << endl;
cout << "b=" << b << endl;
};
// intrerupe executia pana cand este apasata o tasta
Programarea Calculatoarelor
41
cout << endl << "Apasati o tasta...";
getch(); // citeste un caracter de la consola fara sa il afiseze
};
Probleme rezolvate în pseudocod
1. Să se determine aria unei suprafeţe determinate de o linie poligonală închisă P = P1 P2
....Pn, unde Pi (Xi, Yi), i = 1...n sunt determinate de coordonatele carteziene (Xi, Yi), i = 1,
n.
Obs:
n
i
iiii yxyxS1
11 )(2
1, unde xn+1 = x1, yn+1 = y1
Soluţie:
read n;
array x[n+1], y[n+1];
for i = 1, n
read xi , yi
repeat;
xn+1 x1 ; yn+1 y1 ;
s 0;
for i = 1, n
s s + xi * yi+1 - yi * xi+1
repeat;
s abs (s/2);
write s;
P12
P13
P14
P6
P7
P8
P9 P10
P11
P2 P3
P4 P5
P1
Programarea Calculatoarelor
42
2. Să se determine valoarea numărului Pi din dezvoltarea în serie:
Pi/4 = 1 – 1/3 + 1/5 – 1/7 +… luându-se în considerare n termeni
Soluţie:
read n;
s 0 ; termen 1;
for i = 1, n
s s + termen / (2 * i – 1);
termen - termen
repeat;
pi 4 * s
write pi;
3. Se citeşte de la tastatură un număr natural n . Să se afişeze suma cifrelor acestui număr.
Obs:
a mod b = restul împărţirii întregi a lui a la b
a div b = câtul împărţirii întregi a lui a la b
Soluţie:
read n;
s 0;
while n 0
s s + n mod 10;
n n div 10
repeat
write s;
4. Se citeşte de la tastatură un număr natural n . Să se afişeze numărul răsturnat (citit de la
sfârşit spre început).
Soluţie:
read n;
ninv 0;
while n 0
ninv ninv*10 + n mod 10;
n n div 10;
repeat
write ninv;
5. Să se verifice dacă un număr natural n este prim.
Soluţie:
read n; prim 1;
Programarea Calculatoarelor
43
if n = 1 n = 0 then prim 0
else for i = 2, n div 2
if n mod i = 0 then prim 0
endif
repeat;
endif;
if prim = 1 then
write “ Nr. prim”
else
write “Nr. neprim”
endif;
6. Să se afişeze primele nr numere prime.
Soluţie:
read nr; n 2; j 0; /* j contorizează numărul de numere prime*/
while j < nr
prim 1;
for i = 2, int(sqrt(n))
if n mod i = 0 then
prim 0
endif;
repeat;
if prim = 1 then
write n; j j+1;
endif;
n n+1;
repeat;
7. Se citeşte de la tastatură un număr natural n . Să se afişeze descompunerea sa în factori
primi în formatul factor ^ exponent.
Soluţie:
read n;
i 2; /* începând cu i = 2 verificăm dacă i este divizor al lui n*/
while n 1
fm 0; /* în fm contorizăm de câte ori s-a împărţit n la i */
while n mod i = 0
fm fm + 1; n n div i
repeat;
if fm 0 then write i, ^, fm
endif;
i i +1;
repeat;
Programarea Calculatoarelor
44
8. Să se afişeze primele nr numere perfecte. Un număr se numeşte perfect, dacă este egal cu
suma divizorilor lui (mai puţin el).
Soluţie:
read nr;
n 6; // cel mai mic număr perfect este 6
j 0; // în j contorizăm numărul de numere perfecte
while j < nr
perfect 0;
s 0;
for i = 1, n div 2
if n mod i = 0 then
s s +i
endif;
repeat;
if s = n then
perfect 1
endif;
if perfect = 1 then
write n;
j j + 1
endif
n n + 1;
repeat;
9. Se citesc de la tastatură două numere reale a şi b. Scrieţi un algoritm care să realizeze
interschimbarea valorilor numerelor:
a) folosind o variabilă auxiliară
b) fără variabile auxiliare
Soluţie:
a) metoda de interschimbare se bazează pe principiul celor trei pahare:
pas 1: Se goleşte primul pahar în paharul auxiliar;
pas 2: Se goleşte al doilea pahar în primul pahar (rămas gol);
pas 3. Se goleşte paharul auxiliar în al doile pahar (rămas gol).
read a, b
aux a; a b; b aux;
write a, b
b) metoda de interschimbare se bazează pe operaţiile de adunare şi de scădere a celor două
numere:
read a, b
a a-b; b a+b; a b-a;
Programarea Calculatoarelor
45
write a, b
10. Conversii dintr-o bază de numeraţie în altă bază de numeraţie
a) Algoritm de conversie a unui număr scris în baza 10 într-o altă bază b cu b ≤ 9
Soluţie:
read n10, b; // n10 este numărul scris în baza 10
nb 0; // nb este numărul convertit în baza b
p 1;
while (n10 ≠0)
nb nb +p*(n10 mod b);
p p*10;
n10 n10 div b
repeat
write nb
b) Algoritm de conversie a unui număr din baza b în baza 10
Soluţie:
read nb, b; // nb este numărul scris în baza b
n10 0; // n10 este numărul convertit în baza 10
p 1;
do
n10 n10 +p*(nb mod b);
p p*b;
nb nb div 10
until (nb=0)
write n10
11. Se citeşte de la tastatură un număr natural n. Să se verifice dacă este palindrom, adică
citindu-l de la sfârşit spre început se obţine acelaşi număr.
Obs: Algoritmul calculează inversul numărului n prin extragerea pe rând a ultimei cifre din
numărul n şi compune unui nou număr cu aceste cifre.
Soluţie:
read n;
nrn; // în nr salvăm numărul iniţial n
n_inv0; //se iniţializează inversul numărului cu valoarea 0
while nr ≠ 0
n_inv n_inv *10 +nr mod 10;
nrnr div 10
repeat
Programarea Calculatoarelor
46
if n_inv = n then write “este palindrom”
else write “nu este palindrom”
endif
12. Fiind dat un interval [a,b] cu a şi b numere naturale citite de la tastatură, a < b, să se
afişeze toate palindroamele din acest interval.
Soluţie:
read a,b;
for n=a, b
nrn;
n_inv0;
while nr ≠ 0
n_inv n_inv *10 +nr mod 10;
nrnr div 10
repeat
if n_inv = n then
write n “este palindrom”
endif
repeat
13. Se citeşte de la tastatură un vector cu n componente reale.
Să se calculeze triunghiul de perimetru maxim ce se poate forma din aceste numere, iar în
caz că nu se poate forma nici un triunghi, să se afişeze un mesaj corespunzător.
Soluţie:
read n;
array v[n];
for i = 1, n
read vi
repeat;
for i = 1, n – 1
for j = i+1, n
if vi < vj then
aux vi;
vi vj;
vj aux;
endif
repeat
repeat;
gasit 0;
i 1;
Programarea Calculatoarelor
47
while (i< n-2) (gasit = 0)
if vi < vi+1 + vi+2 then
p vi + vi+1 + vi+2;
write p;
gasit 1;
endif
repeat
if gasit = 0 then write “ nu s-a putut forma nici un triunghi”
endif;
14. Se citeşte de la tastatură un vector cu n componente întregi v1, v2, …., vn. Să se reţină
într-un vector U toate numerele, fiecare valoare o singură dată (deci U are numai
componente distincte).
Soluţie:
array v[n], u[n]; read n;
for i = 1, n
read vi
repeat;
u1 v1 ; k 1 ; /* k contorizează poziţiile din vectorul U */
for i = 2, n /* cu indicele j parcurg vectorul U*/
r 0 ; j 1 ; /* dacă vi aparţine mulţimii U formată din k
elemente, r va lua valoarea 1 */
while (j k) (r = 0)
if vi = uj then r 1
else j j + 1
endif
repeat
if r = 0 then /* dacă vi nu aparţine mulţimii U, atunci îl adaug
pe poziţia k+1 */
k k + 1;
uk vi
endif
repeat;
for j = 1, k
write uk
repeat;
15. Fiind dată matricea A(nxm) şi matricea B (mxp), să se calculeze în matricea C(nxp)
produsul celor două matrici.
Obs: ci,j = ai,1 * b1,j + ai,2 * b2,j + …… + ai,m * bm,j = jk
m
k
ki ba ,
1
,
Soluţie:
Programarea Calculatoarelor
48
read n, m, p; array a[n,m], b[m,p], c[n,p];
for i = 1, n
for j = 1, m
read ai,j
repeat
repeat;
for i = 1, m
for j = 1, p
read bi,j
repeat
repeat;
for i = 1, m
for j = 1, p
ci,j 0;
for k = 1, m
ci,j ci,j + ai,k * bk,j ;
repeat
repeat
repeat;
for i = 1, n
for j = 1, p
write ci,j ;
repeat
newline
repeat
16. Fie ecuaţia de gradul al doilea cu coeficienţi reali ax2+bx+c=0 cu a≠0, a, b şi c fiind citite
de la tastatură. Scrieţi un algoritm care, fără a calcula rădăcinile ecuaţiei, să determine
natura şi semnul acestora.
Obs: se utilizează relaţiile lui Viete: x1+x2 = S = -b/a, x1*x2 = P = c/a
Soluţie:
read a,bc;
deltab*b – 4*a*c;
if delta ≥ 0 then
S -b/a ; P c/a;
if S ≥ 0 then
if P > 0 then write “x1 >0 şi x2>0”
else if P=0 then write “x1=0 şi x2>0”
else write “x1>0 şi x2>0,
cu |x1|>|x2|”
endif
endif
Programarea Calculatoarelor
49
else
if P > 0 then write “x1<0 şi x2<0”
else if P=0 then write “x1=0 şi x2<0”
else write “x1>0 şi x2<0,
cu |x1|<|x2|”
endif
endif
endif
else write “ecuaţia nu are soluţii numere reale”
endif
17. Inmulţirea a la russe: Se consideră următoarea metodă de înmulţire (numită
înmulţirea ”a la russe”) a două numere naturale nenule x şi y:
Se scriu deînmulţitul şi înmulţitorul pe aceeaşi linie, în două coloane alăturate. Se împarte
deînmulţitul la 2, succesiv, ignorând restul, până când numărul din prima coloană devine egal cu
1. În acelaşi timp, se înmulţeste înmulţitorul cu 2 atâtea etape câte au fost necesare împărţirii
deînmulţitului pentru a ajunge la valoarea 1. În coloana a treia se adună toate valorile de pe
coloana a doua care corespund unor valori impare aflate pe prima coloană.
Exemplu: fie x=25 şi y=16
Prin applicare algoritmului de mai sus, se va obţine configuraţia următoare:
x y rest suma
25 16 1 16
12 32 0
6 64 0
3 128 1 128
1 256 1 256
----------
400
Obs: În matematică, această metodă de înmulţire (de asemenea, cunoscută sub numele de
înmulţire egipteană sau înmulţire etiopiană), este una dintre cele două metode de înmulţire
utilizate de scribi.
Este o metodă sistematică pentru înmulțirea două numere care nu are nevoie de tabla înmulțirii,
are nevoie numai de înmulţire și împărţire la 2, și de adunare.
Prin această metodă se realizează de fapt conversia în baza 2 a primului număr: resturile obţinute
prin împărţirile succesive la 2 formează cifrele reprezentării în baza doi.
Produsul celor două numere se obţine prin înmulţirea succesivă a celui de al doilea număr cu
puteri ale lui 2 şi prin însumarea acelor produse care corespund unor cifre nenule în
reprezentarea binară a primului număr.
Programarea Calculatoarelor
50
Soluţie:
read a,b; array x[100], y[100];
i1; xia; yib;
sum0;
while xi>1
xi+1xi div 2;
yi+12*yi;
ii+1;
repeat
while i>0
if xi mod 2 =1 then
sumsum+yi;
endif
ii-1;
repeat
write sum
18. Calculul valorii unui polinom într-un punct dat.
Se consideră polinomul P cu coeficienţi reali, definit prin:
p(x) = anXn + an-1X
n-1 ... + a1X + a0
unde ai (i = 0, 1, ..., n) sunt numere reale si reprezintă coeficienţii polinomului P.
Se cere să se calculeze valoarea polinomului în punctul dat x0.
Obs: Pentru calculul valorii polinomului P pentru o valoare dată x = x0 se poate aplica schema
lui Horner, care constă într-o aranjare convenabilă a polinomului P astfel încât calculele să poată
fi executate cu un număr cât mai mic de operaţii.
Pentru reprezentarea polinomului se va utiliza un tablou de coeficienţi al cărui număr de
elemente este determinat de gradul polinomului şi nu depinde de numărul de termeni nenuli din
polinom.
Soluţie:
array a[n];
read n, x0, a0,…,an;
pan;
in-1;
do
pp*x0+ai;
ii-1;
until i=0
write p
Programarea Calculatoarelor
51
19. Adunarea a două polinoame.
Se consideră polinoamele P şi Q cu coeficienţi reali, definite prin:
p(x) = anXn + an-1X
n-1 ... + a1X + a0
unde ai (i = 0, 1, ..., n) sunt numere reale si reprezintă coeficienţii polinomului P.
q(x) = bmXm
+ bm-1Xm-1
... + b1X + b0
unde bi (i = 0, 1, ..., m) sunt numere reale si reprezintă coeficienţii polinomului Q.
Se cere să se determine polinomul sumă, S=P+Q.
Obs: gradul polinomului S va fi max {m,n}, iar coeficienţii săi vor fi:
ai, m+1≤i≤n, atunci când m<n
si = bi, n+1≤i≤m, atunci când m>n
ai +bi, 0≤i≤min {m,n}
Soluţie:
array a[n], b[m]; read n, m, a0,…,an, b0,…,bm;
if n<m then
minn; maxm
else
minm; maxn
endif
if m<n then
for i=m+1,n
siai
repeat
endif
if m>n then
for i=n+1,m
sibi
repeat
endif
for i=0, minim(m,n)
siai + bi
repeat
write s0,…,smax
Programarea Calculatoarelor
52
Probleme propuse
1. În planul xOy, se consideră un dreptunghi specificat prin coordonatele colţurilor stânga-
jos (xs,ys) şi dreapta–sus(xd,yd ). Să se determine dacă un punct oarecare M(x,y) se află sau
nu în interiorul dreptunghiului.
Obs: Un punct M(x,y) se găseşte in interiorul sau pe frontiera unui poligon convex dacă:
aria(A1A2...An) = aria(MA1A2) + aria(MA2A3) +...+ aria(MAnA1)
2. Se dă un poligon convex P specificat prin coordonatele vârfurilor şi un punct oarecare
M(x,y). Se cere să se calculeze distanţa de la punctul M la poligonul P.
Obs: Distanţa de la punctul M(x,y) la poligonul P = A1A2...An este egală cu lungimea celui mai
mic segment de la punctul M la un punct de pe poligonul P.
3. Se citesc trei valori reale, pozitive, a, b,c. Verificaţi dacă ele pot forma laturile unui
triunghi; aflaţi perimetrul şi aria acestuia.
Obs: Pentru arie se va folosi formula lui Heron:
)()()( cpbpappS , unde p=semiperimetrul.
Obs: Dacă triunghiul este dat prin coordonatele vârfurilor sale: A(xA,yA), B(xB,yB), C(xC,yC),
atunci fie se calculează dimensiunile laturilor prin formula distanţei între două puncte din plan şi
apoi se calculează aria prin formula lui Heron, fie se calculează aria pe baza formulei
determinantului:
4. Se dă un cerc C de centru O(x0, y0) şi rază r, cu x0, y0, r citite de la tastatură şi o dreaptă
(d) dată prin ecuaţia dreptei: ax+by+c = 0, cu a, b, c citite de la tastatură. Să se determine
poziţia dreptei (d) faţă de cercul C.
Obs: Distanţa de la centrul cercului la dreapta (d) se calculează cu formula distanţei dintre un
punct şi o dreaptă:
22
00
ba
cybxadist
5. Să se determine dacă un număr n introdus de la tastatură aparţine sau nu şirului lui
Fibonacci: 1,1,2,3,5,8,13,21, ………….
Programarea Calculatoarelor
53
6. Fiind dat un interval [a,b] cu a şi b numere naturale citite de la tastatură, a < b şi un alt
număr c citit de la tastatură, să se afişeze toate numerele din intervalul dat care sunt
divizibile cu numărul c.
7. Fiind date n intervale [a,b], n şi perechile a şi b fiind numere naturale citite de la
tastatură, a < b, să se afişeze capetele intervalului ce reprezintă intersecţia celor n intervale
date.
8. Să se determine toate numerele prime cu maxim 5 cifre care rămân prime şi după
inversarea lor.
9. Să se afişeze toate numerele de două cifre ce îndeplinesc condiţia:
2)( baab
10. Se citeşte de la tastatură un vector v cu n elemente reale, n≤10. Să se realizeze
permutarea circulară la stânga şi la dreapta a elementelor vectorului.
Obs: Permutarea circulară la dreapta: x1, x2, x3, …… xn-1, xn
x2, x3, …… xn-1, xn, x1
Permutarea circulară la stânga: x1, x2, x3, …… xn-1, xn
xn, x1, x2, x3, …… xn-1
11. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se verifice dacă
elementele vectorului formează o mulţime (adică au valori distincte).
12. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se afişeze acele
elemente ale vectorului pentru care suma cifrelor este divizibilă cu 5.
13. Să se determine ultima cifră a numărului 3x, x fiind un număr natural citit de la
tastatură.
Obs: Se va folosi restul împărţirii întregi a lui x la 3: x mod 3.
14. Se citeşte de la tastatură un vector v cu n elemente numere întregi, n≤100. Să se afişeze
elementele vectorului care sunt prime cu un număr dat k, k citit de la tastatură.
15. Să se determine acel k număr natural cu proprietatea: 2k+1
≤n, n fiind un număr natural
citit de la tastatură.
16. Să se determine dacă un număr n citit de la tastatură are cifrele in ordine strict
crescătoare.
Programarea Calculatoarelor
54
17. Pentru o valoare n citită de la tastatură, să se determine primele n triplete de numere
pitagorice.
Obs: x,y,z sunt numere pitagorice dacă x<y<z şi x2+y
2 = z
2.
18. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se construiască un
alt vector u de n elemente, astfel încât u[k] = restul împărţirii lui v[k] la suma cifrelor sale,
k=1,…,n.
19. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se construiască un
alt vector u de n elemente, astfel încât u[k] =
numărul divizorilor lui v[k], k=1,…,n.
20. Se citeşte de la tastatură un număr natural n cu cel mult 9 cifre. Să se afişeze cel mai
mare şi cel mai mic număr care se poate forma cu cifrele distincte ale numărului.
21. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se scrie un program
care să insereze în vector pe poziţia k (k citit de la tastatură, k≤n) un nou element citit de la
tastatură. Celelalte elemente, începând cu poziţia k+1 să fie deplasate la dreapta, rezultând
un vector cu n+1 componente.
22. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se scrie un program
care să mute la sfârşitul vectorului toate elementele sale nule, fără a utiliza un vector
auxiliar.
23. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se scrie un program
care să extragă din acest vector subşirul de dimensiune maximă, ordonat crescător.
24. Se citeşte de la tastatură un număr natural n.
a) Să se scrie un program care să afişeze numărul obţinut prin eliminarea cifrelor care se
repetă în numărul dat.
b) Să se scrie un program care să afişeze numărul obţinut prin interschimbarea cifrelor
egal depărtate de capetele numărului.
c) Să se scrie un program care să afişeze cel mai mare număr care se poate forma din
cifrele numărului dat
Programarea Calculatoarelor
55
Laborator 7
7. ALGORITMI CORESPUNZĂTORI UNOR PRELUCRĂRI
ELEMENTARE REPREZENTAŢI
ÎN SCHEMĂ LOGICĂ / PSEUDOCOD
Partea a doua
TESTE GRILĂ
1. Fie secvenţa de pseudocod :
a ←10;
b ←a+10;
if (a≠b) then b ←b+10;
else a ←a+10;
endif
a ←a*b;
Ce valoare vor avea variabilele a şi b la sfârşitul acestei secvenţe de instrucţiuni?
a) 20 200 b) 30 300 c) 10 30 d) 20 300 e) 30 200
2. Fie secvenţa de pseudocod :
read a;
while (a≠0)
xa mod 10;
a a div 10
repeat
write x
Ce valoare va fi afişată la sfârşitul acestei secvenţe de instrucţiuni pentru a =42765 ?
a) 42764 b) 0 c) 4 d) 5 e) 56724
3. Fie secvenţa de pseudocod :
read temperatura;
if (temperatura > 40) then
write “canicula”;
else
if (temperatura > 30) then
write “foarte cald”;
else
if (temperatura > 25) then
write “cald”;
Programarea Calculatoarelor
56
else
if (temperatura < 25) then
write “optim”;
endif
endif
endif
endif
La implementarea în C++ a secvenţei de mai sus, scrisă în pseudocod, s-a constatat că
pentru valoarea variabilei “temperatura” = 25, programul nu a afişat nimic. Acest lucru
este cauzat de:
a) o eroare logică (de programare)
b) o eroare de compilare
c) o eroare de sintaxă
d) o eroare de rulare (de execuţie)
Pentru valoarea variabilei “temperatura” = 20, programul va afişa:
a) cald b) foarte cald c) optim d) canicula
4. Fie secvenţa de pseudocod :
read a,b;
c ←0;
while (a≠0)
c ←c*10+a mod 10;
a ←[a/100];
repeat
while ((b*c>0) & (b mod10 = cmod 10))
b ←[b/10];
c ←[c/10];
repeat
s ←b+c;
write s
Ce valoare va fi afişată la sfârşitul secvenţei de instrucţiuni prezentată mai jos pentru
pentru a =123456 şi b =642 ?
a) 6 b) 1 c) 0 d) 2
5. Fie secvenţa de pseudocod :
for i=1,5
for j=1,5
if((i=j)∨(i+j=i) then write “*”
else write”0”
endif
Programarea Calculatoarelor
57
repeat
newline
repeat
Ce configuraţie va fi afişată la sfârşitul acestei secvenţe de instrucţiuni ?
a) 00*00 b) *0*0* c) *000* d) 00000
0*0*0* 0*0*0 0*0*0 *0*0*
*0*0*0 *0*0* 00*00 00000
0*0*0* 0*0*0 0*0*0 *0*0*
00*00 *0*0* *000* 00000
6. Trei dintre următoarele patru secvenţe pseudocod verifică dacă numărul natural a citit
de la tastatură este un număr par.
Care este secvenţa care nu realizează acest lucru ?
a) if (a div 2 = a/2) then
write “a este par”;
else
write “a este impar”;
endif
b) if (a mod 2 = 0) then
write “a este par”;
else
write “a este impar”;
endif
c) if ((a-1) mod 2 = 0) then
write “a este par”;
else
write “a este impar”;
endif
d) if ((2*a) mod 2 = 0) then
write “a este par”;
else
write “a este impar”;
endif
7. Ce realizează următorul algoritm scris în pseudocod?
array a[n]; read n;
for k=0,n-1
read ak
repeat
Programarea Calculatoarelor
58
for i=n-2,0
v ←ai;
for j=i,n-2
if v>aj+1 then aj ←aj+1
else break
endif
repeat
aj ←v;
repeat
for k=0,n-1
write ak
repeat
a) Ordonarea descrescătoare a elementelor vectorului a
b) Ordonarea crescătoare a elementelor vectorului a
c) Interschimbarea elementelor vectorului de pe două poziţii consecutive
d) Interschimbarea elementelor vectorului egal depărtate de capete
8. Se consideră următoarea secvență în pseudocod:
read a;
while a < 7
b ← a - 2;
write a + b;
a ← a - b + 1;
repeat;
write b;
Care este valoarea afișată în final pentru b:
a) 3
b) 5
c) -1
d) valoarea lui b nu este afișată
9. Se consideră următoarea secvență în pseudocod:
read a;
i ← 1;
do
read b; write b;
i ← i + 1;
until b<a;
write i;
Pentru care dintre următoarele secvențe de numere introduse se afișează în final valoarea 5:
a) 7, 1, 2, 3, 4, 9
b) 8, 5, 4, 3, 9
Programarea Calculatoarelor
59
c) 7, 7, 2, 2, 5, 9
d) 8, 9, 10, 1, 12
10. Valoarea lui i afișată în final pentru secvența de pseudocod de la exercițiul 9 reprezintă:
a) numărul valorilor citite strict mai mici decât a
b) numărul valorilor citite strict mai mari decât a
c) numărul valorilor citite strict mai mari sau egale cu a
d) o altă valoare
11. Având algoritmii:
i ← 0;
s ← 0;
while i ≠ 5
s ← 2 * s + i;
i ← i + 1;
repeat;
write i;
write s;
i ← 0;
s ← 0;
do
s ← 2 * s + i;
i ← i + 1;
until i = 5;
write i;
write s;
care din afirmațiile următoare este adevărată:
a) algoritmii sunt echivalenți - valorile afișate pentru i și s sunt identice
b) algoritmii nu sunt echivalenți - valorile afișate pentru i și s sunt diferite
c) algoritmii nu sunt echivalenți - valorile afișate pentru i sunt diferite
d) algoritmii nu sunt echivalenți - valorile afișate pentru s sunt diferite
12. Pentru următoarea secvență de pseudocod:
i ← 5;
while i > 0
i ← i - 1;
if i = 1 then
i ← 0;
endif;
repeat;
specificați care din următoarele afirmații este adevărată:
a) structura decizională nu influențează valoarea variabilei i
b) structura decizională nu influențează numărul de execuții ale structurii repetitive
c) condiția i=1 este redundantă (nu influențează numărul de execuții ale structurii repetitive)
d) structura decizională influențează numărul de execuții ale structurii repetitive
13. Pentru algoritmul de la exercițiul 12 specificați de câte ori se repetă bucla:
a) de 3 ori
b) de 4 ori
c) de 5 ori
d) de 6 ori
Programarea Calculatoarelor
60
Laborator 8
8. PROBLEME REZOLVATE ÎN C++ CU ALGORITMI
REPREZENTAŢI ÎN PSEUDOCOD
1. Să se scrie un program care primeşte de la consolă temperatura exprimată în grade
Celsius şi afişează valoarea acesteia în grade Fahrenheit. În final utilizatorul poate relua
conversia.
Formula pentru conversia din grade Celsius în grade Fahrenheit este:
Fo
=9
5× C
o+32
Algoritmul scris în pseudocod:
do
read tempC;
tempF ← 9/5 * TempC + 32; write tempF;
write “Repetati conversia? (d/n)”; read r;
until r ≠ 'd' ⋀ r ≠ 'D';
Programul scris în C++
#include<iostream.h>
#include<conio.h>
void main()
{
float tempC, tempF;
char r;
do
{
clrscr(); // sterge ecranul
cout << "Introduceti temperatura in grade Celsius: "; cin >> tempC;
tempF = tempC * 9 / 5 + 32;
cout << "Temperatura in grade Fahrenheit este: " << tempF << endl;
cout << "Repetati conversia? (d/n)"; cin >> r;
} while ( (r=='d') || (r=='D') );
};
Obs: În evaluarea expresiilor matematice trebuie ţinut seama de tipul operanzilor şi ordinea de
evaluare a expresiilor. Dacă am fi scris formula astfel:
tempF = 9 / 5 * tempC + 32;
prelucrarea acesteia ar fi produs un rezultat eronat.
Programarea Calculatoarelor
61
Expresia 9/5 din cauza faptului că 9 este reprezentat ca întreg este evaluată ca un întreg, iar
valoarea corectă a fracției 9/5 (1,8) este transformată prin trunchiere tot într-un întreg (1) ceea ce
evident denaturează rezultatul expresiei.
Variabila tempC este de tip float şi în această situaţie evaluarea se va face corect dacă formula
este scrisă:
tempF = tempC * 9 / 5 + 32;
2. Să se scrie un program simplu care citeşte de la consolă un număr natural n şi calculează
factorialul acestui număr.
Algoritmul scris în pseudocod:
read n;
factorialN ← 1;
for i=1,n
factorialN ← factorialN * i;
repeat;
write factorialN;
Programul scris în C++:
#include<iostream.h>
void main()
{
unsigned int n;
unsigned long factorialN;
/* daca pentru n se vor folosi valori mai mari decat 33, variabila
factorialN va trebui sa fie de tipul unsigned double pentru a
putea pastra valoarea factorialului */
cout << "n = "; cin >> n;
factorialN = 1;
for(int i=1;i<=n;i++)
factorialN = factorialN * i;
cout << "n! = " << factorialN << endl;
};
Obs: La stabilirea tipurilor variabilelor este necesar să ţinem seama de valorile maxime şi
minime pe care urmează să le memorăm în acele variabile.
În exemplul de mai sus, dacă pentru variabila factorialN am fi utilizat tipul unsigned int (ce
poate memora numere în intervalul 0-65.535) cum probabil am fi fost tentaţi iniţial să o facem,
pentru valori ale lui n mai mari de 8 ar fi fost imposibil să putem memora valoarea factorialului
(9!=362.880) în variabila factorialN.
De aceea am ales unsigned long.
Desigur, nici acest tip nu poate memora numere foarte mari (0-4.294.967.295) şi de aceea cea
mai bună soluţie ar fi să utilizăm tipul unsigned double pentru variabila factorialN.
Programarea Calculatoarelor
62
3. Să se scrie un program simplu care citeşte de la consolă un şir X de n elemente întregi
(n<=50). Să se afişeze:
a. suma elementelor pozitive
b. produsul elementelor pare
c. suma elementelor negative aflate pe poziţii impare
d. media aritmetică a elementelor ce dau restul 2 la împărţirea cu 5
e. numărul elementelor mai mici (strict) decât 5.
f. Să se verifice dacă elementul cu index m este divizibil cu 4.
Notăm în pseudocod: a mod b = restul împărţirii întregi a lui a la b
Algoritmul în pseudocod este fragmentat pentru o mai uşoară înţelegere:
încărcarea elementelor intregi ale vectorului X:
do
read n;
until n>1 and n≤50
for i=1,n
read X(i);
repeat;
a. suma elementelor pozitive:
suma ← 0;
for i=1,n;
if X(i) > 0 then
suma ← suma + X(i);
endif;
repeat;
write “Suma elementelor pozitive este: “;
write suma;
b. produsul elementelor pare:
produs ← 1;
for i=1,n
if X(i) mod 2 = 0 then
produs ← produs * X(i);
endif;
repeat;
write “Produsul elementelor pare este: “;
write produs;
c. suma elementelor negative aflate pe poziţii impare:
suma ← 0;
Programarea Calculatoarelor
63
for i=1,n
if X(i) < 0 and i mod 2 = 1 then
suma ← suma + X(i);
endif;
repeat;
write “Suma elementelor negative aflate pe pozitii impare este: “;
write suma;
d. media aritmetică a elementelor ce dau restul 2 la împărţirea cu 5
suma_elem ← 0;
nr_elem ← 0;
for i=1,n
if X(i) mod 5 = 2 then
nr_elem ← nr_elem + 1;
suma_elem ← suma_elem + X(i);
endif;
repeat
if nr_elem = 0 then
write “Nu exista elemente ce dau restul 2 la impartirea cu 5.”;
else
write “Media aritmetica a elementelor ce dau restul 2 la
impartirea cu 5 este: “;
write suma_elem / nr_elem;
endif;
e. numărul elementelor mai mici (strict) decât 5
nr_elem ← 0;
for i=1,n
if X(i) < 5 then
nr_elem ← nr_elem + 1;
endif;
repeat;
write “Numarul elementelor mai mici ca 5 este: “;
write nr_elem;
f. să se verifice dacă elementul cu index m este divizibil cu 4
do
read m;
until m≥1 and m≤n;
if X(m) mod 4 ≠ 0 then
write “Numarul X(m) NU este divizibil.”;
else
write “Numarul X(m) este divizibil cu 4.”;
endif;
Programarea Calculatoarelor
64
Obs: La scrierea codului în C++ trebuie să ţinem seama de faptul că indexarea vectorului X
începe de la zero (indexul primului element întreg al vectorului X este zero). Acest prim element,
deşi are indexul 0 (care este număr par), este de fapt plasat pe o poziţie impară în cadrul
vectorului (şirului de numere).
Obs: Evaluarea logică (adevărat sau fals) a unei variabile numerice este: fals (false, 0) dacă
variabila are valoarea zero sau adevărat (true, 1) dacă variabila este diferită de zero (are o
valoare nenulă). De exemplu, pentru secvenţa de instrucţiuni:
int a, b;
a=0; b=-7;
evaluarea logică (în instrucţiuni de tip decizional - if) a variabilelor a şi b întoarce rezultatul false
(0) pentru a şi true (1) pentru b.
Programul complet scris în C++ pentru rezolvarea pe rând a celor şase cerinţe ale
problemei 3:
#include<iostream.h>
#include<conio.h>
void main()
{
int n, X[50];
// preia de la consola elementele din sirul X
do
{
clrscr();
cout<<"Introduceti nr. de elemente ale sirului X (2-50): ";
cin>>n;
}while((n<2)||(n>50));
cout<<"Introduceti elementele sirului X"<<endl;
for(int i=0;i<n;i++)
{
cout<<"X["<<i<<"]= ";
cin>>X[i];
};
// a. calculeaza suma elementelor pozitive
int suma=0;
for(i=0;i<n;i++)
if(X[i]>0)
suma+=X[i];
cout<<"Suma elementelor pozitive este "<<suma<<endl;
// b. calculeaza produsul elementelor pare
long produs=1;
for(i=0;i<n;i++)
if(!(X[i]%2)) // conditia se poate scrie si ((X[i]%2)==0)
Programarea Calculatoarelor
65
produs*=X[i];
cout<<"Produsul elementelor pare este "<<produs<<endl;
// c. calculeaza suma el. negative aflate pe pozitii impare
suma=0;
for(i=0;i<n;i++)
if((i%2==0)&&(X[i]<0)) // i este par si X[i] este negativ
suma+=X[i];
cout<<"Suma elementelor negative aflate pe pozitii impare este
"<<suma<<endl;
// d. calculeaza media aritmetica a elementelor care dau restul 2
// la impartirea cu 5
// pentru suma_elem folossim float pt. a calcula corect media
float suma_elem=0; int nr_elem=0;
for(i=0;i<n;i++)
if((X[i]%5)==2)
{
nr_elem++;
suma_elem+=X[i];
};
if(nr_elem==0)
cout<<"Nu exista el. ce dau rest 2 la impartirea cu 5."<<endl;
else
cout<<"Media aritmetica a el. ce dau rest 2 la impartirea cu 5
este " <<suma_elem/nr_elem<<endl;
// e. numara elementele mai mici (strict) ca 5
nr_elem=0;
for(i=0;i<n;i++)
if(X[i]<5)
nr_elem++;
cout<<"Nr. elem. mai mici decat 5 este "<<nr_elem<<endl;
// f. verifica daca elementul cu indexul m este divizibil cu 4
int m;
do
{
cout<<"Indexul elementului pentru verificarea diviziunii cu 4 (0-"<<n-1<<") ";
cin>>m;
}while((m<0)||(m>n-1));
if(X[m]%4) // conditia se poate scrie si ((X[m]%4)==1)
cout<<"Numarul "<<X[m]<<" NU este divizibil."<<endl;
else
cout<<"Numarul "<<X[m]<<" este divizibil cu 4."<<endl;
// asteapta apasarea unei taste pt. a iesi din executie program
cout<<endl<<"Apasati o tasta...";
getch();
};
Programarea Calculatoarelor
66
Obs: Această problemă cu toate subpunctele sale (mai puţin f) poate fi rezolvată folosind o
singură parcurgere a vectorului X – bucla for în care se face încărcarea cu valori a vectorului.
Pentru aceasta, toate variabilele necesare rezolvării cerinţelor vor fi declarate la începutul
funcţiei main şi în cadrul buclei, după citirea valorii pentru X[i] se vor face testele şi prelucrările
necesare rezolvării.
4. Să se scrie un program simplu care citeşte de la consolă un număr natural n şi afişează
suma cifrelor acestui număr.
Notăm în pseudocod: a mod b = restul împărţirii întregi a lui a la b
a div b = câtul împărţirii întregi a lui a la b
Algoritmul scris în pseudocod:
read n;
suma ← 0;
while n ≠ 0
suma ← suma + n mod 10;n ← n div 10;
repeat;
write suma;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
unsigned long n;
unsigned int suma = 0; // declarare si initializare variabila suma
clrscr(); // sterge ecranul
cout << "Introduceti numarul n: "; cin >> n;
while(n>0)
{
suma += n % 10; // se mai poate scrie si suma = suma + n % 10;
n /= 10; // se mai poate scrie si n = n / 10;
};
cout << "Suma cifrelor numarului este " << suma << endl;
cout << endl << "Apasati o tasta...";
getch();
};
Obs: Ne amintim că în prima problemă (conversia din grade Celsius în grade Fahrenheit)
împărţirea a două numere întregi conducea la un rezultat eronat ca urmare a trunchierii fracției
9/5 din cauza faptului că pentru cei doi operanzi compilatorul folosește tipul int.
În rezolvarea problemei curente, acest lucru ne ajută să eliminăm repetat ultima cifră din
numărul n.
5. Să se scrie un program simplu care citeşte de la consolă un număr natural n şi îl afişează
răsturnat (citit de la sfârşit la început).
Programarea Calculatoarelor
67
Algoritmul scris în pseudocod:
read n;
n_invers ← 0;
while n ≠ 0
n_invers ← n_invers * 10 + n mod 10;
n ← n div 10;
repeat;
write n_invers;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
unsigned long n, n_invers;
cout << "Introduceti numarul n: "; cin >> n;
n_invers=0;
while(n>0)
{
n_invers = n_invers*10 + n%10;
n/=10;
};
cout << "Numarul inversat este: " << n_invers << endl;
cout << endl << "Apasati o tasta...";
getch();
};
Obs: Dacă numărul ce este introdus de la tastatură are cifra 0 la sfârșit, algoritmul de mai sus nu
permite rezolvarea corectă a problemei și de aceea el trebuie schimbat astfel (afișare cifră cu
cifră):
read n;
while n ≠ 0
write n mod 10;
n ← n div 10;
repeat;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
unsigned long n;
cout << "Introduceti numarul n: "; cin >> n;
cout << "Numarul inversat este: ";
while(n>0)
Programarea Calculatoarelor
68
{
cout << n%10;
n/=10;
};
cout << endl << "Apasati o tasta...";
getch();
};
6. Să se scrie un program simplu care citeşte de la consolă un număr natural n şi afişează
dacă acesta este un număr prim sau nu.
Algoritmul scris în pseudocod:
read n;
prim ← 1;
case n
0: prim ← 0;
1: prim ← 0;
2: prim ← 1;
else:
for i = 2,√nr
if n mod i = 0 then
prim ← 0;
exit for;
endif;
repeat;
endcase;
if prim = 1 then
write “Numarul este prim”;
else
write “Numarul nu este prim”;
endif;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
#include<math.h>
void main()
{
unsigned int n, prim=1;
clrscr();
cout<<"Introduceti numarul: "; cin>>n;
switch(n){
case 0:
prim=0; // numarul nu este prim
break;
Programarea Calculatoarelor
69
case 1:
prim=0; // numarul nu este prim
break;
case 2:
prim=1; // numarul este prim
break;
default:
for(int i=2;i<=int(sqrt(n));i++)
if(n%i==0)
{
prim=0; // numarul nu este prim
break; // se iese din bucla for
};
};
cout<<endl<<"Numarul"<<prim?" este ":" nu este "<<"prim"<<endl;
cout<<endl<<"Apasati o tasta...";
getch();
};
Obs: Soluţia acestei probleme este prezentată ca un exemplu de utilizare al instrucţiunii switch.
Rezolvarea se poate simplifica verificând ca valoarea lui n să fie mai mare sau egală cu 2 şi
păstrând doar secvenţa de pe ramura default a instrucţiunii switch.
Obs: Afișarea rezultatului este făcută folosind operatorul condiţional.
7. Să se scrie un program care afişează primele n numere prime.
Algoritmul scris în pseudocod:
read n;
nr ← 2;
while n > 0
prim ← 1;
for i=2,√nr
if nr mod i = 0 then
prim ← 0;
exit for;
endif;
repeat;
if prim = 1 then
write nr;
n ← n - 1;
endif;
nr ← nr + 1;
repeat;
Programarea Calculatoarelor
70
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
#include<math.h>
void main()
{
unsigned int n, prim;
unsigned long nr;
cout << "Cate numere prime afisez ? "; cin >> n;
nr=2; // incepem testarea de la 2 care este prim
while(n>0)
{
prim=1; // presupunem ca numarul este prim
for(unsigned long i=2;i<=int(sqrt(nr));i++)
if(!(nr%i)
{ // (nr%i==0)
prim=0; // numarul nu este prim
break; // se intrerupe bucla
};
if(prim)
{ // (prim==1)
cout<<nr<<" ";
n--;
};
nr++;
};
cout<<endl<<"Apasati o tasta...";
getch();
};
8. Să se scrie un program care citeşte de la tastatură zece numere întregi şi afişează
numărul cu valoarea maximă dintre acestea.
Algoritmul scris în pseudocod:
for i=1,10
read A(i);
repeat;
maxim ← A(1);
for i=2,10
if maxim < A(i) then
maxim ← A(i);
endif;
repeat;
write maxim;
Programarea Calculatoarelor
71
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
int A[10], maxim;
clrscr();
for(int i=0;i<10;i++)
{
cout<<"A["<<i<<"]=";
cin>>A[i];
};
maxim=A[0];
for(i=1;i<10;i++)
if(maxim<A[i])
maxim=A[i];
cout << "Numarul maxim este: " << maxim << endl;
cout << endl << "Apasati o tasta...";
getch();
};
Obs: Acest exerciţiu se poate rezolva folosind o singură buclă for, cea în care se face
introducerea elementelor vectorului.
9. Să se scrie un program care citeşte de la tastatură n numere întregi, n<=50 şi afişează
numerele în ordine crescătoare a valorilor.
Obs: Metoda constă în compararea elementelor două câte două. Pentru sortarea crescătoare, dacă
elementul din stânga este mai mare ca cel din dreapta cu care se face comparația, cele două
elemente vor fi inversate. Pentru această inversare se folosește o variabilă temporară.
Algoritmul scris în pseudocod:
repeat
read n;
until n ≥ 2 and n ≤ 50;
for i=1,n
read A(i);
repeat;
for i=1,n
for j=i+1,n
if A(i) > A(j) then
tmp ← A(i); A(i) ← A(j); A(j) ← tmp;
endif;
repeat;
repeat;
Programarea Calculatoarelor
72
for i=1,n
write A(i);
repeat;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
int A[50], tmp;
// preia de la consola elementele
do
{
clrscr();
cout<<"Introduceti numarul de elemente (2-50): "; cin>>n;
}while((n<2)||(n>50));
cout<<"Introduceti valorile"<<endl;
for(int i=0;i<n;i++)
{
cout<<"A["<<i<<"]= ";
cin>>X[i];
};
// sorteaza crescator elementele
for(int i=0;i<n-1;i++) // bucla incepe de la primul element si se
// termina la penultimul
for(int j=i+1;j<n;j++) // bucla incepe de la elementul din
// dreapta celui cu index si se termina la ultimul
if(A[i]>A[j]
{
tmp=A[i];
A[i]=A[j];
A[j]=tmp;
};
// afiseaza elementele sortate
for(int i=0;i<n;i++)
cout<<A[i]<<" ";
cout<<endl<<"Apasati o tasta...";
getch();
};
10. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se scrie un program
care să genereze un nou vector prin intercalarea între oricare două componente
consecutive a vectorului v a mediei lor aritmetice.
Algoritmul scris în pseudocod:
Programarea Calculatoarelor
73
read n; array x[n];
for i=1,n
read xi;
repeat
i ← 1; j ← 1;
while (i≤n-1)
yj ← xi;
yj+1 ← (xi +xi+1)/2;
j← j+2;
i← i+1;
repeat
yj ← xi;
for i=1,j
write yi;
repeat
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
int i,j;
float x[100], y[200];
cout<<”se citeste dimensiune vector”; cin>>n;
for(i=1;i<=n;i++)
{
cout<<”x[”<<i<<”]=”;
cin>>x[i];
}
i=1; j=1;
while (i<=n-1)
{
y[j]=x[i];
y[j+1]=(x[i]+x[i+1])/2;
j=j+2; i++;
}
for(i=1;i<=j;i++)
cout<<y[i]<<” ”;
cout<<endl<<"Apasati o tasta...";
getch();
};
11. Se citeşte de la tastatură un vector v cu n elemente reale, n≤100. Să se scrie un program
care să elimine din vector elementul de pe poziţia k, k citit de la tastatură. Celelalte
elemente, începând cu poziţia k+1 să fie deplasate la stânga.
Programarea Calculatoarelor
74
Algoritmul scris în pseudocod:
read n,k; array x[n];
for i=1,n
read xi;
repeat
for i=k,n-1
xi ← xi+1;
repeat
for i=1,n-1
write xi;
repeat
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
int i,n,k;
float x[100];
cout<<”se citeste dimensiune vector”; cin>>n;
cout<<”se citeste pozitia elementului ce va fi eliminat”; cin>>k;
for(i=1;i<=n;i++)
{
cout<<”x[”<<i<<”]=”;
cin>>x[i];
}
for(i=k;i<=n-1;i++)
x[i]=x[i+1];
cout<<”noul vector obtinut:”;
for(i=1;i<=n-1;i++)
cout<<x[i]<<” ”;
cout<<endl<<"Apasati o tasta...";
getch();
};
12. Două vehicule se deplasează unul spre celălalt, cu vitezele v1 şi v2, între două localităţi
A si B, aflate la distanta d, una faţă de cealaltă. Aflaţi după cât timp se întâlnesc (t) şi la ce
distanţă faţă de A (d1).
d1=v1*t d-d1=v2*t
Avem, deci:
21
*11,
21*2*1
vv
dvdiar
vv
dttvdtd
Programul scris în C++:
Programarea Calculatoarelor
75
#include <iostream.h>
#include <conio.h>
void main()
{
float v1,v2,t,d,d1;
cout<<”Dati vitezele v1 si v2:”; cin>>v1>>v2;
cout<<”Dati distanta d:”; cin>>d;
t=d/(v1+v2);
d1=v1*d/(v1+v2);
cout<<”Se intalnesc dupa timpul ”<<t<<” la distanta ”<<d1<<” fata de A ”<<endl;
getch();
}
Programarea Calculatoarelor
76
Laborator 9
9. FUNCŢII
Prima parte
1. Într-un program C++, toate funcţiile (în afara funcţiei „main”) sunt executate:
a) Înaintea execuţiei funcţiei „main”
b) După încheierea execuţiei funcţiei „main”
c) Niciodată
d) Atunci când sunt apelate de către alte funcţii
2. Se consideră prototipul funcţiei următoare:
int functie(double& a1, double& a2);
a) Funcția poate modifica argumentele transmise atât pentru a1 cât și pentru a2
b) Funcția nu poate modifica argumentele transmise nici pentru a1 și nici pentru a2
c) Funcția poate modifica numai argumentul transmis pentru a1
d) Funcția poate modifica numai argumentul transmis pentru a2
3. Completaţi cu răspunsul corect:
Variabilele………………pot fi modificate în interiorul oricărei funcţii
a) actuale b) formale c) globale d) locale
4. Fiind date cele două funcţii: „spatiu” şi „stea” definite mai jos, care dintre următoarele
secvenţe de cod va produce o afişare de forma:
*****
****
***
**
*
void spatiu(int k)
{
for (int i=1; i<=k; i++)
cout << " ";
}
void stea(int k)
{
for (int i=1; i<=k; i++)
Programarea Calculatoarelor
77
cout << "*";
cout << endl;
}
a) for (int i=1; i<=5; i++)
{
spatiu(i-1);
stea(5-i);
}
b) for (int i=1; i<=5; i++)
{
spatiu(i-2);
stea(6-i);
}
c) for (int i=1; i<=5; i++)
{
spatiu(i-1);
stea(6-i);
}
d) for (int i=1; i<=5; i++)
{
spatiu(i);
stea(5-i);
}
5. Ce valoare va fi afişată pe monitor în urma execuţiei programului de mai jos?
#include <iostream.h>
#include <conio.h>
int f1(int a, int &b);
int f2(int c, int d);
void f3(int &e, int &f);
main(void)
{
int x = 10, y = 20, z = 30;
z = f1(x,y);
cout << f2(y,z) << endl;
getch();
}
int f1(int a, int &b)
{
b = 5 % a;
Programarea Calculatoarelor
78
return a * b;
}
int f2(int c, int d)
{
return c ++ + c*d;
}
void f3(int &e, int &f)
{
int aux;
aux = e;
e = f;
f = aux;
}
a) 200 b) 255 c) 100 d) 50
6. Se consideră prototipul funcţiei: double f1(int, int, int);
Care dintre instrucţiunile de mai jos este corectă?
a) cout<<f1(7, f1(14, 23));
b) cout<<f1(test(7, 14), 23);
c) cout<<f1(14, 23));
d) cout<<f1(7, 14, 23);
7. Care va fi valoarea returnată de funcţia f1 definită mai jos:
int f1(int a, int b)
{
return (a>b) ? a : b;
}
a) Suma numerelor a + b.
b) Diferenţa numerelor a - b.
c) Valoarea minimă dintre numerele a şi b
c) Valoarea maximă dintre numerele a şi b
8. Se consideră prototipul funcţiei: int f1(int, int);
Care dintre instrucţiunile de mai jos este corectă?
a) cin>>f1(x,y);
b) cout<<f1(f1(1, 2), 3);
c) cin>>f1(‘1’, ‘2’);
d) cout<<f1(f1(1), 2);
9. Pentru funcţia definită mai jos, care va fi valoarea expresiei f1(6.3)?
Programarea Calculatoarelor
79
int f1( float v )
{
if (v > 5.0)
return 5 * int(v);
else
return 0;
}
a) 30 b) 30.0 c) 31.5 d) 0
10. În C++ definiţiile funcţiilor nu pot fi imbricate, adică definiţia unei funcţii nu poate fi
inclusă în corpul altei funcţii.
a) adevărat b) fals
11. Definiţi o funcţie care să calculeze, pentru un număr întreg „nr” suma cuburilor
numerelor întregi dintre 1 şi n.
Răspuns:
int f1(int nr)
{
int i, suma = 0;
for (i = 1; i <= nr; i++)
suma += pow(i,3);
return suma;
}
12. Se citeşte n şi un vector v cu n numere naturale. Se cere ultima cifră a numărului
v[1]+v[2]+…+v[n].
Răspuns:
#include<iostream.h>
int n, v[100];
void citire ( )
{
cin>>n;
int i;
for (i=1;i<=n;i++)
cin>>v[i];
}
int suma ( )
{
int i, nr=0;
Programarea Calculatoarelor
80
for (i=1;i<=n;i++)
nr=nr+v[i];
return nr;
}
int cifra (int n)
{
int c;
c=n%10;
return c;
}
void main ( )
{
citire ( );
int x = suma ( );
cout<<cifra(x);
}
13. Programele următoare exemplifică modul de lucru cu parametrii transmişi prin
valoare şi prin referinţă, variabile locale şi globale.
a)
#include <iostream >
#include <conio.h >
using namespace std;
int alfa, beta=10;
int Calcul(int &x, int y);
int main (void)
{
int a, b, c;
a = 25;
b = 35;
alfa = 1;
c = Calcul (a, b);
// Last two output lines
cout << "a = " << a << " b = " << b << endl;
cout << " alfa = " << alfa << " beta = " << beta << endl;
getch();
return 0;
getch();
}
int Calcul (int &x, int y)
{
int beta;
beta = 5;
cout << " x = " << x <<" y = " << y << endl;
Programarea Calculatoarelor
81
cout << " beta = " << beta << endl;
cout << " alfa = " << alfa << endl;
y = 20;
alfa = beta + y;
x = alfa + y;
cout << " alfa = " << alfa <<" y = " << y << endl;
cout << " x = " << x << endl;
return y;
}
În urma rulării, pe monitor va apărea următoarea secvenţă:
x=25 y=35
beta=5
alfa=1
alfa=25 y=20
x=45
a=45 b=35
alfa=25 beta=10
b)
#include <iostream.h>
#include <conio.h>
int f(int a, int& b);
int main()
{
int x=5, y=10;
for (int i=1; i<=2; i++)
{
cout << x << " "<< y << endl << i << endl;
cout<<endl;
x = f(i,y);
}
getch();
}
int f(int a, int& b)
{
b *= a;
return a*b;
}
În urma rulării, pe monitor va apărea următoarea secvenţă:
Programarea Calculatoarelor
82
5 10
1
10 10
2
14. Exemplu de funcţie care calculează ipotenuza unui triunghi dreptunghic, funcţia având
ca parametri lungimile catetelor triunghiului:
double ipotenuza(double cateta1, double cateta22)
{
return sqrt(cateta 1* cateta 1 + cateta 2* cateta 2);
}
15. Exemplificaţi printr-un exemplu ilustrativ diferenţa dintre un parametru formal şi
parametru actual.
Răspuns:
În programul de mai jos, x este un parametru formal, iar y este un parametru actual
#include <iostream.h>
void Functie_Calcul (int x) // x este un parametru formal
{
//………………….
cout<<10*x;
}
void main()
{
int y=50;
//………………….
Functie_Calcul (y); //y este un parametru actual
}
16. Funcţia „triunghi” definită mai jos produce o afişare de forma :
1
1 2
1 2 3
1 2 3 4
………………….
1 2 3 4 5 …………………….n
void triunghi (int n);
{
for (int i= 0; i < n; i++)
{
Programarea Calculatoarelor
83
for (int numar = 1; numar <= i+1; numar++)
cout << numar << " ";
cout << endl;
}
}
17. Funcţia „suma” definită mai jos are ca parametru un număr întreg n şi returnează: 0,
dacă n <= 0, iar dacă n > 0 valoarea returnată va fi 1 +2 + ….+ n.
int suma(int n)
{
int i, s=0;
for (i=1; i<=n; i++)
s += i;
return s;
}
18. Definiţi o funcţie care să calculeze, pentru două numere întregi date, inf şi sup, suma
numerelor întregi dintre ele (inclusiv cele două numere).
Răspuns:
int f1 (int inf, int sup)
{
int i, suma = 0;
if (inf <= sup)
for (i = inf; i <= sup; ++i)
suma+= i;
else
for (i = inf; i >= sup; --i)
suma += i;
return suma;
}
19. care va fi rezultatul rulării următorului program?
#include <iostream.h>
#include <conio.h>
void afisare1(int[][3]);
void afisare2(int[][3]);
main()
{
int a[3][3], i, j;
for (i=0; i<3; i++)
for (j=0; j<3; j++)
Programarea Calculatoarelor
84
a[i][j] = (i+1)*(j+2);
afisare1(a);
cout << endl;
afisare2(a);
getchar();
}
void afisare1(int b[][3])
{
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
cout << b[i][j] << " ";
cout << endl;
}
}
void afisare2(int b[][3])
{
for (int i=2; i>=0; i--)
{
for (int j=2; j>=0; j--)
cout << b[i][j] << " ";
cout << endl;
}
}
Răspuns:
2 3 4
4 6 8
6 9 12
12 9 6
8 6 4
4 3 2
20. Definiţi o funcţie care să calculeze, pentru un număr întreg „nr” cel mai mic număr
întreg n pentru care este îndeplinită relaţia: 1+2+3+. . . +n ≥ nr.
Răspuns:
int f1 (int nr)
{
int n = 1, suma = 1;
while (suma < nr)
suma += ++n;
return n;
Programarea Calculatoarelor
85
}
21. Să se afişeze toate numerele prime dintre a şi b.
Varianta 1:
#include<iostream.h>
int a, b;
void nrprim (int n)
{
int b=1, d=2;
while (d<=n-1)
{
if(n%d= =0)b=0;
d++;
};
if (b= =1) cout<<n<<” “;
}
void main ( )
{
int a, b, x;
cin>>a>>b;
for (x=a+1;x<b;x++)
nrprim (x);
}
Varianta 2:
#include <iostream.h>
#include <conio.h>
#include <math.h>
int a, b;
int prim (int x)
{
int bb=1, d;
for(d=2;d<=x-1;d++)
if (x%d==0)bb=0;
return bb;
}
main ( )
{
int i;
cin>>a>>b;
for (i=a+1;i<b;i++)
if (prim(i)==1) cout<<i<<" ";
getch();
}
Programarea Calculatoarelor
86
Laborator 10
FUNCŢII
Partea a doua
1. Definiţi o funcţie double average(double s[], int n) care să returneze media valorilor: s[0],
s[1],. . . ,s[n-1].
Răspuns:
double average(double s[], int n)
{
double sum=0;
for (int i=0; i<n; i++)
sum += s[i];
return sum/n;
}
2. Definiţi o funcţie care primeşte 3 parametrii reali ce reprezintă lungimea a 3 segmente şi
returnează 1 dacă segmentele formează triunghi şi 0 dacă nu.
Răspuns:
#include <iostream.h>
#include <conio.h>
#include <math.h>
int triunghi (float a, float b, float c)
{
int x;
if (((a+b)>c)&&((a+c)>b)&&((b+c)>a)) x=1;
else x=0;
cout<<x;
return x;
}
main ( )
{
int a, b, c;
cin>>a>>b>>c;
triunghi (a,b,c);
getch();
}
Programarea Calculatoarelor
87
3. Să se tipărească toate numerele dintr-un interval dat [a,b], care se divid cu suma cifrelor
lor.
Răspuns:
#include <iostream.h>
#include <conio.h>
#include <math.h>
int suma (int x)
{
int s=0;
while (x!=0)
{
s=s+x%10;
x=x/10;
}
return s;
}
main ( )
{
int a,b,i;
cin>>a>>b;
for (i=a;i<=b;i++)
if (i%suma(i)==0) cout<<i<<" ";
getch();
}
4. Definiţi o funcţie care citeşte un parametru real ce reprezintă lungimea laturii unui
pătrat şi returnează lungimea diagonalei şi perimetrul.
Răspuns:
#include <iostream.h>
#include <conio.h>
#include <math.h>
void functie (float l, float& d, float& p)
{
d=l*sqrt(2);
p=4*l;
}
main ( )
{
float l, d, p;
cin>>l;
functie (l,d,p);
cout<<d<<" "<<p;
getch();
}
Programarea Calculatoarelor
88
5. Se dă un vector cu n numere întregi. Să se afişeze perechile de numere prime între ele ale
vectorului.
Răspuns:
#include <iostream.h>
#include <conio.h>
#include <math.h>
int n, v[100];
void citire ( )
{
cin>>n;
int i;
for (i=1;i<=n;i++)
cin>>v[i];
}
int cmmdc(int a, int b)
{
int r=a%b;
while (r!=0)
{
a=b;
b=r;
r=a%b;
}
return b;
}
main ( )
{
citire ( );
int i,j;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if (cmmdc(v[i],v[j])==1) cout<<"("<<v[i]<<" ; "<<v[j]<<")"<<" ";
getch();
}
6. Se dau doi vectori cu n numere întregi, x şi y. Să se afişeze suma x[1]*y[1] +…+ x[n]*y[n].
Răspuns:
#include<iostream.h>
#include <conio.h>
int n, x[100], y[100];
void citire (int z[100] )
{
for (int i=1;i<=n;i++)
Programarea Calculatoarelor
89
cin>>z[i];
}
int suma( )
{
int i, e=0;
for (int i=1;i<=n;i++)
e=e+x[i]*y[i];
return e;
}
main ( )
{
cin>>n;
citire(x); citire(y);
cout<<suma( );
getch();
}
7. Să se afle toate numerele naturale divizibile cu 7 mai mici sau egale cu o valoare dată n.
Răspuns:
#include<iostream.h>
#include <conio.h>
int n;
void divizibile( )
{
int i;
for(i=1;i<=n;i++)
if(i%7==0)cout<<i<<” “;
}
main( )
{
cin>>n;
divizibile( );
getch();
}
8. Să se afle valoarea funcţiei:
x3-2 , x<=0
f = 3
x, x∈(0,5)
2*x+3, x>=5
Răspuns:
Programarea Calculatoarelor
90
#include<iostream.h>
#include<math.h>
#include <conio.h>
int x;
float functie(int a )
{
float f;
if(a<=0) f=pow(a,3)-2;
else if (a<5) f=sqrt(a/3);
else f=2*a+3;
return f;
}
void main( )
{
cin>>x;
cout<<functie(x);
getch();
}
9. Se dau n numere. Să se afle suma cifrelor pare din toate numerele.
Răspuns:
#include<iostream.h>
#include <conio.h>
int n, v[100];
void citire( )
{
int i; cin>>n;
for(i=1;i<=n;i++)
{
cout<<”v[“<<i<<”]=”;
cin>>v[i];
};
}
int suma( )
{
int i, c, s=0;
for(i=1;i<=n;i++)
{
while(v[i]!=0)
{
c=v[i]%10;
if(c%2==0)s=s+c;
v[i]=v[i]/10;
};
Programarea Calculatoarelor
91
};
return s;
}
main( )
{
citire( ); cout<<”suma este”<<suma( );
getch();
}
10. Să se afle suma S= 1+ 22
1+
23
1+ …..+
2
1
n
Răspuns:
#include<iostream.h>
#include <conio.h>
#include<math.h>
int n;
void citire( )
{
cin>>n;
}
float suma(int x)
{
int i; float s=0;
for(i=1;i<=x;i++)
s=s+1/pow(i,2);
return s;
}
main( )
{
citire( );
cout<<”suma este”<<suma(n);
}
11. Se dau doi vectori de câte n elemente fiecare. Să se afle:
e =1
1
y
x+
2
2
y
x+….+
n
n
y
x, yi ≠0, i=1,…,n
Răspuns:
#include<iostream.h>
#include <conio.h>
int n; float x[100], y[100];
void citire( )
{
int i;
cin>>n;
Programarea Calculatoarelor
92
for(i=1;i<=n;i++)
{
cout<<”x[“<<i<<”]=”; cin>>x[i];
cout<<”y[“<<i<<”]=”; cin>>y[i];
};
}
float suma( )
{
int i; float s=0;
for(i=1;i<=n;i++)
s=s+x[i]/y[i];
return s;
}
main( )
{
citire( );
cout<<”suma este”<<suma( );
getch();
}
12. Se dă un vector cu n elemente. Să se afle maximul dintre sumele a oricăror două
elemente vecine.
Răspuns:
#include<iostream.h>
#include <conio.h>
int n, v[100];
void citire( )
{
int i;
cin>>n;
for(i=1;i<=n;i++)
{
cout<<”v[“<<i<<”]=”;
cin>>v[i];
};
}
int maxim( )
{
int i, max=v[1]+v[2];
for(i=2;i<=n-1;i++)
if(max<(v[i]+v[i+1])) max=v[i]+v[i+1];
return max;
}
main( )
Programarea Calculatoarelor
93
{
citire( );
cout<<”maximul este”<<maxim( );
getch();
}
13. Să se ordoneze elementele impare dintr-un vector.
Răspuns:
#include<iostream.h>
#include <conio.h>
int n, v[100], u[100]; // elem. impare din vect. v le introduc in vect. u
void citire( )
{
int i;
cin>>n;
for(i=1;i<=n;i++)
{
cout<<”v[“<<i<<”]=”;
cin>>v[i];
};
}
void impare( )
{
int aux,i,j,k=0; // k contor pt. pozitiile vect. u
for(i=1;i<=n;i++)
if (v[i]%2==1)
{
k++;
u[k]=v[i];
};
for(i=1;i<=k-1;i++) // sortez crescator vect. u
for(j=i+1;j<=k;j++)
if(u[i]>u[j])
{
aux=u[i];
u[i]=u[j];
u[j]=aux;
};
for(i=1;i<=k;i++)
cout<<u[i]<<” ”; // afisez elem. vect.u
}
main( )
{
citire( );
Programarea Calculatoarelor
94
impare( );
getch();
}
14. Se dau A(m) şi B(n). Să se afle C = B\A.
Răspuns:
#include <iostream.h>
#include <conio.h>
int m,n,p, a[100],b[100],c[100];
void citire( )
{
int i ;
for(i=1;i<=m;i++)
{
cout<<"a["<<i<<"]= ";
cin>>a[i];
};
for(i=1;i<=n;i++)
{
cout<<"b["<<i<<"]= ";
cin>>b[i];
};
}
void diferenta( )
{
int i,j, s, /* variabila semnal s ia valoarea 1
atunci cand b[i] = a[j], j=1,…,n */
p=0;
for(i=1;i<=n;i++)
{
s=0;
for(j=1;j<=m;j++)
if(b[i]==a[j])s=1;
if(s==0)
{
p++;
c[p]=b[i];
};
};
for(i=1;i<=p;i++)
cout<<"c["<<i<<"]= "<<c[i];
}
main( )
{
Programarea Calculatoarelor
95
cout<<"m="; cin>>m;
cout<<"n="; cin>>n;
citire( );
diferenta( );
getch();
}
Programarea Calculatoarelor
96
Laborator 11
11. PRELUCRĂRI ELEMENTARE CU TABLOURI
BIDIMENSIONALE
1. Să se citească de la tastatură elementele unei matrici de maxim 10 linii şi 10 coloane. Să
se afişeze matricea citită.
#include <iostream.h>
void main(void)
{
int a[10][10], nr_lin, nr_col, i, j;
cout<<"Nr. linii:"; cin>>nr_lin;
cout<<"Nr. coloane:"; cin>>nr_col;
for (i=0; i<nr_lin; i++) //citirea elementelor unei matrici
for (j=0; j<nr_col; j++)
{
cout<<"A["<<i<<","<<j<<"]=";
cin>>A[i][j];
}
for (i=0; i<nr_lin; i++) //afişarea elementelor matricii
{
for (j=0; j<nr_col; j++) cout<<A[i][j]<<” “;
cout<<'\n'; /* după afişarea elementelor unei linii, se trece
pe linia următoare*/
}
}
2. Să se iniţializeze elementele unei matrici aleator, cu cifre o şi 1:
#include <iostream.h>
#include <stdlib.h>
void main ()
{
int tablou[10][10], a, b;
for (a = 0; a < 10; a++)
for (b = 0; b < 10; b++)
tablou[a][b] = rand()%2;
for (a = 0; a < 10; a++)
{
for (b = 0; b < 10; b++)
cout <<tablou[a][b]<<” “ “;
Programarea Calculatoarelor
97
cout<<'\n';
}
}
3. Program care citeşte de la tastatură o matrice de 4 linii şi 6 coloane de numere reale,
calculează transpusa ei şi afişează transpusa:
#include <iostream.h>
void main()
{
// Matricea originala, citita de la tastatura cu patru linii si sase coloane.
float a[4][6];
// Matricea transpusa, va avea sase linii si patru coloane
float tr[6][4];
int i, j;
/* Citim matricea de la tastatura. */
for (i=0; i<4; i++)
for (j=0; j<6; j++)
{
cout<<"a["<<i<<","<<j<<"]=";
cin>>a[i][j];
}
/* Afisam matricea originala. */
for (i=0; i<4; i++)
{
for (j=0; j<6; j++) cout<<a[i][j]<<” “;
cout<<'\n';
}
/* Calculam transpusa. */
for (i=0; i<4; i++)
for (j=0; j<6; j++)
tr[j][i] = a[i][j];
/* Afisam transpusa. */
for (i=0; i<6; i++)
{
for (j=0; j<4; j++)cout<<tr[i][j])<<” “;
cout<<'\n';
}
}
4. Înmulţirea a două matrice: Fiind dată matricea A(l1 x c1) şi matricea B (l2 x c2), să se
calculeze în matricea C(l1 x c2) produsul celor două matrici.
Obs: ci,j = ai,1 * b1,j + ai,2 * b2,j + …… + ai,l1 * bl1,j
Programarea Calculatoarelor
98
#include <iostream.h>
#include <conio.h>
void main()
{
int a[50][50],b[50][50],c[50][50],l1,c1,l2,c2,sum,i,j,k;
cin>>l1>>c1>>l2>>c2;
if(c1!=l2)
cout<<"Inmultirea nu este posibila!"<<endl;
else
{
for (i=0; i<l1; i++)
for (j=0; j<c1; j++)
{
cout<<"a["<<i<<","<<j<<"]=";
cin>>a[i][j];
}
cout<<endl;
for (i=0; i<l2; i++)
for (j=0; j<c2; j++)
{
cout<<"b["<<i<<","<<j<<"]=";
cin>>b[i][j];
}
cout<<endl;
for(i=1;i<=l1;i++)
for(j=1;j<=c2;j++)
{
sum=0;
for(k=1;k<=l2;k++)
{
sum+=(a[i][k]*b[k][j]);
c[i][j]=sum;
}
}
for(i=1;i<=l1;i++) {
for(j=1;j<=c2;j++) cout<<c[i][j]<<' ';
cout<<endl;
}
}
}
5. Se citeşte de la tastatură o matrice A cu m linii şi n coloane ce conţine doar numerele 0 şi
1 (m şi n cu valori între 2 şi 10). Fiecare linie constituie reprezentarea în baza 2 a unui
număr natural.
Afişaţi numerele naturale în baza 10 pentru fiecare linie în parte precum şi suma acestora.
Programarea Calculatoarelor
99
Algoritmul scris în pseudocod:
do
read m;
until m ≥ 2 and m ≤ 10;
do
read n;
until n ≥ 2 and n ≤ 10;
for i=1,m
for j=1,n
do
read A(i,j);
until A(i,j) = 0 or A(i,j) = 1;
repeat;
repeat;
suma ← 0;
for i=1,m
nr ← 0;
for j=1,n
nr ← nr * 2 + A(i,j);
write A(i,j);
repeat;
write nr;
suma ← suma + nr;
repeat;
write suma;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
int A[10][10], m, n, i, j, nr, suma=0;
clrscr();
// citeste numarul de linii pana cand m este in intervalul 2-10
do
{
cout<<"Numarul de linii (2-10): m=";
cin>>m;
} while ((m<2)||(m>10));
// citeste numarul de coloane pana cand n este in intervalul 2-10
do
{
cout<<"Numarul de coloane (2-10): n=";
Programarea Calculatoarelor
100
cin>>n;
} while ((n<2)||(n>10));
for(i=0;i<m;i++) // citeste elementele matricii A
for(j=0;j<n;j++)
// citirea unui el. se repeta pt. valori diferite de 0 sau 1
do
{
cout<<"A("<<i<<","<<j<<")=";
cin>>A[i][j];
} while((A[i][j]!=0)&&(A[i][j]!=1));
// afiseaza matricea A si calculeaza reprezentarea in zecimal a
// liniilor precum si suma acestor numere
for(i=0;i<m;i++)
{
nr=0;
for(j=0;j<n;j++)
{
// calcul numar echivalent linie
nr=nr*2+A[i][j];
// afiseaza elementul matricii
// urmat de spatiu (tab)
cout<<A[i][j]<<"\t";
};
// la sfarsitul unei linii este afisat nr. in zecimal
cout<<" = "<<nr<<endl;
// si se aduna numarul la variabila suma
suma+=nr;
};
cout<<endl<<"Suma numerelor este: "<<suma;
cout<<endl<<"Apasati o tasta..."; getch();
};
6. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze toate liniile
simetrice. O linie se numeşte simetrică, dacă elementele sale egal depărtate de capete sunt
identice.
#include<iostream.h>
void main ( )
{
int a[10][10], m, n, i, j, semnal;
cout<<”numarul de linii :”; cin>>m; cout<<”numarul de coloane :”; cin>>n;
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
{
cout<<”a[“<<i<<”,”<<j<<”]”; cin>>a[i][j];
Programarea Calculatoarelor
101
}
for (i=1;i<=m;i++)
{
semnal =1;
for (j=1;j<=n/2;j++)
if (a[i][j]!= a[i][n-j+1])
{
semnal =0; break;
}
if (semnal)
{
cout<<”(”;
for (j=1;j<=n;j++) cout<<a[i][j];
cout<<”)”;
};
};
}
7. Se citeşte de la tastatură o matrice cu m linii şi n coloane care conţin numai numere 0 şi 1.
Să se afişeze perechile de linii complementare (suma elementelor de pe aceeaşi coloană din
cele două linii este egală cu 1). Se afişează indicii liniilor respective.
#include<iostream.h>
void main ( )
{
int a[10][10], m, n, i, j, i1;
cout<<”numarul de linii :”; cin>>m;
cout<<”numarul de coloane :”; cin>>n;
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
do {
cout<<”a[“<<i<<”,”<<j<<”]”;
cin>>a[i][j];
}
while ((a[i][j]!=0)&&( a[i][j]!=1));
for (i=1;i<=m-1;i++)
for (i1=i+1;i1<=m;i1++)
{
j=1;
while((j<=n)&&( a[i][j]+ a[i1][j]= =1)) j++;
if(j= =n+1)
cout<<”liniile”<<i<<”si”<<i1<<”sunt complementare”<<endl;
}
}
Programarea Calculatoarelor
102
Laborator 12
12. PRELUCRĂRI AVANSATE CU TABLOURI BIDIMENSIONALE
1. Se citeşte de la tastatură o matrice pătratică A de ordin n (2<=n<=10) ce conţine doar
numere naturale nenule și mai mici decât 10.
Să se calculeze şi să se afişeze sumele şi produsele elementelor matricii aflate în
triunghiurile de sub şi respectiv deasupra diagonalei principale a matricei.
Obs: Condiţia ca matricea să conţină doar numere naturale mici a fost adăugată numai pentru a
împiedica produsul elementelor să aibă o valoare mult prea mare.
De exemplu, dacă matricea este de ordinul 10 şi toate elementele sale sunt egale cu 10, produsul
elementelor triunghiului de sub diagonala principală este 1045
. În această situaţie, pentru a
memora această valoare trebuie folosit tipul double.
Prin analogie, suma acestor elemente va fi 450, şi de aceea poate fi folosit tipul int pentru
memorarea acestei valori.
Algoritmul scris în pseudocod:
do
read n;
until n ≥ 2 and n ≤ 10;
for i=1,n
for j=1,n
do
read A(i,j);
until A(i,j) ≥ 1 or A(i,j) ≤ 10;
repeat;
repeat;
suma1 ← 0; produs1 ← 1; suma2 ← 0; produs2 ← 1;
for i=1,n
for j=1,n
if j<i then
suma1 ← suma1 + A(i,j);
produs1 ← produs1 * A(i,j);
endif;
if j>i then
suma2 ← suma2 + A(i,j);
produs2 ← produs2 * A(i,j);
endif;
repeat;
repeat;
Programarea Calculatoarelor
103
write suma1; write produs1; write suma2; write produs2;
Programul scris în C++:
#include<iostream.h>
#include<conio.h>
void main()
{
unsigned int A[10][10], n, i, j;
unsigned int suma1=0, suma2=0;
double produs1=1, produs2=1;
// citeste dimensiunea matricei in intervalul 1-10
do
{
cout<<"Introduceti dimensiunea matricei (2-10): ";
cin>>n;
} while((n<2)||(n>10));
/* citeste elementele matricei si face validarea ca acestea sa fie
in intervalul 0-10 */
for(i=0;i<n;i++)
for(j=0;j<n;j++)
do
{
cout<<"A("<<i<<","<<j<<")=";
cin>>A[i][j];
} while((A[i][j]<1)||(A[i][j]>10));
clrscr();
// afiseaza matricea pe ecran
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<" "<<A[i][j];
cout<<endl;
};
// calculeaza sumele si produsele elementelor de sub /deasupra
// diagonalei principale
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(j<i)
{
// elementele de deasupra
// diagonalei principale
suma1+=A[i][j];
produs1*=A[i][j];
};
Programarea Calculatoarelor
104
if(j>i)
{
// elementele de sub diagonala principala
suma2+=A[i][j];
produs2*=A[i][j];
};
};
// afiseaza sumele si produsele elementelor triunghiurilor
// se foloseste secventa escape \n pentru a trece pe o linie noua
// (echivalent cu endl)
cout<<"\nPentru elementele de deasupra diagonalei\n\nsuma="
<<suma1<<"\nprodus="<<produs1;
cout<<"\n\nPentru elementele de sub diagonala\n\nsuma="
<<suma2<<"\nprodus="<<produs2;
cout<<endl<<"Apasati o tasta...";
getch();
};
Obs: Pentru elementele de deasupra diagonalei secundare condiţia este j<n-1-i, iar pentru
elementele de sub diagonala secundară condiţia este j>n-1-i.
2. Să se calculeze şi să se afişeze sumele şi produsele elementelor matricii pătratice A de
ordin n>1, aflate în triunghiurile haşurate ( elementele de pe diagonale nu se iau în
considerare):
S1, P1 S2, P2 S3, P3 S4, P4
#include<iostream.h>
void main ( )
{
int a[10][10], n, i, j, s1, s2, s3, s4, p1, p2, p3, p4;
cout<<”ordinul matricei :”; cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
cout<<”a[“<<i<<”,”<<j<<”]”; cin>>a[i][j];
}
s1=s2=s3=s4=0; p1=p2=p3=p4=1;
for (i=1;i<=n;i++)
j<n-i+1
j>n-i+1
i<j
i>j
Programarea Calculatoarelor
105
for (j=1;j<=n;j++)
{
if((i>j)&&(j>n-i+1))
{
s1+= a[i][j];
p1*= a[i][j];
}
if((i<j)&&(j<n-i+1))
{
s2+= a[i][j];
p2*= a[i][j];
};
if((i>j)&&(j<n-i+1))
{
s3+= a[i][j];
p3*= a[i][j];
};
if((i<j)&&(j>n-i+1))
{
s4+= a[i][j];
p4*= a[i][j];
}
}
cout<<”jos:”<<s1<<” “<<p1<<endl;
cout<<”sus:”<<s2<<” “<<p2<<endl;
cout<<”stanga:”<<s3<<” “<<p3<<endl;
cout<<”dreapta:”<<s4<<” “<<p4<<endl;
}
3. Funcţia „SumaDiagonale” definită mai jos calculează suma elementelor situate pe
diagonala principală şi pe diagonala secundară a unei matrici A pătrată, de dimensiune
nxn:
void SumaDiagonale (int a[10][10],int n)
{
int SumaDiagonala1=0, SumaDiagonala2=0;
for (int i=0;i<n;i++)
{
SumaDiagonala1+=a[i][i];
SumaDiagonala2+=a[n-i-1][i];
}
cout<<"Suma elementelor diagonalei principale:"<< SumaDiagonala1<<endl;
cout<<"Suma elementelor diagonalei secundare:"<< SumaDiagonala2<<endl;
}
Programarea Calculatoarelor
106
4. Funcţia „SumaLinii” definită mai jos calculează suma elementelor situate pe liniile unei
matrici A, de dimensiune mxn:
void SumaLinii (int A[10][10],int m,int n)
{
for (int i=0;i<m;i++)
{
int Suma=0;
for (int j=0;j<n;j++)
Suma+=A[i][j];
cout<<Suma<<endl;
}
5. Se citeşte o matrice cu m linii şi n coloane. Să de determine o linie din matrice care
conţine cele mai multe elemente nenule.
#include <iostream.h>
#include <conio.h>
int m, n, v[100], a[100][100];
void citire ( )
{
cout<<"m="; cin>>m; cout<<"n="; cin>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
cout<<"a["<<i<<","<<j<<"]= ";
cin>>a[i][j];
};
}
void nenule(int i)
{
int j;
v[i]=0;
for(j=1;j<=n;j++)
if(a[i][j]!=0) v[i]++;
}
void maxim( )
{
int i, l, max=0;
for(i=1;i<=m;i++)
if(v[i]>max)
{
max=v[i];
l=i;
};
Programarea Calculatoarelor
107
cout<<l;
}
main ( )
{
int i,l;
citire ( );
for(i=1;i<=m;i++)
nenule (i);
maxim( );
getch();
}
6. Se dă o matrice A(n,n). Să se afle câte numere negative sunt deasupra diagonalei
principale.
#include<iostream.h>
#include <conio.h>
int i,n, a[100][100];
void citire( )
{
int j ;
cout<<”n=”; cin>>n;
for(i=1;i<=n;i++)
for( j=1;j<=n;j++)
{
cout<<”a[“<<i<<”,”<<j<<”]= “;
cin>>a[i][j];
};
}
int negative( )
{
int j, nr=0 ;
for(i=1;i<=n-1;i++)
for( j=i+1;j<=n;j++)
if(a[i][j]<0) nr++;
return nr;
}
main( )
{
citire( );
cout<<negative( )<<”numere”;
getch();
}
Programarea Calculatoarelor
108
7. Se consideră o funcţie dată prin domeniul şi codomeniul său. Domeniul are m elemente,
iar codomeniul are n elemente.
Legea de compoziţie este definită astfel: fie A o matrice cu m linii şi n coloane a.î.
1, dacă elementului i din domeniul de definiţie îi
corespunde elementul j din codomeniu
A[i,j] =
0, altfel
Să se studieze bijectivitatea funcţiei.
Soluţie:
Funcţia este bine definită dacă unui element din domeniu îi corespunde un unic element din
codomeniu, deci suma elementelor de pe fiecare linie este egală cu 1.
Funcţia este injectivă dacă unui element din codomeniu îi corespunde cel mult un element din
domeniul de definiţie, deci suma elementelor de pe fiecare coloană este cel mult egală cu 1.
Funcţia este surjectivă dacă unui element din codomeniu îi corespunde cel puţin un element din
domeniul de definiţie, deci suma elementelor de pe fiecare coloană este cel puţin egală cu 1.
#include<iostream.h>
#include<process.h> // prototipul pt. funcţia exit
void main ( )
{
int a[10][10], m, n, i, j, sl, sc, binedef=1, inj=1, surj=1;
cout<<”numarul de linii :”; cin>>m;
cout<<”numarul de coloane :”; cin>>n;
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
{
cout<<”a[“<<i<<”,”<<j<<”]”;
cin>>a[i][j];
}
for (i=1;i<=m;i++)
{
sl=0;
for (j=1;j<=n;j++) sl += a[i][j];
if(sl !=1) binedef=0;
}
if(binedef = =0)
{
cout<<”functia nu este bine definita”;
exit(1);
}
for (j=1;j<=n;j++)
{
sc=0;
o valoare diferita de 0 pt. parametrul functiei exit indica o terminare anormala a executiei programului
Programarea Calculatoarelor
109
for (i=1;i<=m;i++) sc += a[i][j];
if(sc >1) inj=0;
}
if(inj) cout<<”functie injectiva”<<endl;
else cout<<”functie neinjectiva”<<endl;
for (j=1;j<=n;j++)
{
sc=0;
for (i=1;i<=m;i++) sc += a[i][j];
if(sc <1) surj=0;
}
if(surj) cout<<”functie surjectiva”<<endl;
else cout<<”functie nesurjectiva”<<endl;
}
8. Se dă o matrice A(m,n). Să se afle pentru fiecare linie c.m.m.d.c. al elementelor liniei.
#include<iostream.h>
int i,m,n, a[100][100];
void citire( )
{
int j ;
cout<<”m=”; cin>>m; cout<<”n=”; cin>>n;
for(i=1;i<=m;i++)
for( j=1;j<=n;j++)
{
cout<<”a[“<<i<<”,”<<j<<”]= “;
cin>>a[i][j];
};
}
int divizor(int i)
// calculam c.m.m.d.c. pentru linia i: d = (….((a[i][1], a[i][2]), a[i][3]),….., a[i][n])
{
int j,d;
d=a[i][1];
for( j=2;j<=n;j++)
while(d!=a[i][j])
if(d>a[i][j]) d=d-a[i][j];
else a[i][j]=a[i][j]-d;
return d;
}
void main( )
{
citire( );
for(i=1;i<=m;i++)cout<< divizor(i);
Programarea Calculatoarelor
110
}
Obs: am folosit următorul algoritm pt. calculul c.m.m.d.c. a două numere a şi b:
while(a!=b)
if(a>b)a=a-b;
else b=b-a;
cout<<a;
Probleme propuse
1. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle maximul elementelor
din matrice.
2. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle minimul elementelor
din matrice.
3. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle elementele maxime
de pe fiecare linie.
4. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle elementele minime de
pe fiecare linie.
5. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle elementele maxime
de pe fiecare coloană.
6. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle elementele minime de
pe fiecare coloană.
7. Se citeşte de la tastatură o matrice cu m linii şi n coloane.
Să se afle suma elementelor din matrice care se găsesc pe linie pară şi coloană impară.
8. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle câte elemente pare,
impare şi nule sunt în matrice.
9. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze matricea în care
fiecare element este adunat cu k.
10. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze matricea în care
fiecare element este înmulţit cu k.
11. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afle media aritmetică a
elementelor pozitive şi pare din matrice.
Programarea Calculatoarelor
111
12. Scrieţi un program care să verifice dacă două matrice citite de la tastatură, cu m linii şi
n coloane sunt egale.
13. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze liniile matricii
care au elementele ordonate descrescător. În caz că nu există nici o astfel de linie, se va
afişa un mesaj corespunzător.
14. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze coloanele
matricii care au elementele ordonate crescător. În caz că nu există nici o astfel de coloană,
se va afişa un mesaj corespunzător.
15. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze indicele liniilor şi
coloanelor care au numai elemente pare.
16. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un
număr k, 1≤k≤m. Să se afle maximul dintre elementele pare ale liniei k a matricei.
17. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr k, 1≤k≤n. Să se
afle minimul dintre elementele impare ale coloanei k a matricei.
18. Se citesc de la tastatură două matrice A (m,n) şi B (m,p). Să se genereze şi să se afişeze
matricea C (m, n+p) formată astfel :
C = [A B].
19. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se afle media aritmetică a
elementelor de deasupra diagonalei principale.
20. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se afle media aritmetică a
elementelor de deasupra diagonalei secundare.
21. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se afle produsul
elementelor de sub diagonala principală.
22. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se afle produsul
elementelor de sub diagonala secundară.
23. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este
simetrică faţă de diagonala principală.
24. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este
simetrică faţă de diagonala secundară.
25. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este
superior triunghiulară faţă de diagonala principală (elementele de sub diagonala
principală sunt nule).
Programarea Calculatoarelor
112
26. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este inferior
triunghiulară faţă de diagonala principală (elementele de deasupra diagonalei principale
sunt nule).
27. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este
superior triunghiulară faţă de diagonala secundară (elementele de sub diagonala
secundară sunt nule).
28. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se verifice dacă este inferior
triunghiulară faţă de diagonala secundară (elementele de deasupra diagonalei secundare
sunt nule).
29. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr p, 1≤p≤m. Să se
afişeze matricea cu linia p eliminată.
30. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr p, 1≤p≤n. Să se
afişeze matricea cu coloana p eliminată.
31. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr p, 1≤p≤m,
împreună cu n valori (se citeşte o nouă linie). Să se afişeze matricea cu noua linie, inserată
pe poziţia p.
32. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr p, 1≤k≤n,
împreună cu m valori (se citeşte o nouă coloană). Să se afişeze matricea cu noua coloană,
inserată pe poziţia k.
33. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se genereze şi să se afişeze
un vector format din elementele matricii.
34. Se citeşte de la tastatură o matrice cu m linii şi n coloane care conţin numai numere 0 şi
1. Fiecare linie constituie reprezentarea în baza 2 a unui număr natural. Să se afle
numerele.
35. Se citeşte de la tastatură o matrice cu m linii şi n coloane care conţin numai numere 0 şi
1. Să se afişeze perechile de linii complementare (suma elementelor de pe aceeaşi poziţie din
cele două linii este egală cu 1). Se afişează indicii liniilor respective.
36. Se citeşte de la tastatură o matrice cu m linii şi n coloane care conţin numai numere 0 şi
1. Să se afişeze perechile de coloane complementare (suma elementelor de pe aceeaşi
poziţie din cele două coloane este egală cu 1). Se afişează indicii coloanelor respective.
37. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se copieze într-un vector
elementele pozitive aflate deasupra diagonalei principale.
38. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se copieze într-un vector
elementele pozitive aflate sub diagonala principală.
Programarea Calculatoarelor
113
39. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se copieze într-un vector
elementele negative aflate deasupra diagonalei secundare.
40. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se copieze într-un vector
elementele negative aflate sub diagonala secundară.
41. Se citeşte de la tastatură o matrice cu m linii şi n coloane. Să se afişeze toate liniile
simetrice din matrice. O linie se numeşte simetrică, dacă elementele sale egal depărtate de
capete sunt identice.
42. Se citeşte de la tastatură o matrice cu m linii şi n coloane şi un număr x. Să se afle de
câte ori apare x pe marginea matricei.
43. Se citeşte de la tastatură o matrice cu n linii şi n coloane şi un număr natural p. Să se
verifice dacă elementele de pe coloana p sunt în progresie aritmetică.
44. Se citeşte de la tastatură o matrice cu n linii şi n coloane şi un număr natural p. Să se
verifice dacă elementele de pe linia p sunt în progresie aritmetică.
45. Se citeşte de la tastatură o matrice cu n linii şi n coloane. Să se determine media
aritmetică a elementelor din matrice care se termină în 0 şi se găsesc pe cele două diagonale.
Programarea Calculatoarelor
114
Laborator 13
13. POINTERI ŞI TABLOURI
1. Ce se afişează în urma execuţiei secvenţei următoare?
int x[50],*a,*b;
a=x+5; b=x+10;
cout<<(b - a);
a) 10 b) 5 c) 15 d) 20
2. Ce se afişează în urma execuţiei secvenţei următoare?
int x[100],*a,*b=x+10;
for ( a=x; a<b; a++) *a=(b - a);
cout<<x[5];
a) 5 b) 10 c) 100 d) 50
3. Pentru declaraţia: int *p; Care din următoarele instrucţiuni afişează corect conţinutul
de la adresa indicată de p?
a) cin>>*p; b) cin>>&p; c) cout<<*p; d) cout<<&(*p) ;
4. Ce se afişează în urma execuţiei secvenţei următoare?
int x=10,*adresa=&x;
(*adresa)++;
cout<<*adresa<< “ ”<<x;
a) 5 5 b) 10 10 c) 10 11 d) 11 11
5. Ce se afişează în urma execuţiei secvenţei următoare?
int x[100],*a, i;
*a=x;
for (i=0;i<10;i++) { *a=i; a--; }
cout<<*(x+10);
a) 10 b) 1 c) 5 d) secvenţa conţine erori
Programarea Calculatoarelor
115
6. Ce se afişează în urma execuţiei secvenţei următoare?
int p=10,q=20,&a=p,&b=q;
a=20;
--a ;
--b ;
cout<<p<<“ ”<<q;
a) 20 20 b) 19 19 c) 19 20 d) 10 10
7. Ce se afişează în urma execuţiei secvenţei următoare?
#include<iostream.h>
void main()
{
int *x, *y;
float a=10.0;
int b=20;
*x=a;
*y=b;
cout<<*x<<" "<<*y<<endl;
}
a) 10.0 20 b) 20 20 a) 10.0 10.0 e) Apare eroare la execuţie
8. Să se citească elementele unui vector cu maxim 10 elemente întregi şi să se înlocuiască
elementul minim din vector cu o valoare introdusă de la tastatură, folosind lucrul cu
pointeri.
#include <iostream.h>
void main()
{
int i, n, min, indice, val, v[10];
cout<<”dimensiune vector:”; cin>>n;
for (i=0; i<n; i++)
{
cout<<”v[“<<i<<”]=”;
cin>> (v+i);
}
min= v;
indice=0;
for (i=0; i<n; i++)
if (min>= (v+i))
{
Programarea Calculatoarelor
116
min= (v+i);
indice=i;
}
cout<<”valoarea de inlocuire:”; cin >> val;
(v+indice)=val;
for (i=0; i<n; i++)
cout<< (v+i)<<” “;
}
9. Să se citească elementele unei matrici cu maxim 10 rânduri şi 10 coloane cu elemente
întregi şi să se afişeze, folosind lucrul cu pointeri.
#include <iostream.h>
void main()
{
int i, j, n, a[10][10];
cout<<"dimensiune matrice";cin>>n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
cout<<"a["<<i<<","<<j<<"]=";
cin>>*(*(a+i)+j)
}
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
cout<<*(*(a+i)+j)<<" ";
cout<<endl;
}
}
Programarea Calculatoarelor
117
Laborator 14
14. ŞIRURI DE CARACTERE
1) Se dă un şir de caractere. Să se scrie o funcţie (în program) care să numere de câte ori
apare caracterul ‘A’ într-un şir.
#include<iostream.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>
char s[30];
int numar()
{
int i,k=0;
for (i=0;i<strlen(s);i++)
if (s[i]= =’A’)k++;
return k;
}
void main()
{
gets(s);
cout<<numar();
getche();
}
2) Se dă o frază (mai multe propoziţii separate de .,!,?). Să se afle câte propoziţii sunt în
frază.
#include<iostream.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>
char s[30]; int k;
void main()
{
gets(s); k=0;
for (i=0; i<strlen(s); i++)
if ((s[i]= =’.’)||(s[i]= = ‘!’)||(s[i]= =’?’))k++;
cout<<k;
getch();
}
Programarea Calculatoarelor
118
3) Să se încerce funcţiile predefinite.
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<conio.h>
char s1[30],s2[30];
int n;
char c;
void main()
{
gets(s1); gets(s2); cin>>n; cin>>c;
cout<<”strlen(s)=”<<strlen(s)<<endl;
cout<<”strcpy(s1,s2)=”<<strcpy(s1,s2)<<endl;
cout<<”strcat(s1,s2)=”<<strcat(s1,s2)<<endl;
cout<<”strncat(s1,s2,n)=”<<strncat(s1,s2,n)<<endl;
cout<<”strcmp(s1,s2)=”<<stricmp(s1,s2)<<endl;
cout<<”strncmp(s1,s2,n)=”<<strcnmp(s1,s2,n)<<endl;
cout<<”strchr(s1,c)=”<<strchr(s1,c)<<endl
….
}
4) Se citeşte un text. Să se scrie o funcţie (în program) care să elimine spaţiile.
char s1[100], s2[100];
void elimin()
{
char * p;
p=strtok(s1,”_”);
strcpy(s2,p); //copiez in s2 prima entitate gasita in sirul s1
while(p)
{
p=strtok(NULL,”_”); /* de cate ori gasesc cate o entitate, o
alipesc la s2*/
strcat(s2,p);
}
}
void main()
{
gets(s1);
elimin();
puts(s2);
}
Programarea Calculatoarelor
119
5) Se citeşte un text. Să se rearanjeze literele în ordine alfabetică, pastrând locul cuvintelor.
Numai literele sunt afectate, celelalte caractere rămân neschimbate.
Ex: Ana_are_3_ani. Aaa_aei_3_nnr.
char s1[100], s2[100]
void ordonez()
{
int i,j;
for (i=0; i<=strlen(s1)-2;i++)
for (j=i+1; j<=strlen(s1)-1;j++)
6) Se citeşte un text. Să se afişeze toate cuvintele din text formate din k caractere.
char s[100], *p;
int k;
void main()
{
gets(s); cin>>k;
p=strtok(s,”_”);
if (strlen(p)= =k) cout<<p;
while (p)
{
p=strtok(NULL,”_”);
if(strlen(p)= =k)cout<<p;
}
}
7) Se citeşte un text. Să se afişeze toate cuvintele de lungime maximă.
char s[100], a[100][100], *p; // vector de cuvinte
//( matrice: a[k] –cuvant de tipul char[100] )
int max;
void main()
{
gets(s);
int k=0;
p=strtok(s,”_”);
k++;
strcpy(a[k],p); //in a[k] se introduc pe rand cuvintele din text
while(p)
{
p=strtok(NULL,”_”)
k++;
strcpy(a[k],p);
}
Programarea Calculatoarelor
120
max=0; int i;
for (i=1,i<=k;i++)
if (max<strlen(a[i])) max=strlen(a[i]);
for (i=1; i<=k;i++)
if (strlen (a[i])= =max) cout<<a[i]<<endl;
}
8) Se dau două numere sub formă de şiruri de caractere. Să se afle suma şi diferenţa.
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<conio.h>
char s1[20],s2[20];
int n1,n2;
void main()
{
gets(s1);gets(s2);
n1=atoi(s1);
n2=atoi(s2);
cout<<”suma=”<<n1+n2; cout<<”diferenta=”<<n1-n2;
}
9) Să se verifice dacă două cuvinte se pot obţine unul din celălalt prin permutarea literelor
circular la stânga.
Exemplu: s1 = “arc” s2 = “car”
Obs:
- nr de permutari=nr de litere din s1
- la fiecare permutare se obtine un cuvant pe care-l comparam cu s2
char s1[100], s2[100], aux;
void main()
{
gets(s1); gets(s2);
int i,j,b=0;
for (i=1;i<=strlen(s1);i++)
{
aux=s1[0];
for (j=1; j<=strlen(s1)-1,j++) s1[j-1]=s1[j];
s1[strlen(s1)-1]=aux;
if (strcmp(s1,s2)= =0) b=1;
}
if (b= =1) cout<<”da”;
else cout<<”nu”;
Programarea Calculatoarelor
121
}
dacă strlen(s1) = n, avem:
aux ← s1[0]
s1[0] ← s1[1]
.................................
s1[n-2] ← s1[n-1]
s1[n-1] ← aux
10) Se dă un şir de caractere care conţine cuvinte separate de spaţiu. Să se afişeze
distribuţia lungimii cuvintelor din şir.
Ex.: s=“Toamna_acesta_ploua_foarte_tare_desi_nu_prea_imi_place_acest_lucru”
1 cuvant de lungime 2
1 cuvant de lungime 3
3 cuvant de lungime 4
4 cuvant de lungime 5
2 cuvant de lungime 6
1 cuvant de lungime 7
- Se citeşte sirul.
- Se scot cuvintele şi se postează într-un vector a
- În vectorul v se postează lungimea fiecărui cuvânt
-Se ordonează vectorul crescător şi se numără câte cuvinte din vectorul a au lungimea v[i]
Char s1[100], a[100][100] , *p;
int v[100] ;
void main ( )
{
gets (s1) ; int k=0 , i , j , aux ;
p=strtok(s, “_”) ;
k++
strcpy (a[k], p);
v[k]=strlen(p);
while (p)
{
p=strtok(null , “_”); k++;
strcpy(a[k],p);
v[k]=strlen(p);
}
for (i=1 ; i<=k-1 ; i++)
for (j=i+1 ; j<=k ; j++)
if (v[i]>v[j])
{
Programarea Calculatoarelor
122
aux=v[i];
v[i]=v[j];
v[j]=aux;
};
for (i=1 ; i<=k ; i++)
{
int nr=0;
for (j=1 ; j<=k; j++)
if (strlen(a[j]==v[i]) nr++;
coutt<<nr<<”cuvinte de lungime “<<v[i]<<endl;
}
}
11) Se citeşte un cuvânt . Sa se afişeze toate prefixele cuvântului .
Ex.: “animal” “a” , “an” , “ani” , “anim” , “anima” , “animal”
char s[20]; int i,j
void main ( )
{
gets(s);
for ( i=0 ; i<=strlen(s)-1 ; i++)
{
for (j=0 ; j<=i ; j++) cout <<s[j]<< ”_”;
cout <<endl;
}
}
12) Se citesc de la tastatură n linii de text. Să se afişeze linia de text cea mai lungă.
char s[100] , ss[100];
int n , max , i ;
void main ( )
{
cin>>n ;
max=0 ;
for (i=1 ; i<=n ; i++)
{
gets(s);
if (strlen(s)>max)
{
max=strlen(s);
strcpy(ss,s);
}
}
Programarea Calculatoarelor
123
cout<<ss<<endl;
}
13) Se da un fişier input.txt care conţine o frază. Să se elimine din frază vocalele şi să se
afişeze ce a rămas în output.txt .
char s[100];
int i,n;
void main( )
{
ifstream f(“input.txt”);
ofstream g(“output.txt”);
f.getline(s,100);
for (i=0 ; i<=strlen(s)-1; i++)
if (strchr(“BC____Zbc__z”,s[i] )) g<<s[i];
f.close( ) ;
g.close( ) ;
}
14) Se dă un fişier care conţine un şir de caractere. Să se mărească toate numerele care
apar în şir cu 12%. Afişarea se va face în alt fişier .
char s[100] , *p ;
Void main( )
{
ifstream f(“sir.txt”);
ofstream g(“sirnr.txt”);
f.getline(s,100);
p=strtok(s,”_”);
if (atoi(p)) g<<112/100*atoi(p)<<”_” ;
while (p)
{
p=strtok(NULL, “_”);
if (atoi(p)) g<<112/100*atoi(p)<<”_” ;
}
f.close( );
g.close( ) ;
}
15) Să se afişeze cuvintele din textul s care încep şi se termin cu aceeaşi literă .
char s[100], *p ;
gets(s);
void cuvinte( )
{
Programarea Calculatoarelor
124
p=strtok(s,”_”) ;
if (p[o]==p[strlen(p)-1]) cout <<p<<”_” ;
while (p)
{ p=strtok (NULL,”_”) ;
if(p[o]= =p[strlen(p)-1]) cout<<p<<”_” ;
}
void main( )
{
cuvinte( ) ;
}
16) Se citeşte un text de la tastatură . Înlocuiţi în text fiecare vocală α cu αpα .
void (main)
{
char s[100], b[100] , voc[10]=”AEIOUaeiou”;
int i;
gets(s) ;
for (i=o; i<=strlen(s)-1; i++)
if (strchr(voc, s[i]))
{
strcat (b , a[i]) ;
strcat (b , “p”) ;
strcat (b , a[i]) ;
}
else strcat(b,a[i])
cout << b;
}
17) Se dă o matrice pătrată cu n linii şi n coloane. Scrieţi o funcţie (într-un program) care
calculează de câte ori apare o valoare dată x , deasupra diagonalei principale.
#include < iostream.h >
Int n , a[100][100], x ;
void citire ( )
{
int i, j ;
for (i=1; i<=n ; i++)
for (j=1; j<=n ; j++)
cin >>a[i][j] ;
}
int cautare ( )
{
Int i ,j , k=0 ;
for (i=1 ; j<=n-1 ; i++)
Programarea Calculatoarelor
125
for (j=i+1 ; j<=n ; j++)
if ( a[i][j]= = x) k++ ;
return k;
}
void main ( )
{
cin>>n>>x ;
citire;
cout<<cautare( );
}
Programarea Calculatoarelor
126
127
Tiparul executat la
TIPOGRAFIA
UNIVERSITĂȚII MARITIME
Constanța