Sunteți pe pagina 1din 34

CURS 6

Tablouri

CUPRINS
1.
2.
3.
4.
5.
6.
7.
8.
9.

10.

Noiuni introductive
Tablouri unidimensionale
Tablouri multidimensionale
Elemente de tablou
Iniializarea tablourilor la declarare
Prelucrarea tuturor elementelor unui tablou
Transmiterea tablourilor ctre funcii
Cutarea n tablouri
Inserarea n tablouri
tergerea din tablouri
2

1. NOIUNI INTRODUCTIVE

Tinand cont de imporanta noiunii de tablou n


domeniul ingineresc relum i detaliem unele aspecte
referitoare la tablouri.
Un tablou este o list de elemente de acelai tip
plasate succesiv ntr-o zon contigu de memorie
Orice tablou are un nume (care este un pointer
constant ctre primul element din tablou)
Tipul elementelor tabloului reprezint tipul tabloului
respectiv
3

2. TABLOURI UNIDIMENSIONALE

Declaraia tabloului:
tip nume_tablou[dimensiune];
tip este un tip de dat (predefinit sau definit de
utilizator)
nume_tablou este un identificator C/C++
dimensiune este o expresie constant ntreag i pozitiv
ce specific numrul de elemente din tablou

TABLOURI UNIDIMENSIONALE

Pentru referirea unui element se folosete


operatorul de indexare [ ], preciznd numele
tabloului i poziia elementului n tablou (indexul
sau indicele):
nume_tablou[index]

Indexul este, n general, o expresie ntreag i


pozitiv
primul element are indexul 0
ultimul are indexul (dimensiune-1)

TABLOURI UNIDIMENSIONALE

Pe baza numrului de elemente i a tipului,


compilatorul determin dimensiunea zonei de memorie
care se aloc tabloului, dup relaia:
dimens_memorie = sizeof(tip) * dimensiune

Exemplu:
int tab[100];
primul element:
ultimul element:
un element oarecare , i+1:
dimensiunea tabloului este:

tab[0]
tab[99]
tab[i]
sizeof(int)*100 = 2(4)00
6

TABLOURI UNIDIMENSIONALE

Dup alocarea memoriei necesare, la compilarea


restului programului sau la execuie, nu se mai fac
verificri de domeniu la indici
de exemplu o referire de genul tab[200] nu va fi
semnalat ca eroare ns va genera surprize la execuie
acest lucru impune o mai mare atenie din partea
programatorului

TABLOURI UNIDIMENSIONALE

Observaii:
Dimensiunea specificat la declarare poate fi o
expresie constant ntreag:
const int SIZE = 10;
int score[SIZE/2];
2. Nu se admite ca dimensiune o expresie n care
intervin variabile:
int size;
cout << Dati numarul de studenti: ";
cin >> size;
int score[size];
// incorect !!!
3. Declaraiile de tablouri pot fi intercalate cu alte
variabile simple de acelai tip:
int i, score[5], x, y, z;
1.

3. TABLOURI MULTIDIMENSIONALE

Declaraie:
tip nume_tablou[dimens1][dimens2]...[dimensN];
dac n=1, tabloul se numete uni-dimensional (vector,
dar e impropriu ca noiune): int tab[100];
dac n=2, tabloul se numete matrice:
float tab[10][5];
n general pentru un n oarecare, tablou n-dimensional

Mediile de programare pot impune restricii legate de


numrul maxim de dimensiuni admise pentru un
tablou multidimensional, limbajul C/C++ nu impune
9
ns o limitare

TABLOURI MULTIDIMENSIONALE

Un tablou cu mai multe dimensiuni este de fapt un


tablou unidimensional avnd ca elemente alte tablouri
Exemplu: int tab[2][3];
este un tablou cu 2 elemente iar fiecare element este
un tablou 3 de numere ntregi

Organizarea logic:
Col

tab[0][0]

tab[0][1]

tab[0][2]

tab[1][0]

tab[1][1]

tab[1][2]

Linie

10

TABLOURI MULTIDIMENSIONALE

Organizarea n memorie:
Referirea unui element se face astfel:

nume_tablou[index1][index2]...[indexN]

tab[0][0]

tab[0][1]

tab[0][2]

tab[1][0]

tab[1][1]

tab[1][2]

11

4. ELEMENTE DE TABLOU

Un element de tablou poate apare oriunde poate s


apar o variabil simpl cu acelai tip:

atribuiri:
tab[i] = 23;
citiri de la consol:
cin >> tab[i];
scanf(%d, &tab[i]);
afiri:
cout << tab[i];
printf(%d, tab[i]);
calcule:
sum += tab[i];
apeluri de funcii:
Celsius = F_to_C(tab[0]);

12

5. INIIALIZAREA TABLOURILOR LA DECLARARE


Dac nu sunt iniializate explicit, tablourile locale (ca
i variabilele simple), vor conine valori nedefinite la
nceperea execuiei
Iniializarea se poate face la declarare, prin utilizarea
unei liste de valori separate prin virgul i delimitat
de acolade

13

