Sunteți pe pagina 1din 8

LUCRAREA NR.

TIPURI DE DATE STRUCTURATE


În C există două categorii de tipuri de date structurate: tablourile şi structurile. Un tablou
este o colecţie omogenă de valori de acelaşi tip identificate printr-un indice, iar o structură este o
colecţie neomogenă de valori identificate prin nume simbolice, denumite selectori.

5.1. Tablouri unidimensionale

Un tablou este o colecţie de variabile de acelaşi tip care sunt referite printr-un nume comun.
În C, un tablou constă din locaţii de memorie contigue. Adresa cea mai mică corespunde primului
element, iar adresa cea mai mare corespunde ultimului element. Un tablou poate avea de la una la
mai multe dimensiuni. Accesul la un element specific al tabloului se face utilizând un index. Cel mai
utilizat tablou este tabloul de caractere. Şirurile de caractere pot fi definite prin conceptele: vector de
caractere şi pointer-caracter.
Declararea unui tablou cu o singură dimensiune are următoarea formă generală:
tip var_nume[size];
Aici, tip, declară tipul de bază al tabloului. Tipul de bază determină tipul de dată al fiecărui element
al tabloului. var_nume este numele tabloului, iar size este numărul elementelor pe care le va conţine
tabloul. Exemple:
int a[10]; // vectorul a contine 10 intregi
float v[3]; // vectorul v contine 3 reali
În C toate tablourile folosesc pe zero ca index al primului lor element. Elementele tabloului
a[10] sunt a[0],...,a[9].

Iniţializarea vectorilor de caractere

• Citirea unui şir de la tastatură utilizând funcţiile scanf() şi gets().


o Utilizarea funcţiei scanf(). Exemplu:
# include <stdio.h>
void main (void) {
char nume[21], adresa[41];
printf ("\n Nume: ");
scanf ("%s", nume);
printf ("\n Adresa: ");
scanf ("%s", adresa);
printf ("%s\n%s\n", nume, adresa); }

S-au definit variabilele nume şi adresa ca tip şir de caractere de maximum 20 şi 40 de


caractere. Şirul "%s" care apare în apelul funcţiei scanf() precizează că se vor citi în variabilele
nume, respectiv adresa, valori de tip şir de caractere. În printf() descriptorul "%s" are rolul de a
preciza cum trebuie convertite valorile datelor de afişat (în cazul de faţă, valorile variabilelor nume
şi adresa).
Cea mai bună cale de a introduce un şir de la tastatură constă în utilizarea funcţiei gets() din fişierul
antet "stdio.h". Forma generală a funcţiei gets() este:
gets (nume_vector)

1
Pentru a citi un şir se apelează gets() având ca argument numele vectorului, fără nici un
index. Funcţia gets() returnează vectorul ce va păstra şirul de caractere introdus de la tastatură. gets()
va continua să citească caractere până la introducerea caracterului CR.
Exemplu: Programul următor afişează şirul de caractere introdus de la tastatură.
# include <stdio.h>
void main (void) {
char sir[80];
gets (sir); /* citeste un sir de la tastatura */
printf ("%s", sir); }

Iniţializarea vectorilor de caractere utilizând constantele şir


Folosind constantele şir, vectorii de caractere se iniţializează sub forma:
char nume_vector[size] = "sir_de_caractere"
unde size = numărul caracterelor din şir plus 1. Exemplu:

# include <stdio.h>
void main (void) {
char nume[14] = "ENE ALEXANDRU";
char adresa[24] = "Str. A. I. Cuza, nr.13";
puts (nume);
puts (adresa); }

Vectorul nume va ocupa începând de la adresa nume, 13 + 1 = 14 octeţi, iar cel de-al doilea
vector va ocupa începând de la adresa adresa, 23 + 1 = 24 locaţii (bytes).
Funcţia puts() scrie pe stdout şirul memorat în vectorul al cărui nume apare ca parametru al
funcţiei puts(), precum şi caracterul "\n".

Funcţii pentru prelucrarea şirurilor (fişierul antet string.h)

