2. La finalul acestei uniti de 樽nvare vei fi capabili s :
identificai diferite tipuri de variabile structurate
efectuai diferite operaii asupra vectorilor
alegei tipul potrivit de variabile pentru rezolvarea problemelor
3. Tipuri simple vs. Tipuri derivate (structurate)
Tipurile de date utilizate p但n acum sunt tipuri simple.
Pe baza tipurilor simple de date se pot contstrui tipuri derivate :
tablouri, structuri, fiiere
4. Tablouri
Un tablou (array) este un ansamblu de variabile de acelai tip la care se face referire folosindu-se
un acelai nume.
Un anume element dintr-un tablou este indicat prin intermediul unui indice (index).
n C, toate tablourile sunt alctuite din loca釘ii de memorie 樽nvecinate. Adresa de memorie cea mai
mic corespunde primului element, iar adresa cea mai mare corespunde ultimului element.
Tablourile pot avea de la una la mai multe dimensiuni.
Tabloul cel mai des folosit 樽n C este irul string, care este un tablou de caractere care se 樽ncheie
cu un zero. Acest mod de a privi irurile confer limbajului C mai mult putere i eficien釘 fa釘 de
altelimbaje.
5. Tablouri unidimensionale Definiie i Declarare
n C, tablourile unidimensionale sunt alctuite dintr-un grup de elemente de acelai tip
(numit tip de baz) i referite printr-un nume comun.
Variabilele de tip tablou se definesc astfel:
tip_de_baza nume_var[dimensiune];
unde tip_de_baza reprezint tipul tabloului, adic al fiecrui element inclus 樽n tablou, iar
dimensiune definete numrul de elemente con釘inute 樽n tablou.
Un element al tabloului este accesat folosind ca index pozi釘ia elementului, astfel
tabloul_meu[6] va referi al aptelea element al tabloului tabloul_meu.
6. ATENIE!
n C, "numerotarea" elementelor tablourilor 樽ncepe cu pozi釘ia 0, astfel, dac avem
defini釘ia:
int tabloul_meu[100];
primul element al tabloului va fi tabloul_meu[0], iar ultimul tabloul_meu[99].
Tablourile sunt stocate 樽n memorie la loca釘ii consecutive, un tablou ocup但nd o zon
contigu de memorie, cu primul element al tabloului aflat la adresa mai mica.
7. ATENIE!
O problem legat de tablouri este c 樽n C nu se face nici o verificare legat de
"marginile" tabloului, astfel c se pot accesa greit elemente din afara tabloului. De
exemplu, pentru defin釘ia:
int tabloul_meu[100];
dac accesm tabloul_meu[105] nu se va semnala nici o eroare, return但ndu-se
valoarea de la o loca釘ie de memorie aflat la o distan釘 de 5 loca釘ii fa釘 de sf但ritul
tabloului, fapt ce va duce la comportri "bizare" ale programului. Aceeai situa釘e, dar fa釘
de 樽nceputul tabloului, se 樽nt但mpl la accesarea tabloul_meu[-5].
Este datoria programatorului s evite astfel de situaii !!!
8. EXEMPLE
char s[100];
int x[25];
Observa釘ii:
- primul element dintr-un vector va avea indexul 0, iar ultimul element stocat va avea indexul dim-1
- dimensiunile tabloului trebuie s fie expresii constante
- compilatorul nu face verificri pentru depirea dimensiunii tabloului
- pentru alocarea unui tablou sunt necesari nr_elemente*sizeof(tip) octe釘i, unde tip este tipul de baz
al tabloului
- atribuirea tablourilor nu poate fi fcut direct
Exemplu :
int x[10],
y[10];
x = y; /*opera釘ie ilegal*/
9. Iniializarea tablourilor
Declara釘ia unui tablou poate fi urmat de o secven釘 de ini釘ializare format din una sau mai multe perechi de acolade 樽ntre
care se pun valori ale tipului de baz, separate prin virgul.
Pentru tablourile unidimensionale este permis omiterea numrului de elemente. El va fi egal cu numrul de valori folosite
la ini釘ializare.
n cazul 樽n care la ini釘ializarea tablourilor de tip numeric sunt folosite mai pu釘ine elemente dec但t dimensiunea
tabloului, restul elementelor sunt ini釘ializate cu 0.
Exemple:
float x[5]={1.2,3.4e3,-2,90.7E-8,-88.5e-7};
char s[100]=test tablou;
short y[]={0,1,2,3,4}; /* y are 5 elemente */
char s[]={t,e,s,t,0}; /* char s[]=test; */
int x[5]={1,2}; /* x=(1, 2, 0, 0, 0) */
10. Prelucrri elementare 樽n vectori
Deoarece limbajul C nu verific depirea 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 numrului de elemente) citite de la intrare. Uzual, un vector se
declar 樽n urmtoarea 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 urmtoarea:
do{
cout << n = ;
cin >> n;
if(n <= 0 || n > MAX) printf(dimensiune incorectan);
}while(n <= 0 || n > MAX);
11. Citirea elementelor unui vector
Dup validarea dimensiunii, citirea elementelor unui vector se face 樽n ordinea cresctoare a indicilor, uzual cu o instruc釘iune for :
for(int i = 0; i < n; i++)
{
cout << a[ << i << ]=;
cin >> a[i];
}
Observa釘ie: Dei 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] rm但n但nd liber. n aceast situa釘ie secven釘a de citire (i toate celelalte secven釘e de prelucrare) se vor
modifica corespunztor, conform modelului de mai jos:
for(int i = 1;i <= n; i++)
{
cout << a[ << i << ]=;
cin >> a[i];
}
12. Determinarea elementului minim / maxim
Metoda tipic de determinare a elementului minim/maxim dintr-un vector este
urmtoarea : 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]; */
13. 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 gsim primul element cu
proprietatea cerut sau p但n c但nd epuizm 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; }
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).
14. 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 descresctoare a indicilor)
p但n c但nd gsim primul element cu proprietatea cerut sau p但n c但nd epuizm
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; }
15. Eliminarea tuturor elementelor care au o anumit
proprietate
Cea mai simpl metod de a elimina dintr-un vector toate elementele cu o anumit
proprietate este s crem un nou vector 樽n care se pstreaz 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]; /* pstram elementul 樽n vectorul b */
n = j; /* actualizm dimensiunea vectorului */
16. Eliminarea tuturor elementelor care au o anumit
proprietate
Metoda este ineficient datorit consumului de memorie necesar pentru vectorul b. O
metod mult mai eficient este s folosim acelai vector 樽n care vom 樽ngrmdi pe
primele pozi釘ii elementele care trebuie pstrate. Prin actualizarea dimensiunii
vectorului, elementele de prisos nu vor mai fi luate 樽n considera釘ie 樽n prelucrrile
ulterioare. Secven釘a care realizeaz aceast opera釘ie este urmtoarea:
j = -1;
for(i
= 0; i < n; i++)
if(a[i] >= 0) /* nu are proprietatea cerut */
a[++j] = a[i]; /* mutm elementul la 樽nceputul
vectorului */
n = j; /* actualizm dimensiunea vectorului */
17. 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 rm但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 rmas
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]; /* deplasm elementele spre st但nga */
n--; /* corectm dimensiunea */
18. Inserarea unui element y 樽n pozi釘ia k dat (1<=k<=n)
Cum inserarea unui element se face fr 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 crete cu o unitate:
for(j=n;j>=k;j--)
a[j]=a[j-1]; /* deplasm elementele spre dreapta */
a[k-1]=y; /* inserm elementul y */
n++; /* actualizm dimensiunea */
19. PROBLEME PROPUSE
1. Se consider n numere 樽ntregi re釘inute 樽ntr-un vector v. (1<n<=50). S se determine celmai mic numr
pozitiv din vector i cel mai mare numr negativ con釘inut de vector. n cazul樽n care una din valori nu
poate fi determinat, s se dea un mesaj corespunztor.
Exemplu: n=8; v={4, -7, 9, 8, -3, 2, 10, -5}, atunci min_poz=2, max_neg=-3
2. Se citete un ir de numere 樽ntregi p但n la introducerea valorii zero. S se formeze doi vectori: unul cu
numerele pare introduse, iar cellalt cu cele impare. S se afieze con釘inuturile celor doi vectori.
Exemplu: numerele introduse sunt: 7, -5, 8, 1, 2, -6, 3, 0
cei doi vectori vor fi: a[0]=8, a[1]=2, a[2]=-6;
b[0]=7, b[1]=-5], b[2]=1, b[3]=3
3. Se citete un numr natural de maxim 10 cifre. S se introduc cifrele numrului 樽ntr-un vector.
Exemplu: dac n= 725943 atunci v[0]=3, v[1]=4, v[2]=9, v[3]=5, v[4]=5, v[5]=2 i v[6]=7.