Sunteți pe pagina 1din 62

Cuprins

Laborator nr. 1: Prezentarea mediului de programare Dev C++


Laborator nr. 2: Funcţii matematice
Laborator nr. 3: Funcţii definite de utilizator
Lucrarea nr.4: Funcţii recursive
Lucrarea nr.5: Tablouri unidimensionale
Lucrarea nr.6: Tablouri bidimensionale
Laborator nr. 7: Prelucrarea şirurilor de caractere
Laborator nr. 8: Structuri
Lucrarea nr.9-10: Pointeri. Pointeri şi tablouri
Lucrarea nr.11-12: Lista simplu înlănţuită. Lista circulară simplu înlănţuită
Lucrarea nr.13: Lista dublu înlănţuită
Lucrarea nr.14: Prelucrarea fişierelor
Lucrarea nr.15: Clase. Proprietăţi. Crearea şi distrugerea obiectelor.

1
Laborator nr. 1: Prezentarea mediului de programare Dev C++
Scop: familiarizarea elevilor cu mediul de programare Dev C++. Rezolvarea problemelor cu funcții de
intrare-ieșire,instrucţiuni de control, instrucţiuni ciclice.

Noţiuni teoretice

Instalarea mediului de programare

Pentru a realiza instalarea mediului de programare Dev C++ pe calculatorul dvs. trebuie să parcurgeţi următoarele
etape:
A. Obţinerea fişierului devcpp4.9.9.2_setup.exe care conţine kit-ul de instalare, de pe unul din site-urile:
http://www.soft32.com/
http://www.bloodshed.net/dev/devcpp.html dev-c.ro.malavida.com
http://sourceforge.net/projects/dev-cpp/files/Binaries/Dev-C%2B%2B
%204.9.9.2/

B. Se lansează în execuţie fişierul devcpp4.9.9.2_setup.exe . Pe ecran se deschide fereastra din figura 1.1.

Figura 1.1.
Figura 1.2.
Se acţionează butonul Ok . Pe ecran se deschide fereastra Installer Language (figura 1.2). Se selectează limba
utilizată în etapele de instalare (selectaţi limba română ) şi se acţionează butonul Ok .
C. Acceptarea contractului de licenţă . După parcurgerea etapei anterioare, pe ecran se deschide fereastra
Contract de licenţă (figura 1.3). Se acţionează butonul De acord.

Figura 1.3. Figura 1.4.

D. Selectarea componentelor pe care dorim să le instalăm . După acceptarea contractului de licenţă pe ecran se
deschide fereastra Selectare componente (figura 1.4). NU SE MODIFICĂ configuraţia implicită şi se
acţionează butonul Înainte .

2
Figura 1.5. Figura 1.6.

E. Selectarea directorului destinaţie . După selectarea componentelor ce urmează a fi instalate, pe ecran se


deschide fereastra Selectare director destinaţie (figura 1.5). Dacă se doreşte se poate modifica directorul unde să
fie instalate fişierele. Se acţionează butonul Instalare . În câteva secunde se realizează instalarea mediului de
programare.
F. Finalizarea instalării . După instalarea fişierelor pe calculatorul dvs. în directorul specificat, pe ecran se deschide
fereastra prezentată în figura 1.6. Pentru finalizarea instalării se acţionează butonul Terminare .
G. Lansarea în execuţie a aplicaţiei . După finalizarea instalării, dacă este activată opţiunea Executare Dev-C++
5 beta 9 release (4.9.9.2) pe ecran se deschide aplicaţia Dev-C++ , a cărei interfaţă este prezentată în figura 1.7.

Figura 1.7. Interfaţa mediului de programare Dev – C++

Prezentarea mediului de programare


Interfaţa mediului de programare este prezentată în figura 1.7. Elementele componente ale acesteia sunt:

3
1 – meniul principal şi bările cu unelte;
2 – fereastra în care sunt afişate numele proiectului şi a fişierelor utilizate – file explorer;
3 – editorul de texte;
4 – zona de afişare a mesajelor şi rezultatelor;

Meniul principal conţine 11 meniuri, în continuare fiind prezentare cele mai importante.

Meniul File (figura 1.8): se utilizează pentru gestionarea fişierelor, având opţiunile:
New : permite crearea unui element nou (fişier sursă, proiect, fişier de resurse, şablon);
Open Project or File … : deschide un fişier sau proiect existent;
Reopen : afişează o listă cu ultimele fişiere deschise (istoric) şi permite deschiderea
acestora;
Save : salvarea fişierului / proiectului curent;
Save as … : salvarea fişierului curent sub un alt nume sau un alt format;
Save Project as … : salvarea proiectului sub un alt nume;
Save All : salvarea tuturor fişierelor deschise;
Close : închiderea fişierului curent;
Close All : închiderea tuturor fişierelor deschise;
Close Project : închiderea proiectului curent;
Properties : afişează fereastra Properties;
Import : importarea unui proiect creat cu MS Visual Studio;
Export : conversia fişierului (proiectului) curent într-unul din formatele: HTML sau RTF
Print : permite tipărirea fişierului / proiectului curent;
Print Setup : stabilirea setărilor referitoare la imprimanta utilizată;
Exit : părăsirea mediului de programare;

Figura 1.8. Meniul File

Meniul Edit : se utilizează pentru operaţii în cadrul editorului de texte (figura 1.9):
Undo : anulează ultima comandă de editare;
Redo : anulează efectul ultimei comenzi Undo;
Cut : decupează zona de text selectată şi o plasează în memoria tampon;
Copy : copiază zona de text selectată şi o plasează în memoria tampon;
Paste : inserează în poziţia curentă a cursorului, conţinutul memoriei tampon;
Swap header / source : permite selectarea alternativă a fişierelor sursă şi header;
Insert : permite inserarea datei şi a orei (Date / Time) sau a unor câmpuri de comentariu în
poziţia curentă a cursorului;
Toggle Bookmarks : inserează un semn de carte;
Goto Bookmarks : realizează deplasarea la semnul de carte ales;
Select All : realizează selectarea întregului conţinut al fişierului curent;
Comment : transformă linia curentă în linie de comentariu;
Uncomment : transformă linia curentă din linie de comentariu într-o linie de program;
Indent : permite deplasarea la dreapta cu un număr de poziţii a textului selectat;
Unindent : permite realinierea textului deplasat la dreapta, adică anularea comenzii Indent;
Figura 1.9. Meniul Edit

Meniul Project : se utilizează pentru gestionarea proiectelor (figura 1.10):


New file : generează un fişier nou;
4
Add to Project : adaugă fişierul curent unui proiect existent;
Remove from Project : elimină un fişier din proiectul curent;
Project Options : permite stabilirea setărilor pentru proiectul curent;
Figura 1.10. Meniul Project

Meniul Execute : permite generarea fişierelor obiect / executabile (figura 1.11):


Compile : realizează compilarea fişierelor deschise;
Compile current file : realizează compilarea fişierului curent;
Run : lansează în execuţie programul compilat;
Parameters… : permite urmărirea parametrilor programului;
Compile & Run : realizează succesiv etapele de compilare şi lansare în execuţie;
Rebuild All : reconstruieşte toate fişierele;
Syntax Check : verifică fişierul din punct de vedere al sintaxei;
Clean : curăţă fişierul curent;
Profile analysis : realizează o analiză a proiectului / fişierului;
Program reset : realizează resetarea programului;
Figura 1.11. Meniul Execute

Structura unui program în limbajul C.


#include <stdio.h> ← directivă preprocesor
#define PI 3.14159 ← directivă preprocesor
main( ) ← funcţia principală
{ ← începutul funcţiei principale
double ung, unr; ← declaraţii de variabile
printf(“\n Introduceti unghiul in grade:”); ← apelul funcţiei printf – pentru afişare pe ecran
scanf(“%lf”,&ung); ← apelul funcţiei scanf – pentru citire de la tastatură
unr = ung*PI/180; ← evaluarea unei expresii
printf(“\n Val. in radiani este: %lf”,unr); ← apelul funcţiei printf
} ← sfârşitul funcţiei principale
Exemple:

Exemplul nr. 1: Program pentru transformarea unui unghi din grade în radiani:
#include <stdio.h>
#define PI 3.14159
main()
{ double ung, unr;
printf(“\n Introduceti unghiul in grade:”); scanf(“%lf”,&ung); unr =
ung*PI/180; printf(“\n Val. in radiani este: %lf”,unr);
}

Exemplul nr. 2: Program pentru inversarea valorilor a două variabile:


#include <stdio.h>
#include <conio.h>
main()
{ float a,b,c;
printf(“\n Introduceti valoarea lui a:”); scanf(“%f”,&a); printf(“\n
Introduceti valoarea lui b:”); scanf(“%f”,&b);
c = a; a = b; b = c; printf(“\n a = %f \t b = %f”,a,b); getch(); }
5
Exemplul nr. 3: Program exemplu în care se realizează următoarele: se citesc de la tastatură două şiruri de caractere
reprezentând numele şi prenumele unei persoane. După citiri se afişează pe ecran numele şi
prenumele citite, iniţiala numelui, iniţiala prenumelui, mesajul “Apasati o tasta pentru terminare!!! şi se
aşteaptă apăsarea unei taste.
#include <stdio.h>
#include <conio.h>
main()
{ char nume[25], prenume[25];
printf(" Introduceti numele dvs.:"); scanf("%s",nume); printf(" Introduceti prenumele dvs.:");
scanf("%s",prenume); printf("\n Numele dvs. este: %s",nume);
printf("\n Prenumele dvs. este: %s",prenume);
printf("\n Initiala numelui este: "); putch(nume[0]);
printf("\n Initiala prenumelui este: "); putch(prenume[0]); printf("\n
Apasati o tasta pentru terminare!!!"); getch(); }

Erori în programare

Exemplu: Program exemplu în care se realizează următoarele: se citeşte o succesiune de trei sau mai mule
caractere, pe ecran afişându-se primele trei caractere împreună cu mesaje adecvate. Atenţie:
Programul conţine erori!!! Editaţi programul, compilaţi, identificaţi erorile semnalate de mediul de
programare, corectaţi erorile. Recompilaţi programul până la înlăturarea tuturor erorilor.
#include <studio.h>
#include <conio.h>
main()
{
prinf("\n Introduceti o succesiune de caractere: "); putchar(getchar()); prntf("\t este
primul caracter introdus \n"); putchr(getchar()); printf("\t este al doilea caracter
introdus \n"); putchar(getcar()); printf("\t este al treilea caracter introdus \n);
gethc(); }

Sărcini propuse
Nr. Sarcina
var.
1. Sa se scrie un program care să determine cifra de control a unui număr natural n dat. Cifra de control a unui număr se
obţine prin însumarea succesiva a cifrelor sale, până când se obţine o singură cifră.
2. Sa se scrie un program care să determine toate perechile de numere natural diferite, mai mici sau egale cu un număr n
şi care îl au ca divizor pe un alt număr natural d.
3. Sa se scrie un program care să determine cel mai mic număr <=n, care are număr maxim de divizori proprii. Divizorii
proprii sunt valorile diferite de 1 şi de numărul respectiv la care numărul se împarte exact. Ex. n=20 nr. 12 are 4
divizori.
4. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură şi o valoarea naturală din intervalul [1,8], în
variabila k. Scrieţi un program C care determină şi afişează cifra de rang k din numărul n citit iniţial(rangul unei cifre se
determină de la dreapta spre stânga).
5. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care construieşte şi
afişează numărul obţinut prin eliminarea cifrelor pare din numărul citit iniţial. Dacă numărul nu conţine nici o cifră pară
se va afişa mesajul „Nimic de eliminat!”.
6. Se citeşte un număr natural nenul n, de minim 2 cifre şi maxim 8 cifre, de la tastatură şi o valoarea naturală din
intervalul [0,9], în variabila c. Scrieţi un program C care construieşte un nou număr prin inserarea cifrei c în mijlocul
numărului citit iniţial.
7. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care determină şi afişează
numărul format doar din cifrele impare a numărul citit iniţial. Dacă numărul citit iniţial e format doar din cifre pare atunci
se va afişa mesajul „Nu există cifre impare”.
8. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care determină şi afişează
cifra minimă şi cifra maximă din numărul citit iniţial, printr-o singură prelucrare a cifrelor numărului.
6
9. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care determină şi afişează
cifra maximă pară şi impară din numărul citit iniţial, printr-o singură prelucrare a cifrelor numărului.
10. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care verifică dacă cifrele
numărului n sunt identice. Dacă cifrele sunt egale între ele se va afişa mesajul „EGALE”, altfel se va afişa mesajul „NU”.
11. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care numără câte cifre
distincte are numărul citit iniţial. Dacă toate cifrele sunt distincte atunci se va afişa mesajul „DISTINCTE”, altfel se va
afişa numărul de apariţii a fiecărei cifre distincte.
12. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C care determină şi afişează
toate sufixele numărului natural citit iniţial.(sufixele unui număr se obţin prin eliminarea repetată a ultimei cifre).
13. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură. Scrieţi un program C/C care determină şi
afişează câte cifre pare şi câte cifre impare există în numărul citit iniţial. Dacă numărul citit iniţial e format:
a) doar din cifre pare atunci se va afişa mesajul „Nu există cifre impare”;
b) doar din cifre impare atunci se va afişa mesajul „Nu există cifre pare”.

14. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură şi o valoarea naturală din intervalul [1,8], în
variabila k. Scrieţi un program C care determină şi afişează cifra de rang k din numărul n citit iniţial(rangul unei cifre se
determină de la dreapta spre stânga).
15. Se citeşte un număr natural nenul n, de maxim 8 cifre, de la tastatură şi o valoarea naturală din intervalul [0,9], în
variabila c. Scrieţi un program C care verifică dacă cifra c există cel puţin o dată în numărul citit iniţial. Dacă cifra
există se va afişa mesajul „EXISTĂ”, în caz contrar se va afişa mesajul „NU EXISTĂ”.

7
Laborator nr. 2: Funcţii matematice
Scop: implementarea funcţiilor matematice la rezolvarea problemelor.

Noţiuni teoretice
Funcţii matematice
In programele in care avem nevoie sa efectuam anumite calcule matematice, putem folosi cateva functii predefinite ale
limbajului C care efectueaza aceste calcule. Prototipurile acestor functii se afla in fisierul de sistem <math.h>, care trebuie inclus
pentru compilarea programului.
Funcţia ceil() se foloseşte atunci când se doreşte să se rotunjească valoarea unei variabile sau a unei expresii, înlocuind-o
cu valoarea întreagă imediat următoare.
Funcţia floor() se foloseşte atunci când se doreşte să se rotunjească valoarea unei variabile sau a unei expresii, înlocuind-o
cu valoarea întreagă imediat anterioară.
Functii aritmetice:
Valori absolute
int abs( int x);
Returneaza un intreg care reprezinta valoarea absoluta a argumentului.
long int labs( long int x );
Analog cu functia abs, cu deosebirea ca argumentul si valoarea returnata sunt de tip long int .
double fabs ( double x);
Returneaza un real care reprezinta valoarea absoluta a argumentului real.
Functii de rotunjire
double floor( double x);
Returneaza un real care reprezinta cel mai apropiat numar, fara zecimale, mai mic sau egal cu x (retunjire prin lipsa).
double ceil( double x);
Returneaza un real care reprezinta cel mai apropiat numar, fara zecimale, mai mare sau egal cu x (rotunjire prin adaos).
Functii trigonometrice
double sin (double x)
Returneaza valoarea lui sin(x), unde x este dat in radiani. Numarul real returnat se afla in intervalul [-1, 1].
double cos (double x)
Returneaza valoarea lui cos(x), unde x este dat in radiani. Numarul real returnat se afla in intervalul [-1, 1].
double tan( double x)
Returneaza valoarea lui tg(x), unde x este dat in radiani.
Functii trigonometrice inverese
double asin
Returneaza valoarea lui arcsin(x), unde x se afla in intervalul [-1, 1]. Numarul real returnat (in radiani) se afla in intervalul [-
pi/2, pi/2].
double acos( double x)
Returneaza valoarea lui arccos(x), unde x se afla in intervalul [-1, 1]. Numarul real returnat se afla in intervalul [0, pi].
double atan(double x)
Returneaza valoarea lui arctg(x), unde x este dat in radiani. Numarul real returnat se afla in intervalul [0, pi].
double atan2(double y, double x)
Returneaza valoarea lui tg(y/x), cu exceptia faptului ca semnele argumentelor x si y permit stabilirea cadranului si x poate fi
zero. Valoarea returnata se afla in intervalul [-pi, pi]. Daca x si y sunt coordonatele unui punct in plan, functia returneaza
valoarea unghiului format de dreapta care uneste originea axelor carteziene cu punctul, fata de axa absciselor. Functia
foloseste, deasemenea, la transformarea coordonatelor carteziene in coordonate polare.
Functii exponentiale logaritmice
double exp (double x)
long double exp( long double x)
Returneaza valoarea lui e la puterea x.
double ldexp(double a, int b); long double ldexpl(long double a, int b)
Returneaza valoarea lui 2 la puterea (a*b).

