Sunteți pe pagina 1din 5

Tablouri

Pentru a pstra n memoria calculatorului diverse informaii se folosesc variabile. Dac informaiile
pe care vrem s le pstrm se pot reprezenta prin numere ntregi atunci folosim variabile de tipul
int, dac se pot reprezenta prin numere reale atunci folosim variabile de tipul float, etc. Spre
exemplu pentru a calcula suma a trei numere reale, vom declara patru variabile de tip float: trei
variabile vor memora cele trei numere, iar a patra variabil va memora suma lor.
Putem avea situaii cnd avem nevoie de un numr mare de variabile, sau de un numr de variabile
care nu este cunoscut dinainte. Spre exemplu dac vrem s facem calcule asupra a 100 de numere,
este incomod s declarm 100 variabile. Sau dac trebuie s facem calcule asupra a N numere, unde
N este introdus de la tastatur, atunci nici mcar nu tim cte variabile s declarm.
n asemenea situaii putem folosi tablouri. Un tablou reprezint un ir de mai multe variabile de
acelai tip, grupate sub un acelai nume. Tablourile sunt compuse din elemente. Fiecare element al
unui tablou poate fi considerat ca fiind o variabila independent, de acelai tip ca i tabloul.
Tablourile au o dimensiune, care reprezint numrul de elemente din tablou. Tablourile se declar
specificnd tipul de date, numele i dimensiunea. Spre exemplu o declarare de forma:
int a[100];

