Metode evoluate de programare Limbajele c şi C++


Atribuiri de nume pentru tipuri de date



Yüklə 1,64 Mb.
səhifə20/44
tarix07.04.2018
ölçüsü1,64 Mb.
#46828
1   ...   16   17   18   19   20   21   22   23   ...   44

8.3. Atribuiri de nume pentru tipuri de date



După cum ştim tipurile de bază ale limbajului C, numite şi tipuri predefinite se identifică printr-un cuvânt cheie (int, char, float, etc). Totodată prin instrucţiunea struct, programatorul poate să introducă un tip nou. Programatorul poate să atribuie un nume unui tip (predefinit sau utilizator) cu ajutorul construcţiei:
typedef tip nume_nou_tip;

unde:


  1. tip este numele unui tip predefinit sau al unui tip utilizator (introdus cu struct);

  2. nume_nou_tip este noul nume atribuit tipului respectiv.

După ce s-a atribuit un nou nume unui tip, numele respectiv poate fi utilizat pentru a declara date de acel tip, la fel cum se utilizează în declaraţii cuvintele cheie int, char, float, etc.
Observaţii:

1o. De obicei numele atribuit unui tip se scrie cu litere mari.

2o. Un exemplu de astfel de nume există în fişierul stdio.h pentru tipul fişier, căruia i s-a atribuit numele FILE.

Exemple:


  1. Fie declaraţiile:

typedef int INTREG;

typedef float REAL;

În continuare, denumirile INTREG şi REAL se pot folosi la fel ca şi cuvintele cheie int şi float. Cu alte cuvinte, declaraţia:
INTREG i, j, tablou[10];
este identică cu declaraţia următoare:
int i, j, tablou[10];
Analog:

REAL x, y, z;


este identică cu declaraţia:
float x, y, z;


  1. typedef struct data_calendaristica

{ int ziua;

char luna[11];

int anul;

} DC;
Prin această declaraţie se atribuie denumirea DC tipului structurat data_calendaristica. În continuare putem declara date de tip DC:

DC data_nasterii, data_angajarii;

DC data_curenta ={31,”august”,1998};




  1. typedef int *PI;

Prin această declaraţie se introduce un sinonim pentru tipul pointer spre întregi: int *.

Putem să declarăm în continuare pointeri spre întregi astfel:


PI p;

care este echivalentă cu:


int *p;


  1. Declaraţia

typdef struct

{ double real;

double imaginar;

} COMPLEX;
introduce numele COMPLEX pentru datele de tip complex.

Funcţia următoare returnează modulul unui număr complex:


typedef struct

{ double real;

double imaginar;

} COMPLEX;

#include

double modul (COMPLEX *x) // returneaza modulul numarului

// spre care pointeaza x

{ return sqrt (x->real * x->real + x->imaginar * x->imaginar);

}


8.4. Uniune

Limbajul C oferă utilizatorului posibilitatea de a folosi aceeaşi zonă de memorie pentru a păstra date de tipuri diferite în momente diferite ale execuţiei programului. Astfel, de exemplu, putem utiliza o zonă de memorie pentru a păstra la un moment dat o dată flotantă, iar ulterior să reutilizăm aceeaşi zonă pentru o dată întreagă sau de tip pointer. Reutilizările zonelor de memorie conduc la utilizarea mai eficientă a acesteia, uneori putându-se obţine o economie substanţială a spaţiului de memorie alocat programului.



O uniune se declară printr-o construcţie asemănătoare declaraţiei de structură. Deosebirea constă în înlocuirea cuvântului struct prin union:
union nume

{ tip_membru_1;

. . .

tip_membru_2;



};

Exemplu:


union u

{ int i;


float f;

double d;

};
Prin această declaraţie s-a definit tipul de date u. În continuare, putem declara date de tipul u printr-o declaraţie de forma:

union u u1;


unde u1 este o dată de tip u căreia i se alocă o zonă de memorie care poate fi utilizată pentru a păstra date de tipurile int, float sau double. Deoarece tipul double necesită memoria cea mai mare se alocă 8 octeţi. Astfel zona u1 poate păstra pe oricare din celelalte componente ale uniunii dar în momente diferite ale execuţiei programului.

Accesul la componentele unei uniuni se face la fel ca şi în cazul structurilor. Astfel, pentru a ne referi la componenta i a uniunii u1 definită în exemplul anterior folosim construcţia:



u1.i
sau dacă p este pointer spre tipul u declarat prin
union u *p;

atunci construcţia

p -> i
permite accesul la componenta i a uniunii spre care pointează p.
Pentru a evita erorile legate de evidenţa în fiecare moment a datei care se prelucrează se ataşează unei uniuni o dată menită să indice componenta curentă. Această dată este specificată pentru fiecare uniune. De exemplu pentru uniunea u1 definită anterior este important să se ştie dacă zona de memorie conţine un întreg, un flotant în simplă precizie sau un flotant în dublă precizie. Se definesc trei constante simbolice:
#define INTREG 1

#define F_SIMPLU 2

#define F_DUBLU 3
Modificăm tipul u ataşând data tip_curent de tip int astfel:

struct u

{int tip_curent;

union { int i;

float f;

double d;

} uu;

};
Declarăm structura us astfel:



struct u us;
În acest caz, în momentul în care se păstrează o dată în zona rezervată uniunii, se atribuie componentei tip_curent una din constantele definite anterior:

  1. INTREG, dacă se păstrează un întreg;

  2. F_SIMPLU dacă se păstrează un flotant în simplă precizie;

  3. F_DUBLU dacă se păstrează un flotant în dublă precizie.

