Sunteți pe pagina 1din 7

4.

TIPURI STRUCTURATE DE DATE


Spre deosebire de tipurile simple de date, care au o singură componentă, tipurile structurate
de date au mai multe componente, care pot fi la rândul lor simple sau structurate.
În limbajul C++ există următoarele tipuri structurate de date: tablou, şir de caractere,
înregistrare ( struct ), fişier. Diferenţa între ele este dată de tipul componentelor, metoda de
structurare şi modalitatea de acces la componente.
Necesarul de memorie pentru o dată de tip structurat rezultă din numărul şi tipul componentelor sale.
El este constant pe parcursul execuţiei programului, motiv pentru care structurile respective se
numesc statice.

4.1. Tipul tablou


Un tablou este un grup de elemente de acelaşi tip, care formează o mulţime ordonată. La
fiecare element se poate face referire prin intermediul unui indice. Valoarea inferioară a indicilor este
implicit 0. Un tablou are asociat un nume. Tipul de bază al tabloului este tipul comun elementelor
sale.
Un tablou se declară astfel :
tip nume [ dim 1 ] [ dim 2 ] … [ dim n ] ;
unde tip este cuvânt cheie pentru un tip predefinit sau definit de utilizator şi dim i este limita
superioară a indicelui i.
Exemplu : int v [ 10 ] ; vector de 10 elemente întregi, identificate prin v[0], v[1],
…,v[9]
float m [ 3 ] [ 4 ] ; matrice de 12 elemente reale
În limbajul C / C++ nu se poate asigna un tablou altui tablou.
Selectarea unei componente – la elementele unui tablou este permis accesul direct, prin
intermediul unui index. Se specifică numele tabloului şi, între paranteze drepte, indicele. Dacă tabloul
este vector, un element al lui se selectează în forma v [ i ]. Dacă tabloul este o matrice, un element al
lui se selecteaza în forma m [ i ] [ j ], unde i este indicele de linie, iar j este indicele de coloană.
Cu elementele tabloului se pot face toate operaţiile admise pentru tipul de bază al tabloului.
Nu sunt permise atribuiri de forma b = a, unde a şi b sunt tablouri. În acest caz atribuirea se
face pe componente.

4.2. Tipul şir de caractere


– operatori, proceduri şi funcţii predefinite pentru citire, afişare,
concatenare, căutare, extragere, inserare, eliminare şi conversii ( şir ↔ valoare
numerică )
În limbajul C++ nu există un tip de date predefinit pentru şiruri de caractere. Un şir de
caractere se declară ca vector, cu elemente de tip char :
char sir[100], nume[30], s[3];
Şirul de caractere trebuie să fie terminat cu caracterul '\0' ( caracterul nul ), care în C++ este marcajul
de sfârşit de şir. Pentru fiecare caracter este reţinut codul ASCII. Vectorii de caractere pot fi
iniţializaţi la declarare, caracterul nul fiind memorat automat.
Exemple : char vect[11]="calculator"; 11 octeţi = 10 octeţi pentru litere + caracterul nul
char vect[]="calculator"; compilatorul face calculul numărului de octeţi
char vect[100]="calculator"; sunt rezervaţi mai mulţi octeţi decât e necesar
Şirurile pot fi citite cu funcţiile :
1. cin >> sir → citeşte şiruri până la spaţiu, Enter sau Tab ( cuvinte ).
Observaţie : Caracterul nul este adăugat automat.
2. cin.get ( vector de caractere , int nr , char = '\n' ) → citeşte un şir de caractere până când este
îndeplinită una dintre condiţiile :
– au fost citite nr – 1 caractere;
– a fost întâlnit caracterul transmis ca ultim parametru ( implicit '\n' Enter ).
Observaţie : Sunt citite şi caracterele albe ( spaţiu, Tab, Enter ).
Este inserat caracterul nul.
Caracterul transmis ca ultim parametru nu este inserat în şir.
Al treilea parametru este opţional. Dacă nu este trecut se presupune că este '\n'.
În C++ pot exista mai multe funcţii cu acelaşi nume, dar care diferă prin parametrii primiţi.
Astfel, există şi funcţia : cin.get() fără parametrii. Ea are rolul de a citi un caracter ( fie că este alb,
fie nu ).
Tipul char*
– Numărul de ordine al unui octet în memoria internă se numeşte adresa octetului respectiv.
– Definiţie. Adresa unui vector de caractere este adresa primului său octet.
– O variabilă de tipul char* poate reţine adresa unui vector de caractere.
– În C++ numele unui vector de caractere este o adresă constantă de vector şi poate fi atribuit unei
variabile de tip char*.
Exemplu :
#include<iostream.h>
char a[]="Exemplu",*p; // a = vector de caractere iniţializat cu un şir;
void main() // p = variabilă de tip char*;
{ p=a; // variabila p reţine adresa lui a, adică adresa
cout<<p<<endl; // primului său octet; a = p incorect pentru că a
p++; // este o constantă ce reprezintă o adresă;
cout<<p<<endl;
p++;
cout<<p[1]<<endl;
cout<<p-a<<endl; // se pot face şi scăderi între adrese; în acest
// caz rezultatul este întreg; prin p-a se obţine
// indicele în a al primului octet reţinut de p.
}
Funcţiile predefinite pentru operarea cu şiruri de caractere sunt incluse în fişierul header
<string.h>.
1) strlen(sir) – determină lungimea şirului de caractere primit ca parametru ( în calculul
lungimii nu intră caracterul nul ).
Exemplu : Să se determine şi să se afişeze lungimea unui şir de caractere.
s = Azi invat siruri de caractere. se va afişa : Sirul contine 30 de caractere.
#include<iostream.h>
#include<string.h>
char s[100];
void main()
{ cout<<"Introduceti un sir de caractere "; cin.get(s,100);
cout<<"Sirul contine "<<strlen(s)<<" de caractere"<<endl;
cout<<"Primul caracter este "<<s[0]<<endl;
cout<<"Ultimul caracter este "<<s[strlen(s)-1]<<endl;
}