nseamn c declarm un tablou de 100 de elemente de tip int. Elementele tabloului se acceseaz
specificnd numele tabloului i indicele dorit. Numerotarea indicilor ncepe de la 0. Primul element
al tabloului de mai sus va fi a[0], al doilea va fi a[1], iar ultimul va fi a[99].
n general prelucrearea tablourilor se face prin instruciuni repetitive: for, while sau
do...while.
Un exemplu de program care folosete tablouri este urmtorul: s se citeasc de la tastatur N
numere ntregi i pe urm s se afieze numerele n ordine invers fa de ordinea n care au fost
citite.
#include <stdio.h>
void main(void)
{
/* Numarul de numere care vor fi citite. */
int N;
/* Tablou in care memoram numerele citite.
E nevoie sa fixam o limita maxima pentru
numere, sa zicem ca pot fi maxim 100. */
int a[100];
int i;
/* Citim N de la tastatura. Verificam sa nu
depaseasca 100. */
printf("N=");
scanf("%d", &N);
if (N>100)
{
printf("Maxim 100 de numere.\n");
return;

}
/* Citim cele 100 de numere intr-o bucla for. */
for (i=0; i<N; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
/* Afisam numerele in ordine inversa. */
for (i=N-1; i>=0; i--)
printf("a[%d]=%d\n", i, a[i]);

/* Pentru exemplificare afisam primul


si ultimul element din tablou. */
printf("Primul element: %d\n", a[0]);
printf("Ultimul element: %d\n", a[N-1]);

Tablouri multidimensionale
Putem defini nu doar tablouri unidimensionale (iruri), ci i bidimensionale (matrici),
tridimensionale, sau n general N-dimensionale. Tablourile N-dimensionale se definesc similar cu
cele unidimensionale, cu diferena c se specific dimensiunea pe fiecare din cele N dimensiuni.
Vom exemplifica printr-un program care citete de la tastatur o matrice de 2 linii i 4 coloane de
numere reale, calculeaz transpusa ei i afieaz transpusa.
#include <stdio.h>
void main(void)
{
/* Matricea originala, citita de la tastatura.
Doua linii si patru coloane. */
float a[2][4];
/* Matricea transpusa, va avea patru linii si
doua coloane. */
float tr[4][2];
int i, j;
/* Citim matricea de la tastatura. */
for (i=0; i<2; i++)
for (j=0; j<4; j++)
{
printf("a[%d,%d]=", i, j);
scanf("%f", &a[i][j]);
}
/* Afisam matricea originala. */
for (i=0; i<2; i++)
{
for (j=0; j<4; j++)
printf("%.2f ", a[i][j]);
printf("\n");
}

/* Calculam transpusa. */
for (i=0; i<2; i++)
for (j=0; j<4; j++)
tr[j][i] = a[i][j];

/* Afisam transpusa. */
for (i=0; i<4; i++)
{
for (j=0; j<2; j++)
printf("%.2f ", tr[i][j]);
printf("\n");
}

Atentie. Pentru accesarea elementului de la linia i i coloana j dintr-un tablou bidimensional a,


fiecare din cei doi indici i i j se va ncadra n paranteze ptrate. Adic vom folosi a[i][j], nu
a[i,j].
Tablouri i pointeri
Un pointer este o variabil care reine adresa de memorie unei alte variabile. Spre exemplu putem
avea o variabil de tip float, f, i un pointer la float, pf, care s rein adresa de memorie a lui
f. Prin adres de memorie nelegem indicele locaiei de memorie unde este alocat variabila.
Putem s ne imaginm memoria ca pe o band mprit n locaii, fiecare locaie de pe band avnd
capacitatea de 1 octet (8 bii). Aceste locaii sunt numerotate ncepnd cu zero. O variabil de tip
float ocup patru octei, adic patru locaii consecutive de pe aceast band a memoriei. Adresa
de memorie a unei variabile de tip float va fi dat de indicele primei locaii de memorie pe care o
ocup. n aceti termeni putem spune c un pointer este n esen o variabil care reine numere, i
anume indici de locaii de memorie unde se gsesc alte variabile.
n C, pentru a declara variabile pointer trebuie s punem caracterul * naintea numelui variabilei
atunci cnd o declarm. Pentru a obine adresa unei variabile folosim operatorul &, iar pentru a
obine valoarea de la adresa de memorie pstrat de un pointer folosim operatorul *. Urmtorul
program exemplific aceste aspecte.
#include <stdio.h>
void main(void)
{
/* O variabila de tip float. */
float f;
/* O variabila pointer la float. */
float *pf;
/* Atribuim o valoare variabilei float. */
f = 12.34;
/* Afisam valoarea variabilei. */
printf("direct: %f\n", f);
/* Initializam pointerul cu adresa
variabilei f. */
pf = &f;

/* Afisam valoarea variabilei, dar folosind


pointerul. */
printf("cu pointer: %f\n", *pf);
/* Modificam valoarea variabile, folosind
pointerul. */
*pf = 56.78;
/* Afisam valoarea variabilei, vom vedea
ca ea este modificata. */
printf("direct: %f\n", f);
}

Variabilele de tip tablou pot fi interpretate ca i pointeri. Spre exemplu fie urmtoarea declarare:
int a[20];

Semnificaia este c undeva pe banda memoriei se aloc spaiu pentru 20 de int-uri. Asta
nseamn 40 de octei, deoarece un int ocup 2 octei. Cu alte cuvinte 40 de locaii consecutive din
memorie vor fi ocupate. Variabila a va reine adresa primei locaii din cele 40.
Putem folosi operaiile cu pointeri pentru a accesa elementele tabloului. Spre exemplu expresia a+i
va furniza adresa de memorie a elementului a[i] (util pentru scanf). Expresia *(a+i) va
furniza valoarea elementului a[i]. Atenie. Dup cum am spus mai sus, fiecare element al tabloului
ocup dou locaii de memorie, deoarece este de tip int. a reine adresa primei locaii de memorie.
Expresia a+1 va returna adresa locaiei de memorie de unde ncepe al doilea element al tabloului,
adic a treia locaie de memorie. La fel, expresia a+2 va returna adresa locaiei de memorie unde
ncepe al treilea element al tabloului, adic a cincea locaie de memorie.
Programul care citete N numere de la tastatur i le afieaz n ordine invers poate fi rescris
accesnd elementele tabloului doar prin operaii cu pointeri.
#include <stdio.h>
void main(void)
{
int N, i;
/* Tabloul se declara la fel, chiar daca accesarea
elementelor sale o facem cu pointeri. */
int a[100];
printf("N=");
scanf("%d", &N);
if (N>100)
{
printf("Maxim 100 de numere.\n");
return;
}
for (i=0; i<N; i++)
{
printf("a[%d]=", i);
/* La citirea numerelor trebuie sa furnizam

functiei scanf adresa elementului a[i].


Folosim aritmetica pointerilor. Stim adresa
primului element, a, si adunam i la aceasta
adresa pentru a gasi adresa elementului i. */
scanf("%d", a+i);

for (i=N-1; i>=0; i--)


/* La afisarea numerelor trebuie sa furnizam
functiei prinf valoarea elementului a[i].
Stim cum sa gasim adresa elementului i,
si aplicam operatorul * pentru a obtine
valoarea de la adresa respectiva. */
printf("a[%d]=%d\n", i, *(a+i) );
/* Valoarea primului element e cel mai simplu
de gasit. Stim direct adresa lui, a, si doar
aplicam operatorul *. */
printf("Primul element: %d\n", *a);
/* Valoarea ultimului element. */
printf("Ultimul element: %d\n", *(a+N-1) );
}

Problem propus
Jocul vieii. Se consider o matrice de dimensiune NxM (N linii, M coloane). Matricea are n total
NxM celule. n unele din aceste celule se gsesc virui, maxim un virus n celul. O celul se
nvecineaz cu 8 alte celule. Celulele de pe marginea matricii se nvecineaz doar cu 5 alte celule,
iar celulele din colurile matricii se nvecineaz doar cu 3 alte celule.
Populaia de virui evolueaz n etape, dup urmtoarele reguli:
1. O celul care la etapa K este goal i are exact trei virui vecini, va da natere unui virus n etapa
K+1.
2. O celul care la etapa K conine un virus i are doi sau trei vecini virui, va pstra virusul i la
etapa K+1.
3. n orice alt situaie o celul care la etapa K conine sau nu virus, la etapa K+1 va deveni goal.
Scriei un program C care citete de la tastatur dimensiunea matricii (N i M), genereaz o
configuraie iniial aleatoare a populaiei de virui i pe urm afieaz evoluia populaiei de virui,
ateptnd afiarea unei taste dup fiecare etap. Programul i va ncheia execuia n momentul cnd
utilizatorul va apsa tasta 'x'.

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