Tablouri
Tablouri unidimensionale
Definitie:
Tabloul este o colectie
finita de elemente de acelasi tip, numit tip
de baza al tabloului, care ocupa un spatiu
continuu de memorie.
Sintaxa
declaratiei:
| tip_de_baza nume_tablou[dimensiune]={const0,const1,...}; |
dimensiune - este o expresie intreaga
constanta, precizand numarul de elemente ale tabloului ( se precizeaza
de obicei printr-o constanta simbolica ).
Memoria ocupata de tablou este: dimensiune*sizeof(tip_de_baza)
Tabloul poate fi initializat
la definire, parte optionala marcata,
prin precizarea constantelor de initializare. Daca numarul acestora:
-
=dimensiune - elementele tabloului se initializeaza
cu constantele precizate
-
<dimensiune - constantele neprecizate
sunt implicit 0
-
>dimensiune - apare eroare in compilare.
Daca este prezenta partea de initializare, dar lipseste
dimensiune,
aceasta este implicit numarul constantelor.
Exemple:
int tab[10]; // defineste un tablou de 10
elemente intregi, care ocupa 20 octeti
#define N 10
int tab[N]; // definitie echivalenta cu cea
de mai sus
#define NR_ELEM 5
float t[NR_ELEM]={1.2,5,3}; //primele trei
elemente se initializeaza cu constantele precizate,
//urmatoarele doua cu 0
double a[]={2,5.9}; //tabloul a este de dimensiune
2
Selectarea
unui element de tablou:
| nume_tablou[indice]//se foloseste operatorul
de indexare [] |
indice - expresie intreaga cu
valori intre 0 si dimensiune -1
Un element de tablou poate fi prelucrat ca orice variabila avand tipul
de baza.
Observatii:
-
Nici compilatorul, nici mediul de executie nu verifica valorile indicilor;
programatorul trebuie sa codifice astfel incat expresiile indice sa ia
valori in intervalul 0 .. dimensiune -1; altfel pot apare erori
imprevizibile, cum ar fi modificarea nedorita a altor variabile:
#define N 10
int tab[N];
tab[N]=5; //se modifica zona de
2 o urmatoare tabloului
tab[-10]=6; //se modifica o zona de 2 o situata
la o adresa cu 20 o
/inferioara celei a tabloului |
-
Pentru a realiza o prelucrare asupra tuturor elementelor
tabloului se foloseste instructiunea for cu o variabila contor
care sa ia toate valorile indicilor ( intre 0 si dimensiune
-1 );
#define N 10
int tab[N],i;
for(i=0;i<N;i++)
*prelucrare tab[i] |
-
Copierea unui tablou in altul se face prin copiere
fiecarui element ( vezi programul urmator, functia copiere );
-
Se poate ca nu toate elementele tabloului sa fie
prelucrate, ci doar primele nr_elem<=dimensiune ( vezi programul
urmator, se pot citi doar primele nr_elem ).
Exemplu:
1. Se considera un tablou de N elemente intregi ( N este constanta
predefinita ). Sa se prelucreze tabloul astfel:
-
sa se citeasca cele N elemente de la tastatura ( varianta: pana la CTRL/Z
- se decomenteaza linia comentata din functia citire si se comenteaza cea
anterioara )
-
sa se afiseze elementele
-
sa se afiseze maximul si media aritmetica pentru elementele tabloului
-
sa se caute in tablou o valoare citita de la tastatura
-
sa se construiasca un tablou copie al celui dat
-
sa se afiseze elementele tabloului copie in ordinea inversa.
#include <stdio.h>
#include <conio.h>
#define N 8
int tablou[N], copie[N], nr_elem; /* tablou va contine nr_elem
de prelucrat */
void citire(void); //prototipuri
void tiparire(void);
void tip_inv(void);
void copiere(void);
void info(void);
void cautare(void);
void main(void){
clrscr();
citire();
tiparire();
info();
cautare();
copiere();
tip_inv();
getch();
} //main
//definitiile functiilor
void citire(void){
int i;
puts("Introduceti elementele tabloului:");
for(i=0;i<N;i++){
printf("elem[%d]=",i); /* se afiseaza indicele
elem ce se citeste */
scanf("%d",&tablou[i]);
//if(scanf("%d",&tablou[i])==EOF)break;
}//for
nr_elem=i;
} //citire
void tiparire(void){
int i;
puts("Elementele tabloului:");
for(i=0;i<nr_elem;i++)
printf("elem[%d]=%d\n",i,tablou[i]);
} //tiparire
void tip_inv(void){
int i;
puts("Elementele tabloului copie in ordine inversa:");
for(i=nr_elem-1;i>=0;i--)
printf("copie[%d]=%d\n",i,copie[i]);
} //tip_inv
void copiere(void){ //copierea se face prin cea a fiecarui
element
int i;
for(i=0;i<nr_elem;i++)
copie[i]=tablou[i];
} //copiere
void info(void){
int i,max,suma; float meda;
for(i=suma=0,max=tablou[0];i<nr_elem;i++){
suma+=tablou[i];
if(tablou[i]>max)max=tablou[i];
}
printf("*** val maxima=%d, media aritm=%f\n",max,(float)suma/nr_elem);
} //info
void cautare(void){
int i,de_cautat;
printf("Se cauta:"); scanf("%d",&de_cautat);
for(i=0;i<nr_elem;i++)
if(de_cautat==tablou[i])break;
//cele doua linii de mai sus se pot scrie echivalent:
// for(i=0;i<nr_elem && de_cautat!=tablou[i];i++)
if(i<nr_elem)
printf("*** s-a gasit la indicele %d\n",i);
else
puts("*** nu s-a gasit");
} //cautare |