2) strcmp(sir1,sir2) – compară două şiruri de caractere; returnează valorile :


> 0, dacă sir1 > sir2 ( în sens lexicografic )
= 0, dacă sir1 = sir2
< 0, dacă sir1 < sir2
Exemplu : Să se compare două şiruri de caractere.
#include<iostream.h>
#include<string.h>
char s1[100],s2[100];
void main()
{ cout<<"Introduceti primul sir: "; cin.get(s1,100);
cin.get();
cout<<"Introduceti al doilea sir: "; cin.get(s2,100);
if (strcmp(s1,s2)>0) cout<<"Primul sir este mai mare";
else if (strcmp(s1,s2)==0) cout<<"Sirurile sunt egale";
else cout<<"Al doilea sir este mai mare";
}

3) strchr(sir,c) – returnează adresa primei apariţii a caracterului c în şir, sau 0 dacă nu există
caracterul c în şir.
Exemplu : Să se determine dacă un şir de caractere conţine cifre. În caz afirmativ să se afişeze cifrele
existente în şir.
#include<iostream.h>
#include<string.h>
char c,s[100];
int are=0;
void main()
{ cout<<"Introduceti un sir de caractere: "; cin.get(s,100);
for (c='0';c<='9';c++)
if (strchr(s,c)!=0)
{ are=1;
cout<<"Sirul contine cifra "<<c<<endl;
}
if (!are) cout<<"Sirul nu contine cifre";
}

4) strrchr(sir,c) – returnează adresa ultimei apariţii a caracterului c în şirul dat, sau 0 dacă nu
exista caracterul în şir.
Exemplu : Să se determine poziţia primei / ultimei apariţii a unui caracter într–un şir.
#include<iostream.h>
#include<string.h>
char c,s[100],*ult,*pr;
void main()
{ cout<<"Introduceti un sir de caractere: "; cin.get(s,100);
cin.get();
cout<<"Introduceti un caracter: "; c=cin.get();
pr=strchr(s,c); // adresa primei aparitii a lui c in s
ult=strrchr(s,c); // adresa ultimei aparitii a lui c in s
if (pr==0) cout<<"Caracterul nu este in sir"<<endl;
else
{ cout<<"Caracterul "<<c<<" are prima aparitie pe poz. "<<pr-s+1;
cout<<endl;
cout<<"Caracterul "<<c<<" are ultima aparitie pe poz. "<<ult-s+1;
cout<<endl;
}
}
s = adresa de început a şirului ( adresa unde este memorat primul
caracter din sir )
pr = adresa caracterului căutat
pr-s+1 = poziţia ( nr. de ordine ) al caracterului căutat în şir