8
double frexp(double x, int *y); long double frexp(long double x, int *y)
Returneaza valoarea x*2y calculand deasemenea si valoara lui y.
Exemplu: Daca x=8, operatia k=frexp(x, y), calculeaza numarul real k, care trebuie inmultit cu 2y pentru a primi rezultatul
egal cu x=8, determinandu-l in acelasi timp si pe y (valoarea puterii la care va trebui ridicata cifra 2). Pentru x=8 si k=frexp(x,
y) vom obtine urmatoarele rezultate: y=4, k=0,5; adica 0,5=8/(2 la puterea 4).
double log( double x)
Returneaza logaritmul natural al argumentului (ln(x)).
double log10( double x)
Returneaza logaritmul zecimal al argumentului (lg(x)).
double pow (double baza, double exponent);
long double pow(long double baza, long double exponent)
Returneaza un real care reprezinta rezultatul ridicarii bazei la exponent (baza la puterea exponent).
double pow10(int x); long double pow101(int x)
Returneaza valoarea lui 10 la puterea x.
double fmod(double x, double y); long double fmod(long double x, long double y)
Returneaza valoarea restului de la impartirea lui x la y.
double sqrt(double x)
Returneaza radacina patrata a argumentului x.
Functii de generare a numerelor aleatoare
Functia randomize. Initializator de generator al numerelor aleatoare.
Prototip: void randomize( void );
Initializeaza generatorul de numere aleatoare. Este necesara includerea bibliotecii <stdlib.h>; Se foloseste impreuna cu
functiarandom().
int random(int x)
Returneaza o valoare aleatoare in intervalul de la 0 la (x-1); Este necesara includerea bibliotecii <stdlib.h>
int rand( void ) Genereaza un numar aleator in intervalul [0, RAND_MAX]. Este necesara includerea bibliotecii <stdlib.h>;
Nu este necesara initializarea.
Exemple:

Exemplul nr. 1: Valoarea absoluta a unui numar intreg - abs()

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
printf("Hello world!\n");
//functia abs din biblioteca de functii math.h
printf("Valoarea absoluta a lui %d este %d\n", 10, abs(10));
printf("Valoarea absoluta a lui %d este %d\n", 3, abs(3));
return 0;}

Exemplul nr. 2: Rotunjirea unei valori reale in virgula mobila ceil() si floor(). Functia ceil() se foloseste atunci cand se
doreste sa se rotunjeasca valoarea unei variabile sau a unei expresii, inlocuind-o cu valoarea intreaga imediat urmatoare.
Functia floor() se foloseste atunci cand se doreste sa se rotunjeasca valoarea unei variabile sau a unei expresii, inlocuind-o
cu valoarea intreaga imediat anterioara.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
9
int main()
{
printf("Hello world!\n");

printf("Valoarea %f rotunjita cu functia ceil() este %f\n ", 1.9, ceil(1.9));


printf("Valoarea %f rotunjita cu functia ceil() este %f\n ", 2.1, ceil(2.1));
printf("Valoarea %f rotunjita cu functia floor() este %f\n ", 1.9, ceil(1.9));
printf("Valoarea %f rotunjita cu functia floor() este %f\n ", 2.1, ceil(2.1));
//functia abs din biblioteca de functii math.h
printf("Valoarea absoluta a lui %d este %d\n", 10, abs(10));
printf("Valoarea absoluta a lui %d este %d\n", 3, abs(3));
return 0;
}
Exemplul nr. 3: Functia exponentiala x la puterea e se calculeaza cu functia exp().

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
printf("Hello world!\n");

double valoare;
for(valoare=0.0; valoare<=1.0; valoare+=0.1)
printf("exp(%f) este %f\n", valoare, exp(valoare));
printf("Valoarea %f rotunjita cu functia ceil() este %f\n ", 1.9, ceil(1.9));
printf("Valoarea %f rotunjita cu functia ceil() este %f\n ", 2.1, ceil(2.1));
printf("Valoarea %f rotunjita cu functia floor() este %f\n ", 1.9, ceil(1.9));
printf("Valoarea %f rotunjita cu functia floor() este %f\n ", 2.1, ceil(2.1));
//functia abs din biblioteca de functii math.h
printf("Valoarea absoluta a lui %d este %d\n", 10, abs(10));
printf("Valoarea absoluta a lui %d este %d\n", 3, abs(3));
return 0;}

Sărcini propuse

Nr.v. Fucţia şi datele de control


1. 12 sin 2
y z 2 z3 z 4 
w  cos x  cos y 1  z    .
 2 3 4 
x=4000 ,y=-0.875, z=-0.000475 w=1.9873
2.  x  y
  ln y  x    sin arctg  z .
2
  2
x=-15.246, y=0.04642, z=2000.1  =-182.036
3.  
  10 3 x  x y  2 arcsin 2 z  x  y . 
x=0.01655, y=-2.75, z=0.15  =-40.6307
4. 1 x  3 x  y  x2
  5arctg  x   arccos x  .
4 x  y z  x2

x=0.1722, y=6.33, z=0.000325  =-205.3056


10
5. e
x y
x y
x y

  3 x 6  ln 2 y .
arctg  x   arctg  z 
x=-0.02235, y=2.23, z=15.221  =39.374
6. z
cos y 
 y  x .
y
y
  xx  3   y  x
1   y  x
2
x
x=182.5, y=18.225, z=-0.03.298  =1.2131

7. a  2 x x4 y 3
e x 1 / sin z .
x=0.03981, y=-1625, z=0.512 a=1.26185.

8.  sin 2 z 
x  y 1 
 x  y 

 cos 3  y 
3 x
b y .
x y x
e 
2
x=6.251, y=0.827, z=25.001 b=0.7121

9.  
y arctg ( z )  
с  2 y   3x
x
  y


1
6
.
x  2
y 1
x=3.251, y=0.325, z=0.0000466 c=4.2514

10. 4
y  3 x 1
f 

x  y sin 2 z  tgz
.

x=17.421, y=0.010365, z=82800 f=0.33056

11. y
x
y x 1 2  x  1 1 / sin z
g 
3 y2 3 2x y
x=1.23, y=15.4, z=252 g=82.8257.

12. x y 1  e y 1
2 3

h 1  y  x   y  x 
yx
1  x y  tgz 2 3
x=2.444, y=0.00869, z=-130 h  -0.49871

13.  
2 cos x  
 6   z2 
.
t 1 
0.5  sin 2 y  3  z 2 / 5 
x=14.26, y=-1.22, z=0.035 t=0.564849

14. 3
8  x  y 1
2

u 2
x  y 2 2
e
x y
tg 2

z 1 .
x

x=-4.5, y=0.000075,z=84.5 u=-55.6848

11
15. 1  sin 2  x  y  y  1
v x  cos 2  arctg .
2y  z
x
1 x y 2 2

x=0.0374, y=-0.825, z=16, v=1.0553

12
Laborator nr. 3: Funcţii definite de utilizator

Scop: implementarea funcţiilor definite de utilizator la rezolvarea problemelor.

Noţiuni teoretice