INIIALIZAREA TABLOURILOR

Tablouri unidimensionale:
tip nume_tablou[dimensiune] = {ec0, ..., ecN-1};
dac dimensiunea lipsete numrul expresiilor constante
d dimensiunea tabloului
elementele care nu se iniializeaz explicit sunt automat
iniializate cu 0 (la tablourile globale)
n cazul irurilor de caractere acoladele pot lipsi

Exemple:

int tab[ ] = {1,3,5,7,9,11};


float tab[5] = {0,1,2};
char tab[ ] = "abcd";//4 elemente si \0
char aa[] ={'a','b','c','d,\0'};//dim. 5 explicit \0
char bb[5] ={'a','b','c','d'};//dim. maxim 5 explicit
specificata

14

INIIALIZAREA TABLOURILOR

Tablouri multidimensionale:
tip nume[n][m]= {
{ec11,...,ec1m},
{ec21,...,ec2m},...,
{ecn1,...,ecnm}
};
unde: n, m, ecij, sunt expresii constante (indicii de la 0 la
n-1, respectiv de la 0 la m-1)
acoladele interioare nu sunt obligatorii, dar ele specific
modul de iniializare pe linii
Exemplu:
int tab[3][2] = { {10,11},
{12,13},
15
{14,15} };

6. PRELUCRAREA ELEMENTELOR UNUI TABLOU

Se utilizeaz cel mai frecvent instruciunea ciclic for


pentru a prelucra secvenial toate elementele:
variabila de ciclare este folosit ca i index n tablou
iar o alt variabil sau constant simbolic ce
conine dimensiunea tabloului se folosete n
condiia asociat instruciunii ciclice

16

PRELUCRAREA ELEMENTELOR UNUI TABLOU

Tablouri unidimensionale
for (int i=0; i<arraySize; i++)
cin >> temperature[i];
for (int i=0; i<arraySize; i++)
cout << temperature[i] << endl;
int sum=0;
for (int i=0; i<arraySize; i++)
sum += temperature[i];
OBS: Toate operatiile (i ultimele dou) puteau fi
realizate n acelai ciclu pentru a mbunti
performana

17

PRELUCRAREA ELEMENTELOR UNUI TABLOU

Tablouri bidimensionale

int numArr[10][10];

for (int row = 0; row < 10; row++)


for (int col = 0; col < 10; col++)
{
cout << "Enter a value for Arr[ " << row << , " << col << ]: ";
cin >> numArr[row][col];
}
for (int row = 0; row < 10; row++)
{
for (int col = 0; col < 10; col++)
cout << numArr[row][col];
cout << endl;
}

18

PRELUCRAREA ELEMENTELOR UNUI TABLOU

Exemplu tablouri bidimensionale: suma elementelor de


pe diagonala principal
int arr[10][10];

int sum = 0;
for (int row = 0; row < 10; row++)
for (int col = 0; col < 10; col++)
if (row == col)
sum += arr[row][col];

cout << Suma elementelor de pe diagonala principala


este: " << sum << endl;
19

7. TRANSMITEREA TABLOURILOR CTRE


FUNCII

Un tablou poate fi transmis ca parametru unei funcii. n


acest caz:

Parametrul formal e declarat ca i un tablou de acelai


tip i dimensiune cu tabloul folosit ca argument, sau

Parametrul formal e declarat ca i un tablou de la care


poate lipsi prima dimensiune (stnga), sau

Parametrul formal e un pointer ctre tipul tabloului.

In toate cazurile, la apel ca argument se d doar


adresa tabloului
20

La tablourile unidimensionale se poate considera


ca parametru un tablou fr dimensiune. Uzual,
n acest caz, se mai transmite i un ntreg ce
poate fi:
dimensiunea tabloului
numrul de elemente din tablou ce se prelucreaz

In acest mod, funcia respectiv poate fi apelat


pentru orice tablou ce are acelai tip precizat n
prototipul funciei

21

TRANSMITEREA TABLOURILOR CTRE FUNCII


// prototip
void read_data(int score[ ], int size);
// definitie
void read_data(int score[ ], int size)
{
for (int i=0; i<size; i++)
cin >> score[i];
}
// apel
int tab1[120], tab2[110];
read_data(tab1,120);
read_data(tab2,110);

22

TRANSMITEREA TABLOURILOR CTRE FUNCII

Primul parametru la apel se mai numete i


parametru tablou (adresa primului element din tablou)
Un astfel de parametru este o form de apel prin
adresa n care se comunic funciei aproape totul
despre tablou (cu excepia dimensiunii)
Pe baza acesteia i a indexului unui element se poate
calcula adresa oricrui element din tablou

La apelul prin adresa, orice modificare, n funcie, a


elementelor unui tablou transmis ca si parametru, se
reflect asupra tabloului iniial
23

TRANSMITEREA TABLOURILOR CTRE FUNCII

Dac se folosete modificatorul const pentru tablou


atunci nu se mai pot face modificri asupra
elementelor tabloului:
void displayArray ( const int arr [ ], int MAXSIZE );

