10.1. Declaratia de structura

2019/03/23 in Programare in C

Pentru a declara o structura se pot folosi mai multe formate. Un format utilizat frecvent este:

(1)

struct nume {
  lista_de_declaratii
} nume1, nume2, ..., numen;

unde:

nume, nume1, nume2, ..., numen sunt nume care pot si lipsi, dar nu toate deodata.

Daca nume este absent, atunci cel putin nume1 trebuie sa fie prezent.

Daca lista nume1, nume2, ..., numen este absenta, atunci trebuie ca nume sa fie prezent.

Daca nume este prezent, atunci el defineste un tip nou, introdus prin declaratia de structura respectiva. El poate fi utilizat in continuare pentru a defini date de acest tip, in mod asemanator cum definim date de tipuri predefinite.

In declaratia de mai sus, nume1, nume2, ..., numen sunt structuri de tip nume.

In declaratia de mai sus, numei pentru i = 0,1,2,...,n se poate inlocui cu:

numei[lim1][lim2]...[limk]

si atunci numei este un tablou k-dimensional de elemente de tip nume.

Prin lista_de_declaratii intelegem una sau mai multe declaratii prin care se declara componentele structurii de tip nume.

O structura de tip nume poate fi declarata si ulterior, folosind formatul:

(2)

struct nume nume_de_structura;

unde:

nume_de_structura este un nume.

Aceasta declaratie seamana cu o declaratie obisnuita in care se folosesc tipuri predefinite:

tip nume_data_izolata;

Deci tip dintr-o declaratie obisnuita se inlocuieste cu struct nume, unde nume este definit in prealabil printr-o declaratie de structura de forma (1), in care nume1, nume2, ..., numen pot si lipsi.

Exemple:

  1. Declaram data_nasterii si data_angajarii ca structuri de tipul data_calendaristica, care este compusa din cele trei date amintite mai sus: zi, luna si an:

    struct data_calendaristica {
      int zi;
      char luna[11];
      int an;
    } data_nasterii, data_angajarii;
    

    Declaratia de fata este de forma (1).

    In cazul in care nu dorim sa introducem tipul data_calendaristica, se poate utiliza declaratia:

    struct {
      int zi;
      char luna[11];
      int an;
    } data_nasterii, data_angajarii;
    

    In sfarsit, este posibil sa definim tipul data_calendaristica si apoi sa declaram datele data_nasterii si data_angajarii, folosind formatul (2):

    struct data_calendaristica {
      int zi;
      char luna[11];
      int an;
    } ;
    
    struct data_calendaristica data_nasterii, data_angajarii;
    

    Prima declaratie introduce tipul utilizator data_calendaristica.

    Declaratia a doua defineste datele data_nasterii si data_angajarii ca fiind structuri de tipul data_calendaristica.

  2. Fie tipul data_calendaristica definit mai sus. Declaratia:

    struct data_calendaristica d[100];

    defineste pe d ca un tablou de 100 de elemente, fieacare element fiind de tipul data_calendaristica.

  3. Consideram un model simplificat de date personale:

    • nume_prenume;
    • adresa;
    • localitatea_nasterii;
    • cod;
    • data_nasterii;
    • data_angajarii;
    • sex;
    • stare_civila;
    • numar_copii.

    Prin declaaratia de mai jos introducem tipul date_pers:

    struct date_pers {
      char nume_prenume[100];
      char adresa[100];
      char localitatea_nasterii[100];
      long cod;
      struct data_calendaristica data_nasterii, data_angajarii;
      char sex;
      char starea_civila[15];
      int numar_copii;
    };

    La definirea tipului date_pers s-a utilizat tipul data_calendaristica. Acest lucru este posibil daca tipul data_calendaristica este in prealabil definit.

    Fie declaratia:

    struct date_pers unangajat, nangajati[1000];

    Prin aceasta declaratie se declara structura unangajat si tabloul de structuri nangajati. Ambele au tipul date_personale.

  4. In acest exemplu se introduce tipul complex:

    struct complex {
      double x;
      double y;
    };

    Datele declarate cu ajutorul declaratiei:

    struct complex z, tz[100];

    sunt date de tipul complex. Atat partea reala, cat si partea imaginara sunt date de tip double.

  5. Fie declaratia:

    struct dmatp2 {
      double matrice[2][2];
    };
    
    struct dmatp2 a, b;
    

    Variabilele a si b sunt fiecare cate o matrice patratica de ordinul 2 a caror elemente sunt numere de tip double.

  6. Fie declaratia:

    struct elev {
      char *nume;
      char *prenume;
      long nr_matricol;
      struct data_calendaristica data_nasterii;
      char *adresa;
      char *locul_nasterii;
      int clasa;
      int note[15];
    };

    Prin aceasta declaratie s-a introdus tipul elev. Declaratia urmatoare defineste date de tipul elev:

    struct elev unelev, clasaelevi[25];
  7. Ecranul pe care se afiseaza datele poate fi gestionat in mod text sau in mod grafic. In mod implicit, ecranul se gestioneaza in mod text. In acest mod, ecranul se compune, de obicei, din 25 de linii a 80 de coloane.

    Pozitia unui punct pe ecran se defineste prin 2 valori (coordonate):

    x numarul coloanei;
    y numarul liniei.

    Coltul din stanga sus are coordonatele:

    x = 1;
    y = 1.

    Coltul din dreapta jos are coordonatele:

    x = 80;
    y = 25.

    Pentru a controla afisarea datelor pe ecran, se pot utiliza diferite functii standard de gestiune a ecranului. O parte din aceste functii folosesc coordonatele x si y de felul celor indicate mai sus.

    Adesea este util sa definim tipul punct printr-o declaratie de felul urmator:

    struct punct {
      int x;
      int y;
    };

    Cu ajutorul acestui tip se pot defini pozitii pe ecran:

    struct punct poz;

Structurile sunt date care se pot aloca la fel ca si celelalte date (variabile simple sau tablouri). Astfel, o structura este globala daca se declara in afara corpului oricarei functii, este automatica daca se declara in corpul unei functii sau statica daca declaratia ei incepe cu cuvantul cheie static.

Datele elementare care sunt componente ale unei structuri se pot initializa. In acest scop, intr-o declaratie sau definitie de structura, dupa numele structurii, se scrie caracterul =, iar dupa aceasta constructiile prin care se vor initializa componentele elementare ale structurii, separate prin virgula si introduse intre acolade. Constructiile utilizate la initializare sunt expresii constante care corespund elementelor pe care le initializeaza.

Exemple:

  1. struct data_calendaristica dc = {1, "septembrie", 1994};

    unde:

    data_calendaristica este tipul declarat in prealabil astfel:

    struct data_calendaristica {
      int zi;
      char luna[11];
      int an;
    };

  2. Fie tipul complex:

    struct complex {
      double x;
      double y;
    };

    Declaratia de mai jos defineste variabila complexa z, care initial are valoarea 1 + 2i:

    struct complex z = {1.0, 2.0};

Componentele elementare neinitializate ale unei structuri au valoarea initiala zero daca structura este globala sau statica.

In cazul structurilor automatice, elementele neinitializate au o valoare initiala nedefinita.

Operatorul unar adresa (&) se poate aplica numelui unei structuri. Ca rezultat se obtine adresa primei sale componente elementare. De asemenea, se pot defini pointeri spre tipuri utilizator.

Exemplu:

struct complex {
  double real;
  double imag;
};
struct complex *p;
struct complex z;
...
p = &z;

10.2. Accesul la elementele unei structuri