O funcţie reprezintă o secvenţă de instrucţiuni care poate fi identificată şi apelată prin intermediul unui nume. Funcţiile
sunt un element foarte important în orice limbaj de programare, deoarece uşurează foarte mult munca programatorului, eliminând
necesitatea scrierii aceluiaşi cod de mai multe ori. De asemenea, prin folosirea funcţiilor programele pot fi structurate în blocuri,
implicând o mai bună depanare şi modularizare a programelor respective. Utilizarea unei funcţii presupune două elemente
distincte: - definirea funcţiei; - apelul funcţiei; Definirea unei funcţii reprezintă precizarea tipului returnat de funcţia respectivă, a
argumentelor funcţiei şi a tipurilor acestora şi scrierea corpului funcţiei (instrucţiunile care vor fi executate când va fi apelată
funcţia).
Forma generală a unei funcţii este următoarea:
tip_returnat nume_functie (tip_date1 arg1, tip_date2 arg2, ..., tip_dateN argN );
{
...
corpul_functiei;
...
}
Exemplu de definire de funcţie care returnează o valoare de tip întreg:
int calcul (int a, int b)
{
int c;
c = a + b;
return c; // valoarea returnată de funcţie
}
Exemplu de funcţie care nu primeşte nici un (argument) şi nu returnează nimic:
void afisare (void) // sau void afisare ()
{
printf (“Functie care nu returnează nici o valoare...”;
}
Apelarea unei funcţii constă în folosirea propriu-zisă a funcţiei, într-o altă funcţie. Apelarea se poate face atât în funcţia
principală (main), cât şi într-o altă funcţie. Returnarea unei valori de către o funcţie se face folosind instrucţiunea return înainte de
încheierea funcţiei respective. De asemenea, instrucţiunea return se poate folosi şi pentru încheierea forţată a execuţiei unei
funcţii. O funcţie poate returna orice valoare dintr-un tip de bază, cu excepţia unui tablou. Dacă funcţia nu returnează nici o
valoare, atunci se consideră că returnează void (tipul vid). Atenţie! dacă nu se specifică nimic la tipul returnat de funcţie,
compilatorul C consideră că funcţia respectivă returnează o valoare de tip întreg (va fi semnalat un avertisment (warning) –
Function should return a value)

Parametrii locali, parametrii formali şi parametrii actuali

În utilizarea funcţiilor se pot deosebi două tipuri de parametri, în funcţie de specificul lor: - parametrii formali; - parametrii
actuali; Variabilele care sunt declarate în interiorul unei funcţii se numesc variabile locale şi sunt accesibile doar în interiorul
funcţiei respective. Valorile reţinute în aceşti parametrii se pierd odată cu ieşirea din blocul respectiv. Exemplu: funcţie pentru
calculul minimului dintr-un şir de numere:
int getmin (int n, int a[])
{ int min, i; // min, i - variabile locale
min = a[0];
for (i = 1; i < n; i++)
I f (min > a[i])
min = a[i];
13
return min; }

Argumentele (parametrii) cu care este definită o funcţie sunt numiţi parametrii formali. După ce a fost definită funcţia,
parametrii formali pot fi folosiţi în funcţia respectivă ca şi variabile locale obişnuite. Ei sunt numiţi “formali” deoarece funcţia nu va
fi apelată cu parametrii respectivi, ci cu parametrii de tipurile respective (ei sunt precizaţi pentru a se cunoaşte prototipul funcţiei
respective). Parametrii actuali sunt parametrii cu care se apelează propriu-zis o funcţie.
În exemplul următor se pot observa cele două tipuri de parametrii:
float medie (int a, int b) // a, b - parametrii formali
{ float c; // c – variabilă locală
c = (a + b) / 2;
return c; }
int main (void) { int y, z; // x, y, z - variabile locale
float x; x = calcul (y, z);// y, z - parametrii actuali
printf (“Rezultatul este %f”, x);
return 0; }
Exemple:
Exemplul nr. 1: Să se scrie câte o funcţie care să determine:
- cel mai mare divizor comun a două numere întregi date ca parametri.
- cel mai mic multiplu comun a două numere întregi date ca parametri
Indicaţii:
- Pentru determinarea cmmdc se va folosi algoritmul lui Euclid prin împărţiri repetate.
- Pentru determinarea cmmmc se va folosi relaţia dintre cmmmc şi cmmdc:
cmmmc(a,b) = (a * b) / cmmdc(a,b)
#include <stdio.h>
int cmmdc(int a, int b){
int r;
r = a % b;
while(r != 0){
a = b;
b = r;
r = a % b;}
return b;}
int cmmmc(int a, int b)
{return( (a * b) / cmmdc(a, b) );}
main(){ int x, y, divizor, multiplu;
printf("Dati primul numar\t "); scanf("%d",&x);
printf("Daţi al doilea număr\t "); scanf("%d",&y);
divizor = cmmdc(x, y);
printf("\nC.m.m.d.c este %d",divizor);
multiplu = cmmmc(x, y);
printf("\nC.m.m.m.c este %d",multiplu);}

Exemplul nr. 2: Să se calculeze suma primelor n numere naturale:


#include<stdio.h>
long int suma(long int i){
if(i==1) return 1;
else return suma(i-1)+i;}
main(){long int n;
printf("Introduceti n= "); scanf("%i",&n);
printf("Suma primelor %i numere este %d ",n,suma(n));}

14
Sărcini propuse:

Nr. Sarcina
var.
1. Se consideră două numere întregi a şi b. Se cere să se verifice dacă sunt sau nu numere prime gemene. Spunem că
două numere se numesc prime gemene dacă sunt prime amândouă şi diferenţa lor este egală cu 2.

2. Se consideră două numere întregi a şi b. Se cere să se calculeze şi să se afişeze cel mai mare divizor comun al lor
împreună cu cel mai mic multiplu comun al lor. Pentru rezolvarea primei cerinţe vom folosi algoritmul lui EUCLID, prin
împărţiri repetate, iar pentru cea de-a doua cerinţă vom folosi relaţia cmmmc( a, b) = ( a * b ) / cmmdc( a, b )

3. Se consideră un număr întreg a şi se cere să se determine dacă este sau nu palindrom. Spunem că un numar este
palindrom dacă este egal cu răsturnatul său ( adică numărul cu cifrele de la dreapta la stânga ). Pentru rezolvare
construim o funcţie care primeşte un parametru prin valoare ( numărul dat ) şi un parametru rpin referinţă ( răsturnatul
său ).

4. Se consideră un număr întreg y. Se cere să se scrie cifrele sale într-un tablou unidimensoinal şi apoi să se afişeze
elementele tabloului astfel încât cifrele să apară în ordinea din numărul considerat. Pentru rezolvare construim o funcţie
care are un parametru dat prin valoare ( numărul dat ), şi doi parametrii daţi prin referinţă ( tabloul de cifre şi
dimensiunea lui ).
5. Să se scrie o funcţie care să rezolve o ecuaţie de gradul II, unde coeficienţii ecuaţiei sunt daţi ca parametri. Funcţia
principală va citi coeficienţii a două ecuaţii şi va afişa soluţiile pentru fiecare ecuaţie în parte.

6. Să se citească 2 valori întregi şi să se interschimbe cele două valori. Se va folosi o funcţie de interschimbare.

7. Să se calculeze cel mai mare divizor comun al unui număr oarecare de numere întregi.

8. Să se scrie o funcţie care să afişeze suma cifrelor unui număr întreg dat ca parametru.

9. Realizaţi o funcţie care să verifice dacă un număr este “rotund“. Spunem că un număr este “rotund“ dacă are un număr
egal de cifre de 0 şi 1 în reprezentarea sa în baza 2.

10. Să se scrie o funcţie care să rezolve o ecuaţie de gradul II, unde coeficienţii ecuaţiei sunt daţi ca parametri. Funcţia
principală va citi coeficienţii a două ecuaţii şi va afişa soluţiile pentru fiecare ecuaţie în parte.

11. Se consideră un număr natural în baza 10. Se cere să se scrie câte o funcţie care să afişeze reprezentarea numărului
dat în bazele 2 şi 8. Exemplu: Pentru n=2510: reprezentarea numărului în baza 2 este 110012 reprezentarea numărului
în baza 8 este 318

12. Se consideră un număr natural n. Se cere să se scrie câte o funcţie care să afişeze toate numerele prime mai mici sau
egale cu n.

13. Se consideră un număr natural n. Se cere să se scrie câte o funcţie care să afişeze toate numerele perfecte mai mici
sau egale cu n.

14. Se consideră un număr natural n. Se cere să se scrie câte o funcţie care să afişeze toate numerele pătrate perfecte
mai mici sau egale cu n.

15. Pentru un număr natural n dat, se cere să se calculeze produsul divizorilor numărului n.

15
Laborator nr. 4: Funcţii recursive

Scop: implementarea principiului recursivităţii la rezolvarea problemelor.

Noţiuni teoretice
Un obiect sau un fenomen este definit în mod recursiv dacă în definitia sa se face referire la el însusi. • Conceptul de
recursivitate oferă posibilitatea definirii unei infinităti de obiecte printr-un număr finit de relatii. • O functie este recursivă atunci
când executarea ei implică cel putin încă un apel către ea însăsi.
Tipuri de recursivitate:
• Recursivitate directă – apelul recursiv se face chiar din functia invocată.
• Recursivitate indirectă (mutuală) – apelul recursiv se realizează prin intermediul mai multor functii care se apelează
circular.
Exemplul : Definirea numerelor naturale:
• 1 este număr natural
• succesorul unui număr natural este un număr natural Se presupune cunoscută definiţia succesorului unui număr: acel
număr obţinut din numărul dat prin adăugarea unei unităţi.
Exemplu : Algoritm de calcul pentru factorialul unui număr N. (notatie N!):
• dacă N = 0 atunci N! = 1
• dacă N > 0 atunci N! = N * (N-1)!
Astfel spus, factorialul unui număr N > 0 se obţine prin înmulţirea numărului cu factorialul predecesorului.
Exemplu: Se dau doua numere intregi a si b si se cere sa se calculeze cel mai mare divizor comun. (Algoritmul lui EUCLID – prin
împărțiri repetate). Formularea recursivă, în cuvinte, a algoritmului:
• Dacă unul dintre numere este zero, c.m.m.d.c. al lor este celălalt număr.
• Dacă nici unul dintre numere nu este zero, atunci c.m.m.d.c. nu se modifică dacă se înlocuieste unul dintre numere cu restul
împărtirii sale cu celălalt.
Algoritmul poate fi implementat sub forma următoarei functii recursive:

int cmmdc (int n, int m) {


if (n==0) return m;
else
return cmmdc(n, m % n); }

Codul sursa al implementarii (varianta prin scaderi succesive) este urmatorul:

#include<iostream.h>
int cmmdc(int a,int b) {
if(a==b) return a;
else if(a>b) return cmmdc(a-b, b);
else return cmmdc(a, b-a); }
int main(void) {
int a, b; char c;
do { cout<<"Introduceti a= "; cin>>a;
cout<<"Introduceti b= "; cin>>b;
cout<<"C.m.m.d.c. "<<a<<","<<b<<" este "<<cmmdc(a,b)<< endl ;
cout<<"Mai doriti sa calculati pentru alte ; valori? (d/n) "; cin>>c; }
while( toupper(c)!='N' ); }

Exemplu : Să se calculeze suma primelor n numere naturale.

#include<iostream.h>
long int suma(long int i) {
if(i==1) return 1;
16
else return suma(i-1)+i; }
int main(void) {
long int n;
cout<<"Introduceti n= "; cin>>n;
cout<<"Suma primelor "<<n<<" numere este "<<suma(n)<<endl;}
Exemplu : Se citeste un numar intreg ca un sir de caractere cu cel mult 255 cifre. Sa se afiseze numarul cu cifrele în
ordine inversa.
#include<iostream.h>
#include<string.h>
char n[255],i,l;
void invers(int i)
{ if(i<1) invers(i+1);
cout<<n[i];}
int main(void){
cout<<”Dati numarul in n=”;cin>>n;
l=strlen(n);
cout<<”numarul rasturnat este”;
invers(0);}

Sarcini propuse:
Nr.var Sarcina
.
1. Sa se scrie o funcţie recursiva care primeşte 3 parametri: n - număr natural, c1,c2 cifre si returnează numărul obţinut
din n prin înlocuirea tuturor apariţiilor cifrei c1 cu c2.
Ex. din n=2324, c1=2 si c2=5 returnează 5354
2. Sa se scrie o funcţie recursiva care primeşte un parametru n număr natural si returnează numărul obţinut din n prin
scăderea cu 1 a cifrelor impare si mărirea cu 1 a celor pare.
Ex. din n=2324 returnează 3235
3. Sa se scrie o funcţie recursiva care primeşte un parametru n număr natural si returnează numărul obţinut din n prin
eliminarea cifrelor pare.
Ex. din n=23524 returnează 35
4. Sa se scrie o funcţie recursiva cu 2 parametri şiruri de caractere care sa determine daca sunt anagrame (sunt
compuse din aceleaşi litere, in alta ordine).
5. Sa se scrie o funcţie recursiva care calculează si returnează suma cifrelor unui număr natural primit ca parametru.
6. Sa se scrie o funcţie recursiva care primeşte ca parametru litera 'A' si afişează in ordine toate literele mari din alfabet.
7. Sa se scrie o funcţie recursiva care sa afişeze descompunerea in factori primi a unui număr natural.
8. Sa se scrie o funcţie recursiva care primeşte ca parametru un sir de caractere format din cel mult 100 de caractere
litere mici si elimina toate vocalele din sir.
9. Se citeşte un vector a cu n elemente numere naturale. Sa se calculeze elementul maxim din vector. Se va folosi o
funcţie recursiva pentru citire si una recursiva pentru determinarea elementului maxim.
10. Sa se determine cifra maxima a unui număr natural folosind o funcţie recursiva.
11. Sa se scrie o funcţie recursiva pentru calculul răsturnatului unui număr natural.
12. Sa se scrie o funcţie recursiva care calculează cate cifre are un număr natural.
13. Sa se scrie o funcţie recursiva pentru calculul primei cifre a unui număr natural.
14. Sa se scrie o funcţie recursiva care primeşte un parametru n număr natural si afişează:
1
12
123
.....
1 2 3 4 ... n
15. Sa se calculeze recursiv suma 1*2 + 2*3 + ... + n*(n+1).

17
Laborator nr. 5: Tablouri unidimensionale
Scop: să folosească practici recunoscute şi recomandate pentru scrierea de cod sursă care implică lucrul cu vectori
Noţiuni teoretice
Tabloul unidimensional este o structură de date căreia i se atribuie un nume. Este format dintr-o colecție de elemente de
același tip, dispuse contiguu într-un bloc de memorie. Elementele pot fi accesate individual prin indici sau ca un tot unitar. Toate
elementele au un predecesor (excepție primul) și un succesor (excepție ultimul).
Declarare tip nume_tablou [dimensiune_max];
tip - precizează tipul datelor (întregi, real, caracter, etc.)
nume_tablou – identificator, precizează numele dat tabloului
Dimensiune max – numărul maxim de componente (o constantă întreagă)
Dimensiune max = memoria fizică alocată. Dimens. logică ≤ dimens.max
Se observă că este obligatorie folosirea parantezelor drepte care să încadreze dimensiunea maximă pe care o alege
utilizatorul pentru acel tablou unidimensional.
Exemple
int a[25]; // declararea unui tablou unidimensional cu maxim 25 de elemente, fiecare de tip întreg
float x[30]; // declararea unui tablou unidimensional cu maxim 30 de elemente, fiecare de tip real simplă precizie
char s[40]; // declararea unui tablou unidimensional cu maxim 40 de elemente, fiecare de tip caracter
Un element al unui tablou poate fi utilizat ca orice alta variabilă. Adresarea unei componente se face prin indicele ei,
trecut între paranteze drepte. Se pot efectua operaţii asupra fiecărui element al tabloului, nu asupra întregului tablou.
Compilatorul C++ alocă un spaţiu de memorie egal cu numărul maxim de elemente ale tabloului, rezervând octeţi în
funcţie de tipul de bază al fiecărui tablou.
Ini țializarea tablourilor
Tablourile, ca şi variabilele simple pot fi iniţializate. Tablourile globale se iniţializează prin definiţiile lor la compilare, iar
tablourile locale se iniţializează prin declaraţiile lor la execuţie.
a. prin introducerea b. prin folosirea instrucţiunii c. prin utilizarea unei constante de tip tablou
datelor de la de atribuire int v[5] = {1,2,3,4,5};
tastatură/fi șier int v[5],n;
int v[100],n; for (int i=0; i<n; ++i) int t[10] = {1,2,3};
cin>>n; v[i] = 0;
for (int i=0; i<n; ++i) /* toate componentele vectorului /* t[0] = 1, t[1] = 2, t[2] = 3; celelalte componente
cin >> v[i]; v sunt iniţializate cu 0. */ ale tabloului t[3], …, t[9] au valoarea 0
dacă tabloul este declarat global sau o valoare
iniţială imprevizibilă dacă tabloul este declarat
local. */

Accesul la elementele tabloului


• Accesul la fiecare element al tabloului se face prin numele acestuia urmat între paranteze, de indicele său (adică
poziţia pe care o ocupă în tablou). Ex. nume[indice]
• În limbajul C++, indicii tablourilor încep numărătoarea de la valoarea 0 şi se termină cu limita superioară minus 1
(n-1).
Exemplu
int vec [4] = {12, 23, 34, 45};
Referirea la elemente

Primul element din vector are numărul de ordine (indicele) zero !


Astfel, elementul cu număr de ordine 0 din vector este 12, elementul al 2-lea este 23 și elementul 45 este al 4-lea element din
vector (are indicele 3).

18
Prelucrări elementare ale vectorilor

Deoarece limbajul C nu verifică depăşirea dimensiunilor maxime declarate pentru tablourile utilizate în aplicaţii, pentru
a evita scrierea accidentală a unor zone de memorie, programatorul trebuie să asigure validarea dimensiunilor reale (implicit a
numărului de elemente) citite de la intrare. Uzual, un vector se declară în următoarea manieră:
#define MAX 100 /* dimensiunea maximă admisă */

…………………………
int a[MAX];

int n; /* dimensiunea reală citită la intrare */

Secvenţa tipică de validare a dimensiunii unui vector este următoarea:


do{

printf(“n=”);
scanf(“%d”,&n);

if(n<=0||n>MAX) printf(“dimensiune incorecta\n”); }while(n<=0||n>MAX);


Citirea elementelor unui vector

După validarea dimensiunii, citirea elementelor unui vector se face în ordinea crescătoare a indicilor, uzual cu o
instrucţiune for :
for(int i=0; i<n; i++)

{printf(“a[%d”]=”,i); scanf(“%d”,&a[i]);

}
Observaţie: Deşi tablourile sunt indexate în C începând de la 0, se pot utiliza elementele numai de la indexul 1 (ca în Pascal),
elementul a[0] rămânând liber. În această situaţie secvenţa de citire (şi toate celelalte secvenţe de prelucrare) se vor modifica
corespunzător, conform modelului de mai jos:
for(int i=1;i<=n;i++)
{ printf(“a[%d]=”,i); scanf(“%d”,&a[i]);
Determinarea elementului minim/maxim

Metoda tipică de determinare a elementului minim/maxim dintr-un vector este următoarea : se iniţializează
minimul/maximul cu primul element din vector apoi se compară cu celelalte elemente din vector reţinându-se, pe rând,
valorile mai mici/mai mari.
minim=a[0]; /* maxim=a[0]; */
for(i=1; i<n; i++)
if(minim>a[i]) /* (maxim<a[i]) */
minim=a[i]; /* maxim=a[i]; */
Determinarea primului element cu o anumită proprietate
Pentru a determina primul element (de indice minim) cu o anumită proprietate, se parcurge vectorul de la stânga la
dreapta până când găsim primul element cu proprietatea cerută sau până când
epuizăm elementele vectorului. De exemplu, determinarea primului element nul dintr-un vector se realizează cu secvenţa:
f=-1;
for(j=0;j<n;j++)
if(!a[j])
{f=j; break; }

19
Verificând valoarea variabilei f decidem dacă în vectorul există cel puţin un element cu proprietatea cerută (f=indicele acestuia)
sau nici unul (f =-1).

Determinarea ultimului element cu o anumită proprietate


Pentru a determina ultimul element (de indice maxim) cu o anumită proprietate, se parcurge vectorul de la dreapta
spre stânga (în ordinea descrescătoare a indicilor) până când găsim primul element cu proprietatea cerută sau până când
epuizăm elementele vectorului. De exemplu, determinarea ultimului element par dintr-un vector se realizează cu secvenţa:
f=-1;
for(j=n-1;j>=0;j--)
if(!(a[j]%2))
{f=j; break; }

Eliminarea tuturor elementelor cu o anumită proprietate


Cea mai simplă metodă de a elimina dintr-un vector toate elementele cu o anumită proprietate este să creăm un nou
vector în care se păstrează elementele care nu au proprietatea respectivă. De exemplu, pentru a elimina dintr-un vector toate
elementele negative, putem utiliza secvenţa:
j=-1;
for(i=0;i<n;i++)
if(a[i]>=0) /* nu are proprietatea cerută */
b[++j]=a[i]; /* păstram elementul în vectorul b */
n=j; /* actualizăm dimensiunea vectorului */
Metoda este ineficientă datorită consumului de memorie necesară pentru vectorul b. O metodă mult mai eficientă este
să folosim acelaşi vector în care vom „îngrămădi” pe primele poziţii elementele care trebuie păstrate. Prin actualizarea
dimensiunii vectorului, elementele de prisos nu vor mai fi luate în consideraţie în prelucrările ulterioare. Secvenţa care
realizează această operaţie este următoarea:
j=-1;
for(i=0;i<n;i++)
if(a[i]>=0) /* nu are proprietatea cerută */
a[++j]=a[i]; /* mutăm elementul la începutul vectorului */
n=j; /* actualizăm dimensiunea vectorului */

Eliminarea elementului din poziţia k dată (1<=k<=n)


Prin eliminarea elementului din poziţia k dată (elementul de indice k-1), se observă că primele k-1 elemente rămân
neschimbate, în timp ce elementele din poziţiile k+1, k+2,…….,n se deplasează cu o poziţie spre stânga pentru a “umple”
golul rămas prin eliminarea elementului din poziţia k.
Evident, dimensiunea vectorului scade cu o unitate :
for(j=k-1;j<=n-2;j++) a[j]=a[j+1]; /* deplasăm elementele spre stânga */
n--; /* corectăm dimensiunea */

Inserarea unui element y în poziţia k dată (1<=k<=n)


Cum inserarea unui element se face fără a pierde vreun element din vectorul iniţial, elementele din poziţiile k,
k+1,.......n trebuie să se deplaseze cu o poziţie spre dreapta pentru a face loc noii valori

y introdusă în poziţia k (indice k-1). Dimensiunea vectorului creşte cu o unitate:

for(j=n;j>=k;j--) a[j]=a[j-1]; /* deplasăm elementele spre dreapta */


a[k-1]=y; /* inserăm elementul y */
n++; /* actualizăm dimensiunea */

Permutarea circulară cu o poziţie spre stânga


Prin acestă operaţie, elementele din poziţiile 2,3,……..,n se deplasează cu o poziţie spre
stânga şi elementul din prima poziţie ajunge în poziţia n. Vectorul nu îşi modifică dimensiunea:

20
aux=a[0]; /*salvăm temporar primul element */
for(j=0;j<=n-2;j++) a[j]=a[j+1]; /* deplasăm elementele spre stânga */
a[n-1]=aux; /* mutăm elementul în ultima poziţie */

Permutarea circulară cu o poziţie spre dreapta


Prin această operaţie, elementele din poziţiile 1,2,……,n-1 se deplasează cu o poziţie spre
dreapta, iar elementul din poziţia n ajunge în poziţia 1. Vectorul nu îşi modifică dimensiunea:
aux=a[n-1]; /* salvăm temporar ultimul element */
for(j=n-1;j>=1;j--) a[j]=a[j-1]; /*deplasăm elementele spre dreapta */
a[0]=aux; /* mutăm elementul în prima poziţie */

Problema 1 : Se citeşte un tablou unidimensional cu n (1<=n<=100) componente numere naturale. Se cere să se


construiască şi să se afişeze un nou vector cu componentele pătrate perfecte ale vectorului iniţial.

#include <iostream.h>
#include <math.h>
int main(void) {
unsigned int x[100], y[100], n, i, j;
cout<<"Dati numarul elementele ale tabloului n = ";
cin>>n;
cout<<"Dati elementele tabloului"<<endl;
for(i = 1; i <= n; i++) {
cout<<"x["<<i<<"]="; cin>>x[i];
}
j = 0; // numărul de elemente din noul vector
for(i = 1; i <= n; i++) { if(sqrt(x[i]) == int(sqrt(x[i])))
{ j++;
y[j] = x[i]; } }
cout<<"Elementele patrate perfecte sunt : "<<endl;
for(i= j;i<=j; i++) { cout.width(6); // afişează pe 6 caractere
cout<<y[i];}}

Problema 2: Se consideră n numere intregi. Se cere să se verifice dacă ele sunt sau nu în ordine crescătoare, afisând
câte un mesaj corespunzător.
#include<iostream.h>
int main(void)
{ int i, n, verif=1;
int x[50];
cout<<"Dati numarul de elemente ale tabloului X "; cin>>n; for(i=1; i<=n; i++)
{
cout<<"x[“<<i<<"]= ";
cin>>x[i];
}
for(i=1; i<=n-1; i++)
if( x[i] > x[i+1] ) verif=0;
if( verif == 1 )
cout<<"Numerele din tablou sunt in ordine CRESCATOARE"; else cout<<"Numerele din tablou NU
sunt in ordine CRESCATOARE"; }

Sarcinile propuse:
Nr. Sarcina
var.
21
1. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează minimul par din şirul de elemente citit iniţial.
2. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează maximul impar din şirul de elemente citit iniţial.
3. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează numărul de apariţii a minimului în şirul de elemente
citit iniţial.
4. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează numărul de apariţii a maximului în şirul de elemente
citit iniţial.
5. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează minimul şi poziţia minimului în şirul de elemente citit
iniţial.
6. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează maximul şi poziţia maximului în şirul de elemente
citit iniţial.
7. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează cel mai mare număr negativ din şirul de elemente
citit iniţial.
8. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează cel mai mic număr pozitiv din şirul de elemente citit
iniţial.
9. Se citeşte un număr natural nenul n(1<=n<=50) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere întregi, de maxim 9 cifre fiecare, apoi interschimbă valoarea minimului cu valoarea maximului, apoi afişează
vectorul rezultatul în urma interschimbării.
10. Se citeşte un număr natural nenul n(1<=n<=100) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere naturale, de maxim 9 cifre fiecare, apoi determină şi afişează indicele elementelor prime din şirul de elemente
citit iniţial, apoi numărul lor. Dacă în şir nu există nici un număr prim se va afişa mesajul „NU EXISTĂ!”.

11. Se citeşte un număr natural nenul n(1<=n<=100) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere naturale, de maxim 9 cifre fiecare, apoi determină şi afişează numărul elementelor din şirul citit iniţial care au
proprietatea că suma cifrelor lor este nu număr prim. Dacă în şir nu există nici un număr cu proprietatea cerută se va
afişa mesajul „NU EXISTĂ!”.
12. Se citeşte un număr natural nenul n(1<=n<=100) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere naturale, de maxim 9 cifre fiecare, apoi determină şi afişează numărul elementelor din şirul citit iniţial care au
proprietatea că sunt divizibile cu suma cifrelor lor.
13. Se citeşte un număr natural nenul n(1<=n<=100) şi k(k>1) de la tastatură. Scrieţi un program C care citeşte un şir de
n elemente numere întregi, de maxim 9 cifre fiecare, apoi determină şi afişează elementele din şirul citit care au
proprietatea că au exact k divizori(proprii şi improprii). Dacă în şir nu există nici un număr cu proprietatea cerută se va
afişa mesajul „NU EXISTĂ!”.
14. Se citeşte un număr natural nenul n(1<=n<=100) de la tastatură. Scrieţi un program C care citeşte un şir de n elemente
numere naturale, de maxim 9 cifre fiecare, apoi
determină şi afişează pentru fiecare element din şir, care nu este număr prim, toţi divizorii numărului(fără 1 şi el însuşi).

15. Se citeşte un număr natural nenul n(1<=n<=100) şi un număr natural x, de la tastatură. Scrieţi un program C care
citeşte un şir de n elemente numere naturale, de maxim 9 cifre fiecare, apoi determină şi afişează toate elementele
din vector care sunt divizori de-ai lui x. Dacă în şir nu există nici un element cu proprietatea cerută se va afişa mesajul
„NU EXISTĂ!”

Laborator nr. 6: Tablouri bidimensionale


22
Scop: să folosească practici recunoscute şi recomandate pentru scrierea de cod sursă care implică lucrul cu matrici
Noţiuni teoretice
Tablourile bidimensionale funcţionează ca o matrice şi se pot declara astfel:
tip nume_tablou[dim_linie][dim_coloana];
La fel ca şi în cazul tablourilor unidimensionale, şi în cazul tablourilor bidimensionale, la declarare, se trece dimensiunea
maximă a liniilor (dim_linie) şi dimensiunea maximă a coloanelor (dim_coloana).
Exzemplu : declararea tablourilor bidimensionale
 int a[10][10]; // declararea unui tablou bidimensional cu maxim 100 de // elemente (10*10), fiecare de tip întreg;
 float x[5][5]; // declararea unui tablou bidimensional cu maxim 25 de // elemente(5*5), fiecare de tip real simplă
precizie;
 char s[20][10]; // declararea unui tablou bidimensional cu maxim 200 de // elemente(20*10), fiecare de tip caracter;
Compilatorul C++ alocă un spaţiu de memorie egal cu numărul de linii înmulţit cu numărul de coloane ale tabloului ,
rezervând bineînţeles octeţi în funcţie de tipul de bază al fiecărui tablou.
Accesul la fiecare element al tabloului se face prin numele acestuia urmat între paranteze, de indicele liniei şi
indicele coloanei (adică poziţia pe care o ocupă în tablou).
Câteva modalităţi de acces la elementele ce pot fi memorate în tablourile bidimensionale declarate anterior:
 a[0][0] – reprezintă elementul aflat pe linia 0 coloana 0 a[9][9] - reprezintă elementul aflat pe linia 9 coloana 9
 x[i][j] - reprezintă elementul aflat pe linia i, coloana j în matrice, unde i şi j pot avea valori între 0 şi 4.
Iniţializarea elementelor unui tablou se poate face total sau parţial la declararea lor:
int b[2][3]={ {1, 2, 3}, {4, 5, 6} };
Astfel, elementul b[0][0] are valoarea 1, elementul b[0][1] are valoarea 2, elementul b[0][2] are valoarea 3, elementul b[1]
[0] are valoarea 4, elementul b[1][1] are valoarea 5, elementul b[1][2] are valoarea 6.
Problema 1: Se consideră două tablouri bidimensionale (matrici) A şi B cu nXm, respectiv mXp numere întregi.Se cere
să se calculeze matricea produs: C = A * B.
#include<iostream.h>
int main(void)
{
int a[10][10], b[10][10], c[10][10];
int n, m, i, j, k, p;
cout<<"Dati dimensiunile matricei A "<<endl;
cout<<"Dati numarul de linii n = "; cin>>n;
cout<<"Dati numarul de coloane m = "; cin>>m;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
{
cout<<"a["<<i<<", "<<j<<"] = ";
cin>>a[i][j];
}
cout<<"Elementele matricei A sunt: “<<endl;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
cout<<a[i][j]<<" ";
cout<<endl;}
cout<<"Dati dimensiunile matricei B " <<endl;
cout<<"Dati numarul de linii m = "; cin>>m;
cout<<"Dati numarul de coloane p = "; cin>>p;
for(i=1; i<=m; i++)
for(j=1; j<=p; j++)
{
cout<<“b["<<i<<", "<<j<<"] = ";
cin>>b[i][j];
}
cout<<"Elementele matricei B sunt : “<<endl;
for(i=1; i<=m; i++)
{
for(j=1; j<=p; j++) cout<<b[i][j]<<" ";
cout<<endl;
}
23
for(i=1; i<=n; i++)
for(j=1; j<=p; j++)
{
c[i][j] = 0;
for(k=1; k<=m; k++)
c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
cout<<"Elementele matricei produs C sunt : “<<endl;
for(i=1; i<=n; i++)
{
for(j=1; j<=p; j++) cout<<c[i][j]<<" "; cout<<endl;
}}

Problema 2: Se consideră o matrice A cu nm numere întregi. Se cere să se obţină transpusa sa.

#include<iostream.h>
int main(void)
{
int a[10][10], b[10][10];
int n, m, i, j;
cout<<"Dati dimensiunile matricei A "<<endl;
cout<<"Dati numarul de linii n = "; cin>>n;
cout<<"Dati numarul de coloane m = ";cin>>m;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
{
cout<<"a["<<i<<", "<<j<<"] = ";
cin>>a[i][j];
}
cout<<"Elementele matricei A sunt : “<<endl;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++) cout<<a[i][j]<<" ";
cout<<endl;
}
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
b[j][i] = a[i][j];
cout<<"Elementele matricei transpuse sunt “<<endl; for(i=1; i<=m; i++)
{
for(j=1; j<=n; j++) cout<<b[i][j]<<" "; cout<<endl;
}
}
Sarcini propuse:

Nr. var. Problema


1. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determină
suma elementelor pozitive pe fiecare colană şi creează un vector ce va conţine elementele impare ale tabloului
bidimensional citit iniţial.
2. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determină
produsul elementelor negative pe fiecare linie şi creează un vector ce va conţine elementele pare divizibile la 4 ale
tabloului bidimensional citit iniţial.
3. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care schimbă cu
locul linia ce conţine elementul maxim cu linia ce conţine elementul minim.
4. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care atribuie
valoare zero elementelor de pe diagonal secundară şi creează un vector din elementele diagonalei secundare.
24
5. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care să creeze un
vector din elementele minime de pe fiecare coloană şi să determine media aritmetică a lor
6. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determina
numărul elementelor pozitive pare pentru fiecare coloană şi numărul elementelor negative pozitive pentru fiecare
linie.
7. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care interschimbă
diagonal principal cu diagonal secundară şi creează un vector din elementele de sub diagonal secundară.
8. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care interschimbă
pe fiecare linie elementul maxim cu elementul minim şi elementele minime le înscrie în vectorul B[1..n].

9. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determina
suma elementelor pozitive pe fiecare colană şi creează un vector ce va conţine elementele impare ale tabloului
bidimensional citit iniţial.

10. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care creează un
tablou Y de elemente maxime de pe liniile tabloului A.

11. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determina
numărul liniei cu cea mai mare sumă şi afişează elementele ei.

12. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determina
numărul coloanei cu cel mai mic produs şi numărul linei cu cele mai multe elemente pozitive.

13. Se consideră două tablouri A [1..n,1..m] şi B[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un
program care verifică dacă fiecare element din A are aceiaşi valoare ca şi elementul de pe locul corespunzător din
B.

14. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care calculează
suma elementelor de pe “perimetrul” tabloului şi suma celorlalte elemente.

15. Se consideră tabloul A[1..n,1..m] de numere întregi, unde n şi m<=20. Să se scrie un program care determina
dacă tabloul A este simetric faţă de diagonala principal.

Sarcini propuse:

Var. Condiţia Folosirea funcţiilor pentru:


Sunt date trei masive unidimensionale A[n], B[m] şi C[k]. De aranjat Aranjarea elementelor în ordine
elementele fiecărui masiv în ordine crescătoare. crescătoare.

Sunt date două masive bidimensionale X[n,n] şi Y[m,m]. De calculat Calcularea sumelor şi cantităţilor
suma şi cantitatea elementelor de sub diagonala secundară pentru elementelor de sub diagonale secundare.
fiecare masiv.

Sunt date trei masive unidimensionale X[n] şi Y[m]. De aflat media Aflarea mediei aritmetice şi abaterii
aritmetică şi abaterea maximală de la ea pentru fiecare din masive. maximale de la ea.

Sunt date două masive bidimensionale A[x,x] şi B[y,y]. De calculat suma Calcularea sumei şi produsului elementelor
şi produsul elementelor deasupra diagonalei secundare pentru fiecare deasupra diagonalei secundare.
masiv.

25
Sunt date două masive bidimensionale A[n,m] şi B[k,g]. De calculat Calcularea cantităţilor elementelor negative
cantităţile elementelor negative de pe fiecare rând în parte în ambele de pe fiecare rând în parte în ambele
masive. masive.

Sunt date două masive bidimensionale A[n,m] şi B[k,g]. De aflat valorile şi Aflarea valorilor şi poziţiilor elementelor
poziţiile elementelor minimale de pe fiecare rând al ambelor masive. minimale de pe fiecare rând al ambelor
masive
Sunt date două masive bidimensionale S[n,m] şi Z[k,g]. De calculat Calcularea cantităţilor şi sumelor
cantităţile şi sumele elementelor divizibile la cinci din ambele masive. elementelor divizibile la cinci

Sunt date două masive bidimensionale A[n,m] şi B[k,g]. De calculat Calcularea sumelor elementelor pozitive de
sumele elementelor pozitive de pe fiecare coloană în ambele masive. pe fiecare coloană

Sunt date două masive unidimensionale X[k] şi Y[m]. De aranjat în ordine Aranjarea elementelor în ordine inversă
inversă elementele ambelor masive.

Sunt date două masive bidimensionale X[n,m] şi Y[k,g]. De calculat suma Calcularea sumei elementelor maximale de
elementelor maximale de pe fiecare coloană a fiecărui masiv. pe fiecare coloană

Sunt date două masive bidimensionale X[n,n] şi Y[m,m]. De calculat Determinarea valorilor elementelor
suma dintre elementul maximal deasupra diagonalei principale a maximale deasupra diagonalelor principale
masivului X şi elementul maximal deasupra diagonalei principale a în ambele masive.
masivului C.

Sunt date două masive bidimensionale X[n] şi Y[m]. De calculat valorile şi Determinarea valorilor şi poziţiilor
poziţiile elementelor minimale din ambele masive. elementelor minimale din ambele masive.

Sunt date două masive bidimensionale X[m,n] şi Y[k,p]. De calculate Calcularea sumelor elementelor pozitive
sumele elementelor pozitive pe fiecare coloană în ambele masive. pe fiecare coloană în ambele masive.

Sunt date două masive bidimensionale X[n] şi Y[m]. De aranjat în ordine Aranjarea elementelor ambelor masive în
inversă elementele ambelor masive. ordine inversă .

Sunt date două masive bidimensionale X[m,n] şi Y[k,p]. De calculate Calcularea sumelor elementelor maximale
suma elementelor maximale de pe fiecare coloană a masivului X şi suma de pe fiecare coloană în ambele masive.
elementelor maximale de pe fiecare coloană a masivului Y.

26
Laborator nr. 7: Prelucrarea şirurilor de caractere

Scop: Implementarea funcţiilor pentru prelucrarea şirurilor de caractere

Noţiuni teoretice
1. Functia strlen.

Are rolul de a returna lungimea unui şir(fără a lua în considerare caracterul nul).

Forma generală : strlen(nume sir);

Exemplu1 : Se citește un şir de caractere şi se afișează numărul de caractere a șirului

#include<iostream.h>
#include<string.h>

void main()
{
char s1[100];
cin.get(s1,100);cin.get();
cout<<"Sirul citit are"<<" "<<strlen(s1)<<" "<<"caractere";,
}

2 Functia strcpy.

Forma generală: strcpy(destinatie,sursa)

Funcția are rolul de a copia șirul de la adresa sursa la adresa destina ție .

#include<iostream.h>
#include<string.h>
void main()
{
char s1[20]="Limbalul Turbo C++",s2[20]="Limbajul C++";
strcpy(s1,s2);

cout<<s1;
}

3. Functia strcat.

Forma generală: strcat(destinație,sursă)

Funcţia are rolul de a adăuga șirului de la adresa destina ție șirul de la adresa sursă.

#include<iostream.h>
#include<string.h>
void main()
{
char s1[20]="Limbajul Turbo C++",s2[20]=" si Limbajul C++";
strcat(s1,s2);

27
cout<<s1;
}

4. Functia strncat

Forma generală: strncat(destinație,sursă,n)

Funcția adaugă șirului destina ție primii n octeți ai șirului sursă

#include<iostream.h>
#include<string.h>
void main()
{
char s1[20]="Limbajul Turbo C++",s2[20]=" şi Limbajul C++";
strncat(s1,s2,5);

cout<<s1;
}

5. Functia strchr

Forma generală: strchr(nume şir, 'caracter' )

Functia căută în șirul nume şir caracterul caracter şi returnează subșirul care începe cu prima
apariție a caracterului citit
#include<iostream.h>

#include<string.h>
void main()
{
char s1[20]="Limbajul Turbo C++";

cout<<strchr(s1,'T');
}

6. Functia strrchr

Returnează adresa ultimei apariții a caracterului căutat strrchr(şir, 'caracter' )

char s1[20]="Limbajul Turbo C++";


cout<<strrchr(s1,'u')-s1;

Returnează valoarea 10

7. Functia strcmp

Forma generală strcmp(sir1, sir2 )

Funcția are rolul de a compara 2 șiruri de caractere şi va returna valoarea:

C. 0 dacă
sir1<sir2 = 0
28
dacă
sir1=sir2 > 0
dacă
sir1>sir2
Exemplu Se compară șirul a cu șirul b şi se listează relația dintre cele 2 șiruri astfel:
D. dacă primele n caractere sunt identice se compară caracterele n+1
E. dacă caracterul n+1 al șirului a este situat alfabetic înaintea caracterului n+1 al șirului b se afișează a<b
F. dacă caracterul n+1 al șirului a este situat alfabetic după caracterul n+1 al șirului b se afișează a>b

G. dacă primul caracter al șirului a este situat alfabetic înaintea primului caracter al șirului b se afișează a<b indiferent de
lungimea celor 2 șiruri

H. dacă primul caracter al șirului a este situat alfabetic după primul caracter al șirului b se afișează a>b indiferent de
lungimea celor 2 șiruri

#include<iostream.h>
#include<string.h>
void main()
{
char a[20], b[20];

int semn;
cout<<"Introduceti sirul a: "; cin>>a;

cout<<"Introduceti sirul b: "; cin>>b;


semn=strcmp(a,b);
if(semn<0) cout<<"a < b";
else
if(semn>0) cout<<"a > b";
else cout<<"a = b";

}
8. Functiile strlwr şi struwr

strlwr(s1) - converte ște toate literele șirului s1 în litere mici


struwr(s2) - converte ște toate literele șirului s2 în litere mari

#include<iostream.h>
#include<string.h>
void main()
{

char a[100]="este acesta un sir?", b[100]="Acest Lucru Nu Ma


Deranjeaza"; cout<<strupr(a)<<endl<<strlwr(b);

9. Functia strstr

Forma generală: strstr(sir1,sir2)

29
Funcția identifică dacă șirul sir2 este subșir al șirului sir1

10. Functia strcspn

Forma generală: strcspn(s1,s2)

Funcția returnează numărul caracterelor din șirul s1 care nu se găsesc în șirul s2

11. Functia spn

Forma generală: strspn(s1,s2)

Funcția returnează numărul caracterelor din șirul s1 care se găsesc în șirul s2

1.1. Functii utilizate pentru conversia valorilor numerice în sir


La utilizarea acestor funcții se introduce directiva #include<stdlib.h>

a) Func ția atof - convertește un şir către tipul double

b) Func ția atold - convertește un şir către tipul long double

#include <stdlib.h>
#include <iostream.h>
void main()

{
float f;
char *str = "12345.67"; f = atof(str);
cout<<"string = "<<str<<endl<<"float = "<< f;
}

Func ția atoi - convertește un şir către tipul int


Func ția atol - convertește un şir către tipul long

Exemplu
#include <stdlib.h>

#include <iostream.h>
void main()
{
int n;
char *str = "12345.67"; n = atoi(str);

cout<<"string = "<<str<<endl<<"float = "<< n;


}

Func ția ecvt - convertește o valoare double către un sir

Func ția itoa - convertește o valoare de tip int către un sir

Func ția ltoa - convertește o valoare de tip long int către un sir
Exemplu: Sã se citeascã n cuvinte ( şiruri de caractere). Sã se determine maximul, în sens lexicografic.
30
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main() {
int i,n;
char a[20], max[20]; clrscr();
printf("\n n = ");
scanf("%d", &n);
strcpy(max, "");
printf("\n Dati cuvintele: "); for(i = 1;i<=n; i++){
printf("\n sir %d: ",i);
scanf("%s", &a); if(strcmp(max,a)<0)
strcpy(max,a);}
printf("\n maximul este %s",max); getch();}

Exemplu: Sã se citeascã n şiruri de caractere şi sã se ordoneze crescãtor.

#include<stdio.h>
#include<conio.h>
#include<string.h> void main()
{
int n, i, j;
char a[20][100], aux[100]; clrscr();
printf("\n n = ");
scanf("%d", &n);
printf("\n Dati sirurile: ");
for(i = 0;i <= n-1; i++)
{
printf("\n a[%d]= ",i);
scanf("%s", &a[i]);
}
//ordonare crescatoare
for( i = 0; i <= n-2; i++)
for( j = i + 1; j <= n-1; j++) if (strcmp(a[i],[j]) > 0 )
{
strcpy(aux, a[i]);
strcpy(a[i], a[j]);
strcpy(a[j], aux);
}
printf("\n Sirul ordonat este: "); for(i = 0;i <= n-1; i++)
printf("%s ",a[i]); getch();}

31
1.3 Sarcini propuse
Nr. Sarcina
var.
1. Să se scrie un program C care să citească de la tastatură un cuvânt şi să verifice dacă respectivul cuvânt este palindrom
(cuvânt care poate fi citit de la stânga la dreapta şi de la dreapta la stânga fără să-şi piardă sensul: cojoc, capac, rar).

2. Să se scrie un program C care să citească de la tastatura N şiruri de caractere (N < 10, introdus de la tastatura) şi
afişează cel mai mare dintre şiruri din punct de vedere alfabetic.

3. Sa se scrie un program care citeste cuvintele tastate fiecare pe cate un rand nou, pana la CTRL/Z ( varianta: pana la
introducerea un cuvant vid ) şi afiseaza cuvantul cel mai scurt.

4. Să se scrie un program C care să determine numărul de apariţii ale unui anumit cuvânt, într-un text introdus de la
tastatură.

5. Să se scrie un program C care să afişeze numărul de vocale dintr-un text scris cu litere mici, memorat intr-o variabilă de
tip șir de caractere.

6. Să se scrie un program C care să afişeze cu litere mari un text dat, de maxim 255 caractere.

7. Să se scrie un program C care citește un șir de caractere. Să se afișeze litera cea mai des întâlnită.

8. Se citește de la tastatură un caracter c și un text de maxim 100 de carectere. Afișați de câte ori apare caracterul c în
cadrul textului. Literele mari se vor considera diferite de literele mici.

9. Se citește de la tastatură un șir de maxim 100 de carectere format numai din litere și cifre. Afișați numărul literelor mari,
numărul literelor mici și numărul caracterelor de tip cifră din textul dat.

10. Sa se verifice daca doua cuvinte citite de la tastatura rimeaza (spunem ca doua cuvinte
rimeaza daca ultimele doua caractere sunt identice).

11. Se citesc trei siruri s1, s2 si s3. Sa se afiseze sirul obtinut prin inlocuirea in s1 a tuturor aparitiilor lui s2 prin s3.
( Observatie: Daca s3 este sirul vid, din s1 se vor sterge toate subsirurile s2 ).

12. Sa se scrie un program care construieste si afiseaza cuvantul format din ultima litera din cuvintele introduse,
transformata in minuscula ( nu vor fi prelucrate cuvintele ce nu se termina cu o litera )

13. Sa se scrie un program care citeste cuvintele tastate fiecare pe cate un rand nou, pana la CTRL/Z ( varianta: pana la
introducerea un cuvant vid ) şi afiseaza cuvantul cel mai lung

14. Scrieti un program care citeste un sir de caractere si transforma sirul in sir cu litere mici.

15. Se citesc n cuvinte. Se cere sa se ordoneze alfabetic.

32
Lucrarea nr.8 Structuri
Scop: Implementarea datelor de tip structură
Noţiuni teoretice
Structurea este un grup de variabile de tipuri diferite reunite sub acelaşi nume, ce pune la dispoziţia utilizatorului un
mod convenabil de păstrare a informaţiilor legate între ele.
Declararea unei structuri crează un nou tip de date ce poate fi folosit pentru a crea variabile de acel tip sau pentru a crea direct
variabile de acel tip. Variabilele care fac parte din structură se numesc membri, elementele sau câmpurile structurii. Între membri
structurii deobicei există o legătură logică.
Spre deosebire de tablouri, fiecare element al unei structuri poate avea propriul său tip care poate diferi de tipul oricărui
alt element.
Forma generala a declarării unei structuri este:
struct nume – generic {
tip nume – membrul 1;
tip nume – membrul 2;
..............
tip nume – membrul;
} listă_variabile;
unde:
- struct - este cuvânt rezervat, numele tipului de date;
- tip – este orice tip de dată admis de C; nu trebuie să fie acelaşi pentru toate campurile;
- nume–generic – tipul dat structurii, optional;
- listă_variabile -este o listă de variabile de tip nume_generic daca apare sau anonim daca nu apare, este optionala;
- nume_membru i – este numele campului (membrului) i al structurii.
Nume_generic şi listă_variabile sunt opţionale, dar cel putin una apare. Dacă nume_generic apare înseamnă că s-a
creat un nou tip de date,. Daca lista_variabile apare inseamna ca s-au declarat variabile de tip structură, fără ca structura să
aibe tip( tipul structurii create este anonim).
Exemplu:
struct carte {
char nume_carte [30];
char nume_autor [40];
char editură [20];
long data_ap;
unsigned char ed;
} carte1, carte2;
Carte este tipul structurii, variabilele de tip structură sunt carte1 şi carte2. Odată definit un tip de structură, se pot crea
mai multe variabile de acel tip, folosind forma generală:
struct nume_generic listă_variabile;
Declaraţia de mai sus se poate rescrie astfel:
struct carte {
char nume_carte [30];
char nume_autor [40];
char editură [20];
long data_ap;
unsigned char ed; //ediţia
};
struct carte carte 1, carte 2;
Deci nu este necesar să se declare toate variabilele de tipul respectiv atunci cand este definită o structură. Variabilele se
pot declara separat, pe masură ce apare necesitatea folosirii lor.
În cazul în care se ştie exact variabilele de tip structură folosite în program, nume_generic poate lipsi. De exemplu
dacă programul va folosi doar variabilele carte1, carte2 si carte3 în cadrul programului putem declara structura astfel:
struct {
char nume_carte [30];
33
char nume_autor [40];
char editură [20];
long data_ap;
unsigned char ed;
float preţ;
} carte1, carte2, carte3;

unde lipseste numele tipului structurii create.

Accesul la membrii structurii

Pentru a accesa un camp al unei structuri, trebuie specificate atat numele variabilelor de tip structură cat şi numele
campului, separate printr-un punct. Forma generală de acces la un membru:
Nume_variabilă . nume_membru
Pentru structura şi variabilele declarate mai sus putem realiza urmatoarele operatii:
- atribuirii de forma:
carte1 . data_ap = 1999;
carte2 . editura = “Teora”;
carte1 . nume_carte = “Programare în C”;
carte1 . preţ = 12345.50;
- citirea unor campuri ale unei structuri :
scanf (“% ld %f %s “,&carte1.data_ap, &carte1.preţ, carte1.editură);
gets (carte1.nume_carte);
- scrierea / afişarea unor campuri ale unei structurii:
printf (“ %ld %f %s “, carte1.data_ap, carte1.preţ, carte1.editura);
- afişarea un caracter dintr-un camp:
printf (“ %c “, carte1.nume_autor [5]);
- atribuirea unei variabile a unui caracter dintr-un camp:
ch= carte1.nume_autor [5]);
- conţinutul unei variabile de tip structură poate fi asignat unei alte variabile de tip structură, dar de acelaşi tip:
carte2 = carte1;
atribuire echivalenta cu atribuirile:
carte2.nume_autor = carte1.nume_autor;
carte2.nume_carte = carte1 . nume_carte;
carte2.editura = carte1.editura;
. . . .. . . . . . . . .
carte2.preţ = carte1.preţ;
- determinarea dimensiunii unei structuri folosind operatorul sizeof :
printf (“Numărul de octeţi ai structurii = %d”, sizeof (struct carte));