• Funcţia strcpy()
Apelul funcţiei strcpy() are următoarea formă generală:
strcpy (nume_sir, constanta_sir);
Funcţia strcpy() copiază conţinutul constantei_sir (inclusiv caracterul terminator '\n') în nume_sir.
Exemplu:
# include <string.h>
void main(void) {
char sir[80];
strcpy (sir, "hello");
printf("%s", sir); }
Acest program va copia "hello" în şirul sir.
• Funcţia strcat()
Apelul funcţiei strcat() are forma:
strcat (s1, s2);
Funcţia strcat() concatenează şirul s2 la sfârşitul şirului s1 şi întoarce şirul s1. §irul s2 nu se
modifică. Ambele şiruri trebuie să aibă caracterul terminator NULL, iar rezultatul va avea de
asemenea caracterul terminator NULL.
Exemplu:
# include <stdio.h>
# include <string.h>
void main(void) {

2
char first[20], second[10];
strcpy (first, "hello");
strcpy (second, "there");
strcat (first, second);
printf ("%s", first); }
Acest program va afişa "hellothere" pe ecran.
• Funcţia strcmp()
Se apelează sub forma:
strcmp (s1, s2);
Această funcţie compară şirurile s1 şi s2 şi returnează valori negative, dacă s1 < s2, 0, dacă s1 = s2
şi un număr pozitiv, dacă s1 > s2.
Exemplu: Această funcţie poate fi folosită ca o subrutină de verificare a parolei:
# include <stdio.h>
# include <string.h>
void main (void) {
char s[80];
printf ("Introduceti parola: ");
gets (s);
if (strcmp (s, "pasword")) {
printf (" Invalid pasword \n ");
return 0;}
return 1; }

• Funcţia strlen()
Funcţia strlen() se apelează sub forma:
strlen (s)
unde s este un şir. Funcţia strlen() returnează lungimea şirului s.

Exemplu: Programul următor returnează lungimea unui şir introdus de la tastatură.


# incude <stdio.h>
# incude <string.h>
void main (void) {
char sir[80];
printf ("Introduceti un sir: ");
gets (sir);
printf ("Sirul %s contine %d caractere ", sir, strlen(sir));
}

Observaţie: Funcţia strlen() nu numără şi caracterul NULL.

Exemplu: Programul următor afişează inversul unui şir de caractere introduse de la tastatură.
# include <stdio.h>
# include <string.h>
void main (void) {
char sir[80];
int i;
gets(sir);
for(i=strlen(sir)-1;i>=0;i--) printf("%c",sir[i]);
}

3
5.2. Tablouri cu două dimensiuni (matrice)

Tablourile bidimensionale (matricele) sunt reprezentate ca vectori de vectori. De exemplu,


declaraţia:
int v[2][5];
declară un vector cu 2 elemente, fiecare element fiind un vector de tip int[5]. Se observă că fiecare
dimensiune a tabloului este separată (închisă) între paranteze, iar dimensiunile nu sunt separate prin
virgulă. Astfel, declaraţia: int v[2, 5]; conduce la eroare.

Iniţializarea matricelor

Declaraţia :
char v[2][5] = { 'a', 'b', 'c', 'd', 'e',
'0', '1', '2', '3', '4' };
conduce la iniţializarea primului vector cu primele 5 litere, iar a celui de-al doilea cu primele 5 cifre.

Exemplu: Programul:

# include <stdio.h>
void main (void) {
char v[2][5] = { 'a', 'b', 'c', 'd', 'e',
'0', '1', '2', '3', '4' };
int i, j;
for (i = 0; i < 2; i++){
for(j = 0; j < 5; j++)
printf ("v[%d][%d] = %c", i, j, v[i][j]);
printf ("\n"); }
}

va produce :

v[0][0]=a v[0][1]=b v[0][2]=c v[0][3]=d v[0][4]=e


v[1][0]=0 v[1][1]=1 v[1][2]=2 v[1][3]=3 v[1][4]=4.

Exemplu: Secvenţa de instrucţiuni:

# include <stdio.h>
void main (void) {
int l, c, num[3][4];
for (l = 0; l < 3; ++l)
for (c = 0; c < 4; ++c)
num[l][c] = (l * 4) + c + 1;
}

