|
Structuri
|
Definirea structurilor
|
O structura
este o colectie de valori eterogene, stocate intr-o zona compacta de memorie.
Componentele unei structuri, denumite
campuri,
sunt identificate prin nume simbolice, denumite selectori.
Campurile unei structuri pot fi de orice tip, simplu sau derivat, dar nu
void
sau functie.
Declararea
structurilor:
Declararea
structurilor se face folosind cuvantul cheie struct:
struct nume_structura{
lista_campuri //declaratii
de forma tip_campi nume_campi;
}lista_declaratori; //variabile
de tip structura |
nume_structura saulista_declaratori
pot
lipsi, dar nu simultan. Daca se precizeaza nume_structura,
atunci inseamna ca se face definirea tipului struct
nume_structura,
care poate fi apoi folosit pentru declararea de variabile, ca tip de parametri
formali sau ca tip de rezultat returnat de functii:
struct coordonate{//se
declara tipul struct coordonate
float x,y;
}punct,*ppunct,puncte[20]; //variabile
struct coordonate alt_punct={1,4.5},
alte_puncte[10]={{2,4},{8},{9,7}},
mai_multe_puncte[25]={1,2,3,4};
//variabilele
de tip structura se pot initializa lase pot initializa la declarare;
//campurile
neprecizate sunt implicit 0 |
struct persoana{ //se
declara tipul struct persoana
char nume[20];
int varsta;
}; //lipseste
lista_declaratori
struct persoana pers={"Ion Ionescu",21}, *ppers,
persoane[12]; |
struct{ //lipseste
nume_struct
char titlu[20],autor[15],editura[12];
int an_aparitie;
}carte,biblioteca[1000]; //nu
se declara un tip, deci
//doar aici pot fi facute declaratiile de variabile |
Un
camp al unei structuri poate fi de tip structura, dar nu aceeasi cu cea
definita - se poate insa sa se declare un camp pointer la structura definita
( aspect care va fi utilizat la implementarea listelor
):
struct persoana{ //se
declara tipul struct persoana
char nume[20];
struct{
int zi,an,luna
}data_nasterii; //camp
de tip structura
}p; |
struct nod_lista{
tip_info info;
struct nod_lista * urm;//camp
pointer la structura
//definita
}; |
Numele
de structuri se afla intr-un spatiu de nume diferit de cel al numelor de
variabile - se pot declara deci variabile si tipuri structura cu acelasi
nume - de evitat insa. Se pot declara tipuri structuri care au nume de
campuri identice.
Observatie:
Folosind
cuvantul cheie typedef se pot defini tipuri utilizator echivalente pentru
cele structura - s-a discutat la Modulul Tipuri
fundamentale; a se vedea Exemplul 1 rezolvat mai jos.
Operatii cu structuri
|
-
Selectarea
unui camp al unei variabile structura se realizeaza folosind operatorul
de selectie .
.
Campul selectat se comporta ca o variabila de acelasi tip, deci i se pot
aplica aceleasi prelucrari ca oricarei variabile de tipul respectiv.
variabila_structura.nume_camp
|
Selectia
campurilor pentru variabila p de mai sus:
p.nume //tablou
de caractere
p.nume[0] //primul
caracter din nume
p.nume[strlen(p.nume)-1]
//ultimul caracter din nume
p.data_nasterii.an
p.data_nasterii.luna
p.data_nasterii.an
-
Deoarece
structurile se prelucreaza frecvent prin intermediul pointerilor, a fost
introdus operatorul ->
care
combina cel de indirectare *
cu
cel de selectie..Cele
doua expresii de mai jos sunt echivalente:
(*variabila_pointer).nume_camp
variabila_pointer->nume_camp
|
-
Unei variabile
de tip structura i se pot aplica operatorii &
si
sizeof
-
O variabila
structura poate fi initializata la declarare prin precizarea
intre {} a valorilor campurilor; cele neprecizate sunt implicit 0
-
O variabila
structura poate fi copiata in alta variabila de acelasi tip
Cu
declaratiile
de mai sus:
printf("%d %d\n",sizeof(pers),sizeof(struct
persoana));
ppers=&pers;
persoane[0]=*ppers;
//atribuirea
intre doua variabile structura
-
O variabila
structura nu poate fi citita sau scrisa direct, ci prin intermediul campurilor
-
Functiile
pot avea parametrii de tip structura
-
Tipul
rezultatului returnat de o functie poate fi structura - a se studia exemplele
de mai jos.
Quiz
|
Sa vedem daca notiunile
prezentate sunt clare:
Se
considera urmatoarea declaratie pentru tipul struct
figura:
struct
figura{
char nume[20];
int nr_laturi;
int egale;
};
1.Cum
se declara doua variabile fig1 si fig 2 de acest tip?
2.Cum
se poate citi variabila fig1?
3.Care
este secventa corecta pentru a copia campurile lui fig1 in cele ale lui
fig2?
Exercitii
|
1.a.
Definiti tipul ORAS care contine campurile:
-
nume -
sir de 20 caractere;
-
precip
- real ( pentru cantitatea de precipitatii );
-
zona -
caracter,
putand avea valorile 'N', 'S', 'E', 'V' ( punctele cardinale );
b. Scrieti
functia CITIRE_ORAS, fara parametri, care citeste informatiile despre o
structura ORAS, pe care o returneaza; se va face validarea campurilor:
nume - poate contine doar litere; precip - o valoare pozitiva; zona - poate
fi doar unul din caracterele de mai sus;
c.
Definiti tabloul ORASE de MAX elemente de tip ORAS, MAX fiind o constanta
predefinita;
d.
Scrieti functia CITIRE_ORASE, void, fara parametri, care initializeaza
tabloul ORASE, considerat variabila globala, prin apelul functiei CITIRE_ORAS;
e.
Scrieti functia TIPARIRE care primeste doi parametri, un real si un caracter
si tipareste informatiile despre orasele din tabloul ORASE, care au campul
precip mai mare decat primul parametru, au zona egala cu caracterul primit
si numele incepe cu o consoana; functia va returna numarul de orase gasite
ca avand caracteristicile de mai sus;
f.
Scrieti programul care sa apeleze functiile de la d,e.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#define LUNG 21
#define MAX 4
typedef struct{ //a
char nume[LUNG];
float precip;
char zona;
}ORAS;
ORAS ORASE[MAX]; //c
//b
int nume_valid(char *); //tipul
parametrului formal mai poate fi scris char []
//numele
parametrilor formali nu e obligatoriu
//sa
apara in prototip
int precip_valid(float);
int zona_valida(char);
ORAS CITIRE_ORAS(void){
ORAS o; //variabila
locala ale carei campuri se citesc
while(printf("Nume oras:"),gets(o.nume),!nume_valid(o.nume));
while(printf("Cantitate precipitatii:"),scanf("%f",&o.precip),
!precip_valid(o.precip));
getchar(); //se
scoate codul lui ENTER din buffer-ul de intrare
while(printf("Zona (N,S,E,V):"),o.zona=toupper(getche()),!zona_valida(o.zona));
putchar('\n');
return o;
}
/*void
CITIRE_ORAS(ORAS *po){ //varianta
a functiei care primeste pointerul
//la structura de citit
while(printf("Nume oras:"),gets(po->nume),!nume_valid(po->nume));
while(printf("Cantitate precipitatii:"),scanf("%f",&po->precip),
!precip_valid(po->precip));
getchar(); //se
scoate codul lui ENTER din buffer-ul de intrare
while(printf("Zona (N,S,E,V):"),po->zona=toupper(getche()),
!zona_valida(po->zona));
putchar('\n');
}*/
int nume_valid(char * n){
int i;
if(strlen(n)==0)
return 0; //numele
e invalid daca e vid
for(i=0;i<strlen(n);i++) //expresia
conditie mai poate fi scrisa n[i]
if(!isalpha(n[i]))
return 0;
//caracter
curent nu e alfabetic, se returneaza 0
return 1; //toate
caracterele au fost litere
}
int precip_valid(float p){
return p>=0;
}
int zona_valida(char z){
return z=='N'||z=='S'||z=='E'||z=='V';
}
void CITIRE_ORASE(void){ //d
int i;
for(i=0;i<MAX;i++)
ORASE[i]=CITIRE_ORAS();
//apel
pentru varianta
//CITIRE_ORAS(&ORASE[i]);
}
int verif(ORAS,float,char); //e
//verifica
si tipareste informatiile despre un oras
int TIPARIRE(float p,char z){
int i,contor;
for(i=contor=0;i<MAX;i++)
if(verif(ORASE[i],p,z))
contor++;
return contor;
}
int verif(ORAS o,float p,char z){
char c;
if((c=toupper(o.nume[0]),c!='A'&&c!='E'&&c!='I'&&c!='O'&&c!='U')
//primul
caracter din nume nu e vocala
&& o.precip>=p
&& o.zona==toupper(z)){
printf("%s
%f %c\n",o.nume,o.precip,o.zona);
return
1;
}
return 0;
}
void main(void){ //e
CITIRE_ORASE();
printf("%d orase indeplinesc criteriile\n",TIPARIRE(23,'v'));
getche();
} |
2.a.
Definiti tipul MECI cu campurile:
echipa1, echipa2 - siruri de 20 caractere
nr1, nr2 - intregi ( nr de goluri marcate de fiecare echipa );
b.
Scrieti functia CITIRE_MECI, fara parametri, care citeste informatiile
despre o structura MECI, pe care o returneaza - nr1, nr2 trebuie sa fie
pozitive;
c.Sa
se defineasca tabloul CAMPIONAT cu MAX elemente de tip MECI, MAX fiind
o constanta predefinita;
d.
Scrieti functia CITIRE_CAMP, void, fara parametri, care initializeaza tabloul
CAMPIONAT, considerat variabila globala, prin apelul functiei CITIRE_MECI;
e.
Sa se scrie functia TIP care primeste un sir de caractere si tipareste
informatiile despre toate meciurile din tabloul CAMPIONAT, in care echipa
cu numele primit a obtinut victoria sau rezultat egal; functia va returna
numarul de meciuri tiparite;
f.
Scrieti programul care sa apeleze functiile de la d,e.
3.a.
Definiti tipul MATERIA care contine campurile: nume - sir de 15 caractere;
ore_curs - intreg; tip_examen - caracter, putand avea valorile 'C', 'S',
'A' ( colocviu, examen de semestru sau de an );
b.
Scrieti functia CITIRE_MAT, fara parametri, care citeste informatiile despre
o structura MATERIA, pe care o returneaza; se va face validarea tuturor
campurilor: nume - contine doar litere sau blancuri; ore_curs - intreg
strict pozitiv; tip_examen - doar unul din caracterele de mai sus;
c.
Definiti tabloul PROGRAMA de MAX elemente de tip MATERIA, MAX fiind o constanta
predefinita;
d.
Scrieti functia CITIRE_PROGRAMA, void, fara parametri, care initializeaza
tabloul PROGRAMA, considerat variabila globala, prin apelul functiei CITIRE_MAT;
e.
Scrieti functia TIP care primeste ca parametru un caracter si un intreg,
tipareste informatiile despre materiile din PROGRAMA care au campul
tip_examen identic cu parametrul si nr_ore egal cu intregul si returneaza
numarul de materii gasite si tiparite.
f.
Scrieti programul care sa apeleze functiile de la d,e.
Copyright
© 2001-2002. Carmen Holotescu
All
rights reserved. Published by Timsoft
|