Numele tipului structurii trebuie să fie precedat de cuvantul cheie struct la folosirea operatorului sizeof.

Exemplu :De definit o structură cu N înscrieri, care conţine informaţia despre angajaţii unei întreprinderi.
a) De realizat căutarea angajaţilor după numele de familie.
b) De aranjat înscrierile în ordinea descrescătoare după mărimea salariului.
# include<stdio.h>
# include<conio.h>
# include<string.h>
struct angajat{
char nume[30];
char post[20];
34
float salariu;};
void main (void){
struct angajat x[50], art;
int i,n,k,z,d; float aux,max;
char caut[30],r; clrscr();
printf(“Culege numarul de angajati\n”);
scanf(“%d”,&n);
for(i=1; i<=n; i++){
printf(“\n Culege numele angajatului%d:”, i);
scanf(“%s”,&x[i].nume);
printf(”\n Culege postul angajatului%d:”,i);
scanf(“%s”,&x[i].post);
printf(”\n Culege salariul angajatului%d:”,i);
scanf(“%f”,&aux); x[i].salar=aux;}
printf(“\n\n\t*****Baza initiala este*****\n\n”);
printf(“\t-------------------------------------------\n”);
printf(“\t| Numele | Postul | Salariul|\n”);
printf(“\t| |\n”);
for(i=1; i<=n; i++){
printf(“\n Pentru continuare culegeti orice tasta...”);
getch();
r1:crlscr();
printf(“\n Cautarea angajatilor dupa nume.\n Culegeti numele cautat:”);
scanf(“%s”,&caut);
printf(“\n\n\t***** Rezultatul cautarii *****\n\n”);
printf(“\t-------------------------------------------\n”);
printf(“\t| Numele | Postul | Salariul|\n”);
printf(“\t| ----------------------------------------------|\n”);
k=0;
for(i=1; i<=n; i++){
if(strcmp(x[i].nume,caut)= =0){ k++;
printf(“\t|%16s|%14s|%10.2f|\n”,x[i].nume,x[i].post, x[i].salar);
printf(“\t| ----------------------------------------------|\n”);}}
if(k= =0) printf(“\n Nu exista angajat cu asa nume.\n”);
printf(“\n Dariti sa repetati cautarea?(y/n) : “);
r=getch(); if ((r= =’y’)||(r= =’Y’) goto r1;
for(i=1; i<=n; i++){
max=x[i].salar; z=i;
for(d=i;d<=n; d++){
if(max<x[d].salar) {max=x[d].salar; z=d;}}
art=x[i]; x[i]=x[z]; x[z]=art;}
clrscr();
printf(“\n\n\t ***** Baza aranjata este *****\n\n”);
printf(“\t| --------------------------------------------------------------|\n”);
printf(“\t| Numele | Postul | Postul | Salariul |\n”);
printf(“\t| ---------------------------------------------------------------|\n”);
for(i=1; i<=n; i++){
printf(“\t|%16s|%14s|%10.2f|\n”,x[i].nume,x[i].post, x[i].salar);
printf(“\t| ----------------------------------------------|\n”);}
printf(“\n Pentru iesire culegeti orice tasta...”); getch();}
Sarcini propuse:
Nr. ord. Condiţia
35
1. De definit o structură cu N înscrieri, care conţine informaţia despre orarul primirii pacienţilor de către medic.
a) De realizat căutarea pacienţilor după numele de familie.
b) De aranjat înscrierile în ordinea crescătoare după ora primirii pacientului.
2. De definit o structură cu N înscrieri, care conţine informaţia despre emisiunile difuzate de către un post TV.
a) De realizat căutarea emisiunilor după denumire.
b) De schimbat cu locul înscrierile cu durata minimă şi maximă.
3. De definit o structură cu N înscrieri, care conţine informaţia despre amplasarea cărţilor pe rafturile unei biblioteci.
a) De realizat căutarea după numărul raftului.
b) De aranjat înscrierile în ordinea descrescătoare după numărul raftului.
4. De definit o structură cu N înscrieri, care conţine informaţia despre mărimea datoriei beneficiarilor centralei
telefonice.
a) De realizat căutarea beneficiarilor după numele de familie.
b) De aranjat înscrierile în ordinea crescătoare după mărimea datoriei de abonat.
5. De definit o structură cu N înscrieri, care conţine informaţia necesară despre studenţii unei facultăţi.
a) De realizat căutarea studenţilor după denumirea grupei.
b) De aranjat înscrierile în ordinea inversă.
6. De definit o structură cu N înscrieri, care conţine informaţia despre un grup de angajaţi.
a) De realizat căutarea angajaţilor după postul ocupat.
b) De aranjat înscrierile în ordinea crescătoare după vechimea în muncă.
7. De definit o structură cu N înscrieri, care conţine informaţia despre un grup de studenţi.
a) De realizat căutarea studenţilor după vârsta lor.
b) De schimbat cu locul înscrierile pentru studenţii cu cea mai mică şi cea mai mare vârstă.
8. De definit o structură cu N înscrieri, care conţine informaţia despre abonaţii unei biblioteci.
c) De realizat căutarea abonaţilor după familie
d) De şters din fişier înscrierile abonaţilor cu cantităţile minimă şi
maximă de cărţi împrumutate.
9. De definit o structură cu N înscrieri, care conţine informaţia despre un grup de studenţi.
De calculat balul mediu pentru fiecare student reieşind din rezultatele la trei examene.
b) De aranjat înscrierile în ordine descrescătoare după balul mediu.
10. De definit o structură cu N înscrieri, care conţine informaţia despre paşapoartele unui grup de persoane.
a) De realizat căutarea persoanei după numărul paşaportului.
b) De aranjat înscrierile în ordine inversă.