conduce la încărcarea tabloului num[3][4]cu numerele de la 1 la 12. Astfel, num[0][0] = 1, ...,


num[2][3] = 12.
Se observă că limbajul C memoreză tablourile bidimensionale într-o matrice linii-coloane,
unde primul indice se referă la linie şi al doilea indice se referă la coloană. Cantitatea de memorie
alocată permanent pentru un tablou, exprimată în bytes, este:
nr_linii * nr_coloane * sizeof(tipul_datei)

4
Tablouri bidimensionale de şiruri

Pentru crearea unui tablou de şiruri se foloseşte un tablou de caractere, bidimensional, în


care mărimea indicelui din stânga determină numărul de şiruri, iar indicele din drepta specifică
lungimea maximă a fiecărui şir. De exemplu, declaraţia :

char sir_tablou[30][80];

defineşte un tablou de 30 de şiruri, fiecare şir având maximum 80 de


caractere. Accesul la un singur şir este foarte uşor: se specifică numai primul indice. De exemplu:

gets (sir_tablou[2])

întoarce al treilea şir din tabloul sir_tablou. Funcţional, instrucţiunea anterioară este echivalentă cu:

gets (&sir_tablou[2][0]);

5.3. Tablouri multidimensionale

Forma generală a declaraţiei unui tablou multidimensional este:


tip nume[size1][size2]...[sizeN];
De exemplu, declaraţia:
int trei[4][10][3];
creează un tablou de 4*10*3 întregi.
Forma generală de iniţializare a tablourilor este următoarea:
specificator_tip nume_tablou[size1][size2]...[sizeN]={lista_valori};
unde lista_valori este o listă de constante separate prin virgulă, compatibile cu tipul de bază al
tabloului.
Observaţie: Limbajul C permite şi iniţializarea tablourilor multidimensionale fără dimensiune.
Trebuie menţionat că pentru aceasta este necesară precizarea indicelui celui mai din dreapta. Astfel,
declaraţia:
int sqrs[5][2] = {1, 1, 2, 4, 3, 9, 4, 16, 5, 25};
este echivalentă cu declaraţia:

int sqrs[ ][2] = {1, 1, 2, 4, 3, 9, 4, 16, 5, 25};

5.4. Structuri

O structură este o colecţie de variabile (de tipuri diferite) referite sub un singur nume.
Definiţia unei structuri formează un aşa numit şablon (template, tag) ce poate fi folosit la crearea
variabilelor tip structură. Variabilele care formează structuri se numesc elementele structurii.
Exemplu de program pentru actualizarea unei liste de corespondenţa - maillist
Pentru a ilustra modul de utilizare a structurilor şi tablourilor de structuri prezentăm un
exemplu de program pentru actualizarea unei liste de corespondenţă.
Informaţiile ce vor fi memorate se referă la name, street, city, state, zip.

5
Listingul complet al programului este următorul:

# include <stdio.h>
# include <ctype.h>
# include <string.h>
# define SIZE 100
struct addr {
char name[20];
char street[30];
char city[15];
char state[10];
unsigned int zip;
} addr_info[SIZE];
FILE *fp;
void init_list(),enter(),save(),load();
void display();
char menu();

void main() {
char choice;
init_list();
for (;;) {
choice = menu();
switch (choice) {
case 'e' : enter(); break;
case 'd' : display(); break;
case 's' : save(); break;
case 'l' : load(); break;
case 'q' : exit(0); }}}

/* Functia init_list() */

void init_list() {
register int t;
for (t = 0; t < SIZE; t++)
*addr_info[t].name = '\0'; }

/* Functia menu() */

char menu() {
char s[5],ch;
do {
printf ("(E)nter\n");
printf ("(D)isplay\n");
printf ("(L)oad\n");
printf ("(S)ave\n");
printf ("(Q)uit\n");
printf (" Alegeti optiunea: ");
gets(s);
ch=s[0];
} while (!strrchr("edlsq",ch));
return tolower(ch); }

/* Functia enter() */