5) strcpy(dest,sursa) – copiază şirul "sursa" în şirul "destinatie", inclusiv '\0' ( caracterul nul
).
5') strncpy(dest,sursa,n) – copiază cel mult n caractere din şirul sursă în şirul destinaţie;
completează şirul destinaţie cu '\0' dacă în sursă nu sunt n caractere la dispoziţie; dacă sunt n
carcactere de copiat nu se adaugă '\0'.
Exemplu : Să se copieze un şir în altul.
#include<iostream.h>
#include<string.h>
char s1[100],s2[100],s3[100],s4[100];
void main()
{ cout<<"Introduceti primul sir de caractere: "; cin.get(s1,100);
cin.get();
cout<<"Introduceti al 2-lea sir de caractere( sub 20 caractere ):";
cin.get(s2,100);
cout<<"Primul sir: "<<s1<<endl;
cout<<"Al doilea sir: "<<s2<<endl<<endl;

strcpy(s1,s2); // Copiaza s2 in s1
cout<<"Dupa copierea sirului 2 in sirul 1:";
cout<<"Primul sir: "<<s1<<endl;
cout<<"Al doilea sir: "<<s2<<endl<<endl;

strncpy(s3,s2,2); // Copiaza din s2 in s3 primele 2 caractere


s3[strlen(s3)]='\0'; // Pune marcajul de sfarsit de sir in s3
cout<<"Dupa copierea a doua caractere din sirul 2 in sirul 3:";
cout<<"Al doilea sir: "<<s2<<endl;
cout<<"Al treilea sir: "<<s3<<endl<<endl;

strncpy(s4,s2,20); // Copiaza din s2 in s3 primele 20 de caractere;


// Pentru ca in s2 nu exista 20 de caractere
// vor fi copiate toate cele aflate la dispozitie;
// Marcajul de sfarsit de sir se ataseaza automat
cout<<"Dupa copierea a 20 de caractere din sirul 2 in sirul 4:";
cout<<"Al doilea sir: "<<s2<<endl;
cout<<"Al patrulea sir: "<<s4<<endl;
}

6) strstr(sir1,sir2) – determină adresa primei apariţii a lui sir2 în sir1, sau 0 dacă sir2 nu
apare în sir1.
Exemplu : Să se determine numărul de apariţii ale unui şir în altul.
#include<iostream.h>
#include<string.h>
char s1[100],s2[100],*p;
int n;
void main()
{ cout<<"Introduceti un sir de caractere: "; cin.get(s1,100);
cin.get();
cout<<"Introduceti subsirul cautat: "; cin.get(s2,100);
p=strstr(s1,s2); // p este adresa de la care apare s2 in s1
while (p) // cat timp p<>0, subsirul s2 mai apare in sirul s1
{ n++;
strcpy(s1,p+1); // sterg din s1 toate caracterele, pana la primul
p=strstr(s1,s2); // caracter din s2, inclusiv acest caracter
}
cout<<"Sirul contine "<<n<<" aparitii ale subsirului"<<endl;
}

7) strcat(sir1,sir2) – concatenează sir2 la sfârşitul lui sir1.


7') strncat(sir1,sir2,n) – concatenează cel mult n caractere din sir2 la sfârşitul lui sir1;
adaugă '\0' după concatenare.
Exemplu : Să se concateneze două şiruri de caractere.
#include<iostream.h>
#include<string.h>
char s1[100],s2[100],cs1[100],cs2[100];
void main()
{ cout<<"Introduceti primul sir de caractere: "; cin.get(s1,100);
strcpy(cs1,s1); // Face o copie a primului sir
cin.get();
cout<<"Introduceti al doilea sir de caractere: "; cin.get(s2,100);
strcpy(cs2,s2); // Face o copie a sirului 2

strcat(s1,s2); // Adauga s2 la sfarsitul lui s1;


// rezultatul e memorat in s1
cout<<cs1<<"+"<<s2<<"="<<s1<<endl;
strcpy(s1,cs1); // Reface sirul 1

strcat(s2,s1); // Adauga s1 la sfarsitul lui s2;


// rezultatul e memorat in s2
cout<<cs2<<"+"<<s1<<"="<<s2<<endl;
}

8) strtok(s,delimitatori) – caută în şirul s subşirurile separate de caracterele din şirul de


