Documente Academic
Documente Profesional
Documente Cultură
96
Nota\ia indicial[ a variabilelor nu este nou[; ea a fost =i este folosit[ ]n special de matematicieni ori de c`te ori este nevoie ca o prelucrare s[ fie exprimat[ c]t mai sintetic. Este evident c[ prelucrarea S=a+b+c+d+e+f arat[ mult mai pu\in elegant dec`t
S = xi
i =1 6
}n ultimul
caz cele =ase variabile a,b,c,d,e,f au fost redenumite x1,x2,...,x6; ele pot fi privite astfel drept primele 6 componente ale vectorului x. Tablourile reprezint[ tocmai implementarea no\iunilor de vector matrice sau masiv multidimensional ]ntr!un limba" de nivel ]nalt. Ele reprezint[ colec\ii omogene de date # adic[ de acela=i tip$ stocate ]n loca\ii de memorie ]nvecinate. %ccesul la oricare din elementele tabloului se face cu a"utorul indicilor. ABLOURI UNIDIMENSIONALE &eclara\ia unui tablou unidimensional se face dup[ forma general['
tip nume_tablou[dim];
unde'
indexate; dim reprezint[ num[rul de elemente ale tabloului; nume_tablou este un identificator reprezent`nd numele tabloului. &imensiunea zonei continue alocate se calculeaz[ prin rela\ia
dimens_alloc=dim*sizeof tip!.
97
se vor aloca vectorului a 1""*2=2"" de octe\i ]ntr!o zon[ continu[ de memorie. Observa\ii: alocarea se face ]n timpul compil[rii; o dat[ f[cut[ alocarea, ]n scopul m[ririi vitezei de execu\ie nu se mai face nici o verificare a dimensiunii; gestionarea corect[ a zonei de memorie alocate cade, deci, exclusiv ]n sarcina programatorului. (eferirea la un element al tabloului unidimensional se face preciz`nd numele tabloului urmat de o expresie ]ntreag[ ]ntre paranteze drepte adic[
nume_tablou[exp#]
Expresia exp# poate lua valori ]ntregi cuprinse ]n intervalul [",dim$1]. %stfel ]n urma declara\iei float %[1"]; vectorului % va avea 1" componente reale =i anume'
%["] componenta _1 %[1] componenta _2 . . . . . . . . %[&] componenta _1"
)nten\ia de a referi ultimul element al unui tablou sub forma nume_tablou[dim] este o gre=eal[ cu at`t mai grav[ cu c`t \in`nd cont de observa\iile anterioare ea nu este depistat[ de compilator. &e obicei expresiile ] ntregi folosite pentru a accesa componentele unui tablou sunt constante sau variabile simple #indici$. Comutarea componentelor unui vector =i afi=area lor ] n coloan[.
#include "stdio.h" #include "conio.h" void main(void) {
98
int x[50],i,n,c; /* citirea elementelor vectorului */ rint!(""n lun#imea sirului n$50 este%"); scan!("&d",'n); !or (i(0;i$n;i))) { rint!(""n x[&i](",i); scan!("&i",'x[i]); * /* comutarea elementelor */ !or (i(0;i$n/+;i)))
{ c(x[i]; x[i](x[n,-,i]; x[n,-,i](c; * /* a!isarea elementelor vectorului comutat */ !or (i(0;i$n;i))) rint!(""n com onenta x[&i] este &i",i,x[i]); #etch(); *
ABLOURI MULTIDIMENSIONALE &ac[ elementele unui tablou unidimensional sunt la r]ndul lor tablouri unidimensionale ob\inem un tablou bidimensional sau o matrice. &e exemplu declara\ia'
int x['][(];
se poate interpreta astfel' x este un tablou cu ' elemente x[i], i=",1,2,(. *iecare element x[i] cu i=",1,2,( este un tablou cu ( elemente ]ntregi x[i][)] cu )=",1,2. +eneraliz`nd un tablou multidimensional poate fi considerat ca un tablou unidimensional care are ca elemente un tablou cu restul de dimensiuni; declara\ia
99
unde indicei ia valori ]ntregi ]n intervalul [",dimi$1] pentru i=1,2,...,n. Observa\ii: Referirea clasic[ la elementele unui tablou prin separarea indicilor prin virgul[ este incorect[ ]n C =i are semnifica\ia rezultat[ din folosirea operatorului de secven\iere. De exemplu, consider nd declara\ia de mai sus, referirea x[i,)] este ec!ivalent[ cu x[)]. Dimensiunea zonei continue de memorie alocate este dat[ "]n octe\i# de valoarea dim1*dim2*dim(*dimn*sizeof tip!.
100
{ rint!(""n a[&i][&i](",i,/); scan!("&i",'a[i][/]); rint!(""n .[&i][&i](",i,/); scan!("&i",'.[i][/]); * /* calculul matricii suma c(a). */ !or (i(0;i$m;i))) !or (/(0;/$n;/))) c[i][/](a[i][/]).[i][/]; /* a!isarea matricii suma c */ rint!(""n matricea suma este%"n"); !or (i(0;i$m;i))) { !or (/(0;/$n;/))) rint!("&3i",c[i][/]); rint!(""n"); * #etch(); *
NI|IALIZAREA TABLOURILOR Exemplele anterioare ne!au ar[tat cum se poate ini\ializa un tablou prin valori date de la tastatur[. Exist[ ]ns[ posibilitatea ini\ializ[rii unui tablou printr!o defini\ie de forma'
decla#atie tablou=*lista +alo#i_initiale,;
unde +alo#ile_initiale sunt expresii constante compatibile cu tipul de baz[ al tabloului. Exemple:
int +ecto#[6]=*$-,$2,&.,21,.,$2(,; float a[(][2]=*1,2,(,',.,6,; int b[(][2][2]=*1,2,(,',.,6,-,/,&,1",11,12,;
}n cel de!al doilea caz a fost ini\ializat[ o matrice. ,um se vor completa elementele matricii- ([spunsul este simplu' .pe linii. adic[ se completeaz[ linia " apoi linia 1 =i ]n sf`r=it linia 2. /atricea a va ar[ta astfel'
101
0entru a sugera modul de ini\ializare al tablourilor multidimensionale se pot folosi acolade desp[r\itoare ] n interiorul listei de valori. %stfel matricea a se poate scrie mai sugestiv
int b[(][2]= * *1, 2,, *(, ',, *., 6,,
1 ( .
2 ' 6
}n general ini\ializarea elementelor unui tablou multidimensional se face dup[ regula 1ultimul indice variaz[ cel mai rapid2 care este o generalizare a regulii de memorare 1pe linii2. %stfel cele dou[sprezece componente ale tabloului b[(][2][2] vor fi ini\ializate astfel'
b["]["]["]=1 b["]["][1]=2 b["][1]["]=( b["][1][1]=' b[1]["]["]=. b[1]["][1]=6 b[1][1]["]=b[1][1][1]=/ b[2]["]["]=& b[2]["][1]=1" b[2][1]["]=11 b[2][1][1]=12
,;
%ceste reguli decurg din modul de liniarizare a unui tablou in ,' pozi\iei i1*i2*...*in din tablou ]i corespunde ]n forma sa liniarizat[ #form[ sub care i se va aloca memoria$ pozi\ia 0 dat[ de formula'
0=i1*dim2*...*dimn+i2*dim(*dimn+...+in$1*dimn+in.
&e exemplu ]n cazul unei matrici a[m][n] liniarizarea se face dup[ formula 0=i*n+).
102
3[ not[m ]n cazul general cu dim produsul dim1*dim2*...*dimn =i cu n+al_in num[rul constantelor din lista de ini\ializare. &ac[ dim=n+al_in ini\ializarea tabloului decurge normal dup[ regula de mai sus. &ac[ dim1n+al_in se va produce o eroare iar dac[ dim2n+al_in restul de elemente sunt ini\ializate cu zero. 3e observ[ c[ formula de alocare nu depinde de prima dimensiune a tabloului fapt ce permite urm[toarele ini\ializ[ri ec4ivalente cu cele prezentate la ]nceputul sec\iunii'
int +ecto#[]=*$-,$2,&.,21,.,$2(,; float a[][2]=*1,2,(,',.,6,; int b[][2][2]=*1,2,(,',.,6,-,/,&,1",11,12,;
ABLOURI +I +IRURI DE
ARA TERE
}n , nu exist[ un tip special pentru definirea unui !ir de caractere . 5irurile de caractere se construiesc cu a"utorul tablourilor unidimensionale. &eclara\ia unui =ir cu numele nume_si# de lungime maxim dim$1 caractere se face sub forma'
c3a# nume_si#[dim];
3f`r=itul unui =ir este marcat de caracterul 45"4; din acest motiv ]n declaratia =irului dimensiunea tabloului trebuie s[ fie cel pu\in cu o unitate mai mare dec`t num[rul de caractere al =irului pe care vrem s[!l memor[m. &e exemplu'
c3a# s#[1"];
con\ine declara\ia =irului s#. )ni\ializarea se poate face printr!o defini\ie a =irului sub forma'
103
c3a# s#[1"]=6a7b8c9d:6;
&ac[ num[rul elementelor din =ir este mai mare dec`t dimensiunea =irului caracterele ]n plus sunt ignorate ]n caz contrar restul elementelor este ini\ializat cu zero #caracterul nul$. &ac[ nu se precizeaz[ dimensiunea se poate face urm[toarea ini\ializare'
c3a# s#[]=6a7b8c9d:6;
3e observ[ prezen\a explicit[ a terminatorului de =ir 45"4. 6ltimele dou[ variante rezerv[ =irului un num[r de loca\ii egal cu num[rul elementelor din =ir plus o unitate #corespunz[toare terminatorului 45"4$ =i este mai comod[ deoarece nu precizeaz[ o limit[ maxim[ pentru num[rul de caractere permi\`nd programatorului s[ evite num[rarea elementelor din =ir. 7eg[tura dintre =iruri =i tablouri unidimensionale permite referirea indexat[ la caracterele =irului. *olosind acest lucru ]n exemplul de mai "os se selecteaz[ =i afi=eaz[ literele mici din =irul si#.
104
UN |II "ENTRU "RELU RAREA +IRURILOR DE ARA TERE #UN |II U "ROTOTI"UL IN $STDIO%&'
0entru opera\iile de intrare8ie=ire cu =iruri se pot folosi func\iile scan()* respectiv +rint()* cu
Citirea a dou[ =iruri sub forma nume prenume =i afi=area lor sub forma prenume nume.
#include "stdio.h" #include "conio.h"
105
void main(void) { char nume[+5], renume[+5]; rint!(""n :umele("); scan!("&s",nume); rint!(""n ;renumele("); scan!("&s", renume); rint!(""n &s &s", renume,nume); #etch(); *
0entru citirea unui =ir de la tastatur[ se poate folosi func\ia ,ets)* cu forma general['
<ets si#_destinatie!;
iar pentru afi=area unui =ir pe ecran func\ia +uts)* cu forma general['
puts si#!.
Observa\ie % &unc\ia gets() transfer[ ]n si#_destinatie toate caracterele p n[ la ap[sarea tastei =nte#. #UN |II U "ROTOTI"UL IN $STRIN-%&'
*i=ierul 6st#in<.36 con\ine prototipurile func\iilor specializate pentru manipularea =irurilor de caractere. )at[ c`teva dintre acestea'
compar[ cele doua =iruri caracter cu caracter =i ] ntoarce o valoare' 1" dac[ si#11si#2; =" dac[ si#1=si#2;
106
dac[ si#12si#2. ,ompara\ia =irurilor se face lexicografic. *unc\ia strlen)* cu forma general['
2" unsi<ned int st#len si#!;
$e cite=te de la tastatur[ un num[r neprecizat de =iruri de caractere. Citirea se termin[ c nd se ] nt lne=te =irul stop. 'rogramul stabileste =irul (minim) "]n sens lexicografic# =i ]l afi=eaz[ ] mpreun[ cu lungimea sa.
#include "stdio.h" #include "conio.h" #include "strin#.h" void main(void) { char min[+0],x[+0]; rint!(""n <ntroduceti siruri de caractere = "); rint!(""n 9a s!arsit tastati 8>?; "n"); strc @(min,#ets(x)); 0hile (strcm (x,"sto ")) { strcm (min,x)$0 A min % strc @(min,x); #ets(x); * rint!(""n 8irul minim este "); uts(min); rint!(""n si are lun#imea &i",strlen(min)); #etch();
107
float x[1""];
]nseamn[ a$ rezervarea ]n memorie a 1"" loca\ii la adrese consecutive b$ rezervarea ]n memorie a 1"" loca\ii la adrese ] nt`mpl[toare c$ rezervarea a 1"" de octe\i pentru variabila real[
x
este corect[ deoarece dimensiunile m =i n ale matricii sunt cunoscute b$ este gre=it[ deoarece m =i n trebuia s[ fie declara\i ]nainte de x c$ este gre=it[ deoarece la declarare ]n main)* dimensiunile unui tablou trebuie s[ fie constante =i nu variabile
a$
a$ b$
atribuirea x[1,2]=. este ec4ivalent[ cu x[1][2]=. atribuirea x[1,2]=. este corect[ sintactic =i ] nseamn[ x[2]
int x[6]; int x[(][2];
108
int x[2][(];
,; b! int a[(][2]=*
,;
/%6 )ni\ializarea
float x[2][(]=*1,2,(,',.,6,;
este ec4ivalent[ cu
a$ float x[][]=*1,2,(,',.,6,; b$ float x[][(]=*1,2,(,',.,6,; c$ float x[2][]=*1,2,(,',.,6,;
a$ este gre=it[ sintactic b$ nu ini\ializeaz[ toate componentele vectorului x c$ produce eroare la execu\ie /%08 3ecven\a de program
109
c3a# x[]=6abcd6;
este ec4ivalent[ cu' a$ ini\ializarea c3a# x[]=*4a4,4b4,4c4,4d4,; b$ ini\ializarea c3a# x[']=*4a4,4b4,4c4,4d4,; c$ ini\ializarea c3a# x[]=*4a4,4b4,4c4,4d4,45"4,; /%00 3ecven\a de program
c3a# x[]=6abcd6; putc3 x[1]!;
afi=eaz[ caracterul 4a4 b$ afi=eaz[ caracterul 4b4 c$ este gre=it[ deoarece elementele dintr!un =ir nu se pot referi indexat
a$
afi=eaz[ mesa"ul
a! ?un<imea si#ului=2" b! ?un<imea si#ului=' c! ?un<imea si#ului=.
afi=eaz[ o valoare a$ egal[ cu zero b$ mai mic[ strict dec`t zero c$ mai mare strict dec`t zero
110
afi=eaz[
a! aca# b! a#ac
a$ este gre=it[ b$ este gre=it[ iar copierea =irului 6@loiesti6 ]n variabila x se realizeaz[ prin st#cp% x,6@loiesti6!; c$ este corect[ /%04 3ecven\a de program
c3a# x[2"]; <ets x!; puts x!;
apelul
111
R*$'+,$+R;.<!a ;.@!b ;.<<!b ;.<@!a b ;.=!c ;.A!a ;.<=!b c ;.>!b ;.?!b ;.;!b ;.B!b ;.C!b ;.<D!c ;.<>!c ;.<?!a ;.<;!a b ;.<A!a b