Tablouri multidimensionale
Definirea
unui tablou multidimensional:
tip_de_baza nume_tablou[dim1][dim2]...[dimn]={{const10,...},{const20,...},
...,{constn0,...}}; |
dim1,dim2,...,dimn - expresii intregi
constante ( de obicei constante simbolice ).
Memoria continua ocupata de tablou este de dimensiune:
dim1*dim2*...*dimn*sizeof(tip_de_baza).
Elementele tabloului multidensional sunt memorate
astfel incat ultimul indice variaza cel mai rapid.
Tabloul poate fi initializat
la definire, parte optionala marcata,
prin precizarea constantelor de initializare.
Tablourile bidimensionale se numesc matrici,
prima
dimensiune reprezentand numarul de linii, iar a doua, de coloane.
Exemple:
int m[10][5]; // defineste un tablou dimensional
de elemente intregi, cu 10 linii si 5 coloane, care ocupa 10*5*2=100 octeti
#define NL 10
#define NC 5
int m[NL][NC]; // definitie echivalenta cu
cea de mai sus
double a[3][2]={{2},{5.9,1},{-9}}; //elementele
pe linii sunt: 2 0 5.9 1 -9 0
double a[3][2]={2,5.9,1,-9}; //elementele
pe linii sunt: 2 5.9 1 -9 0 0
Selectarea
unui element de tablou:
| nume_tablou[ind1][ind2]...[indn] |
ind1,ind2,...,indn - expresii
intregi cu valori intre 0 si dimi-1, i=1..n
Un element de tablou poate fi prelucrat ca orice variabila avand tipul
de baza.
Exemplu:
Sa se scrie un program care realizeaza urmatoarele prelucrari asupra
unei matrici patratice M de ordin N ( constanta simbolica ), avand elemente
intregi, fiecare prelucrare fiind realizata de cate o functie void fara
parametri:
-
citeste - elementele matricii pe coloane
-
afiseaza - elementele matricii pe linii
-
modifica - aduna la fiecare element al matricii suma indicilor
elementului respectiv; se afiseaza apoi matricea modificata prin apelul
functiei de mai sus
-
verif_sim - verifica daca matricea este simetrica, afisand un
mesaj corespunzator
-
det_linia - determina linia din matrice care are produsul elementelor
maxim, afisand indicele liniei si produsul
-
calc_sume - calculeaza si afiseaza patru sume: a elementelor aflate
pe diagonala principala, a celor de pe diagonala secundara, a celor aflate
deasupra diagonalei principale si a elementelor aflate pe "marginile" matricii
-
transpusa - construieste si afiseaza transpusa matricii M.
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#define N 10
char optiune;
int n,matrice[N][N];
void citire(void){
int i,j;
do{ //citire cu validare a ordinului matricii
printf("\nIntroduceti nr de linii si coloane:(1..%d)",N);
scanf("%d",&n);
}while(n<=0||n>N);
for (j=0;j<n;j++)
for (i=0;i<n;i++){
printf("elem[%d][%d]:",i,j);
scanf("%d",&matrice[i][j]);
}
}
void afisare(void){
int i,j;
puts("Matricea:");
for (i=0;i<n;i++){
for (j=0;j<n;j++)
printf("%d\t",matrice[i][j]);
putchar('\n');
}
}
void modifica(void){
int i,j;
afisare();
for (i=0;i<n;i++)
for (j=0;j<n;j++)
matrice[i][j]+=i+j;
puts("Dupa modificare:");
afisare();
}
void verif_sim(void){
int i,j;
for (i=0;i<n;i++) // se compara fiecare elem de deasupra
for (j=i+1;j<n;j++)// diag cu simetricul
sau
if (matrice[i][j]!=matrice[j][i]){
puts("Matricea
nu este simetrica");
return;
}
puts("Matricea este simetrica");
}
void linia_max(void){
int i,j,linia;long produsmax,produs;
for (i=0;i<n;i++){
for (produs=1,j=0;j<n;j++) // calcul produs
linia i
produs*=matrice[i][j];
if(i==0){
produsmax=produs;
linia=0;
}
else if (produs>produsmax){
produsmax=produs;
linia=i;
}
} // for i
printf("Produsul maxim este %ld,se afla pe linia d;", produsmax,linia);
}
void calc_sume(void){
int i,j,diagprinc=0,diagsec=0,deasupradiagprinc=0,margine=0;
for (i=0;i<n;i++){
diagprinc+=matrice[i][i];
diagsec=diagsec+matrice[i][n-1-i];
margine+=matrice[i][0];
margine+=matrice[i][n-1];
for > optiune=getche();
putchar('\n');
}
void main(void)
{
n=0;
do{
clrscr();
citire_optiune();
switch(toupper(optiune)){
case 'I':citire();break;
case 'A':afisare();break;
case 'M':modifica();break;
case 'V':verif_sim();break;
case 'L':linia_max();break;
case 'C':calc_sume();break;
case 'T':transpusa();break;
case 'X':puts("La revedere!");break;
default:puts("*** Optiune eronata ***\n");
}
getch();
}while(toupper(optiune)!='X');
}
|

martie 2000