11. De definit o structură cu N înscrieri, care conţine informaţia despre orarul lecţiilor unui student într-o zi a săptămânii.
a) De realizat căutarea lecţiei după ora curentă.
b) De schimbat cu locul prima şi ultima înscriere.
12. De definit o structură cu N înscrieri, care conţine informaţia despre orarul primirii pacienţilor de către medic.
a) De realizat căutarea pacienţilor după familie.
b) De aranjat înscrierile în ordine crescătoare după ora primirii pacienţilor.
13. De definit o structură cu N înscrieri, care conţine informaţia despre meniul într-un restaurant.
a) De aflat preţul celor trei bucate alese de client.
b) De aranjat înscrierile în ordine descrescătoare după preţul bucatelor.

14. De definit o structură cu N înscrieri, care conţine informaţia despre cursul valutar la o casă de schimb.
a) De realizat căutarea valutei după denumirea sa.
b) De aranjat înscrierile în ordine crescătoare după cursul de schimb.

15. De definit o structură cu N înscrieri, care conţine informaţia despre un grup de automobile.
a) De realizat căutarea automobilelor după numărul de înregistrare a lor.
b) De aranjat înscrierile în ordine alfabetică după marca automobilelor.

36
Lucrarea nr.9-10: Pointeri. Pointeri şi tablouri
Scop: Implementarea şi prelucarea datelor de tip pointer
Noţiuni teoretice

