|
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:
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 - vezi partea 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 egala implici cu 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, dimensiunea fiind data de numarul constantelor
de initializare
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 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 multidimensional sunt memorate astfel incat ultimul indice variaza
cel mai rapid.
Tabloul
poate fi initializat la definire - vezi 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 (j=i+1;j<n;j++)
deasupradiagprinc+=matrice[i][j];
}
for (j=1;j<n-1;j++){
margine+=matrice[0][j];
margine+=matrice[n-1][j];
}
afisare();
printf("\nSuma elementelor de pe diagonala principala este %d;",diagprinc);
printf("\nSuma elementelor de pe diagonala secundara este %d;",diagsec);
printf("\nSuma elementelor de deasupra diag principale %d;",deasupradiagprinc);
printf("\nSuma elementelor de pe marginea matricii %d;",margine);
}
void
transpusa(void){
int i,j,transp[N][N];
for (i=0;i<n;i++)
for (j=0;j<n;j++)
transp[j][i]=matrice[i][j];
afisare();
printf("\nMatricea transpusa este:\n");
for (i=0;i<n;i++){
for (j=0;j<n;j++)
printf("%d\t",transp[i][j]);
putchar('\n');
}
}
void
citire_optiune(void)
{
clrscr();
putchar('\n');
puts("[I]ntroducere
matrice;");
puts("[A]fisare
matrice;");
puts("[M]odifica
matricea adunand indicii la element;");
puts("[V]erifica
daca matricea este simetrica;");
puts("[L]inia
din matrice care are produsul elem max;");
puts("[C]alculeaza
diferite sume;");
puts("[T]ranspusa
matricii;");
puts("E[x]it;\n");
puts("Optiunea
dvs.:");
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');
}
|

Quiz
|
Iata cateva autoteste prin
care sa verificati intelegerea notiunilor de mai sus. Programele
exemplu au fost deja rulate, nu?
1.Se
defineste un tablou de 5 elemente de tip float:
int
nr=5;
float
tablou_reali[nr];
2.Se
defineste un tablou de 4 elemente intregi:
int
tablou_intregi[]={3,2,8,6};
3.Se
initializeaza elementele tabloului tab cu patratele indicilor:
#define
DIM 10
int
i, tab[DIM];
for(i=0;i<=DIM;i++)
tab[i]=i*i;
4.Se
defineste matricea matr cu L linii si C coloane, avand elemente intregi:
#define
L 5
#define
C 7
int
matr[L][C];
5.Se
tiparesc elementele matricii de mai sus pe coloane:
int
i,j;
for(j=0;j<C;j++){
for(i=0;i<L;i++)
printf("%d
",matr[i][j]);
putchar('\n');
}
Exercitii
|
1.Sa
se ruleze programul exemplu. Sa se adauge prelucrarile:
-modificarea
elementelor tabloului initial la patratul lor
-afisarea
tabloului dupa modificare.
Sa
se tranforme programul intr-unul interactiv, fiecare prelucrare executandu-se
la o comanda corespunzatoare ( citirea la comanda 'C' sau 'c', s.a.m.d.
). Vezi instructiunea switchsi
rezolvarea problemei urmatoare.
2.Sa
se scrie un program interactiv care prelucreaza un tablou de max N intregi
( N - constanta predefinita ), prin urmatoarele comenzi - optiunile marcate
cu ? trebuie
adaugate:
I - initializeaza tabloul, prin citirea dimensiunii sale si apoi a elementelor
V ? initializeaza
tabloul, prin citirea elementelor pana la introducerea lui CTRL/Z sau a
numarului maxim de elemente
A ? initializeaza
tabloul, fiecare element fiind egal cu indicele sau
B ? initializeaza
tabloul astfel: primele doua elemente cu 0, 1, iar urmatoarele ca suma
anterioarelor doua (numerele Fibonacci)
L - listeaza elementele tabloului
O - listeaza elementele tabloului ordonate crescator ( in tablou elementele
trebuie sa ramana in ordinea introducerii )
D ? analog cu
O, dar in ordine descrescatoare
C - cauta o valoare in tablou, afisand indicele in cazul gasirii
M ? cauta o valoare
in tablou, pe care o sterge in cazul gasirii - dimensiunea tabloului va
scadea astfel cu o unitate ( nr_elem, nu N!!!); stergerea se realizeaza
prin mutarea cu o pozitie inspre indicii mici, a tuturor elementelor de
tablou urmatoare celui care se sterge; o alta varianta este de a copia
ultimul element peste cel care se sterge
P - afiseaza maximul, suma, produsul, media aritmetica si cea geometrica
X - terminare.
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <math.h> //pentru
functia pow
#define N 10
#define NL '\n'
#define MIN -32768
int tablou[N], copie[N], nr_elem;
/* tablou va contine nr_elem de prelucrat, copie salveaza tablou inainte
de ordonare */
char optiune; /*
caracterul ce indica operatia */
void citire_optiune(void){ /*
fara validare */
printf("Optiunea(I,L,O,C,P,X)=");optiune=getche();
putchar(NL);
}
void citire_numar_elem(void){ /*
cu validare */
do{
printf("numar elem(1..%d)=",N);scanf("%d",&nr_elem);
}while(nr_elem<1 || nr_elem>N);
}
void citire_elem(void){
int i;
puts("Introduceti elementele tabloului");
for(i=0;i<nr_elem;i++){
printf("elem[%d]=",i);scanf("%d",&tablou[i]);
/*
se afiseaza indicele
elem ce se citeste */
}
}
void init(void){
citire_numar_elem();
citire_elem();
}
void list(void){ /*
se listeaza elem din tablou */
int i;
puts("Elementele tabloului:");
for(i=0;i<nr_elem;i++)
printf("elem[%d]=%d%c",i,tablou[i],NL);
}
void salv(void){ /*
se salveaza tablou in copie */
int i;
for(i=0;i<nr_elem;i++)
copie[i]=tablou[i];
}
void refac(void){ /*
se reface tablou din copie */
int i;
for(i=0;i<nr_elem;i++)
tablou[i]=copie[i];
}
void ordonare(void){ /*
se ordoneaza elem din tablou prin metoda bubblesort*/
int i,ordonat,aux;
do{
ordonat=1;
for(i=0;i<nr_elem-1;i++)
if(tablou[i]>tablou[i+1]){
/*
interschimbare */
aux=tablou[i+1];
tablou[i+1]=tablou[i];
tablou[i]=aux;
ordonat=0;
}
}while(!ordonat);
}
void list_ord(void){ /*
se face ordonarea elem din tablou, dupa listare,
tablou revine la configuratia de la citire */
salv();
ordonare();
list();
refac();
}
void prel(void){
int max=MIN, suma=0, i;
float produs=1, media_aritm, media_geom;
for(i=0;i<nr_elem;i++){
if(tablou[i]>max) max=tablou[i];
suma+=tablou[i];
produs*=tablou[i];
}
media_aritm=(float)suma/nr_elem;
media_geom=pow(produs, 1/(float)nr_elem);
printf("max=%d, suma=%d, produs=%0.0f,
media aritm=%f, media geom=%f%c",
max,suma,produs,media_aritm,media_geom,NL);
}
void cauta(void){
int pe_cine,i;
printf("valoare cautata:");
scanf("%d",&pe_cine);
for(i=0;i<nr_elem;i++)
if(tablou[i]==pe_cine)break;
if(i==nr_elem)puts("***Nu exista***");
else printf("gasita la indicele %d\n",i);
}
void main(void){
clrscr();
do{
citire_optiune();
switch(toupper(optiune)){
case 'I':init();break;
case 'L':list();break;
case 'O':list_ord();break;
case 'C':cauta();break;
case 'P':prel();break;
case 'X':puts("La
revedere");break;
default:puts("***
Optiune eronata ***");
}
}while(toupper(optiune)!='X');
getch();
} |
3.Sa
se scrie un program care citeste coeficientii unui polinom de x, cu gradul
maxim N ( N este o constanta predefinita), calculand apoi valoarea sa in
puncte x citite, pana la introducerea pentru x a valorii 0. Sa se afiseze
si valoarea obtinuta prin apelarea functiei de biblioteca poly. Sa
se modifice programul astfel incat sa citeasca ciclic polinoame, pe care
sa le evalueze.
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define N 10
double coeficient[N+1],x,val;//numarul
de coeficienti e cu 1 mai mare decat gradul
int grad; //grad
variabil <=N
void citire_grad(void){ /*
cu validare */
do{
printf("grad maxim(0..%d)=",N);scanf("%d",&grad);
}while(grad<0 || grad>N);
}
void citire_coef(void){
int i;
citire_grad();
puts("Introduceti coeficientii:");
for(i=0;i<=grad;i++){
printf("coef[%d]=",i);scanf("%lf",&coeficient[i]);
/*
se afiseaza indicele
elem ce se citeste */
}
}
void list_polin(void){ /*
se listeaza polinomul */
int i;
printf("P(x)=");
for(i=grad;i>0;i--)
if(coeficient[i])
printf("%lf*x^%d+",coeficient[i],i);
if(coeficient[0])
printf("%lf\n",coeficient[0]);
/*
termenul liber */
}
void eval(void){
int i;
val=coeficient[grad];
for(i=grad-1;i>=0;i--){
val*=x;
val+=coeficient[i];
}
}
void main(void){
clrscr();
citire_coef();
list_polin();
while(printf("x="),scanf("%lf",&x),x){
/* while(printf("x="),scanf("%lf",&x)
!= EOF )//daca oprire la CTRL/Z */
eval();
printf("P(%lf)=%lf\n",x,val);
printf("poly(%lf)=%lf\n",x,poly(x,grad,coeficient));
/*
evaluare cu functia de
biblioteca poly - cititi Help-ul pentru poly, dand CTRL/F1 avand cursorul
pe un car din poly*/
}
getch();
} |
4.Pentru o matrice cu NL
linii si NC coloane ( NL, NC constante simbolice ), declarata ca variabila
globala si avand elemente intregi, sa se scrie urmatoarele functii void
fara parametri:
-
citire - citeste elementele
matricii pe coloane
-
tiparire - tipareste
elementele matricii pe linii
-
det_maxim - determina
si afiseaza valoare si pozitia elementului maxim din matrice
-
constr_tab - construieste
un tablou unidimensional declarat ca variabila globala, ale carui elemente
sunt sumele elementelor de pe cate o linie a matricii
-
interschimbare - interschimba
elementele de pe doua coloane ale matricii cu indicii cititi
-
cauta - cauta in matrice
o valoare citita, afisandu-i pozitia.
Ce mai trebuie adaugat pentru
a avea un program C complet?
Mai jos sunt definite functiile
de citire si tiparire.
#define NL 5
#define NC 3
int m[NL][NC];
void citire(void){ //citire
pe coloane
int i,j;
printf("Introduceti
elementele matricii de %d linii si %d coloane, pe\ coloane\n",NL,NC);
for(j=0;j<NC;j++)
for(i=0;i<NL;i++){
printf("elem %d,%d:",i,j);scanf("%d",&m[i][j]);
}
} /*
citire */
void tiparire(void){ /*
elementele unei linii a matricii se tiparesc separate printr-un blanc,
apoi se trece la un rand nou pe ecran */
int i,j;
puts("Elementele matricii pe linii");
for(i=0;i<NL;i++)
{ for(j=0;j<NC;j++) printf("%d ",m[i][j]);
putchar('\n'); } /*
for i */
/*
linia de mai sus mai poate fi scrisa:
for(j=0;j<NC;j++) printf("%d%c",m[i][j],j==NC-1?'
':'\n'); */
} /*
tiparire */
void main(void){
citire();
tiparire();
} |
5.Sa se scrie un program
care calculeaza si afiseaza matricea suma a doua matrici de elemente intregi,
initializate la declarare. Suma si afisarea vor fi realizate de cate o
functie void fara parametri, iar cele trei matrici se vor considera variabile
globale.
6.Sa se scrie un program
care calculeaza si afiseaza matricea produs a doua matrici de elemente
intregi, initializate la declarare. Produsul si afisarea vor fi realizate
de cate o functie void fara parametri, iar cele trei matrici se vor considera
variabile globale.
Copyright
© 2001-2002. Carmen Holotescu
All
rights reserved. Published by Timsoft
|