delimitatori; la primul apel se va returna primul subşir din s format numai cu caractere care nu sunt în
lista de delimitatori; la fiecare din apelurile următoare, strtok foloseşte valoarea 0 sau NULL în locul
şirului s; subşirurile obţinute din impărţire sunt terminate cu '\0'.
Exemplu : Să se împartă un text în cuvinte. Cuvintele sunt separate de caracterele spaţiu, punct,
virgulă, :, ?.
#include<iostream.h>
#include<string.h>
char sir[100],*cuv,sep[10]=" .,:?";
void main()
{ cout<<"Introduceti textul: "; cin.get(sir,100);
cuv=strtok(sir,sep); // la primul apel strtok are ca parametrii
// textul de separat in cuvinte si lista de separatori
while (cuv)
{ cout<<cuv<<endl;
cuv=strtok(0,sep); // de la al doilea apel strtok are ca
// parametrii constanta 0 si sirul de separatori
}
}

9) strlwr(sir) – converteşte toate literele mari în litere mici.


9') strupr(sir) – converteşte toate literele mici în litere mari.
Exemplu : Să se citească un şir de caractere şi să se afişeze şirul cu toate literele mari şi apoi cu toate
literele mici.
#include<iostream.h>
#include<string.h>
int n;
char s[100];
void main()
{ cout<<"Dati un sir de caractere: "; cin.get(s,100);
cout<<strupr(s)<<endl;
cout<<strlwr(s)<<endl;
}
Următoarele funcţii au prototipul în <stdlib.h> şi folosesc pentru conversia valorilor numerice
în şir şi invers.
10) atoi(sir) – converteşte şirul primit ca parametru într-un număr de tip int; rezultatul este 0
dacă şirul de convertit nu începe cu o cifră.
Exemplu : Să se transforme un şir de caractere într-un număr.
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
int n;
char s[100];
void main()
{ cout<<"Dati un sir de caractere: "; cin>>s;
n=atoi(s);
if (n==0)
if (strlen(s)==1) cout<<"Numarul este 0";
else cout<<"Sirul nu reprezinta un numar";
else cout<<"Numarul este "<<n;
}

11) atof(sir) – converteşte şirul primit ca parametru într-un număr de tip double; rezultatul este
0 dacă şirul de convertit nu începe cu o cifră.

12) _atold(sir) – converteşte şirul primit ca parametru într-un număr de tip long double;
rezultatul este 0 dacă şirul de convertit nu începe cu o cifră.

13) atol(sir) – converteşte şirul primit ca parametru într-un număr de tip long; rezultatul este 0
dacă şirul de convertit nu începe cu o cifră.

14) itoa(valoare,sir,baza) – converteşte o valoare de tip int în şir ; valoarea baza reţine
baza de numeraţie către care să se facă conversia.

15) ltoa(valoare,sir,baza) – converteşte o valoare de tip long int în şir ; valoarea baza
reţine baza de numeraţie către care să se facă conversia.

16) ultoa(valoare,sir,baza) – converteşte o valoare de tip unsigned long în şir ; valoarea


baza reţine baza de numeraţie către care să se facă conversia.

4.3. Tipul înregistrare


Tipul înregistrare fixă cuprinde un număr fix de componente, numite câmpuri, care pot avea
tipuri diferite. Fiecărui câmp i se atribuie un nume, cu ajutorul căruia poate fi referit. Se declară o
înregistrare respectând sintaxa:
struct nume_structura
{ tip 1 id_camp1;
tip 2 id_camp2;
......................
tip n id_campn;
}
Câmpuri de acelaşi tip se declară prin identificatori separaţi prin virgule. Identificatorii
câmpurilor unei înregistrări trebuie să fie distincţi, chiar dacă nu au acelaşi tip. Câmpurile
înregistrărilor pot fi şi ele de tip înregistrare. Tipi poate fi orice tip de date C++, predefinit sau
utilizator, exceptând tipul fişier.
Identificatorii câmpurilor sunt locali definiţiei de tip înregistrare şi invizibili în exterior. În
program pot fi folosiţi identificatori identici cu identificatorii de câmpuri dintr-o definiţie de
înregistrare. Pot apare identificatori identici în declaraţii diferite de înregistrări.
Definirea unui tip înregistrare face numai descrierea structurii ei. Alocarea memoriei se face la
declararea variabilelor de tipul respectiv.
Exemplu :
struct elev { char nume[20],clasa[5];
float medie; } a,b;
elev e;
elev v[10];
Operaţiile care se pot face cu date de tip record sunt :
1. atribuire – se poate face între variabile înregistrare de acelaşi tip.
2. selectarea componentelor – se face prin intermediul operatorului de selectie, . , în forma
identif_inregistrare.identif_camp. Dacă tipul înregistrare conţine componente de tip înregistrare, se
folosesc mai mulţi operatori de selecţie.
Cu câmpurile unei înregistrări se pot face toate operaţiile admise de tipul lor de bază.

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