Un pointer este o variabilă care are ca valoare adresa unui obiect cu care operează limbajul C/C++ (variabilă,
constantă, funcţie).
• Folosirea pointerilor este determinată de două motive şi anume:
1. este singura modalitate de a efectua anumite calcule
2. folosirea pointerilor duce la generarea unui cod sursă de program mai eficient şi mai compact
Declararea unei variabile de tip pointer se face astfel:
tip *nume_pointer;
Unde:
• tip reprezintă oricare dintre tipurile limbajului C/C++ şi indică tipul variabilei a cărei adresă este memorată de
variabila pointer.
• nume_pointer reprezintă numele ales de utilizator pentru a identifica pointerul respectiv.
• operatorul ‘*’ este obligatoriu la declarare.

Exemplu 1: Să se realizeze un program care citeşte şi afişează un vector cu ajutorul pointerilor.

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
int citire(int tab[]){
//citeste elementele lui tab - accesarea fiecarui element se face printr-un pointer la el
int *pi,i, N;
printf("Introduceti nr de elemente: "); scanf("%d", &N);
pi=tab;
printf("Introduceti elementele tabloului:\n");
for (i=0;i<N;i++)
{
scanf("%d",pi); pi++;
}
return pi-tab;
}
void tiparire(int tab[], int n){
// tipareste elementele lui tab prin accesare prîn pointeri
int *pi;
printf("Elementele tabloului:\n");
for (pi=tab; pi<tab+n; pi++)
printf("%d ",*pi);
}
int main(){
int tab[20], n;
system("cls"); n=citire(tab);
tiparire(tab, n); getch();
return 0;
}

37
Exemplu 2:
Sarcini propuse:
Nr. Sarcina
var.
1. Folosind numai pointeri şi expresii cu pointeri să se scrie funcţii de citire, afişare şi înmulţire a două matrice.

2. Folosind numai pointeri şi expresii cu pointeri să se scrie funcţii de sortare a unui vector cu elemente reale.

3. Folosind numai pointeri şi expresii cu pointeri să se scrie o funcţie de interclasare a doi vectori, care conţin elemente de
tip real ordonate crescător.

4. Să se scrie o funcţie care sortează în ordine crescătoare n şiruri de caractere.

5. Să se scrie o funcţie care determină rădăcina unei funcţii f(x), în intervalul [a, b], ştiind că admite o singură rădăcină în
acest interval. Funcţia f va fi transmisă ca parametru efectiv.

6. Să se scrie o funcție pentru calculul derivatei unui polinom P(x) de grad n, într-un punct dat x=x0. Gradul și coeficienții
polinomului precum și punctul x0 se for trimite ca și argumente la apelul funcției.

7. Să se scrie o funcție pentru calculul produsului a două polinoame. Se vor utiliza numai pointeri și expresii cu pointeri.

8. Să se scrie o funcție pentru calculul matricei Ak , unde A este o matrice pătratică. Se vor utiliza pointeri și expresii cu
pointeri pentru accesul la elementele matricei. Matricea inițială și cea rezultată vor fi ulterior afișate în format natural (sub
formă de linii și coloane).

9. Să se scrie o funcție pentru calculul matricei transpuse AT a unei matrice A. Se vor utiliza pointeri și expresii cu pointeri
pentru accesul la elementele matricei. Matricea inițială și cea rezultată vor fi ulterior afișate în format natural (sub formă
de linii și coloane).

10. Folosind numai pointeri şi expresii cu pointeri să se scrie funcţii de citire, afişare şi adunare a două matrice.

11. Folosind numai pointeri şi expresii cu pointeri să se scrie funcţii de sortare în ordinea crescătoare a unui vector cu
elemente reale.

12. Să se citească un şir de la tastatură şi apoi să se afişeze pe ecran caracter cu caracter. Elementele şirului vor fi accesate
prin indecşi şi prin aritmetica pointerilor.

13. Se introduc de la tastatură mai multe şiruri formate din cuvinte despărţite prin spaţii, până la tastarea sirului “terminat”. Să
se afişeze numărul de cuvinte din fiecare şir precum şi numarul caracterelor din fiecare cuvânt al şirului, utilizându-se
referirea caracterelor cu ajutorul unui pointer la şir.

14. Să se ordoneze cu ajutorul metodei qsort() din biblioteca stdlib.h elementele unui vector de întregi.

15. Să se realizeze un program care citește două șiruri de la tastatură și în funcție de opțiunea utilizatorului să se afișeze
dacă lungimea șirurilor este egală, sau primul caracter de la cele două șiruri este același, sau dacă cele două șiruri au
același conținut. Se va lucra cu cel puțin un pointer la funcție.

38
Lucrarea nr.11-12: Lista simplu înlănţuită. Lista circulară simplu înlănţuită
Listele simplu înlănţuite sunt structuri de date dinamice omogene. Fiecare nod al listei conţine, în afară de informaţia utilă,
adresa următorului element. Această organizare permite numai acces secvenţial la elementele listei.
Reprezentarea grafică

Listele circulare simplu inlantuite sunt liste liniare simplu inlantuite cu deosebirea ca nu exista ultimul element, adica
pointerul de legatura din ultimul element al listei liniare nu are valoarea NIL, ci indica spre primul element.
Structura unui element al unei liste circulare fiind aceeasi cu a unuia dintr-o lista liniara, putem reprezenta o lista circulara
grafic astfel:

Operaţii cu liste
Structura listei
// Structura unui element dintr-o lista simplu înlănţuită
struct Element
{
Date valoare; // datele efective memorate
Element* urmator; // legatura catre nodul urmator
};
Parcurgerea şi afişarea listei
void Afisare(Element* cap) {
while (cap != NULL) // cît timp mai avem elemente în listă
{ printf (“%d”, cap->valoare); // afişează elementul curent
cap = cap->urmator; // avansează la elementul următor
}}
Inserare element
a) Inserare la început
void InserareInceput(Element* &cap, Date val) {
// Alocare nod şi iniţializare valoare
Element *elem = new Element;
elem->valoare = val;

39
// legare nod în listă
elem->urmator = cap;
// mutarea capului listei
cap = elem; }
b) Inserare la sfarsitul listei
void InserareSfarsit(Element* &cap, Date val){
// Alocare şi iniţializare nod
Element *elem = new Element;
elem->valoare = val; elem->urmator = NULL;
// dacă avem lista vida
if (cap == NULL)
// doar modificam capul listei
cap = elem;
else { // parcurgem lista pînă la ultimul nod
Element *nod = cap; while (nod->urmator != NULL)
nod = nod->urmator;
// adăugam elementul nou in lista
nod->urmator = elem; } }
c) inserare după un element dat
void InserareInterior(Element* &cap, Element* p, Date val){
// Alocare şi iniţializare nod
Element *elem = new Element;
elem->valoare = val;
elem->urmator = NULL;
// lista vida
if (cap == NULL)
{ cap = elem;
return;}
// inserare la inceputul listei
if (cap == p) { elem->urmator = cap; cap = elem; return; }
// inserare in interior
elem->urmator = p->urmator; p->urmator = elem;}
Căutare element
a) Căutarea după poziţie
// Căutare element după poziţie
Element* CautarePozitie(Element* cap, int pozitie){
int i = 0; // poziţia curenta
// parcurge lista pînă la poziţia cerută sau pînă la sfîrşitul listei
while (cap != NULL && i < pozitie) {
cap = cap->urmator; i++; }
40
// dacă lista conţine elementul
if (i == pozitie) return cap; else return NULL; }
b) Căutarea după valoare
// Căutare element după valoare
Element* CautareValoare(Element* cap, Date val)
{
// parcurge lista pînă la găsirea
// elementului sau epuizarea listei
while (cap != NULL && cap->valoare != val)
cap = cap->urmator;
return cap;
}
Ştergere element
a) Ştergerea unui element din interiorul listei
// şterge un element din interiorul listei primind ca parametru adresa predecesorului
void StergereElementInterior(Element* predecesor) {
// salvăm referinţa la elementul de şters
Element* deSters = predecesor->urmator;
// scurcircuitam elementul
predecesor->urmator = predecesor->urmator->urmator;
// şi îl stergem
delete deSters; }
b) Ştergerea unui element de pe o anumită poziţie
void StergerePozitie(Element* &cap, int pozitie) {
// daca lista e vida nu facem nimic
if (cap == NULL) return;
// daca este primul element, atunci il stergem si mutam capul
if (pozitie == 0) {
Element* deSters = cap;
cap = cap->urmator;
delete deSters; return; }
// daca este in interor, atunci folosim functia de stergere
Element* predecesor = CautarePozitie(cap, pozitie-1);
StergereElementInterior(predecesor);
}
c) stergerea după o valoare
void StergereValoare(Element* &cap, Date val) {
// daca lista e vida nu facem nimic
if (cap == NULL) return;
// daca este primul element, atunci il stergem si mutam capul
41
if (cap->valoare == val) {
Element* deSters = cap;
cap = cap->urmator;
delete deSters; return; }
// cautam predecesorul
Element* elem = cap;
while (elem->urmator != NULL && elem->urmator->valoare != val)
elem = elem->urmator;
// daca a fost gasit, atunci il stergem
if (elem->urmator != NULL)
StergereElementInterior(elem); }
Exemplu:Să se creeze o listă cu numere întregi folosind crearea prin adăugarea elementelor la începutul listei. Să se afişeze
conţinutul listei.
# include <stdio.h> for(i=2;i<=n;i++)
# include <conio.h> {
struct lista{ printf("Dati informatia %d=",i);
int info; scanf("%d",&inf);
lista *leg;}; p=new lista;
lista *p, *prim, *ultim; int n; p->info=inf;
void creare(lista *&prim, lista *&ultim) p->leg=prim;
{ prim=p;}}
int i,inf; void afisare(lista *prim){
printf("Dati numarul de elemente al listei n = "); p=prim;
scanf("%d",&n); while(p!=NULL){
printf("Dati prima informatie "); printf("%d",p->info);
scanf("%d",&inf); p=p->leg;}}
prim=new lista; int main(void){
prim->info=inf; creare(prim,ultim);
prim->leg=NULL; afisare(prim);}
ultim=prim;

Exemplu:Să se creeze o listă cu numere întregi folosind crearea prin adăugare la sfîrşitul listei.
Se cere:
a) Să se afişeze conţinutul listei
b) Să se determine numărul de numere prime
42
# include <stdio.h> void afisare(lista *prim){
struct lista{ p=prim;
int info; while(p!=NULL){
lista *leg;}; printf("%d",p->info);
lista *p, *prim, *ultim;int n; p=p->leg;}}
void creare(lista *&prim, lista *&ultim){ int verif_prim(int x){
int i,inf; int q=1;
printf("Dati numarul de elemente al listei n = "); for(int i=2;i<=x/2;i++)
scanf("%d",&n); if(x%i==0) q=0;
printf("Dati prima informatie "); return q;}
scanf("%d",&inf); int nr_prime(lista *prim){
prim=new lista; int nr=0;
prim->info=inf; p=prim;
prim->leg=NULL; while(p!=NULL){
ultim=prim; if(verif_prim(p->info)==1) nr++;
for(i=2;i<=n;i++){ p=p->leg;}
printf("Dati informatia %d=",i); return nr;}
scanf("%d",&inf); int main(void){
p=new lista; creare(prim,ultim);
p->info=inf; afisare(prim);
p->leg=NULL; printf("numarul de numere prime =
ultim->leg=p; %d“,nr_prime(prim));}
ultim=p;}}

43
Sarcina propusă:
Realiza ți un program care con ține un meniu prin intermediul căruia:
a) Se testează dacă o listă este sau nu vidă.
b) Se creează o listă de numere întregi din valorile citite dintr-un fișier.
c) Să se afișeze cheile elementelor din listă (in ordinea de la primul la ultimul).
d) Să se afișeze cheile elementelor din listă (in ordinea de la ultimul la primul).
e) Să se insereze un element la inceputul listei;
f) Să se adauge un element la sfârșitul listei;
g) Să se adauge un element dupa al k-lea element din lista. Daca nu exista k elemente in lista se va adauga la sfarsit.
h) Să se elimine primul element din listă;
i) Să se elimine ultimul element din listă;
j) Să se elimine elementul aflat dupa cel de-al k-lea element din lista. Daca nu exista k elemente in lista atunci nu se va
realiza stergerea.
k) Să se elimine fiecare element din lista (golind practic lista).
l) Să caute un element de cheie dată în listă;
m) Să însumeze elementele pare din listă;
n) Să se adauge intre oricare doua elemente consecutive ale listei cate un element nou care sa aiba ca informatie
(cheie) media aritmetica a celor doua valori.
o) Ieșire din aplicație.
Lucrarea nr.13: Lista dublu înlănţuită
Noţiuni teoretice
Listele dublu inlantuite sunt structuri de date dinamice. Ele au aceleasi caracteristici de baza ca si listele simplu
inlantuite. Diferenta fata de acestea consta in faptul ca, pentru fiecare nod, se retine si adresa elementului anterior, ceea ce
permite traversarea listei in ambele directii.
Lista dublu inlantuita poate fi reprezentata grafic astfel:

Memorarea unei liste dublu inlantuite


Pentru memorarea listei se foloseste structura struct. Acesta structura va avea forma:
struct Nod
{
int numar; //Memorarea efectiva a numarului
Nod* urmator; //Memorarea legaturii catre urmatorul nod
Nod* anterior; //Memorarea legaturii catre nodul anterior
};

Nod* cap = NULL; //Declararea listei vida


Parcurgerea si afisarea elementelor din lista dublu inlantuita
void afisareLista(Nod* cap)
{
while (cap != NULL)
{
cout << cap->numar << "\n"; // Afisam numarul stocat
cap = cap->urmator; // Mutam elementul curent la urmatorul element din lista
}
}
Inserarea unui element intr-o lista dublu inlantuita
Inserare la inceput
Acesta este cazul cel mai simplu: trebuie doar alocat elementul, legat de primul element din lista si
repozitionarea capului listei:

void inserareInceput(Nod* &cap, int valoare)


{
//Creeam noul nod si ii atribuim valoarea din paramentru
Nod *elem = new Nod;
elem->numar = valoare;

elem->urmator = cap; //Mutam sageata catre primul element din lista


elem->anterior = NULL;

if(cap != NULL)
cap->anterior = elem; // Actualizam sageata primului element din lista

cap = elem; //Inlocuim primul element din lista


}
Inserare la sfarsitul listei

void inserareFinal(Nod* &cap, int valoare)


{
//Creeam noul nod si ii atribuim valoarea din paramentru
Nod *elem_final = new Nod;
elem_final->numar = valoare;
elem_final->urmator = NULL;
elem_final->anterior = NULL;
if (cap == NULL) // In cazul in care lista noastra este vida, punem elementul in lista
cap = elem_final;
else
{
//Parcurgem lista pana la final
Nod *nod_curent = cap;
while (nod_curent->urmator != NULL)
nod_curent = nod_curent->urmator;

//Mutam sageata ultimului element catre elementul creat anterior


nod_curent->urmator = elem_final;
elem_final->anterior = nod_curent;
}
}
Inserarea dupa un element dat