void enter() {
register int i;
for (i=0; i < SIZE; i++)

6
if (!*addr_info[i].name) break;
if (i == SIZE) {
printf ("addr_info full \n"); /* Lista plina */
return;}
printf ("Name: ");
gets (addr_info[i].name);
printf ("Street: ");
gets (addr_info[i].street);
printf ("City: ");
gets (addr_info[i].city);
printf ("State: ");
gets (addr_info[i].state);
printf ("Zip: ");
scanf ("%d",&addr_info[i].zip);}

/* Functia save() */

void save() {
register int i;
if ((fp = fopen("maillist", "wb")) == NULL) {
printf (" Cannot open file\n ");
return;}
for (i = 0; i <= SIZE; i++)
if(*addr_info[i].name)
if(fwrite(&addr_info[i], sizeof(struct addr), 1,fp) !=1)
printf (" File write error \n ");
fclose (fp);}

/* Functia load() */

void load()
{ register int i;
if ((fp = fopen("maillist","rb")) == NULL) {
printf("Cannot open file\n ");
return;}
for (i = 0; i < SIZE; i++)
if(fread(&addr_info[i],sizeof(struct addr),1,fp)==1);
else if (feof(fp)) {
fclose (fp); return;}
else printf ("File read error\n"); }

/* Functia display() */

void display() {
register int t;
printf("\n%20s","Name");
printf("%30s","Street");
printf("%15s","City");
printf("%10s","State");
printf("%5s\n","Zip");
for (t=0;t<SIZE;t++) {
if (*addr_info[t].name!='\0') {
printf("%20s",addr_info[t].name);
printf("%30s",addr_info[t].street);
printf("%15s",addr_info[t].city);
printf("%10s",addr_info[t].state);
printf("%5d",addr_info[t].zip);
getchar();}}}

7
5.5. Uniuni

În C o uniune este o zonă de memorie utilizată de mai multe variabile ce pot fi diferite ca tip.
Definitia uniunilor este similară celei a structurilor.
Exemplu:
union tip_u {
int i;
char ch;};
O variabilă de acest tip poate fi declarată fie prin plasarea numelui său la sfîrşitul acestei
definiţii, fie utilizând o instrucţiune de declarare separată. Când se declară o variabilă union
compilatorul C rezervă o zonă de memorie suficient de lungă capabilă să preia variabila cu lungimea
cea mai mare.

TEME:

1. Să se realizeze un program ce realizează suma şi diferenţa a două matrici oarecare.


2. Să se realizeze un program ce realizează produsul a două matrici.
3. Să se realizeze un program ce ordonează crescător şi descrescător un vector de n numere
reale.
4. Să se realizeze un program care determină cel mai mare element şi cel mai mic element
dintr-un vector de numere reale precum şi poziţia lor în vector. Dacă există mai multe
elemente cu aceeaşi valoare (maximă sau minimă) se afişează toate poziţiile în care acestea
apar.
5. Să se realizeze un program ce concatenează două şiruri de caractere şi afişează şirul rezultat
reversat (de la coadă la cap).
6. Să se realizeze un program care determină dacă un număr X citit de la tastatură se află într-o
matrice cu n linii şi m coloane. În caz afirmativ să se afişeze poziţia în care se află.
7. Să se realizeze un program care determină valoarea unui polinom într-un punct x citit de la
tastatură.
8. Să se realizeze un program care calculează c.m.m.d.c a două polinoame.
9. Să se realizeze un program care calculează suma, diferenţa şi produsul a două polinoame.
10. Să se creeze o structură STUDENT cu următoarele câmpuri: nume (de tip şir de caractere),
prenume (de tip şir de caractere), adresă (de tip şir de caractere), vârstă (de tip întreg), note
(vector de 5 numere reale), medie (de tip real). Să se realizeze un program ce citeşte de la
tastatură numele, prenumele, adresa şi cele 5 note pentru 5 studenţi şi afişează cei 5 studenţi
în ordine alfabetică şi în ordinea descrescătoare a mediilor.
11. Să se realizeze un program care afişează clasamentul campionatului de fotbal. (Se va folosi o
structură ce va conţine numele, nr. de victorii, nr de egaluri, nr. de înfrângeri şi nr. de puncte
pentru o echipă. Numărul de puncte se va calcula din celelalte câmpuri.).

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