Documente Academic
Documente Profesional
Documente Cultură
Ioan Cauil
Indrumar de laborator
Programarea calculatoarelor n limbajele C i C++
Cuvnt nainte
Prezenta lucrare fructific experiena didactic a autorilor dobndit pe parcursul mai multor
ani n urma susinerii orelor de curs i aplicaii la disciplinele Programarea calculatoarelor
cu studenii facultilor de profil electric de la Universitatea din Craiova.
Lucrarea permite i unor cititori neiniiai n domeniul informaticii s neleag cu uurin
aspecte ale bazelor programrii n C i C++, noiunile fiind prezentate gradual.
Pentru a uura efortul depus de cei care nu au n fa un calculator la citirea acestei lucrri,
majoritatea problemelor rezolvate sunt acompaniate de extrase de ecrane generate n timpul
execuiei.
Bibliotecile i funciile prezentate sunt cele corespunztoate standardelor limbajelor C/C++..
Se propun 13 lucrri de laborator, care urmresc noiunile teoretice prezentate la cursul
Programarea Calculatoarelor adresat studenilor facultii de Electrotehnic.
Prezenta carte poate fi util att studenilor de la facultile de profil tehnic , informatic i
tiinele naturii, ct i tuturor celor care trebuie s studieze Programarea Calculatoarelor i
Informatica sau vor s dezvolte programe n limbajele C i C++.
Autorii
Operanzii se pot introduce de la tastatur sau cu butoanele aplicaiei. La activarea unuia din
butoanele Hex, Dec, Oct sau Bin, numrul afiat este convertit n baza respectiv.
1.3 Tipuri fundamentale de date. Declararea tipului variabilelor
Un tip de date reprezint valorile pe care le poate lua o variabil precum i operaiile care se
pot efectua asupra acesteia. Orice variabil trebuie s fie asociat unui tip de date i numai
unuia. Tipurile fundamentale de date ale limbajelor C i C++ sunt :
int, float, double, char, bool (numai n C++) , wchar_t (numai n C++).
n funcie de modul de reprezentare n memoria calculatoarelor i de domeniul de definiie al
acestor date, n limbajele C i C++ exist mai multe tipuri de date derivate, formate din
tipurile de baz de mai sus, (char, int, float i double) precedate de modificatorii tipurilor de
baz (signed, unsigned, short i long), dup cum urmeaz:
6
Domeniu de
valori
Numere ntregi
Dimensiune
n octei
4
Numere naturale
[0 2 )
Numere ntregi
[-2 2 )
Numere naturale
[0 2 )
+-*/%
(10 38 10 38 )
+-*/
+-*/
[-2 2 )
[0, 2 )
[0 2 )
+-*/%
false,true
and, or,
not
Tip
Semnificaie
int
unsigned
int
short int
unsigned
short int
float
double
char
unsigned
char
wchar_t
bool
31
31
[-2 2 )
32
15
15
16
16
Operaii
+-*/%
+-*/%
+-*/%
+-*/%
+-*/%
Tipul fundamental bool definete valorile valorile false i true i operaiile || (or), && (and)
i ! (not). Variabilele booleene sunt reprezentate pe un octet. Valoarea false este reprezentat
prin 0 iar true prin 1.
Utilizatorul poate defini tablouri de unul dintre tipurile fundamentale, noi tipuri de date
bazate pe tipurile fundamentale cu instruciunea typedef i date de tipuri enumerare cu
instruciunea enum.
Variabilele de un anumit tip se declar cu instruciuni de forma
tip lista de variabile;
unde tip este unul din cele de mai sus. De exemplu, instruciunea
int i, j, k;
declar trei variabile i, j, k de tip intreg.
Orice variabil poate fi inializat la definire. Atribuirea unei valori variabilei la definire se
face cu una din formele:
variabila = expresie
variabila (expresie)
De exemplu, pentru a defini i iniializa variabilele reale x i y la valorile 1 + cos(0.2) i
29.33 putem scrie
double x = 1 + cos(0.2), y (29.33);
Definirea i iniializarea tablourilor este artat n exemplele din lucrrile urmtoare.
1.4
Instruciunea de atribuire
Instruciunea de atribuire simpl atribuie o anumit valoare unei variabile. Sintaxa
instruciunii de atribuire simpl este urmatoarea:
v = expresie;
7
unde:
= este operatorul de atribuire.
v este identificatorul unei variabile de un anumit tip declarat corespunztor i se mai
numeste i variabil rezultat.
"expresie" este o expresie de un anumit tip, compatibil cu tipul variabilei rezultat v,
expresie numeric (ntreag sau real), expresie relaional, expresie logic, etc.
Limbajele C i C++ ofer posibilitatea de a atribui aceeai valoare la mai multe variabile n
cadrul instruciunilor de atribuiri multiple, ca mai jos:
v1 = v2 = v3 = vn = expresie;
unde:
v1,v2,v3, .. vn sunt variabile de acelai tip sau de tipuri compatibile;
expresie este o expresie de tip compatibil cu variabilele vi, i=1,n.
Instruciunile de atribuire multipl se evalueaz de la dreapta la stnga. Asfel, se evalueaz
expresia a crei valoare va fi atribuit variabilei vn, care la rndul sau va fi atribuit variabilei
vi-1 .a.m.d pn la atribuirea aceleiai valori variabilei v1.
Exemplu. Variabilele de mai jos primesc valoarea 2.
x = y = z = a = b1 = 2 ;
Expresii aritmetice
Expresiile aritmetice sunt formate din constante, variabile i funcii. Operatorii utilizai n
expresiile aritmetice sunt +, - * /, iar n cazul operanzilor de tip ntreg i % (restul mpririi a
dou numere ntregi). Pentru a grupa termeni se pot utiliza parantezele rotunde ( i ).
Prototipurile funciilor matematice standard sunt definite n biblioteca <cmath> n limbajul
C++ i n biblioteca <math.h> n limbajul C.
Tabelul 1. Funcii matematice standard.
Funcia
int abs(int)
double acos(double)
double asin(double)
double atan(double)
double atan2(double x, double y)
int atoi(char [])
float atof(char [])
double ceil(double x)
double cos(double)
double cosh(double)
double exp(double)
double fabs(double)
double floor(double)
fmod(double, double)
long labs(long)
double log(double)
double log10(double)
double pow(double a, double b)
double sin(double)
double sinh(double)
double sqrt(double)
double tan(double)
Descriere
Calculeaz valoarea absolut a unui ntreg
Calculeaz arcos
Calculeaz arcsin
Calculeaz arctg
Calculeaz arctg(x/ y)
Convertete un ir n ntreg
Convertete un ir n double
Calculeaz cel mai mic ntreg >= cu x
Calculeaz cos
Calculeaz cosh
Calculeaz exp
Calculeaz valoarea absolut a unui real
Calculeaz rotunjire inferioar
Calculeaz restul mpririi a dou numere reale
Calculeaz valoarea absolut a unui ntreg long
Calculeaz logaritmul natural
Calculeaz logaritmul zecimal
Calculeaz a la puterea b
Calculeaz sin
Calculeaz sinh
Calculeaz rdcina ptrat
Calculeaz tan
double tanh(double)
Calculeaz tanh
1.5
Orice aplicaie ce ruleaz pe un calculator are un director curent asociat i fiiere standard de
intrare i ieire. Fiierul standard de intrare este tastatura iar cel de ieire este ecranul. In
program, orice fiier este asociat unui obiect numit stream. Fiierele standard asociate unei
aplicaii sunt de tipul text. Fiierul text este este compus dintr-un ir de caractere grupate n
linii. Liniile constau din zero sau mai multe caractere urmate de un caracter \n. Streamul de
intrare asociat tastaturii are denumirea cin, streamul de ieire asociat ecranului se numete
cout.
Operatorul de scriere a datelor
Operatorul de scriere a datelor este <<. El insereaz date n streamul de ieire. De exemplu,
secvena de instruciuni
int i = 123;
cout << i = << i;
afiaz pe ecran
i = 123
Operatorul << insereaz n stream valoarea expresiei din dreapta sa. Pentru a afia valori pe
mai multe linii, trebuie ca dup fiecare linie s scriem caracterul \n, care este predefinit ca
endl. Operatorul << poate scrie orice tip predefinit de date: int, float, iruri de caractere, etc.
Operatorul de citire a datelor
Operatorul de citire dintr-un stream este >>. El extrage date din streamul de intrare i le
atribuie unor variabile. Operatorul >> este urmat de numele variabilei ce va memora valoarea
citit. De exemplu, secvena de instruciuni
int a;
cin >> a;
va citi o valoare introdus de la tastatur i o va atribui variabilei a
Instruciunea cin analizeaz valorile introduse de la tastatur sunt i le atribuie variabilelor.
Pentru fiecare variabil se procedeaz astfel :
se citesc i se ignor toate caracterele spaiu, \t sau \n (acesta din urm este generat
la apsarea tastei Return),
se citesc urmtoarele caractere corespunznd tipului variabilei sau pn la ntlnirea
unui caracter spaiu, \t sau \n i valoarea citit se atribuie variabilei.
Instruciunea cin analizeaz valorile introduse dup apsarea tastei Return.
Pentru a modifica formatul de scriere sau citire a datelor putem utiliza manipulatori definii n
biblioteca iomanip. Pentru scrierea sau citirea unui numr ntreg n n diferite baze, se
utilizeaz n instruciunile cout sau cin manipulatorii:
hex pentru baza 16,
dec pentru baza 10,
oct pentru baza 8.
Aceti manipulatori rmn la valoarea prescris pn sunt modificai. La nceperea
execuiei unui program baza 10 este implicit.
Pentru afiarea bazei se utilizeaz manipulatorii:
showbase pentru scrierea bazei,
noshowbase pentru a nu scrie baza.
In cazul numerelor reale avem manipulatorii:
fixed numrul este scris fr exponent,
scientific numrul este scris cu exponent.
9
Probleme rezolvate
10
int a, b, c;
a = 31;
b = 76;
c = a + b;
cout << a = << a << endl;
cout << b = << b << endl;
cout << a + b = << c << endl;
return 0;
}
Problema 3. S se scrie un program ce calculeaz aria unui cerc. Raza cercului se citete de
la tastatur la apariia mesajului : "Introducei raza".
#include <iostream>
using namespace std;
int main(){
double r;
cout << Introduceti raza cercului << endl;
cin >> r;
cout << aria cercului este << 3.14*r*r << endl;
return 0;
}
Rezultatul rulrii programului este cel de mai jos.
Problema 4. S se scrie un program care s tipreasc valorile false i true ale tipului bool.
#include <iostream>
using namespace std;
int main() {
bool bv;
bv = false;
cout << false = << bv << endl;
bv = true;
cout << true = << bv << endl;
return 0;
}
Se vor nlocui cele dou instruciuni cout cu cele de mai jos. Se vor explica rezultatele.
cout << "bv = " << boolalpha << bv << endl;
cout << "bv = " << boolalpha << bv << endl;
Problema 5. S se scrie un program care s afieze caracterele A, a, * i ! i valoarea lor n
codul ASCII.
#include <iostream>
11
12
13
#include<iostream>
using namespace std;
int main(){
float x = 8.7, y = 3.5, z = -5.2;
// se afiseaza valorile variabilelor
cout << "x = " << x << " y = " << y << " z = " << z << endl;
// se calculeaza expresiile
cout << "x+y+z=" << x + y + z << endl;
cout << "2y+5(x-z) = " << 2*y+5*(x-z) << endl;
// se completeaza programul cu calculul celelalte expresii
cout<<"2 x / (3 y+2.4)="<<2*x/(3*y+2.4)<<endl;
cout << "(x+y)/(x+2y+z)=" << (x+y)/(x + 2 * y +z) << endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
Problema 9. Se d circuitul electric de mai jos, n care rezistenele au valorile R1= 1k, R2
= 3k. La bornele circuitului se aplic o tensiune U=10V. S se calculeze curentul i cderea
de tensiune pe fiecare rezisten.
14
#include<iostream>
using namespace std;
#include<cmath>
int main() {
double x, y, e;
x = 14.3;
y = 2.5;
e = sqrt(x * x + y * y);
cout<<"sqrt (x^2+y^2) = "<<e<<endl;
e = exp(x);
cout<<"e^x = "<<e<<endl;
e = log(x);
cout<<"ln(x) = "<<e<<endl;
e = cos(x + y);
cout << "cos(x+y) = " << e <<endl;
e = tan(x);
cout << "tg(x) = " << e << endl;
e = log10(x);
cout << "log.10(x) = " << e <<endl;
e = fabs(x + y);
cout << "|x+y| = " << e << endl;
int i = 2, j = -7;
e = abs(i + j);
cout<<"|i+j| = "<<e<<endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
15
# include <iostream>
using namespace std;
# include <iomanip>
int main() {
char x1 = '5', x2 = '?', x3 = 'G';
char e;
int i;
cout << "codurile ASCII ale caracterelor folosite" << endl;
cout << "\t" << x1 << "\t" << int(x1) << endl
<< "\t" << x2 << "\t" << int(x2) << endl
<<"\t" << x3 << '\t' <<int(x3) << endl
<<"\t" << '@' << '\t'<<int('@')<<endl;
cout << setw(12) << "expresie" << setw(10) << "rezultat" << setw(12)
<< " conversie la char" << endl;
i = x1 / x2; e = x1 / x2;
cout << setw(12) << "x1/x2" <<setw(10) << i << setw(10) << e << endl;
i = x1 % x2; e = x1 % x2;
cout << setw(12) << "x1%x2" <<setw(10) << i << setw(10) << e << endl;
i = x1 + x2 - x3 + 200; e = x1 + x2 - x3 + 200;
cout << setw(12) << "x1+x2-x3+2" <<setw(10) << i << setw(10) << e << endl;
i = '2' + '3'; e = '2' + '3';
cout << setw(12) << "'2'+'3'" <<setw(10) << i << setw(10) << e <<endl;
i = x1 + '@' + 1; e = x1 + '@' + 1;
cout << setw(12) << "x1+'@'+1" <<setw(10) << i << setw(10) << e <<endl;
i = x1 + 2; e = x1 + 2;
cout << setw(12) << "x1+2" <<setw(10) << i << setw(10) << e <<endl;
i = 2 * x1; e = 2 * x1;
cout << setw(12) << "2*x1" <<setw(10) << i << setw(10) << e <<endl;
i = '3' * x1; e = '3' * x1;
cout << setw(12) << "'3'*x1" <<setw(10) << i << setw(10) << e <<endl;
i = (x1 / x2) * x3; e = (x1 / x2) * x3;
cout << setw(12) << "(x1/x2)*x3" <<setw(10) << i << setw(10) << e<<endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
16
17
4.67
2.5
5
0.99
3.14
9.42
S se calculeze expresia
b11 + b012 + 1
+ cos( b12 )
b102 * b12
18
2.1 Operatorii ++ i
Operatorii de incrementare i decrementare ++ i se aplic asupra variabilelor ntregi. Ei pot
fi prefix (++operand) i postfix (operand++) i au urmtoarea definiie:
++operand, preincrementare, (operand=operand+1, dup care este folosit n alte
calcule),
operand++, postincrementare, (operand se folosete mai nti n calcule dup care
operand=operand+1)
--operand, predecrementare, (operand=operand-1, dup care este folosit n alte
calcule)
operand--, posdecrementare, (operand se folosete mai nti n calcule, dup care
operand=operand-1)
Problema 1. Operatorii ++ i --. Se va executa urmtorul program.
#include <iostream>
using namespace std;
int main() {
// operatorul ++ prefix
int i = 1;
cout << i = << i << endl;
cout << ++i = << ++i << endl;
cout << i = << i << endl;
// operatorul ++ postfix
int j = 1;
cout << j = << j << endl;
cout << j++ = << j++ << endl;
cout << j = << j << endl;
return 0;
}
Rezultatele rulrii programului sunt prezentate mai jos. Se vor explica aceste rezultate.
Problema 2. Fie variabila ntreg x = 12. Sa se deplaseze la stanga cu trei bii. Fir variabila
ntreag t = 33. S se deplaseze la dreapta cu doi bii.
#include <iostream>
using namespace std;
int main()
{
int x = 12;
int rez = x << 3;
cout << "x = " << x << endl << "x << 3 = " << rez << endl;
int y(33);
rez = y >> 2;
cout << "y = " << y << endl << "y >> 3 = " << rez << endl;
return 0;
}
Rezultatul rulrii programului este cel de mai jos.
b
0
1
0
1
a|b
0
1
1
1
a&b
0
0
0
1
a^b
0
1
1
0
a
0
1
~a
1
0
Operatorii |, &, ^ sunt binari, operatorul ~ este unar. Operatorii binari sunt comutativi i
asociativi la stnga. Prioritile lor sunt ~, apoi & i n final | i ^.
Problema 3. Fie variabila ntreag i = 0xf i variabila ntreag j = 0xc. S se scrie un
program care s calculeze valorile : i & j ; i |j ; i ^ j ; ~i. Rezultatele se vor afia n
zecimal i hexazecimal.
Indicaie. Pentru a afia o variabil ntreag n hexazecimal se va folosi manipulatorul hex ca
20
21
y
false
true
false
true
x && y
false
false
false
false
x||y
false
true
true
true
x
!x
false
true
true
false
Rezultatul evalurii unei expresii booleene este true sau false. Operatorii and i or sunt
comutativi i asociativi la stnga.
2.6 Structuri de control fundamentale
Instruciunile de selecie permit executarea unui anumit grup de instruciuni n funcie de
indeplirea unei condiii. Instruciunile de selecie sunt if, ? i switch.
Instruciunile de ciclare sau iterative permit executarea unui grup de instruciuni de un anumit
numr de ori, sau ct timp este ndeplinit o condiie logic. Instruciunile de ciclare sunt: for,
while i do-while.
Toate aceste instruciuni pot executa instruciuni compuse (blocurri de instruciuni) ce conin
instruciuni cuprinse ntre acolade, { i }. In instruciunile compuse se pot defini variabile
locale ce exist doar n interiorul instruciunii.
22
{
double x[3];
int i;
cout << " Introduceti componentele vectorului x" << endl;
for(i = 0; i < 3; i++)
{
cout << "x[" << i << "] = ";
cin >> x[i];
}
cout << "Componentele lui x" << endl;
for(i = 0; i < 3; i++)
cout << "x[" << i << "] = " << x[i] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
25
a = a << 1;
cout << "a << "<< i << '\t' << dec << a << '\t' << hex << a << endl;
}
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
27
Problema 10. S se scrie un program care s calculeze cmmdc al dou numere ntregi.
Programul va citi repetat seturi de dou numere ntregi de la tastatur pn cnd primul numr
citit este zero. Programul este urmtorul.
#include<iostream>
using namespace std;
int cmmdc(int a,int b){
28
int r,m;
if(a < b) {
//interschimba pe a cu b
m = a; a = b; b = m;
}
r=a%b;
while (r!=0){
a=b; b=r; r=a%b;
}
return(b);
}
int main(){
int a,b,d;
cout << "calculul cmmdc al doua numere intregi" << endl;
cout << "a = "; cin >> a;
cout << "b = "; cin >> b;
while(a){
d = cmmdc(a, b);
if(d == 1)
cout << "numerele sunt prime intre ele" << endl;
else
cout << "numerele nu sunt prime intre ele, cmmdc = " << d << endl;
cout << "a = "; cin >> a;
cout << "b = "; cin >> b;
}
return (0);
}
Rezultatele rulrii programului sunt cele de mai jos.
Problema 11. Fie vectorii a = (1.2, -1.0, 7.5) i b = (-2.33, 1.244, 13.1) S se scrie un
program care s calculeze suma celor doi vectori. Programul este cel de mai jos.
#include<iostream>
using namespace std;
29
int main(){
float c[3],a[3]={1.2, -1.0, 7.5};
float b[3]={-2.33, 1.244, 13.1};
cout << "suma a doi vectori, a si b" << endl;
for (int i=0;i<3;i++)
cout << "a[" << i << "] = " << a[i] << '\t';
cout << endl;
for (int i=0;i<3;i++)
cout << "b[" << i << "] = " << b[i] << '\t';
cout << endl;
for (int i=0;i<3;i++) {
c[i]=a[i]+b[i];
cout<<"c["<<i<<"] = "<<c[i]<< '\t';
}
cout <<endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
30
Problema 8. S se fac un program care s calculeze minimul a trei numere ntregi care se
citesc de la tastatur.
Problema 9. S se fac un program care s citeasc vrsta i s afieze mesajele: tnr dac
vrsta < 18, adult dac 18 <= vrsta <= 65 i btrn dac vrsta > 65.
Problema 10. Fie un vector x cu cinci componente reale care se citesc de la tastatur. S se
calculeze cel mai mare dintre componentele vectorului.
Problema 11. Fie a un vector cu patru componente reale ce se citesc de la tastatur. S se
calculeze norma vectorului a.
Indicaie. Norma vectorului a este n =
a
i =0
2
i
f ( x) = sin( x) +
1 + cos(2 x)
1+ x2
pentru
Problema 14. Fie A o matrice cu 2 linii i 3 coloane cu elemente reale. Elementele matricei
se citesc de la tastatur. S se determine valoarea celui mai mare dintre elementele matricei.
Problema 15. S se citeasc dou numere reale de la tastatur i un operator +, - *, / i s se
calculeze rezultatul operaiei corespunztoare. Operatorul se va citi ntr-o variabil de tip
char.
Indicaie. Pentru a calcula rezultatul se va utiliza instruciunea switch.
Problema 16. S se calculeze valorile funciei f(x) = sin(x) + sin(2x) pentru x [0,2] cu
pasul 0.1 i s se afieze valorile minim i maxim calculate pe acest interval.
Problema 17. S se calculeze produsul a n numere reale citite de la tastatur. Valoarea n se
va citi de la tastatur. Citirea i produsul numerelor se vor face ntr-un ciclu realizat cu
instruciunea while.
2.9 Precizia calculelor. Depirea. Rotunjirea.
Problema 1. Depirea gamei de reprezentare la operaii cu numere ntregi i reale.
a) Se d numrul ntreg n = 1000. S se calculeze valorile n2, n3, n4.
b) Se d numrul real x = 1000.0. S se calculeze valorile x2, x4, x8, x16.
Gama numerelor ntregi de tip int este [-231..231-1] adic [-2147483648.. 2147483647].
Numrul n4, = 1012, depete acest gam.
Gama numerelor reale de tip float este 3.4*10 -38..3.4*1038. Numrul x16, = 1048, depete
aceast gam.
Programul este cel de mai jos.
#include<iostream>
using namespace std;
#include<cmath>
int main(){
int n=1000, p;
cout << "n=" << n << endl;;
31
p=n*n;
cout << "n*n=" << p << endl;
p=n*n*n;
cout << "n*n*n=" << p << endl;
p=n*n*n*n; cout << "n*n*n*n=" << p;
cout<<" gresit, depasire gama de reprezentare int !!!"<<endl;
float x=1.0e3, xp;
cout << "x=" << x << endl;
xp=x*x;
cout<<"x*x="<<xp<<endl;
xp=xp*xp; cout<<"x^4="<<xp<<endl;
xp=xp*xp; cout<<"x^8="<<xp<<endl;
xp=xp*xp;
cout<<"x^16="<<xp;
cout<<" gresit, depasire gama de reprezentare float!!!"<<endl;
double putere;
putere=pow(x,16);
cout<<"x^16="<<putere<<" corect, folosind tipul double"<<endl;
return 0;
}
Rezultatele rulrii programului sunt cele din caseta de mai jos. Se vor explica rezultatele
pentru n 4 i x 16 .
Problema 2. Erorile de rotunjire. Se vor calcula valorile variabilelor reale de tip float
x=
1000.0
1
1
; y=x-333; z=3y-1. Ele trebuie s aib valorile: x = 333 ; y = ; z = 0.
3.0
3
3
Problema 3. Erorile de rotunjire. Se vor calcula valorile expresiei x*x*cos(x) pentru 1 <= x
32
float x, e;
double x, e;
Pentru a vedea erorile de rotunjire vom afia doar valorile variabilei x tip float i tip double,
cu 5 zecimale i respectiv cu 15 zecimale.
#include <cstdlib>
#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
float x;
33
// double x;
cout << setw(5) << "x" << " " << setw(12) << "x" << endl;
cout << fixed;
for(x = 1; x <= 2.95; x = x + 0.15){
cout << setprecision(5) << x << " " << setprecision(15) << x << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Rezultatele sunt cele de mai jos. Se vor observa valorile variabilei x afiate cu 15 zecimale.
float x;
double x;
34
Funcii
36
Problema 3. S se defineasc o funcie care s calculeze cea mai mare dintre dou variabile
ntregi. Prototipul funciei va fi
int max(int x, int y);
Programul este cel de mai jos.
#include<iostream>
using namespace std;
int max(int x, int y){
if(x >= y)
return x;
else
return y;
}
int main(){
int x, y, z;
cout << "x="; cin >> x;
cout << "y="; cin >> y;
z = max(x, y);
cout << "max(x, y) = " << z << endl;
}
Rezultatele rulrii programului sunt prezentate mai jos.
Problema 4. S se defineasc o funcie care s calculeze cel mai mare element al unui vector
de numere reale. ablonul funciei va fi:
float max(float a[], int n);
unde :
a vector de numere reale;
n dimensiunea vectorului a
Se va rescrie funcia astfel nct rezultatul s fie asociat unui parametru. Prototipul funciei va
fi n acest caz
void max(float a[], int n, float& rez);
Soluia primei cerine, cnd rezultatul este asociat numelui funciei:
37
#include<iostream>
using namespace std;
float max(float a[], int n) {
int i;
float max_t;
max_t = a[0];
for(i = 1; i < n; i++)
if(max_t < a[i])
max_t = a[i];
return max_t;
}
int main(){
int i,n;
float x[20], x_max;
cout << " calculul maximului a n numere reale" << endl;
cout << "n = "; cin >> n;
for(i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
}
x_max = max(x,n);
cout<<"max = "<<x_max << endl;
return 0;
}
Rezultatele rulrii programului sunt prezentate mai jos.
Soluia celei de-a doua cerine, cnd rezultatul este asociat unui parametru:
#include<iostream>
using namespace std;
void max(float a[], int n, float& rez){
int i;
rez = a[0];
for(i = 1; i < n; i++)
if(rez<a[i])
rez=a[i];
}
void main(){
int i, n;
float x[20], x_max;
cout << "n = "; cin >> n;
for(i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
38
}
max(x, n, x_max);
cout << "max = " << x_max << endl;
}
Problema 5. S se defineasc o funcie care s calculeze valoarea medie i dispersia unui ir
de numere reale. Sablonul funciei va fi
float mean(float x[], int n, float& var);
unde :
x vector cu numere reale;
n dimensiunea vectorului x;
var dispersia irului x
Valoarea medie va fi asociat numelui funciei mean.
Se va rescrie funcia asfel nct valoarea medie i dispersia s fie asociate unor parametri.
ablonul funciei va fi
void mean(float x[], int n, float& m, float& var);
1 n
Indicaie. Valoarea medie a irului x este dat de formula m = xi . Dispersia irului x
n i =1
n
1
( x i m) 2 .
este dat de formula var =
n 1 i =1
Soluia primei cerine, cnd media este asociat numelui funciei.
#include<iostream>
using namespace std;
float mean(float x[], int n, float& var){
float s, m;
s = x[0];
for(int i = 1; i < n; i++)
s = s + x[i];
m = s / n;
s = 0;
for(int i = 0; i < n; i++)
s = s + (x[i] - m) * (x[i] - m);
var = s / (n - 1);
return m;
}
int main(){
int n;
float x[20], medie, dispersie;
cout << " media si dispersia a n numere naturale" << endl;
cout << "n = "; cin >> n;
for(int i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
}
medie = mean(x, n, dispersie);
cout<<"media = "<< medie <<" dispersia = "<<dispersie << endl;
return 0 ;
39
}
Rezultatele rulrii programului sunt prezentate n caseta text.
Soluia celei de-a doua cerine, cnd media este asociat unui parametru.
#include<iostream>
using namespace std;
void mean(float x[], int n, float& m, float& var){
float s;
s=x[0];
for(int i = 1; i < n; i++)
s = s + x[i];
m =s / n;
s = 0;
for(int i = 0;i < n; i++)
s = s + (x[i] - m) * (x[i] - m);
var = s / (n - 1);
}
int main(){
int n;
float x[20],medie=0,dispersie=0;
cout << " media si dispersia a n numere naturale" << endl;
cout<<"n = "; cin >> n;
for(int i = 0; i < n; i++){
cout<<"x[" << i << "] = "; cin >> x[i];
}
mean(x, n, medie, dispersie);
cout<<"media = " << medie <<" dispersia = " << dispersie;
return 0 ;
}
Problema 6. S se defineasc o funcie care s verifice dac un an este bisect. Prototipul
funciei va fi
bool bisect(int an);
Anii biseci sunt divizibili cu 4. Anii divizibili cu 100 nu sunt biseci cu excepia c anii
divizibili cu 400 sunt biseci.
Exemplu. Anul 1992 este bisect, anul 1900 nu este bisect, anul 2000 este bisect.
Rezultatul funciei bisect este de tipul bool. Valorile acestui tip sunt afiare cu manipulatorul
boolalpha.
Programul este urmtorul.
#include<iostream>
40
41
x3 x5
+
3!
5!
x2
.
i ( i 1)
42
y = ( x1 x2 xn ) n
Sirul de numere i lungimea lui sunt parametrii de intrare ai funciei. Prototipul funciei va fi
double med(double x[], int n) ;
Problema 4. S se defineasc o funcie care s calculeze n!. Variabila ntreag n va fi
parametrul de intrare al funciei. Funcia se va scrie n dou variante : recursiv i nerecursiv.
Prototipul funciei va fi
int fact(int n) ;
S se defineasc o funcie care s calculeze valoarea C nk . Prototipul funciei va fi
int comb(int n, int k);
Pentru calculul factorialului n funcia comb() se va utiliza funcia fact().
Problema 5. S se definesc o funcie care s calculeze suma a doi vectori, x i y, cu cte n
componente reale fiecare. Prototipul funciei va fi
void suma(double x[], double y[], double z[], int n);
unde z este suma vectorilor x i y, iar n este dimensiunea celor trei vectori.
Problema 6. S se defineasc o funcie generic pentru calculul valorii maxime a unui ir de
numere. Prototipul funciei va fi
template <typename T>
T minval(T x[], int n);
Se va utiliza funcia scris pentru calculul maximului unor iruri de valori de tip int sau
double.
Problema 7. S se defineasc o funcie care s calculeze suma primelor n numere naturale
impare. Prototipul funciei va fi
int suma(int n);
Problema 8. S se defineasc o funcie care s calculeze produsul scalar a doi vectori, x i y
cu n componente reale fiecare. Prototipul funcie va fi
double prodscalar(double x[], double y[], int n) ;
Indicaie. Produsul scalar a doi vectori , x i y are expresia
n
p = xi y i
i =1
Problema 9. S se defineasc o funcie care s testeze dac un numr ntreg este par.
Prototipul funciei va fi
bool estepar(int n) ;
Problema 10. S se defineasc o funcie care s calculeze o cifr hexazecimal a unui numr
ntreg. Prototipul funciei va fi
int hexdigit(int n, int k);
Funcia va calcula cifra zecimal k a numrului ntreg n. De exemplu, pentru numrul ntreg
n = 0x1b2, hexdigit(n, 0) va avea ca rezultat 2, hexdigit(n, 1) va avea ca rezultat b, etc.
44
4.1 Pointeri
Un pointer este o variabil ce conine adresa unei alte variabile. O variabil de tip pointer se
definete cu instruciunea
tip * nume;
Variabilele tip pointer pot fi iniializate doar cu adrese.
Pentru a calcula adresa unei variabile se utilizeaz operatorul &. Dac x este o variabil
oarecare, expresia &x este adresa lui x. De exemplu putem scrie
int n;
int * pn;
// pn este o variabila de tipul pointer la int
pn = &n;
// initializeaz pn cu adresa lui n
Variabilele de tip pointer pot fi iniializate la declararea lor. Putem scrie de exemplu
int n, *pn = &n;
Pentru a obine valoarea variabilei indicate de un pointer se utilizeaz operatorul * (numit i
operator de adresare indirect).
Fie de exemplu instruciunile
int k, n= 10;
int * pn, *pk;
Instruciunile
k = n;
i
pn = &n;
k = *pn;
sunt echivalente, k primete valoarea 10. (Variabila pn a fost iniializat n prealabil cu adresa
lui n).
Instruciunile
k = n;
i
pk = &k;
*pk = n;
sunt echivalente.
n final, instruciunile
k = n;
i
pk = &k;
pn = &n;
*pk = *pn;
sunt echivalente;
Menionm c orice variabil tip pointer trebuie iniializat nainte de a fi utilizat. De
exemplu, urmtoarea secven de instruciuni nu este corect
int *pn;
*pn = 5;
deoarece variabila pn nu a fost iniializat. O secven corect este:
int *pn;
int x;
pn = &x;
*pn = 5;
n acest caz variabila pn a fost iniializat cu adresa unei variabile de tip ntreg, x.
45
Probleme rezolvate
Problema 1. S se defineasc o funcie care s permute valorile a dou variabile de tip
double. Prototipul funciei va fi
void perm(double * a, double * b);
Programul este urmtorul.
# include <iostream>
using namespace std;
// functie ce permuta valorile a doua variabile
void perm(int* a, int* b)
{
int c;
c = *a;
*a = *b;
*b = c;
}
// testarea functiei perm
int main()
{
int x = 3, y = -4;
// scrie variabilele inainte de permutare
cout << "x = " << x << " y = " << y << endl;
perm(&x, &y);
// scrie variabilele dupa permutare
cout << "x = " << x << " y = " << y << endl;
return 0;
}
Rezultatele execuiei programului sunt prezentate n caseta text.
Amintim c, n limbajul C, singura modalitate ca un parametru al unei funcii s fie un
parametru de ieire este ca el s fie de tip pointer.
Problema 2. Se consider un vector cu 4 componente ntregi. S se afieze adresele
corespunztoare componentelor vectorului
utiliznd operatorul & de calcul al adresei
utiliznd o variabil tip pointer ce va primi ca valoare iniial adresa elementului
x[0].
Programul este cel de mai jos.
#include <iostream>
using namespace std;
int main(){
int x[4], i;
/* afiseaza adr. componentelor cu operatorul & */
cout<<"indice adresa folosind &"<<endl;
46
47
return 0;
}
Mai jos sunt prezentate rezultatele execuiei programului.
4.2 Referine
O referin este un alt nume pentru o variabil. Fie T tipul unei variabile i fie
instruciunea ce definete o variabil
T nume_variabil;
Instruciunea de definire a unei referine este
T& nume_referin = nume_variabil
48
unde
nume_referin este numele variabilei referin.
Variabila nume_variabil trebuie s fie declarat nainte i s aib tipul T. De exemplu
instruciunile
int x;
int& rx = x;
declar pe rx ca fiind o referin a lui x (este obligatoriu ca variabila x de tip ntreg s fie
declarat anterior). Secvena anterioar se poate scrie
int x, &rx = x;
Numele x i rx sunt dou nume diferite pentru aceeai variabil. Ele au totdeauna
aceeai valoare i aceeai adres.
Probleme rezolvate
Problema 1. S se defineasc o funcie care s permute valorile a dou variabile tip double.
Prototipul funciei va fi
void perm(double & a, double & b);
Programul este prezentat n continuare.
# include <iostream>
using namespace std;
/* functie ce permuta valoarea a doua variabile */
void perm(double& a, double& b)
{
double c;
c = a;
a = b;
b = c;
return;
}
// testarea functiei perm
int main()
{
double x = 7.2, y = 12.5;
cout << "valorile initiale x = " << x << " y = " << y << endl;
perm(x, y);
cout << "valorile permutate x = " << x << " y = " << y << endl;
return 0;
}
Mai jos sunt reproduse rezultatele execuiei programului.
49
{
int a = 3;
int& ra = a;
// scrie valoarea variabilei i referintei
cout << valoare variabilei este << a << endl;
cout << valoarea referintei este << ra << endl;
// scrie adresa variabilei i referintei
cout << adresa variabilei este << &a << endl;
cout << adresa referintei este << &ra << endl;
return 0;
}
Rezultatele execuiei programului sunt cele de mai jos.
delete x;
elibereaz memoria alocat cu new double, n timp ce instruciunea
delete [] y;
elibereaz memoria alocat vectorului cu new double[17].
4.4 Probleme rezolvate
Problema 1. Se va aloca un vector de 5 componente tip double folosind operatorul new. Se
vor citi componentele vectorului de la tastatur i se va calcula suma componentelor. Sluia
problemei este urmtoarea.
# include <iostream>
using namespace std;
int main(){
double * v = new double[5];
cout << "introduceti 5 numere " << endl;
for(int j = 0; j < 5; j++)
cin >> v[j];
double suma = 0;
for(int j = 0; j < 5; j++)
suma = suma + v[j];
cout << "suma : " << suma << endl;
delete [] v;
return 0;
}
Mai jos este reprodus un exemplu de execuie.
51
}
Un exemplu de execuie este urmtorul :
52
Descriere
Test dac un caracter este alfanumeric
Test dac un caracter este alfabetic
Test dac un caracter este o cifr zecimal
Test dac un caracter este o cifr hexazecimal
Test dac un caracter este liter mic
Test dac un caracter este liter mare
Test dac un caracter este spaiu ( , \n, \t)
Funciile au un rezultat diferit de zero dac argumentul este conform descrierii funciei.
Urmtoarele funcii convertesc literele mari n litere mici i invers.
Funcie
int tolower(int c);
int toupper(int c);
Descriere
Convertete n litere mici
Convertete n litere mari
<0
=0
>0
a < b
irurile sunt egale
irul abcd este mai lung
cin >> x ;
cout << x << endl ;
In limbajul C irurile de caractere e citesc de la tastatur i se scriu pe ecran cu instruciunile
scanf i printf cu specificatorul de format %s.
Un ir de caractere x se citete i se afiaz astfel
scanf(%s, x);
printf(% s \n, x)
Sirul de caractere citit se termin la primul caracter spaiu, tab sau \n.
5.2 Probleme rezolvate
In exemplele de mai jos vom scrie programe C i C++, deci vom utiliza stilurile
corespunztoare pentru directivele include.
Problema 1. Se d irul de caractere aBxE12+? \t\nY. S se calculeze numrul de cifre,
litere, spaii i caractere alfanumerice. Datele se vor afia n felul urmtor
Sirul studiat :
Lungimea irului :
Litere :
Cifre :
Spatii :
Caractere alfanumerice :
Indicaie. Se vor utiliza funciile standard isalpha(), isdigit(), isalnum(), isspace(), strlen().
Programul ce rezolv problema este urmtorul.
# include <iostream>
# include <cstring>
# include <cctype>
using namespace std;
int main()
{
char x[] = "aBxE12+? \t\nY";
int nc = 0;
int nl = 0;
int ns = 0;
for(int i = 0; i <strlen(x); i++)
{
if(isdigit(x[i]))
nc = nc + 1;
if(isupper(x[i]) || islower(x[i]))
nl++;
if(isspace(x[i]))
ns++;
}
cout << "Sirul studiat : " << x << endl;
cout << "Lungimea sirului : " << strlen(x) << endl;
cout << "Cifre : " << nc << endl;
cout << "Litere : " << nl << endl;
cout << "Spatii : " << ns << endl;
54
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos. De ce este afiat irul cu litera Y pe
rndul urmtor?
55
# include <stdlib.h>
int main(){
char a[] = "-12", b[] = "1.25e1";
int i = atoi(a);
double d = atof(b);
printf("i = %d\n", i);
printf("d = %lf \n", d);
return 0;
}
Rezultatul rulrii programului este cel de mai jos
Not. Se vor aduga instruciunile necesare pentru calcului expresiilor xi i cos(i * x).
5.3 Probleme propuse
Problema 1. Se d irul xyz2j7M=*&^. S se nlocuiasc primele dou caractere din ir cu
primele dou caractere din irul abc.
Problema 2. S se compare irurile
abcxd i abdf89k.
xyz i adk
mnp i mnp
Se va utiliza o instruciune for n care se va citi de la tastatur cte o pereche de iruri cu
instruciunea cin, se vor compara irurile i se va afia rezultatul.
Se va explica de fiecare dat rezultatul.
Indicaie. Se va utiliza funcia standard strcmp().
Problema 3. S se scrie o funcie cu un parametru n de tip ntreg care afieaz n linii cu
caracterul *, un caracter pe prima linie, dou caractere pe linia a doua, n caractere pe linia n.
De exemplu, pentru n = 3 rezultatul funciei va fi
*
**
***
Prototipul funciei va fi
void print(int n);
Problema 4. S se construiasc o funcie care s transforme literele mari dintr-un ir de
caractere n litere mici. Prototipul funciei va fi
void strcnv2(char[] x);
Problema 5. S se defineasc o funcie cu un parametru n de tip ntreg care afiaz n linii de
cte cinci caractere, caracterele abcde pe prima linie, caracterele bcdef pe linia a doua, etc.
De exemplu, pentru n = 4 rezultatul funciei va fi
abcde
bcdef
cdefg
defgh
Prototipul funciei va fi
57
void prtcar(int n) ;
Problema 6. S se fac un program care s citeasc un ir de la tastatur i s afieze irul
citit i apoi irul n ordine invers.
Problema 7. S se citeasc un ir de caractere de la tastatur i s se afieze pe ecran fiecare
caracter al irului mpreun cu valoarea sa n codul ASCII.
Problema 8. S se citesc de la tastatur un ir ce conine litere i cifre. S se afieze pe
ecran doar litere coninute n ir.
Problema 9. S se scrie o funcie care s calculeze lungimea unui ir de caractere. Prototipul
funciei va fi
int strglen(char x[]) ;
Problema 10. S se codifice un ir de caractere adugnd valoarea 1 la codul ASCII al
fiecrui caracter. S se decodifice apoi irul de caractere. Se vor afia pe ecran irul iniial,
irul codificat i cel decodificat.
58
Prelucrarea fiierelor n limbajul C se face asociind fiecrui fiier un stream. Pentru aceasta
se definete un pointer la o variabil tip FILE cu instruciunea:
FILE* ptrfile;
Un fiier trebuie deschis nainte de prelucrare i trebuie nchis dup prelucrare. Asocierea
unui fiier cu un stream se face la deschiderea fiierului cu instruciunea:
ptrfile = fopen(nume_fiier, mod);
unde ptrfile este o variabil de tipul FILE* iar nume_fiier este un ir de caractere cu numele
fiierului. Parametrul mod este un ir de caractere ce conine modul de descriere al fiierului,
n citire sau n creare. Functia fopen() returneaz un pointer ce nu trebuie modificat. Funcia
fopen() returneaza un pointer NULL cnd operaia de deschidere a fiierului a euat.
nchiderea fiierului se face cu instruciunea:
fclose(ptrfile);
Prototipurile tuturor funciilor pentru operaii cu fiiere n limbajul C sunt definite n
biblioteca <stdio.h> (sau <cstdio> pentru limbajul C++).
In aceast lucrare vom scrie programe C pentru prelucrarea fiierelor, deci vom utiliza stilul
C pentru directiva include.
Menionm c, totdeauna sunt predefinite streamurile stdin, asociat fiierului standard de
intrare i stdout asociat fiierului standard de ieire.
Fiierele au un indicator de poziie ce d adresa urmtorului octet de citit sau scris. Acest
indicator este iniial pus la zero i este actualizat de operaiile de citire sau scriere.
6.1 Fiiere text
n cazul fiierelor text, parametrul mod al funciei fopen() este r pentru citire i w pentru
creare. Instruciunile de scriere i citire cu format sunt :
fprintf(ptrfile, format, list de variabile);
fscanf(ptrfile, format, list de variabile);
n care ptrfile este variabila tip FILE* asociat fiierului.
Instruciunile de scriere i citire cu format asociate fiierelor standard sunt:
printf(format, list de variabile);
scanf(format, list de variabile);
Parametrul format este un ir de caractere compus din specificatori de conversie definii de %
i alte caractere. Specificatorii de conversie sunt :
%d ntreg cu semn n baza 10
%x - ntreg cu semn n baza 16
%c caracter
%s ir de caractere
%p - pointer
%f numr real tip float
%lf numr real tip double
Menionm c, n cazul instruciunilor scanf, fscanf, argumentele sunt parametri de
ieire, deci de tip pointer.
Fiierele text sunt formate din linii ce conin zero sau mai multe caractere, urmate de
caracterul \n. Pentru prelucrarea acestor fiiere este util s putem citi sau scrie caractere i
linii, adic iruri de caractere terminate cu caracterul \n.
Fiierele text au indicator de poziie ce conine numrul urmtorului caracter de scris sau de
citit. Acest indicator are valoarea zero la deschiderea fiierului i apoi este modificat de
instruciunile de citire sau scriere a fiierului.
Funciile intrare / ieire tip caracter sunt urmtoarele:
59
60
a + x2
. S se calculeze valorile expresiei pentru a=1.25 i x
1 + 3x
lund valori de la 1 la 2 cu pasul 0.2. Valorile expresiei se vor scrie intr-un fiier sub forma
x
e(x)
1.0
1.2
2.0
Se va citi apoi fiierul creat i se va afia pe ecran. Se va examina fiierul creat cu un editor.
Programul ce rezolv problema este urmtorul.
#include<stdio.h>
int main()
{
FILE* file;
const double a=1.25;
float x, e;
int i;
char sir1[20], sir2[20];
// deschide fisierul in scriere
file = fopen("rez.txt", "w");
// scrie capul de tabel
fprintf(file, " x e(x)\n");
// scrie rezultatele in fisier
for(i = 0; i <= 5; i++)
{
x = 1 + i * 0.2;
e = (a + x * x) / (1 + 3 * x);
fprintf(file, "%3.1f %f \n", x ,e);
}
fclose(file);
// deschide fisierul in citire
file = fopen("rez.txt", "r");
// citeste capul de tabel
fscanf(file, "%s %s",sir1,sir2);
printf("%s %s\n",sir1,sir2);
// citeste fisierul
for(i = 0; i<= 5; i++) {
fscanf(file, "%s %s",sir1,sir2);
printf("%s %s\n",sir1,sir2);
}
fclose(file);
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
61
62
63
}
fclose(fil);
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
64
Structuri i uniuni
7.1 Structuri
O structur este un tip de date definit de utilizator. O structur este o colecie de date de tipuri
diferite. Datele dintr-o structur sunt numite componente sau cmpuri. O structur se
definete cu instruciunea
struct nume {lista de declaraii de tip};
unde nume este noul tip de date.
De exemplu, urmtoarea structur poate defini tipul numere complexe
struct complex {
float real;
float imag;
};
Menionm c o structur poate conine componente de orice tip, chiar i alte structuri.
Variabilele de tipul unei structuri se definesc cu instruciunea
struct nume lista de variabile;
De exemplu, ntr-un program putem defini numerele complexe a i b cu instruciunea
struct complex a, b;
Adresarea unui element al unei structuri se face cu operatorul . cu forma
nume.membru
Putem da valori variabilelor definite anterior astfel:
a.real = 1.0;
a.imag = -1.2 + sin(0.3);
Putem utiliza valorile componentelor unei structuri n expresii, ca de exemplu:
float x;
x = a.real * a.imag;
La fel ca i n cazul variabilelor putem defini variabile tip pointer la o structur, ce vor
conine adresa unei structuri. Instruciunea de definire a unui pointer la o structur are
formele
struct nume * identificator;
unde nume este numele structurii. De exemplu,
struct complex * pc;
definete un pointer de tip struct complex. Variabila tip pointer poate fi iniializat ca orice
variabil tip pointer, folosind operatorul de calcul al adresei &
pc = &a;
n cazul unui pointer p la o structur, un cmp al structurii este adresat astfel
(*p).membru
deoarece operatorul . are preceden mai mare dect operatorul *.
Prin definiie, aceast scriere se prescurteaz ca
p->membru
Putem defini un tip de date structur cu instruciunea typedef
typedef struct {
// definiia structurii
} tipnou ;
In acest caz definirea unor variabile de tipul structurii se face mai simplu cu instruciunea
tipnou lista de variabile ;
In aceast lucrare vom scrie programe C pentru lucrul cu structuri i uniuni.
7.2
Problema 1. Se consider structura
Probleme rezolvate
65
struct complex
{
double real, imag;
};
ce descrie numerele complexe. S se defineasc o funcie care s adune dou numere
complexe. S se fac un program care s defineasc trei variabile de tipul complex, s
atribuie valori la dou dintre variabile i s calculeze suma lor utiliznd funcia. Se vor scrie
apoi valorile variabilelor pe ecran sub forma (real, imag). Vom defini tipul de date cu
instruciunea typedef. Programul ce rezolv problema este urmtorul.
# include <stdio.h>
// structuri tip C
typedef struct
{
float real;
float imag;
} numcmp;
numcmp addcmp(numcmp a, numcmp b)
{
numcmp c;
c.real = a.real + b.real;
c.imag = a.imag + b.imag;
return c;
}
int main ()
{
numcmp cx, cy, cz;
numcmp * pv;
cx.real = 1;
cx.imag = 1;
cy.real = 0;
cy.imag = 1;
cz = addcmp(cx, cy);
// apeleaza componentele cu operatorul .
printf("(%f , %f)\n", cz.real, cz.imag);
pv = &cz;
// apeleaza componentele prin pointer
printf("(%f , %f)\n", pv->real, pv->imag);
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
66
67
Timpul curent este msurat n secunde ncepnd cu 1 ianuarie 1990 ora 0, GMT.
Variabilele ce conin timpul au tipul time_t.
Funcia
time_t time(time_t*);
iniializeaz variabile de tipul time_t cu timpul curent.
Funcia
char * ctime(time_t * t1);
convertete timpul curent GMT indicat de variabila t1 ntr-un ir de caractere
ce
conine timpul curent local.
Structura predefinit
struct tm {
int tm_sec;
/* seconds after the minute - [0,59] */
int tm_min;
/* minutes after the hour - [0,59] */
int tm_hour; /* hours since midnight - [0,23] */
int tm_mday; /* day of the month - [1,31] */
int tm_mon; /* months since January - [0,11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday - [0,6] */
int tm_yday; /* days since January 1 - [0,365] */
68
int tm_isdst;
};
conine timpul curent convertit n an, luna, zi, ore, minute, secunde.
Funcia
struct tm * localtime(time_t * timeptr);
convertete timpul coninut ntr-o variabil time_t n structura tm.
Probleme rezolvate
Problema 1. S se completeze o variabil de tipul tm cu informaiile corespunztoare i s se
afieze aceste informaii pe ecran. Se va completa mai nti o variabila tip time_t cu funcia
time() i apoi structura tip tm cu funcia localtime(). Se va afia timpul curent local i cu
funcia ctime(). Se va afia i timpul GMT gmtime().
Programul ce rezolv problema este urmtorul.
# include <stdio.h>
# include <time.h>
// functii de timp
int main()
{
time_t t1, t4;
struct tm t3;
struct tm * t2;
// calculeaza timpul
t1 = time(NULL);
printf("%s\n", ctime(&t1));
// calculeaza timpul local
t2 = localtime(&t1);
t3 = * t2;
printf("local time : %i:%i:%i\n", t3.tm_hour, t3.tm_min, t3.tm_sec);
// converteste structura tm n time_t
t4 = mktime(t2);
printf("%s\n", ctime(&t4));
// calculeaza timpul GMT
t2 = gmtime(&t1);
t3 = * t2;
printf("GMT time : %i:%i:%i\n", t3.tm_hour, t3.tm_min, t3.tm_sec);
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
69
Clase
71
private:
double m, n;
public:
double value(double x)
{return m * x + n;}
double intgrl(double a, double b)
{return m * (b * b - a * a) / 2 + n * (b - a);}
void print()
{cout << "functia f(x) = m * x + n, "
<< " m = " << m << " n = " << n << endl;}
Line(double a, double b) : m(a), n(b) {}
};
int main(){
// creaza un obiect de tipul Line
Line a(1.7, 1.5);
a.print();
cout << "f(0.5) = " << a.value(0.5) << endl;
cout << "intgrala f(x) de la 0 la 2 = " << a.intgrl(0, 2) << endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
b) A doua variant, funciile membre sunt definite n afara clasei. n acest caz utilizm
operatorul de rezoluie "::" pentru a arta c funciile definite n afara clasei sunt membre ale
clasei.
# include <iostream>
using namespace std;
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double);
double intgrl(double, double);
void print();
Line(double, double);
};
double Line::value(double x)
{
return m * x + n;
72
}
double Line::intgrl(double a, double b)
{
return m * (b * b - a * a) / 2 + n * (b - a);
}
void Line::print()
{
cout << "functia f(x) = m * x + n, "
<< " m = " << m << " n = " << n << endl;
}
Line::Line(double a, double b)
{
m = a;
n = b;
}
int main(){
// creaza un obiect de tipul Line
Line a(-1.7, 1.5);
a.print();
cout << "f(0.5) = " << a.value(0.5) << endl;
cout << "intgrala f(x) de la 0 la 1.5 = " << a.intgrl(0, 1.5) << endl;
return 0;
}
n unele cazuri avem nevoie s utilizm i s modificm datele unui obiect n timpul execuiei
programului. Dac datele sunt declarate private, nu putem face acest lucru direct. O soluie
este urmtoarea. Pentru ca o funcie extern s aib acces la membri privai ai clasei, ea
trebuie declarat n definiia clasei ca funcie prieten, friend. Diagrama sintactic a
definiiei unei funcii prietene este
friend tip numeFuncie ( parametri);
Vom aplica aceast metod n cazul definirii unei funcii care s efectueze suma a dou
funcii liniare.
Problema 2. Vom defini o funcie global care s adune dou funcii liniare. Considerm
dou funcii liniare, f 1 ( x) = m1 x + n1 i f 2 ( x ) = m2 x + n2 . Suma lor va fi funcia
f ( x) = (m1 + m2 ) x + (n1 + n2 ) . Mai jos vom prezenta doar definiiile funciei sum i
constructorului fr parametri, definiiile celorlalte funcii sunt neschimbate.
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double);
73
class Complex
{
private:
double real, imag;
public:
Complex(double m, double n);
Complex();
double getReal();
double getImag();
void setReal(double m);
void setImag(double n);
double cabs();
void print();
};
Clasa definete dou variabile private de tip double, real i imag, ce corespund prii reale i
imaginare a numrului complex. Clasa va defini urmtoarele funcii
Constructor cu parametri ce va iniializa variabilele real i imag ale obiectului creat
Complex(double m, double n);
Constructor implicit care iniializeaz variabilele obiectului la valoarea zero
Funciile de acces
double getReal();
double getImag();
care dau valoarea variabilelor real i imag ale obiectului.
Funciile de acces
void setReal(double m);
void setImag(double n);
care iniializeaz variabilele real i imag ale obiectului,
Funcia cabs() ce calculeaz modulul numrului complex
double cabs()
Funcia print() ce afiaz numrul complex.
Indicaie. Funcia print() va conine instruciunea
cout << "numarul complex = " << real << "+i*(" << imag << ")" << endl;
Se va testa clasa Complex calculnd modulul numrului complex 3+4i.
Problema 2. S se defineasc funciile globale sum, dif, mul, div care s fac cele patru
operaii aritmetrice cu numere complexe descrise de clasa Complex. Prototipurile lor sunt
Complex sum(Complex a, Complex b);
Complex dif(Complex a, Complex b);
Complex mul(Complex a, Complex b);
Complex div(Complex a, Complex b);
Funciile sum i dif vor fi declarate funcii prietene ale clasei pentru a accesa variabilele real
i imag ale obiectelor. Funciile mul i div vor utiliza funciile de acces getReal() i getImag()
pentru a accesa variabilele obiectelor.
Se va testa clasa Complex calculnd expresiile a+bc i (a + b) / (a + c) pentru numerele
complexe a = 1.5 2i, b = 3.28 + 4.35i, c = -3.84 + 5.42i.
75
76
care citesc caractere n vectorul de caractere s, cel mult size 1 caractere, sau pn la
ntlnirea caracterului delimitator, delim (prima variant), sau caracterului \n (a doua
variant). In aceste funcii se citete i delimitatorul. In acest fel este posibil citirea unei linii
dintr-un fiier tip text.
9.2 Probleme rezolvate
Problema 1. S se construiasc un program care citete un ir de caractere de la tastatur
ntr-un ir tip C++ i afieaz lungimea lui.
se va citi un ir ce nu conine spaii cu operatorul >> ntr-un ir tip string,
se va citi un ir ce conine spaii cu operatorul >> ntr-un ir tip string,
se va citi un ir ce conine spaii cu funcia getline().
Conform celor de mai sus, operatorul >> citete un ir de caractere doar pn la primul
spaiu. Programul ce rezolv problema este urmtorul.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string s;
cout<<"dati un sir care nu contine spatii \n";
cin>>s;
cout<<"lungimea sirului="<<s.length() << endl;
cout<<"dati un sir care contine spatii \n";
cin>>s;
cout<<"lungimea sirului= "<<s.length() << endl;
cout<<"sirul tine pana la primul spatiu, tab sau CR \n";
// se citeste restul sirului anterior
getline(cin, s, '\n');
cout << "sirul ramas = " << s << endl;
// citirea unei linii intregi intr-un sir tip string cu functia getline
cout<<"dati un sir care contine spatii \n";
getline(cin, s, '\n');
cout<<"lungimea sirului="<<s.length()<<endl;
cout<<"citirea cu getline() citeste toata linia \n";
return EXIT_SUCCESS;
}
Rezultatele rulrii programului sunt cele de mai jos.
77
Funcia
cin >> s ;
citete pn la primul spaiu, deci irul abc. In zona tampon rmne restul irului introdus,
citit cu prima instruciune getline().
Problema 2. Se d irul aDe3-RU*yt. S se converteasc literele mici n litere mari.
Indicaie.Se va utiliza funcia standard
int toupper(char)
din bibliotecile <cctype> sau <cstdlib>. Programul ce rezolv problema este urmtorul.
#include<string>
#include<iostream>
#include<cctype>
using namespace std;
int main(){
string s="aDe3-RU*yt";
cout << "sirul initial : " << s << endl;
for(int i = 0; i < s.length(); i++)
{
s[i]=toupper(s[i]);
}
cout << "sirul cu majuscule : " << s << endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
78
79
}
Rezultatele rulrii programului sunt cele de mai jos.
Problema 6. Fie un ir de caractere citit de la tastatur. S se verifice dac n irul citit exist
subirul abc. Sirul citit poate conine i spaii, astfel nct l vom citi cu funcia getline().
Programul ce rezolv problema este urmtorul.
#include<string>
#include<iostream>
using namespace std;
int main(){
string sir_citit;
char * sir_abc="abc";
int poz_aparitie;
cout << "dati sirul \n";
// citirea unei linii intregi intr-un sir tip C
getline(cin, sir_citit,'\n');
poz_aparitie = sir_citit.find(sir_abc);
if(poz_aparitie != -1)
cout << "subsirul " << sir_abc << " apare in pozitia " << poz_aparitie << endl;
else
cout << "subsirul " << sir_abc << " nu apare n sirul citit" << endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
80
81
10 Motenirea
Motenirea este un concept al programrii cu obiecte. Motenirea ne permite s crem clase
care sunt derivate din alte clase existente, astfel nct ele includ unii dintre membri claselor
printe, variabile i funcii. Clasa derivat motenete membrii clasei printe, funcii i
variabile. n acest fel putem construi programe complexe din obiecte simple. Clasa care este
motenit se numete clas de baz sau superclas, iar clasele care motenesc se numesc clase
derivate sau subclase. Clasa de baz conine caracteristicile comune ale mai multor elemente.
Clasele care motenesc sunt clase particulare ce adaug doar elementele proprii. Cu ajutorul
motenirii reutilizm clase deja construite.
Diagrama sintactic a definirii unei clase derivate este
class NumeClasaDerivata : acces NumeClasaBaza
{
// definitia clasei derivate
};
n aceast definiie cuvntul cheie acces din definiia clasei poate fi public, protected sau
private. Specificatorii de acces au urmtoarea semnificaie.
public, spune c variabilele declarate public i protected n clasa de baz sunt
motenite cu acelai tip de acces,
protected, spune c variabilele declarate public i protected n clasa de baz sunt
motenite cu specificatorul protected. Ele pot fi utilizate n clasele derivate, dar nu
de obiecte,
private, spune c variabilele declarate public i protected n clasa de baz sunt
motenite cu specificatorul private.Ele nu pot fi utilizate de obiecte.
O clas derivat motenete toi membri clasei de baz exceptnd constructorii, destructorul
i operatorul =. Dei constructorii nu sunt motenii, constructorul implicit i destructorul
clasei de baz sunt totdeauna apelai cnd un obiect de tipul clasei derivate este creat sau
distrus. n constructorul clasei derivate se apeleaz la nceput constructorul implicit al clasei
de baz. Dac este nevoie, putem apela explicit un constructor al clasei de baz pentru
iniializarea variabilelor. Apelarea sa se face astfel
NumeClasaDerivata(lista de parametri) : NumeClasaBaza (lista de parametri)
{
/* definitia constructorului clasei derivate */
}
10.1 Probleme rezolvate
Problema 1. Se va defini o clas Base ce conine dou numere ntregi x, y i o functie care s
afieze aceste numere. Programul ce rezolv problema este urmtorul.
class Base
{
protected:
int x, y;
public:
Base();
Base(int, int);
void print();
82
};
Se va defini o clas Pixel ce descrie un pixel pe ecran i motenete clasa Base. Un pixel este
caracterizat de coordonatele punctului (care sunt cele din clasa Base) i culoare ce va fi o
variabil de tip ntreg din clasa Pixel.
class Pixel : public Base
{
protected:
int culoare;
public:
Pixel();
Pixel(int, int, int);
};
Se va defini o funcie global ce va descrie un pixel translat cu valorile dx, dy, cu prototipul :
translate(Pixel&, int dx, int dy);
Coordonatele noului punct sunt x + dx i y + dy.
#include<iostream>
using namespace std;
class Base
{
protected:
int x, y;
public:
Base(){x=0;y=0;};
Base(int x1, int y1) {x=x1;y=y1;};
void print(){cout<<"(x,y)=("<<x<<','<<y<<')'<<endl;};
};
class Pixel: public Base
{
protected:
int culoare;
public:
Pixel(int x1, int y1, int c1){x=x1;y=y1;culoare=c1;};
Pixel() : Base(){culoare=0;};
friend void translate(Pixel &p,int dx,int dy);
void printp(){print();cout<<"culoare="<<culoare<<endl;};
};
void translate(Pixel &p,int dx,int dy)
{
p.x = p.x + dx; p.y = p.y + dy;
}
int main(){
Pixel p(2,3,1);
cout<<"pixelul initial"<<endl;
83
p.printp();
translate(p,1,1);
cout<<"pixelul translatat"<<endl;
p.printp();
}
Rezultatele rulrii programului sunt cele de mai jos.
Menionm c am definit variabilele clasei de baz x i y de tipul protected. In acest fel ele
pot fi utilizate n clasa derivat.
Problema 2. S se defineasc o clas Ratio ce descrie numere raionale, ce motenete din
clasa Base. Numrtorul i numitorul numrului raional vor fi variabilele x i y din clasa
Base. Programul ce rezolv problema este urmtorul.
class Ratio : public Base
{
public:
Ratio();
Ratio(int, int);
};
Se vor defini funcii globale care s efectueze cele patru operaii aritmetice cu numere
rationale, +, -, *, /. Funciile au prototipurile
Ratio add(Ratio&, Ratio&);
Ratio sub(Ratio&, Ratio&);
Ratio mul(Ratio&, Ratio&);
Ratio div(Ratio&, Ratio&);
Fie numerele ntregi a = 2 / 5, b = 3 / 7, c = - 4 / 3, d = -1 / 1. Se vor calcula expresiile a + b, a
+ b * c, (a + b) / (a + d). Programul ce rezolv problema este urmtorul.
#include<iostream.h>
using namespace std;
class Base
{
protected:
int x, y;
public:
Base(){x=0;y=0;};
Base(int x1, int y1) {x=x1;y=y1;};
void print(){cout<<"(x,y)=("<<x<<','<<y<<')'<<endl;};
};
class Ratio : public Base
{
84
public:
Ratio() : Base(){};
// se va observa modul de apel al constructorului din clasa
// de baza n clasa derivata
Ratio(int x1, int y1): Base(x1,y1){}
friend Ratio add(Ratio a, Ratio b);
friend Ratio sub(Ratio a, Ratio b);
friend Ratio mul(Ratio a, Ratio b);
friend Ratio div(Ratio a, Ratio b);
};
Ratio add(Ratio a, Ratio b)
{
Ratio temp;
temp.x=a.x*b.y+a.y*b.x;
temp.y=a.y*b.y;
return temp;
}
Ratio sub(Ratio a, Ratio b)
{
Ratio temp;
temp.x=a.x*b.y-a.y*b.x;
temp.y=a.y*b.y;
return temp;
}
Ratio mul(Ratio a, Ratio b)
{
Ratio temp;
temp.x=a.x*b.x;
temp.y=a.y*b.y;
return temp;
}
Ratio div(Ratio a, Ratio b)
{
Ratio temp;
temp.x=a.x*b.y;
temp.y=a.y*b.x;
return temp;
}
void main(){
Ratio a(2,5),b(3,7),c(-4,3),d(-1,1),rez;
rez=add(a,b);
cout<<"a+b=";
rez.print();
rez=add(a,mul(b,c));
cout<<"a+b*c=";
rez.print();
rez=div(add(a,b),add(a,d));
cout<<"(a + b) / (a + d)=";
85
rez.print();
}
Rezultatele rulrii programului sunt cele de mai jos.
86
pointer.
Probleme rezolvate
Problema 1. S se defineasc o clas de baz numit Persoana ce conine un cmp nume cu
numele persoanei i o funcie print() ce afiaz numele. Funcia print() va fi virtual. Definiia
clasei este cea de mai jos.
class Persoana
{
protected:
string name;
public:
Persoana(string s) { name = s;}
virtual void print()
{cout << "nume : " << name << "\n";}
};
S se defineasc o clas numit Angajat ce motenete clasa Persoana. Clasa va conine un
cmp cu numele departamentului i o funcie print() ce va afia numele angajatului i numele
departamentului. Definiia clasei este cea de mai jos.
class Angajat : public Persoana
{
protected:
string dept;
public:
Angajat(string s, string d) : Persoana(s)
{dept = d;}
virtual void print()
{Persoana::print(); cout << " departament : " << dept << "\n"; }
};
S se defineasc o clas numit Manager ce motenete clasa Angajat. Clasa va conine un
cmp cu poziia managerului i o funcie print() ce va afia numele, departamentul i poziia
managerului. Definiia clasei este cea de mai jos.
class Manager : public Angajat
{
protected:
string position;
public:
Manager(string s, string d, string p) : Angajat(s, d)
{position = p;}
virtual void print()
{Angajat::print();cout << " pozitia : " << position << "\n"; }
};
Se vor crea obiecte cu angajai i manageri i se vor afia datele acestora (numele,
departamentul i poziia managerial). Programul de rezolvare a problemei este prezentat mai
jos.
88
int main()
{
Angajat x1(Alex, proiectare);
Manager m1(George, proiectare, sef);
Persoana * ps[2];
ps[0] = &x1;
ps[1] = & m1;
// scrie datele pentru x1 si m1
for(int i = 0; i < 2; i++)
ps[i]->print();
return 0;
}
Observaii. Se va explica de ce funcia print() trebuie s fie virtual.
Rezultatele rulrii programului sunt cele de mai jos.
90
Line::Line()
{
m = 0;
n = 0;
}
Line::Line(double a, double b)
{
m = a;
n = b;
}
Line operator+( Line x, Line y)
{
Line temp(x.m + y.m, x.n + y.n);
return temp;
}
Line Line::operator*( Line x)
{
Line temp(m * x.m, n + m * x.n);
return temp;
}
Line & Line::operator = (const Line & r)
{
// obiectul ce a apelat operatorul primeste valoarea obiectului r
m = r.m;
n = r.n;
// rezultatul functiei este referinta obiectului ce a apelat operatorul
return *this;
}
ostream& operator << (ostream& stream, Line x)
{
stream << "(" << x.m << "," << x.n << ")";
return stream;
}
int main(int argc, char *argv[])
{
Line f1(1.5, -2.5), f2(2.0, 3.0);
Line f3, f4, f5;
cout << "f1 = " << f1 << endl << "f2 = " << f2 << endl;
f3 = f1 + f2;
cout << "f1 + f2 = " << f3 << endl;
f4 = f1 * f2;
cout << "f1(f2) = " << f4 << endl;
return 0;
}
91
92
93
94
ifstream fil2;
fil2.open(filename);
if(!fil2.is_open())
{
cout << " nu se poate deschide fisierul " << filename << endl;
return 0;
}
cout << "x" << '\t' << "e" << endl;
fil2 >> x >> e;
while(!fil2.eof())
{
cout << x << separator << e << endl;
fil2 >> x >> e; }
fil2.close();
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
int nl = 0;
fila.get(car);
while(!fila.eof())
{
filb.put(car);
nl++;
fila.get(car);
}
fila.close();
filb.close();
cout << "lungimea fisierului " << nl << " caractere" << endl;
return 0;
}
Rezultatele rulrii programului pentru un exemplu concret sunt cele de mai jos.
{
char filename[] = fis.txt;
char x[11];
ofstream fila;
// creaza fisierul
fila.open(filename, ios::out | ios::binary);
if(!fila.is_open())
{
cout << Nu se poate crea fisierul << filename << endl;
return 0;
}
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
x[j] = 0 + i;
x[10] = 0;
fila.write(x, 11);
}
fila.close();
ifstream filb;
// citeste si afisaza fisierul
filb.open(filename, ios::binary | ios::in);
if(!filb.is_open())
{
cout << Nu se poate citi fisierul << filename << endl;
return 0;
}
filb.read(x, 11);
while(!filb.eof())
{
cout << x << endl;
filb.read(x, 11);
}
filb.close();
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
97
# include <iostream>
using namespace std;
template <class T>
class X
{
private:
T a;
public:
X(T b) {a = b;}
T square() {return a * a;}
T geta() {return a;}
};
S definim obiecte de tipul X ce conin elemente de tip int sau double utiliznd clasa generic
X. Programul de rezolvare a problemei este cel de mai jos.
int main()
{
// creaz un obiect cu ablonul <int>
98
X<int> n(2);
cout << "patratul valorii" << n.geta() << " este " << n.square() << endl;
// creaz un obiect cu ablonul <double>
X<double> d(3.14);
cout << "patratul valorii" << d.geta() << " este " << d.square() << endl;
return 0;
}
12.2 Vectori
Clasa generic vector implementeaz vectori cu elemente de un anumit tip. Un obiect de tip
vector are un numr iniial de componente i dimensiunea lui crete dac este nevoie. Clasa
vector are ca parametru tipul componentelor vectorului.
Clasa definete urmtorii constructori
constructorul implicit (fr parametri)
vector();
creaz un vector vid
constructorul copiere
vector(vector p);
creaz un vector n care copiaz elementele vectorului p care este parametru
Fie T tipul componentelor vectorului (parametrul clasei generice). Clasa definete
urmtoarele funcii
void push_back(T&); adaug un element la sfritul vectorului
void pop_back(); trege ultimul element al vectorului
int size(); d numrul de componente ale vectorului
bool empty(); are valoarea true dac vectorul este vid
operatorul [] i funcia T& at(int) selecteaz un element al vectorului
T& front(); are ca rezultat primul component al vectorului
T& back();are ca rezultat ultimul component al vectorului
Menionm c un vector poate avea dou sau mai multe elemente egale. Clasa vector este
definit n biblioteca <vector>.
Problema 2. S crem i s listm un vector cu componente ntregi. Programul este
urmtorul.
# include <iostream>
# include <vector>
using namespace std;
int main()
{
// definim un vector cu componente intregi
vector <int> v;
// adauga 4 elemente
v.push_back(12);
v.push_back(-5);
v.push_back(7);
v.push_back(13);
// afiseaza componentele vectorului
int k;
for(k = 0; k < v.size(); k++)
99
12.3 Liste
Clasa generic list implementeaz o list dublu nlnuit, adic o list ce poate fi parcurs n
ambele sensuri. Lista poate avea oricte elemente de acelai tip. Prototipul clasei este definit
n biblioteca <list>. Clasa definete urmtorii constructori
constructorul implicit
list();
definete o list vid
constructorul
list(list p);
creaz o list n care copiaz elementele listei p
Fie T tipul elementelor listei. Funciile definite de clasa list sunt urmtoarele.
void push_back(T&); adaug un element la sfritul listei
void push_front(T&); adaug un element la nceputul listei
void pop_front(); terge primul element din list
void pop_back(); terge ultimul element din list
T& front(); are ca rezultat primul element din list
T& back(); are ca rezultat ultimul element din list
Parcurgerea listelor
Pentru parcurgerea componetelor unei liste se pot utiliza iteratori. Un iterator este asemenea
unui pointer la un element al listei. O list poate fi parcurs n sens direct sau n sens invers.
Parcurgerea listelor n ordine direct
Pentru parcurgerea unei liste n ordine direct se utilizeaz clasa iterator care este o clas
intern a clasei list. Un obiect de tipul acestei clase se definete astfel
list<tip>::iterator nume_obiect;
Operatorii implementai de clasa iterator sunt ++, -- i *. Pentru parcurgerea direct a listelor
clasa list definete funciile
begin();
end();
ce au ca rezultat un iterator ce indic primul element al listei i respectiv ultimul element al
listei.
Parcurgerea listelor n ordine invers
Pentru parcurgerea invers a listelor se utilizeaz clasa reverse_iterator care este tot o clas
intern a clasei list. Un obiect de tipul acestei clase se definete ca
list<tip>::reverse_iterator nume_obiect;
Operatorii implementai de clasa iterator sunt ++, -- i *. Clasa list definete funciile
rbegin();
rend();
100
ce au ca rezultat un iterator pentru parcurgerea n sens invers a listei ce indic ultimul element
al listei i respectiv primul element al listei.
Sortarea listelor
Pentru sortarea n ordine direct i invers a listelor clasa list definete funciile
void sort();
void reverse();
ce sortez elementele listei n ordine direct i invers.
Problema 3. Vom crea o list cu elemente ntregi, o vom sorta ascendent i descendent i
vom afia elementele listei. Programul este urmtorul.
# include <iostream>
# include <list>
using namespace std;
int main()
{
list <int> ls;
// adauga elemente la sfarsitul i inceputul listei
ls.push_back(11);
ls.push_back(7);
ls.push_front(4);
ls.push_front(12);
// parcurgerea listei
cout << "lista initiala\n";
list<int>::iterator iter;
for(iter = ls.begin(); iter != ls.end(); iter++)
cout << *iter << endl;
// sortarea elementelor listei n ordine crescatoare
ls.sort();
// parcurgerea listei sortate
cout << "lista sortata\n";
for(iter = ls.begin(); iter != ls.end(); iter++)
cout << *iter << endl;
// sortarea elementelor liste n ordine descrescatoare
ls.reverse();
// parcurgerea listei sortate
cout << "lista sortata n ordine inversa\n";
for(iter = ls.begin(); iter != ls.end(); iter++)
cout << *iter << endl;
// parcurgerea listei
cout << "parcurgerea listei n ordine inversa\n";
list<int>::reverse_iterator iter1;
for(iter1 = ls.rbegin(); iter1 != ls.rend(); iter1++)
cout << *iter1 << endl;
return 0;
}
Rezultatele rulrii programului sunt cele de mai jos.
101
102
T abs(complex<T>&);
d valoarea absolut (norma) a numrului complex
T norm(complex<T>&);
d ptratul valoarii absolute (normei) a numrului complex
s +1
s + 3s + 2
2
103