void inserareElement(Element* &cap, Element* element_dat, int valoare)


{
//Creeam noul nod si ii atribuim valoarea din paramentru
Nod *elem_creat = new Nod;
elem_creat->numar = valoare;
elem_creat->urmator = NULL;
elem_creat->anterior = NULL;

if (cap == NULL)
{
cap = elem_creat;
return;
}

if (cap == element_dat)
{
elem_creat->urmator = cap;
cap->anterior = elem_creat;
cap = elem_creat;
return;
}

elem_creat->urmator = element_dat->urmator;
elem_creat->anterior = element_dat;
element_dat->urmator->anterior = elem_creat;
element_dat->urmator = elem_creat;
}
Cautarea unui element intr-o lista dublu inlantuita
Cautarea dupa valoare
Se parcurge lista pana la epuizarea acesteia sau identificarea elementului:

Nod* cautareValoare(Nod* cap, int valoare)


{
while (cap != NULL && cap->numar != valoare)
cap = cap->urmator;
return cap;
}
Cautarea dupa pozitie

Nod* cautarePozitie(Nod* cap, int pozitie)


{
int i = 0; //Pozitia curenta

//Parcurgem lista pana la pozitia curenta, sau


//pana ajungem la ultimul element al listei
while (cap != NULL && i < pozitie)
{
cap = cap->urmator;
i++;
}

//In cazul in care am gasit pozitia ceruta, o returnam


if (i == pozitie)
return cap;
else
return NULL;
}
Stergerea unui element dintr-o lista dublu inlantuita
Stergerea unui element din interiorul listei

void stergereElement(Nod* elem)


{
elem->anterior->urmator = elem->urmator;
elem->urmator->anterior = elem->anterior;

delete elem;}
Stergerea unui element de pe o anumita pozitie

void stergereElementPozitie(Nod* &cap, int pozitie)


{
if (pozitie == 0)
{
Nod* victima = cap;
cap = cap->urmator;
cap->anterior = NULL;
delete victima;
}
else
{
Nod* predecesor = cautarePozitie(cap, pozitie);
stergereElement(predecesor);
}
}
Stergerea dupa o valoare
Stergerea unui element dintr-o lista dublu inlantuita, cunoscand valoarea

void stergereElementValoare(Nod* &cap, int valoare)


{
//In cazul in care elementul vizat este capul listei noastre
if(cap->numar == valoare)
{
Nod* victima = cap;
cap = cap->urmator;
cap->anterior = NULL;
delete victima;
return;
}

//Parcurgem lista si cautam elementul cerut


Nod* elem = cap;
while (elem->urmator != NULL && elem->urmator->numar != valoare)
elem = elem->urmator;

//Daca am gasit nodul, il stergem


if (elem->urmator != NULL)
stergereElement(elem);}
Sarcinia propusă:
Să se scrie un program care implementeaza cerintele de la lucrarea precedentă folosind, de aceasta data, liste dublu inlantuite.
Lucrarea nr.14: Prelucrarea fişierelor
Scop: Implementarea funcţiilor de prelucrare a fişierelor
Noţiuni teoretice
Prin fişier se înţelege o structură de date, cu componente numite înregistrări, ce pot avea o dimensiune fixă sau
variabilă, cel de-al doilea caz impunând existenţa unor marcaje speciale numite separatori de înregistrări. Biblioteca de funcţii
stdio.h oferă posibilitatea operării cu fişiere printr-o structură numită FILE. Orice operaţie cu fişiere necesită o asemenea
structură, care se iniţializează la deschiderea unui fişier şi al cărei conţinut devine nefolositor după închiderea sa.Gestionarea
fişierelor se face printr-un pointer la structura predefinită FILE. Declararea unui astfel de pointer se face conform sintaxei:
FILE *identificator_fisier;
Deschiderea unui fişier
Se realizează cu ajutorul funcţiei fopen care are sintaxa de mai jos:
FILE *fopen(”nume_fisier”, ”mod_deschidere”);
în care : nume_fişer este numele complet (calea pe disc) a fişierului care se deschide, iar mod_deschidere precizează modul
în care se deschide fişierul şi poate avea următoarele valori:
D. ”r” pentru citirea unui fişier existent; se produce o eroare dacă fişierul nu există
E. ”w” deschide un fişier pentru scriere; dacă fişierul există, îi distruge conţinutul
F. ”a” se adaugă informaţie în fişier, la sfârşitul acestuia
G. ”r+” în acelaşi timp citeste, respectiv scrie în fişier; acesta trebuie să existe
H. ”w+” deschide un fişier pentru citire şi scriere; dacă acesta există, conţinutul este distrus
I. ”a+” adăugare; dacă fişierul există, conţinutul este distrus
J. ”t” fişierul este de tip text
K. ”b” fişierul este binar
Închiderea unui fişier
Se poate face cu ajutorul funcţiilor:
L. int fclose(FILE *f); care închide fişierul specificat şi returnează 0 în caz de succes sau EOF în cazul apariţiei unei erori
M. int fcloseall(void); care închide toate fişierele deschise şi returnează numărul total de fişiere pe care le-a închis sau
EOF la apariţia unei erori
Exemple: Fie declaraţia FILE *f ; vom încerca următoarele deschideri de fişiere:
f=fopen(”test1.in”,”rt”); Am deschis fişierul ”test1.in” din directorul curent
pentru citire în mod text. Litera ”t” nu era necesară, modul text fiind modul de deschidere implicit al
fişierelor în C. Dacă fişierul nu există, atunci funcţia întoarce NULL. O deschidere mai riguroasă ar fi:
if((f=fopen (”test1.in”,”rt”))==NULL)
{ printf(“Eroare la deschiderea fisierului !”); exit(1); }
f=fopen(“test2.out”,”wb”); Este deschis/creat fişierul ”test2.out” din directorul curent în mod binar pentru scriere.
f=fopen(“c:\\tc\\test3.bin”,”ab+”); Este deschis fişierul ”test3.bin” din directorul ”c:\tc” în mod binar pentru citire/scriere
fiind poziţionat la sfârşitul fişierului.
Pentru a verifica dacă poziţia curentă de citire/scriere a ajuns la sfârşitul unui fişier se foloseşte funcţia int feof(FILE
*f); care întoarce valoarea 0 dacă poziţia curentă nu este la sfârşitul fişierului şi o valoarea diferită de 0 dacă poziţia actuală
indică sfârşitul de fişier.
Pentru citirea unui caracter dintr-un fişier text se foloseşte funcţia int fgetc(FILE
*f);
Dacă citirea a avut loc cu succes, se întoarce valoarea caracterului citit, iar în caz de eroare este întoarsă valoarea EOF.
Pentru scrierea unui caracter într-un fişier text se foloseşte funcţia int fputc(int
c,FILE *f);
Funcţia întoarce caracterul care s-a scris în caz de succes, respectiv EOF în caz de eroare.
Exemplul 1: Copierea unui fişier caracter cu caracter.
#include<stdio.h>
#include<stdlib.h>
void main()
{
FILE *in,*out;
A. se incearca deschiderea fisierului sursa
if((in=fopen(“test.c”,”r”))==NULL)
{ printf(“fisierul nu poate fi deschis pentru citire”); exit(1);
}
B. se incearca deschiderea fisierului destinatie
if((out=fopen(“test2.bak”,”w”))==NULL)
{ printf(“fisierul nu poate fi deschis pentru scriere”); exit(1);
}
C. se copie un caracter din sursa si se scrie in destinatie while(!feof(in)) fputc(fgetc(in),out);
fclose(in); fclose(out);
}
Exemplul 2: Se numără câte caractere de fiecare tip (litere, cifre şi neafişabile) sunt într-un fişier text.
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
void main()
{
FILE *f; int l,c,g; char ch;
l=c=g=0;
if((f=fopen(„in.txt”,”r”))==NULL)
{ printf(„nu se poate deschide fisierul pentru citire”); exit(1);
}
do{
ch=fgetc(f);
if(isalpha(ch)) l++;
if(isdigit(ch)) c++;
if(!isprint(ch)) g++; // caracterul nu este afisabil
}while(ch!=EOF);
printf(”\n numarul de litere este %d”,l); printf(”\n numarul de cifre
este %d”,c);
printf(”\n numarul de caractere neafisabil este %d”,g); fclose(f);
}
Exemplu 3: Un program care citeşte un şir de numere de la tastatură şi apoi scrie în fişierul "FISIER.DAT", pe o linie,
câte două numere consecutive, inserând între ele suma lor.
#include <stdio.h>
#include <iostream.h>
FILE *pf; int i, n, x[30], nr; double a;
int main() {
cout<<"\ndati nr. de elemente : ";
cin>>nr;
for(i = 1; i <= nr; i++) { cout<<"x["<<i<<"] = "; cin>>x[i]; }
pf = fopen("fisier.dat","w");
for(n=1 ; n<=nr; n++) { a = x[n] + x[n+1];
fprintf(pf, "%d %4.2f %d\n", x[n], a, x[n+1]); }
fclose(pf); }
Exemplu 4:De alcătuit un fişier cu N înscrieri, care conţine informaţia despre calculatoarele unui laborator de programare.
a) De realizat căutarea staţiilor după denumirea lor.
b) De aranjat înscrierile în ordine descrescătoare după memoria RAM.
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct laborator {
char nume[30];
int ram;};
FILE *fl;
void main (void)
{
struct laborator x[50],art,aux;
int i,n,k,z,d,max,q;
char caut[30],r,w;

//Afisarea meniului
m0:clrscr;
printf("\n\n\t***MENIU***\n\n");
printf("\t1: Comletarea bazei de date.\n");
printf("\t2: Citirea bazei de date din fisier.\n");
printf("\t3: Introducerea unei noi inscrieri.\n");
printf("\t4: Cautarea statiilor dupa denumire.\n");
printf("\t5: Aranjarea inscrierilor in descrestere.\n");
printf("\t6: Iesire.\n\t");
scanf("%d",&q);
switch(q){
case 1: goto m1;
case 2: goto m2;
case 3: goto m3;
case 4: goto m4;
case 5: goto m5;
case 6: goto m6;
default: goto m0;}
//1: Completarea BD
m1: clrscr;
printf("\n\Culege numarul de calculatoare\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{printf("\nCulege numele statiei %d:",i);
scanf("%s",x[i].nume);
printf("\nCulege volumul memoriei RAM a statiei %d:",i);
scanf("%d",x[i].ram);}
// 1:Inscrierea bazei in fisierul baza.txt
fl=fopen("baza.txt","w");
for(i=0;i<n;i++)
{fwrite(&x[i], sizeof(x[i]),1,fl);}
fclose(fl);
printf("\nBaza de date completata a fost inscrisa in fisierul \"baza.txt\"\n");
printf("\nPentru iesire in meniu culegeti ENTER\n");
getch();
goto m0;
//2: Citirea bazei de date din fisierul baza.txt si afisarea ei la monitor
m2: clrscr();
printf("\n\n\t***Baza citita din fisier este***\n\n");
printf("\t-------------------------------\n");
printf("\t| N U M E L E | R A M (Mb) |\n");
printf("\t|--------------|--------------|\n");
fl=fopen("baza.txt","r");
i=0;
while (fread(&x[i],sizeof(x[i]),1,fl)==1)
{ printf("\t|%2ls|%16d|\n",x[i].nume,x[i].ram);
i++;
printf("\t|--------------|--------------|\n");
fclose(fl);
n=i;
printf("\nPentru iesire in meniu culegeti ENTER\n");
getch();
goto m0;
//3: Introducerea unei noi inscrieri
m3:clrscr();
printf("\nDoriti sa mai adaugati o inscriere? y/n\n");
w=getch();
if ((w=='n')||(w=='N'))
goto m0;
if ((w=='y')||(w=='Y'))
{
printf("\nCulege numele statiei");
scanf("%s",&aux.nume);
printf("Culege volumul memoriei RAM");
scanf("%d",&aux.ram);
fl=fopen("baza.txt","a");
fwrite(&aux,sizeof(aux),1,fl);
fclose(fl);
printf("\nInscrierea a fost adaugata la sfirsitul fisierului\n");
printf("\nPentru iesire in meniu culegeti ENTER\n");
getch();
goto m0;}
//4: Cautarea statiilor dupa nume
m4: clrscr();
fl=fopen("baza.txt","r");
i=0;
while (fread(&x[i],sizeof(x[i]),1,fl)==1)
i++;
n=i;
fclose(fl);
printf("\nCautarea calculatorului dupa nume.\nCulegeti numele cautat:");
scanf("%s",caut);
printf("\n\n\t*****Rezultatul cautarii*****\n\n");
printf("\t-------------------------------\n");
printf("\t| N U M E L E | R A M (Mb) |\n");
printf("\t|--------------|--------------|\n");
k=0;
for(i=0;i<n;i++)
{
if(strcmp(x[i].nume,caut)==0)
{k++;
printf("\t|%2ls|%16d|\n",x[i].nume,x[i].ram);
printf("\t|--------------|--------------|\n");}}
if(k==0)
printf("\nNu exista statie cu asa nume.\n");
printf("\nPentru iesire in meniu culegeti ENTER\n");
getch();
goto m0;
//5: Aranjarea inscrierilor
m5: fl=fopen("baza.txt","r");
i=0;
while (fread(&x[i],sizeof(x[i]),1,fl)==1)
i++;
n=i;
fclose(fl);
for(i=0;i<n;i++)
{max=x[i].ram;
z=i;
for(d=i;d<n;d++)
{
if(max<x[d].ram)
{max=x[d].ram;
z=d; } }
art=x[i];
x[i]=x[z];
x[z]=art;
}
clrscr();
printf("\n\n\t*****Baza aranjata este*****\n\n");
printf("\t-------------------------------\n");
printf("\t| N U M E L E | R A M (Mb) |\n");
printf("\t|--------------|--------------|\n");

for(i=0;i<n;i++)
{
printf("\t|%2ls|%16d|\n",x[i].nume,x[i].ram);
printf("\t|--------------|--------------|\n");}}
printf("\nPentru iesire in meniu culegeti ENTER\n");
getch();
goto m0;
//6: Iesire
m6:clrscr();
printf("\nPentru iesire culegeti orice tasta... ");
getch();
}
Sarcina propusă:
Să se scrie un program care trebuie să conţină următoarele puncte:
1. Completarea bazei de date şi înscrierea ei în fişierul „baza.txt”
2. Citirea bazei de date din fişierul „baza.txt” şi afişarea ei la monitor
3. Introducerea unei noi înscrieri la sfîrşitul fişierului existent „baza.txt”
4. Căutarea informaţiei în bază conform punctului a) din condiţie
5. Aranjarea înscrierilor conform punctului b) din condiţie şi afişarea bazei finale ordonate la monitor
6. Ieşire

Nr. Sarcina
var.
1. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre cursul valutar la o casă de schimb.
a) De realizat căutarea valutei după denumirea sa.
b) De aranjat înscrierile în ordine crescătoare după cursul de schimb.
2. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre un grup de automobile.
a) De realizat căutarea automobilelor după numărul de înregistrare a lor.
b) De aranjat înscrierile în ordine alfabetică după marca automobilelor.
3. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre abonaţii unei biblioteci.
a) De realizat căutarea abonaţilor după familie
b) De şters din fişier înscrierile abonaţilor cu cantităţile minimă şi maximă de cărţi împrumutate.
4. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre un grup de studenţi.
a) De realizat căutarea studenţilor după vîrsta lor.
b) De schimbat cu locul înscrierile pentru studenţii cu cea mai mică şi cea mai mare vîrstă.
5. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre studenţii unei grupe.
a) De calculat balul mediu pentru fiecare student reieşind din rezultatele la trei examene.
b) De aranjat înscrierile în ordine descrescătoare după balul mediu.
6. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre numerele de telefoane la un grup de persoane.
a) De realizat căutarea unei persoane după numărul de telefon.
b) De aranjat înscrierile în ordine descrescătoare după numărul de telefon.
7. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre paşapoartele unui grup de persoane.
a) De realizat căutarea persoanei după numărul paşaportului.
b) De aranjat înscrierile în ordine inversă.
8. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre orarul lecţiilor unui student într-o zi a săptămînii.
a) De realizat căutarea lecţiei după ora curentă.
b) De schimbat cu locul prima şi ultima înscriere.
9. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre orarul primirii pacienţilor de către medic.
a) De realizat căutarea pacienţilor după familie.
b) De aranjat înscrierile în ordine crescătoare după ora primirii pacienţilor.
10. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre meniul într-un restaurant.
a) De aflat preţul celor trei bucate alese de client.
b) De aranjat înscrierileîn ordine descrescătoare după preţul bucatelor.
11. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre paşapoartele unui grup de persoane.
a) De realizat căutarea persoanei după IDNP.
b) De aranjat înscrierile în ordine crescătoare.
12. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre un grup de studenţi.
a) De realizat căutarea studenţilor după medie.
b) De schimbat cu locul înscrierile pentru studenţii cu cea mai mică şi cea mai mare medie.
13. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre un grup de automobile.
a) De realizat căutarea automobilelor după marcă.
b) De aranjat înscrierile în ordine alfabetică după anul de producere.

14. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre orarul lecţiilor unui student într-o zi a săptămînii.
a) De realizat căutarea lecţiei după denumire.
b) De schimbat cu locurile orarul de vineri cu cel de luni.
15. De alcătuit un fişier cu N înscrieri, care conţine informaţia despre meniul într-un restaurant.
a) De aflat preţul celei mai scumpe bucate alese de client.
b) De aranjat înscrierileîn ordine descrescătoare după preţul bucatelor.
Lucrarea nr.15: Clase. Proprietăţi. Crearea şi distrugerea obiectelor.

O definitie “bruta” a clasei ar fi aceea ca este un concept extins al unui tip de date abstract : in loc sa contina numai
informatii – variabile – , contine si functii.
Un obiect este o instantiere a unei clase. Mai precis, clasa ar fi tipul de date si obiectul ar fi variabila.
Asadar, printr-o analogie la limita, am putea spune despre clase ca reprezinta echivalentul tipului de date struct din C.

Declarare

Schema unei clase este:


class nume_clasa
{
specificator_de_acces1:
membru1;
specificator_de_acces2:
membru2;

...
} nume_obiect;

Explicatii:

– pentru declararea unei clase se foloseste cuvantul cheie (rezervat) “class” la inceput (ca la struct);
– apoi dam un nume valid clasei – in schema de fata acesta fiind nume_clasa ;
– in interior se observa imediat specificatorul de acces (specificator_de_accesX ); acesta poate fi de trei tipuri:
1. private – membrii cu aceasta proprietate pot fi accesati doar din interiorul altor membrii ai aceleiasi clase sau din
interiorul prietenilor lor
2. protected – membrii cu aceasta proprietate pot fi accesati ca si cei private (din alti membrii ai aceleiasi clase sau din
prieteni) dar si din membrii claselor derivate
3. public – ultimul specificator permite ca membrii sai sa poata fi accesibili de oriunde este obiectul vizibil
– membrii clasei (membru1, membru2, …membruX ) pot fi atat variabile, structuri de date (deci si clase) sau functii.
– in final, numele obiectului (nume_obiect ) sau lista de obiecte din moment ce pot fi mai multe, este optional (ca
la struct).

Ca o observatie, se poate mentiona faptul ca datele si functiile declarate intr-o clasa devin proprii clasei respective. De
aceea, ele se vor numi date membre, respectiv functii membre (metode)ale acelei clase.

Implementare

Pentru o intelegere mai ampla a acestor notiuni, vom trece la aplicarea lor in practica. Vom crea un nou proiect C++
gol in IDE unde vom avea doua fisiere: main.cpp si main.h . In header vom defini clasa si metodele acesteia, iar
in main.cpp o vom folosi.
//main.h

class Elev
{
private:
float media_generala;
float medii_la_obiecte[20];
int nr_obiecte;
int corigent;

public:
Elev(); //constructorul
int este_corigent() { return corigent==1; };
float MG();
void introducere_medii(int, float* );
void returnare_medii(float *);
};

//definirea functiilor clasei


Elev::Elev()
{
media_generala = 0;
nr_obiecte = 0;
corigent = 0; //presupunem ca a trecut
}

void Elev::introducere_medii(int contor, float v[10])


{
float suma = 0;

for(int i=1; i<=contor; i++)


suma += v[i];

nr_obiecte ++;
medii_la_obiecte[ nr_obiecte ] = suma / contor;

if(medii_la_obiecte[ nr_obiecte ] <=4 )


corigent = 1; //este corigent la cel putin un obiect
}

float Elev::MG()
{
float suma;

for(int i=1; i<=nr_obiecte; i++)


suma += medii_la_obiecte[i];

media_generala = suma / nr_obiecte;

return media_generala;
}

void Elev::returnare_medii(float v[20])


{
for(int i=1; i<=nr_obiecte; i++)
v[i] = medii_la_obiecte[i];
}

Utilizare
//main.cpp

#include <iostream>
#include "main.h"

using namespace std;


int main(void)
{
Elev Ionut;

float fizica[10] = {0, 5, 7, 8 , 8, 6};


float engleza[10] = {0, 10, 10, 9};
float sport[10] = {0, 10, 10};
float biologie[10] = {0, 7, 8, 10, 10 };

float aux[20];

//calculam situatia elevului Ionut


Ionut.introducere_medii(5, fizica);
Ionut.introducere_medii(3, engleza);
Ionut.introducere_medii(2, sport);
Ionut.introducere_medii(4, biologie);

//preluam mediile la obiecte si afisam situatia


//intrebam daca Ionut este corigent
if(Ionut.este_corigent())
cout<<"Elevul Ionut este corigent."<<'\n';
else
cout<<"Ionut este un elev silitor, asa ca nu a ramas corigent la nici o materie."<<'\n';

//afisam media generala


cout<<"Media generala a lui Ionut este: "<<Ionut.MG()<<'\n';

//si restul mediilor

Ionut.returnare_medii( aux );
cout<<"Mediile lui Ionut sunt: "<<'\n';
cout<<"Fizica : "<< aux[1]<<'\n';
cout<<"Engleza : "<<aux[2]<<'\n';
cout<<"Sport : "<<aux[3]<<'\n';
cout<<"Biologie : "<<aux[4]<<'\n';

return 0;
}

In acest moment se poate observa clasa Elev care ajuta la calcularea mediei generale si a mediilor (aritmetice numai)
la diferite obiecte. Astfel, se disting cele 4 variabile cu acces privateprecum si cele 5 metode publice.

Explicatii:

1. Elev() – aceasta functie este specifica claselor, purtand numele de constructor. In general, obiectele au nevoie sa-si
initializeze variabilele sau sa le aloce memorie dinamic in timpul procesului de creare pentru ca acestea sa devina operabile
si pentru a evita prezenta unor valori random in interiorul acestora care ar putea genera bug-uri, erori sau destabilizarea
intregului algoritm. Din aceste motive, clasa include o functie speciala, numita constructor, care este apelata automat cand
un obiect al clasei este creat. Constructorul unei clase poarta acelasi nume ca si clasa, aici fiind Elev . Foarte important in
cazul functiilor constructor este faptul ca NU AU TIP (nici macar void). In exemplul de fata, in momentul in care obiectul
Ionut se creeaza in main(), variabilele media_generala , nr_obiecte si corigent iau valoarea 0.
2. int este_corigent() – aceasta functie este inline, adica definita in interiorul clasei. Toate metodele unei clase se pot defini
astfel dar aspectul practic ii forteaza pe multi programatori doar sa declare functia in interiorul clasei si sa o defineasca
ulterior. Pentru o astfel de definire este utilizat operatorul de specificare de domeniu “::”. Acesta indica faptul ca domeniul
functiei respective este acelasi cu domeniul clasei din care face parte. Sintaxa definitiei unei functii membre a unei clase:
tip nume_clasa :: nume_functie_membra(...)
{
...
}

3. Restul functiilor sunt definite in exteriorul clasei folosind schema de mai sus. Asadar, functia MG() va fi definita in
urmatorul mod:
float Elev::MG()
{
float suma;
for(int i=1; i<=nr_obiecte; i++)
suma += medii_la_obiecte[i];
media_generala = suma / nr_obiecte;

return media_generala;
}

Utilizarea variabilelor si metodelor clasei se face ca in cazul struct-urilor din C:

nume_obiect.VariabilaMembra = valoare , pentru accesul la o variabila membra


nume_obiect.FunctieMembra() , pentru apelarea unei functii membre.
Sarcina propusă:
1. Testaţi şi analizaţi aplicaţiile propuse.
2. Încercaţi să realizaţi o aplicaţie proprie (puteţi combina aplicaţiile propuse).
Aplicaţia 1: Să creăm o aplicaţie care va efectua operaţii aritmetice cu numere relae, a cărei fereastră va arăta ca în
următoarea imagine:

Rezolvare:
1. Executăm File\New\Application
2. Plasăm pe formă o casetă de editare, 17 butoane de comandă conform imaginii.
3. Modificăm valoarea proprietăţii Caption a fiecărui buton de comandă şi cea a formei conform imaginii.
4. Atribuim proprietăţii Text a casetei de editare valoare vidă.
5. Prelucrăm evenimentul OnClick al fiecărui buton de comandă(la efectuarea unui clic pe unul din butoanele 0...9 este
necesară adăugarea valorii butonului în caseta de editare).
6. Deoarece datele iniţiale sunt de tip AnsiString, le vom transforma în număr, le vom prelucra şi apoi le vom transforma
înapoi în text pentru a le afişa. Pentru a exclude introducerea datelor greşit din punct de vedere sintactic (se acceptă
doar cifre şi caracterul “.”) vom prelucra evenimentul OnKeyPress a casetei de editare.
7. Pentru a interzice scrierea caracterilor în cutia de editare se va seta proprietatea ReadOnly la valoarea true.
8. Prelucrăm evenimetul OnCreate al formei.
9. Salvăm şi lansăm aplicaţia la execuţie.
Conţinutul fişierului Unit1.cpp
#include<vcl.h>
#include hdrstop
#include”Unit1.h”
#pragma package(smart_init)
#pragma resource”*.dfm”
TForm*Form1 ;
AnsiString s= “”;
_fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner){}
Double eval(AnsiString exp){
AnsiString op=” ”, c=” ”;
double a; int i;
for(i=1;i<=exp.Length();i++){
if(exp[i]>=’0’&&exp[i]<=’9’||exp[i]==’.’) c=c+exp[i];
else{
if(op==’+’||op==’-‘||op==’*’||op==’/’){
if(op==’+’) a=a+c.ToDouble();
if(op==’-’) a=a-c.ToDouble();
if(op==’*’) a=a*c.ToDouble();
if(op==’/’) a=a/c.ToDouble();
op=s[i];}
else{
a=c.ToDouble();
op=exp[i];}
c=” “;}}
if(op==’+’) a=a+c.ToDouble();
if(op==’-’) a=a-c.ToDouble();
if(op==’*’) a=a*c.ToDouble();
if(op==’/’) a=a/c.ToDouble();
return a;}
void _fastcall TForm1::FormCreate(TObject *Sender){
Edit1->Clear();
Edit1->SetFocus();}
void _fastcall TForm1::Button12Click( TObject *Sender){
Edit1->Clear();
Edit1->Text=AnsiString(eval(s));
s=” “;
Edit1->SetFocus();}
void _fastcall TForm1::Button13Click( TObject *Sender){
Edit1->Clear();
s=a+”+”;
Edit1->SetFocus();}
void _fastcall TForm1::Button14Click( TObject *Sender){
Edit1->Clear();
s=a+”-”;
Edit1->SetFocus();}
void _fastcall TForm1::Button15Click( TObject *Sender){
Edit1->Clear();
s=a+”*”;
Edit1->SetFocus();}
void _fastcall TForm1::Button16Click( TObject *Sender){
Edit1->Clear();
s=a+”/”;
Edit1->SetFocus();}
void _fastcall TForm1::Button9Click( TObject *Sender){
Edit1->Text=Edit1->Text+”1”;
s=s+”1”;
Edit1->SetFocus();}
void _fastcall TForm1::Button10Click( TObject *Sender){
Edit1->Text=Edit1->Text+”0”;
s=s+”0”;
Edit1->SetFocus();}
void _fastcall TForm1::Button11Click( TObject *Sender){
Edit1->Text=Edit1->Text+”.”;
s=s+”.”;
Edit1->SetFocus();}
void _fastcall TForm1::Button5Click( TObject *Sender){
Edit1->Text=Edit1->Text+”5”;
s=s+”5”;
Edit1->SetFocus();}
void _fastcall TForm1::Button6Click( TObject *Sender){
Edit1->Text=Edit1->Text+”4”;
s=s+”4”;
Edit1->SetFocus();}
void _fastcall TForm1::Button7Click( TObject *Sender){
Edit1->Text=Edit1->Text+”3”;
s=s+”3”;
Edit1->SetFocus();}
void _fastcall TForm1::Button8Click( TObject *Sender){
Edit1->Text=Edit1->Text+”2”;
s=s+”2”;
Edit1->SetFocus();}
void _fastcall TForm1::Button1Click( TObject *Sender){
Edit1->Text=Edit1->Text+”9”;
s=s+”9”;
Edit1->SetFocus();}
void _fastcall TForm1::Button2Click( TObject *Sender){
Edit1->Text=Edit1->Text+”8”;
s=s+”8”;
Edit1->SetFocus();}
void _fastcall TForm1::Button3Click( TObject *Sender){
Edit1->Text=Edit1->Text+”7”;
s=s+”7”;
Edit1->SetFocus();}
void _fastcall TForm1::Button4Click( TObject *Sender){
Edit1->Text=Edit1->Text+”6”;
s=s+”6”;
Edit1->SetFocus();}
void _fastcall TForm1::Button17Click( TObject *Sender){
Edit1->Clear();
Edit1->SetFocus();}
void _fastcall TForm1::Edit1KeyPress(TObject *Sender, char&Key){
switch(Key){
case’.’:
case’1’:
case’2’:
case’3’:
case’4’:
case’5’:
case’6’:
case’7’:
case’8’:
case’9’:
case’0’:Edit1->Text=Edit1->Text+Key;s=s+Key; break;
case’+’:Button13Click(Sender);break;
case’-’:Button14Click(Sender);break;
case’*’:Button15Click(Sender);break;
case’/’:Button16Click(Sender);break;
case’=’:Button12Click(Sender);break;}}
Aplicaţia 2: Să creăm o aplicaţie a cărei fereastră va avea un buton de comandă (cu denumirea Intrare). Butonul va
afişa următoarea fereastră:

Utilizatorul va scrie în casetele de editare numele şi parola. În cazul scrierii şi confirmării parolei corectre(şirul 123) se va afişa
mesajul Corect, iar fereastra aplicaţiei îşi va modifica culoarea. În caz contrar se va fişa mesajul Scrie parola corect şi confirmă.
Rezolvare:
1. Executăm File\New\Application.
2. Executăm File\New\Form.
3. Plasăm pe formă două etichete, două casete de editate şi un buton de comandă conform emaginii din enunţ.
4. Modificăm proprietatea Caption a formei Form2, a etichetilor şia butoanelor de comandă conform enunţului. Proprietăţii
ModalResult al Butonului Confirmă îi atribuim valoarea mrOk.
5. În fişierul Unit1.cpp adăugăm derectiva #include”Unit2.h”.
6. Prelucrăm evenimentul OnClick al fiecărui buton de comandă.
7. Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp:


#include<vcl.h>
#pragma hdrstop
#include”Unitl1.h”
#include”Unitl2.h”
#pragma package(smart_init)
#pragma resource “*.dfm”
Tform1 *Form1 ;
_fastcall TForm1 ::TForm1(TComponent* Owner) :TForm(Owner){}
Void _fastcall TForm1::ButtonClick(TObject *Sender){
Form2->Edit2->Text=” “; Form2->ShowModal();
Form2->Edit1->Text=” ”;
If(Form2->Edit2->Text==”123”&&Form2->ModalResult==mrOk)
{ShowMessage(“Corect”);Color=clLime;}
else ShowMessage(“Scrie parola corecta si confirma”);}
Conţinutul fişierului Unit2.cpp:
#include<vcl.h>
#pragma hdrstop
#include”Unitl2.h”
#pragma package(smart_init)
#pragma resource “*.dfm”
Tform2 *Form2 ;
_fastcall TForm2 ::TForm2(TComponent* Owner) :TForm(Owner){}

Sarcina propusă:
1. Testaţi secvenţele de program propuse.
2. Creaţi o aplicaţie care să conţină câteva ferestre de dialog

S-ar putea să vă placă și