n cazul tablourilor multidimensionale, prima


dimensiune, (cea din stnga) poate lipsi datorit
mecanismului de alocare a tablourilor n memorie n C:
void display(char p[ ][100], int size)

24

TRANSMITEREA TABLOURILOR CTRE FUNCII


const int SIZE=5;
double calcAvg (double numbers[ ], int max); // prototip
void printArray(double[ ], int); // prototip
void main( ) {
double temps[SIZE];
int index;
double avg;
cout << "Enter " << SIZE << " temperatures\n";
for (index=0; index< SIZE; index++)
cin >> temps[index];
avg = calcAvg(temps, SIZE); // apel functie
cout << "The average is: " << avg << endl;
printArray(temps, SIZE); //apel funcie
}

25

TRANSMITEREA TABLOURILOR CTRE FUNCII


//implementarea functiei calcAvg
double calcAvg (double numbers[ ], int count)
{
double sum=0;
for (int i=0; i<count; i++)
sum += numbers[i];
return sum/count;
}
//implementarea functiei printArray
void printArray(double numbers[ ], int count)
{
for (int i=0; i<count; i++)
cout << numbers[i] << endl;
}
26

7. CUTAREA N TABLOURI
Este o operaie foarte frecvent
De obicei se caut poziia unui element cu o anumit
valoare
Dac tabloul nu este sortat se aplic cutarea
liniar:

care const n parcurgerea secvenial a elementelor


tabloului i compararea acestora cu valoarea de cutat
dac este gsit un element ce are acea valoare, se
returneaz indicele elementului, altfel se returneaz
valoarea -1
acest algoritm permite gsirea primului element ce are o
anumit valoare ns pot fi mai multe elemente cu
aceeai valoare

27

CUTAREA N TABLOURI
int linear_search(int arr[ ], int n, int val)
{
int pos;
for(pos = 0; pos < n; pos++)
if (arr[pos] == val)
return pos;
return -1;
}

Aceast metod este suficient de bun pentru tablouri


mici (sute de elemente)
Pentru tablouri mari este necesar o operaie
prealabil de sortare dup care se pot folosi ali
algoritmi ce permit reducerea numrului de
comparaii

28

CUTAREA N TABLOURI

Cutarea binar:
tabloul se consider sortat
se verific dac elementul din mijloc are valoarea
cutat
dac da, se returneaz poziia acestuia
dac nu, se restrnge cutarea la una din cele dou
jumti (stnga sau dreapta)
se continu n acest mod pn la gsirea unui
element sau pn cnd intervalul de cutare devine
nul

29

CUTAREA N TABLOURI
// se presupune ca tabloul este sortat crescator
int binarySearch(int arr[ ], int size, int target){
int middlePosition, middleValue;
int low = 0, high = size - 1;
while (low <= high)
{
middlePosition = (low + high) / 2;
middleValue = arr[middlePosition];
if (target == middleValue)
return middlePosition;
else if (target < middleValue)
high = middlePosition - 1;
else
low = middlePosition + 1;
}
return -1;
}

30

8. INSERAREA N TABLOURI

In cazul tablourilor nesortate, pentru a insera


elemente noi ntr-un tablou trebuie s inem cont de
urmtoarele:
trebuie s existe poziii libere n tablou;
pentru elementul nou se creaz loc prin deplasarea altor
elemente, de obicei spre dreapta

In cazul tablourilor sortate trebuie gsit mai nti


poziia n care se va face inserarea astfel nct dup
inserare tabloul s rmn sortat

31

INSERAREA N TABLOURI

Tablouri nesortate

void insert_at(int arr[ ], int n, int idx, int val)


{
if (idx == -1)
arr[n] = val; // adaugare
else
{
// deplasare dreapta
for(int i = n; i > idx; i)
arr[i] = arr[i-1];
// inserare valoare noua
arr[idx] = val;
}
}

32

INSERAREA N TABLOURI

Tablouri sortate
void insertElement ( int arr [ ], int &size, int newElement )
{
int insertPosition, k;
// cautare pozitie inserare
insertPosition = -1;
do
insertPosition++;
while ( newElement > arr[insertPosition] && insertPosition !=
size - 1 );

if ( newElement <= arr[insertPosition] ) {


// deplasare dreapta
for ( k = size - 1; k >= insertPosition; k-- )
arr[k+1] = arr[k];
// inserare
arr[insertPosition] = newElement;
}
else
arr[size] = newElement; // adaugare
size++;//se va vedea si in exterior

33

9. TERGEREA DIN TABLOURI


Ca i inserarea, tergerea presupune deplasarea unor
elemente, de obicei spre stnga
Se presupune c se cunoate poziia n care se face
tergere (dac nu se face cutarea elementului de
tablou cu o anumit valoare)

void deleteElement ( int arr [ ], int &size, int position )


//size is reference to have the modified value outside
{
int k;

if ( position >= size )


cout << "Eroare ! Index incorect. ";
else
{
// deplasare stanga
for ( k = position; k < size - 1; k++ )
arr[k] = arr[k+1];
--size;
}

34

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