Astfel când se foloseşte componenta de tip int se va asocia atribuirea:
us.tip_curent=INTREG;
Analog se vor folosi ţi atribuirile următoare când se vor folosi componentele de tip float sau de tip double:

us.tip_curent=F_SIMPLU;

respectiv:



us.tip_curent=F_DUBLU;
În felul acesta, se poate testa, în fiecare moment, tipul de dată prezent în zona rezervată. Aceasta se poate face printr-o secvenţă de instrucţiuni if sau prin intermediul instrucţiunii switch.
if (us.tip_curent = = INTREG) // se foloseste us.uu.i

else if (us.tip_curent = = FSIMPLU) // se foloseste us.uu.f

else if (us.tip_curent = = FDUBLU) // se foloseste us.uu.d

else eroare

sau folosind switch avem o construcţie mai clară de forma:
switch (us.tip_curent)

{ case INTREG:



// se foloseste us.uu.i

break;


case FSIMPLU:

// se foloseste us.uu.f

break;


case FDUBLU

// se foloseste us.uu.d

break;


default:

// eroare

}
Programul următor calculează ariile pentru următoarele figuri geometrice:


  1. cerc;

  2. dreptunghi;

  3. pătrat;

  4. triunghi.

Programul citeşte datele pentru o figură geometrică, calculează aria figurii respective şi scrie rezultatul:

La intrare se folosesc următoarele formate:

- pentru cerc C raza;

- pentru dreptunghi D lungime laţime;

- pentru pătrat P latură;

- pentru triunghi T latură latură latură;

- sfârşit fişier EOF.


În cazul triunghiului, se utilizează formula lui HERON pentru calculul ariei:
aria = sqrt (p*(p-a)(p-b)(p-b))
unde p este semiperimetrul, iar a, b, c sunt cele 3 laturi.
#include

#include

#define PI 3.14159265

#define EROARE -1

#define CERC 1

#define PATRAT 2

#define DREPT 3

#define TRIUNGHI 4

typedef struct

{ int tip; // tipul figurii

union

{ double raza // cerc



double lp ; // patrat

double ld[2] ; // dreptunghi

double lt[3] ; // triunghi

} fig;


}FIG;
void main (void) // calculeaza arii

{

double aria,p;



int i;

char car[2];

FIG zfig;

for(; ;) // citeste primul caracter,el defineste tipul figurii geometrice

{ printf(“se cere o litera mare\n”);

if ((i = scanf("%1s",car)) == EOF) break;

if (i != 1)

{ printf (" se cere o litera mare\n");

continue;

}

zfig.tip = EROARE;



switch(car[0])

{case 'C': // cerc

printf("se cere raza cercului in flotanta\n");

i = scanf("%lf", &zfig.fig.raza);

if(i != 1)

{ printf("se cere raza cercului in flotanta\n");

break;

}

zfig.tip = CERC; // se pastreaza tipul figurii



break;
case 'P': // patrat

printf("se cere latura patratului in flotanta\n");

i = scanf("%lf",&zfig.fig.lp);

if( i !=1)

{ printf("se cere latura patratului in flotanta\n");

break;


}

zfig.tip = PATRAT;

break;

case 'D': // dreptunghi



printf("se cer laturile dreptunghiului in flotanta\n");

i = scanf("%lf %lf",&zfig.fig.ld[0],&zfig.fig.ld[1]);

if(i != 2)

{ printf("se cer laturile dreptunghiului in flotanta\n");

break;

}

zfig.tip = DREPT;



break;
case 'T': // triunghi

printf("se cer laturile triunghiului in flotanta\n");

i = scanf("%lf %lf %lf", &zfig.fig.lt[0], &zfig.fig.lt[1],&zfig.fig.lt[2]);

if(i != 3)

{ printf("se cer laturile triunghiului in flotanta\n");

break;


}

zfig.tip =TRI;

break;

printf("laturile nu formeaza un triunghi\n");



break;

default:


printf("se cere una din literele urmatoare\n");

printf("C pentru cerc\n");

printf("P pentru patrat\n");

printf("D pentru dreptunghi\n");

printf("T pentru triunghi\n");

} // sfarsit switch


switch (zfig.tip)

{case CERC: // aria cercului

printf("raza=%g aria=%g\n", zfig.fig.raza, PI*zfig.fig.raza*zfig.fig.raza);

break;


case PATRAT: // aria patratului

printf("latura =%g aria=%g\n",zfig.fig.lp, zfig.fig.lp*zfig.fig.lp);

break;

case DREPT: // aria dreptunghiului



printf("lungimea =%g latimea =%g\n", zfig.fig.ld[0], zfig.fig.ld[1]);

printf("aria=%g\n", zfig.fig.ld[0]*zfig.fig.ld[1]);

break;

case TRIUNGHI: // aria triunghiului



p=(zfig.fig.lt[0] + zfig.fig.lt[1] + zfig.fig.lt[2])/2;

if(p>zfig.fig.lt[0] && p>zfig.fig.lt[1] && p>zfig.fig.lt[2])

{p=p*(p-zfig.fig.lt[0])*(p-zfig.fig.lt[1])* (p-zfig.fig.lt[2]);

printf("a=%g b=%g c=%g\n", zfig.fig.lt[0], zfig.fig.lt[1], zfig.fig.lt[2]);

printf("aria = %g\n",sqrt(p));

}

else { printf (“ laturile nu formeaza un triunghi”);



break;

}

default : // avans pana la newline sau EOF



while ((i = getchar()) != ‘\n’ && i != EOF);

} // sfarsit switch

if (i = = EOF) break;

} // sfarsit for

} // sfarsit main


Yüklə 1,64 Mb.

Dostları ilə paylaş:
1   ...   16   17   18   19   20   21   22   23   ...   44




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin