Sunteți pe pagina 1din 11

PCLP. Laborator 12: typedef, uniuni și câmpuri de biţi.

Intrări și ieșiri (Cursul 10)


typedef
Limbajul C pune la dispoziţie o facilitate numită typedef pentru crearea de noi nume de tipuri de date. Spre
exemplu, declaraţia
typedef int Lungime;

face numele Lungime sinonim cu int. Tipul Lungime poate fi folosit în declaraţii, conversii etc., în exact
aceleaşi moduri ca şi tipul int:
Lungime lung, maxlung;
Lungime *lungimi[];
În mod asemănător, declaraţia
typedef char *Sir;

face numele de tip de dată Sir un sinonim pentru char* (pointer către char), care apoi poate fi folosit în
declaraţii şi conversii:
Sir p, ptrlinie[MAXLINII], alloc(int);
int strcmp(Sir, Sir);
p = (Sir) malloc(100);

Observaţi că nume de tip de dată declarat într-o construcţie typedef apare în poziţia unui nume de variabilă şi
nu imediat după cuvântul typedef.

Aplicație propusă 1. Folosind typedef creați un nou nume byte pentru tipul de dată unsigned char. Scrieți
un program care sa citească și să afișeze o variabilă de tipul byte.

Aplicație propusă 2. Scrieți un program care citește notele la cele două subiecte de la examenul de PCLP ale
unui student și calculează media studentului la proba scrisă a examenului de PCLP. Se va folosi typedef
pentru a da numele mai specific: nota tipului int si medie tipului float.

Aplicație rezolvată 1. Rescrieți programul anterior care citește notele la cele două subiecte de la examenul de
PCLP ale unui student și calculează media studentului la proba scrisă a examenului de PCLP. Se vor folosi
pointeri către int și către float și typedef pentru a da numele mai specific: pointer_la_intreg, tipului
int* si pointer_la_real, tipului float*.
#include <stdio.h>
main()
{
typedef int *Pointer_la_intreg;
typedef float *Pointer_la_real;
typedef int Nota;
typedef float Medie;
Nota nota1, nota2;
Medie media;
Pointer_la_intreg nota_subiect1_pclp = &nota1, nota_subiect2_pclp = &nota2;
Pointer_la_real nota_examen_pclp = &media;
printf("nota la primul subiect la PCLP : ");
scanf("%d", nota_subiect1_pclp);
printf("nota la al 2-lea subiect la PCLP : ");
scanf("%d", nota_subiect2_pclp);
*nota_examen_pclp = *nota_subiect1_pclp + *nota_subiect2_pclp;
*nota_examen_pclp = *nota_examen_pclp/2;
1
printf("\nnota examen scris PCLP : %5.2f\n", *nota_examen_pclp);
return 0;
}
UNIUNI

O uniune este o variabilă care poate stoca la momente diferite obiecte de diferite tipuri şi dimensiuni. Menirea
unei uniuni este ca o singură variabilă să stocheze în mod legal o valoare ce poate aparţine oricăruia dintr-o
anumită colecţie de tipuri.
union n_nume {
int ival;
float fval;
char *sval;
}u;

Variabila u va fi suficient de voluminoasă pentru a stoca cel mai voluminos dintre cele trei tipuri (int, float,
char). Oricare dintre aceste tipuri poate fi atribuit lui u şi apoi folosit în expresii. Tipul folosit trebuie să fie
tipul cel mai recent stocat. Din punct de vedere sintactic, membrii unei uniuni sunt accesaţi astfel:
nume-uniune.membru
sau
pointer_spre_uniune -> membru

la fel ca în cazul structurilor. Dacă variabila utip este folosită pentru a ţine evidenţa tipului curent stocat în u,
atunci aţi putea întâlni cod precum:
if (utip == INT)
printf("%d\n", u.ival);
if (utip == FLOAT)
printf(”%f\n", u.fval);
if (utip == SIR)
printf(“%s\n", u.sval);
else
printf("tip necorespunzator %d in utip\n", utip);

Uniunile pot apărea în interiorul structurilor şi tablourilor şi invers. Notaţia pentru accesarea unui membru al
unei uniuni aflată în interiorul unei structuri (şi invers) este identică aceleia folosite pentru structurile imbricate.
Spre exemplu, în tabloul tabsim[] de structuri definit prin:
struct {
char *nume;
int indicatori;
int utip;
union {
int ival;
float fval;
char *sval;
}u;
}tabsim[NSIM];

Referinţa la membrul ival se face astfel


tabsim[i].u.ival

Referinţa la primul caracter al şirului sval prin oricare dintre expresiile


*tabsim[i].u.sval
tabsim[i].u.sval[0]

Aplicație rezolvată 2. Să se definească o uniune și o structură cu aceleași câmpuri, să se declare câte o


variabilă de tipul uniunii și al structurii și să se afișeze mărimea în octeți pe care o ocupă în memorie fiecare din
cele două variabile declarate.
Observații:
• Deși membrii (câmpurile) uniunii și structurii sunt identice ca tip de date, spațiul ocupat în memorie este
2
diferit; pentru că spațiul ocupat în memoria internă de o structură este suma spațiilor ocupate de fiecare
membru al ei, pe câtă vreme spațiul ocupat în memoria internă de o uniune este egal cu dimensiunea ocupată
de membrul cu cea mai mare întindere.
• Folosim fgets() pentru a citi un șir de caractere ce poate conține spații. Citirea cu scanf() se oprește la
întâlnirea primului spațiu.
• scanf("%g%*c", &student_uniune.inaltime); conține %*c pentru a elimina caracterul <Enter> pe care
scanf() nu îl citește și astfel rămâne în buffer. Dacă nu îl eliminăm din buffer, caracterul <Enter> va fi citit
de următoare instrucțiune fgets(), care astfel nu va mai citi nimic de la utilizatorul programului. Încercați
să eliminați secvența %*c din scanf() și observați ce se întâmplă.
• O variantă la utilizarea secvenței %*c în scanf() ar fi să utilizăm fflush(stdin) după scanf() pentru a
goli bufferul. Astfel
scanf("%g%*c", &student_uniune.inaltime);
se va înlocui cu
scanf("%g", &student_uniune.inaltime);
fflush(stdin) ;
obținând același efect.
#include <stdio.h>

union uniune {
char nume[20];
int greutate;
float inaltime;
} student_uniune;

struct structura {
char nume[20];
int greutate;
float inaltime;
} student_structura;

int main()
{
printf("CITIRE DATE FOLOSIND UNIUNEA \n");
printf("nume student = "); fgets(student_uniune.nume, 20, stdin);
printf("numele studentului = %s\n", student_uniune.nume);
printf("greutate student = "); scanf("%d", &student_uniune.greutate);
printf("greutatea studentului = %d\n", student_uniune.greutate);
printf("\ninaltime student = "); scanf("%g%*c", &student_uniune.inaltime);
/* %*c elimina \n ca sa nu il citeasca fgets() */
printf(„inaltimea studentului = %5.2f\n”, student_uniune.inaltime);

printf(„\n\nCITIRE DATE FOLOSIND STRUCTURA \n”);


printf(„nume student = „); fgets(student_structura.nume, 20, stdin);
printf(„greutate student = „); scanf(„%d”, &student_structura.greutate);
printf(„inaltime student = „); scanf(„%g”, &student_structura.inaltime);
printf(„\nnumele studentului = %s”, student_structura.nume);
printf(„greutatea studentului = %d\n”, student_structura.greutate);
printf(„inaltimea studentului = %5.2f\n”, student_structura.inaltime);

printf(„\n\nmarimea in octeti a uniunii = %d”, sizeof(student_uniune));


printf(„\nmarimea in octeti a structurii = %d\n”, sizeof(student_structura));

return 0;
}
Observație: Pentru o structură putem stoca în orice ordine membrii și îi putem folosi în orice ordine. Pentru o
uniune membrul folosit este membrul stocat ultimul.

Aplicație propusă 3. Scrieți un program care să declare o variabilă x de tip uniune cu trei câmpuri ca mai jos:
3
union nume {
int i;
float f;
char s[100];
}x;

și să folosească variabila xtip pentru a ţine evidenţa tipului curent stocat în x, conform modelului:
if (xtip == INTREG)
printf("%d\n", x.i);
else if (xtip == REAL)
printf(”%f\n", x.f);
else if (xtip == SIR)
printf(“%s\n", x.s);
else
printf("eroare\n");

Temă: Înlocuiți
instrucțiunile if
imbricate cu un
switch.

Aplicație propusă 4. Rescrieți aplicația de mai sus folosind pointeri pentru a accesa membrii uniuni.
union nume *pu;

Aplicație rezolvată 3. Să se definească un


tablou de structuri de tip figuri geometrice
(cerc, triunghi, dreptunghi) care să memoreze
- folosind o uniune - pentru fiecare figură
caracteristicile acesteia (rază, laturi). Să se
scrie un program care să citească fiecare
element al tabloului corespunzând unui tip de
figură împreună cu caracteristicile ei, apoi să
afișeze elementele tabloului.
#include <stdio.h>
#include <stdlib.h>

#define N 5

enum tip {CERC, TRIUNGHI, DREPTUNGHI};

struct figuri {
enum tip tip_fig;
union {
float raza;
struct {
float l1, l2, l3;
} triunghi ;
struct {
float l1, l2;
} dreptunghi ;
} caracteristici;
} ;
4
main()
{
enum tip xtip;
struct figuri figura[N];
int i;

printf("CITIREA DATELOR CORESPUNZATOARE FIGURILOR");


for(i = 0; i < N; ++i){
printf("\nFigura[%d]: 0 (cerc), 1 (triunghi), 2 (dreptunghi) ?", i);
scanf("%d%*c", &xtip);

if (xtip == CERC){
figura[i].tip_fig = CERC;
printf("Raza cercului (nr real pozitiv) = ");
scanf("%f", &figura[i].caracteristici.raza);
}
else if (xtip == TRIUNGHI){
figura[i].tip_fig = TRIUNGHI;
printf("Latura 1 (nr real pozitiv) = ");
scanf("%g", &figura[i].caracteristici.triunghi.l1);
printf("Latura 2 (nr real pozitiv) = ");
scanf("%g", &figura[i].caracteristici.triunghi.l2);
printf("Latura 3 (nr real pozitiv) = ");
scanf("%g", &figura[i].caracteristici.triunghi.l3);
}
else if (xtip == DREPTUNGHI){
figura[i].tip_fig = DREPTUNGHI;
printf("Latura 1 (nr real pozitiv) = ");
scanf("%g", &figura[i].caracteristici.dreptunghi.l1);
printf("Latura 2 (nr real pozitiv) = ");
scanf("%g", &figura[i].caracteristici.dreptunghi.l2);
}
else {
printf("Eroare introducere cod figura!");
exit(1);
}
}

printf("\nAFISAREA DATELOR CITITE PENTRU FIGURI\n");


for(i = 0; i < N; ++i){
if (figura[i].tip_fig == CERC){
printf("Figura %d = CERC cu raza = %g\n", i, figura[i].caracteristici.raza);
}
else if (figura[i].tip_fig == TRIUNGHI){
printf("Figura %d = TRIUNGHI cu laturile = (%g, %g, %g)\n", i,
figura[i].caracteristici.triunghi.l1, figura[i].caracteristici.triunghi.l2,
figura[i].caracteristici.triunghi.l3);
}
else if (figura[i].tip_fig == DREPTUNGHI){
printf("Figura %d = DREPTUNGHI cu laturile = (%g, %g)\n", i,
figura[i].caracteristici.dreptunghi.l1, figura[i].caracteristici.dreptunghi.l2);
}
}

return 0;
}
Teme:
• Înlocuiți instrucțiunile if imbricate cu un switch.
• Adăugați în uniunea caracteristici și alte caracteristici cum ar fi cele legate de poziționarea figurii într-un
sistem cartezian Oxy: coordonatele centrului cercului (float x, y;), considerând triunghiul și
dreptunghiul cu o latură paralelă cu axa Ox, coordonatele colțului din stânga jos pentru triunghi/ dreptunghi
(float x, y;) etc.

5
• Adăugați programului posibilitatea citirii și de alte figuri geometrice (e.g. romb, paralelogram) fiecare cu
caracteristici proprii.
• Adăugați structurii un membru observatii de tip șir de caractere care să memoreze anumite proprietăți
ale figurilor (e.g. triunghi: oarecare, isoscel, echilateral, dreptunghi cu laturi egale: pătrat)

CÂMPURI DE BIŢI (bit-fields)

Când spaţiul de stocare este prioritar, ar putea fi necesar să împachetăm mai multe obiecte într-un singur cuvânt
de maşină. O practică des întâlnită este o colecţie de indicatori pe câte un bit în interiorul unui singur char sau
int. Modalitatea obişnuită de a realiza acest lucru este de a defini un set de „măşti“ corespunzătoare poziţiilor
de biţi relevante, cum ar fi:
#define CUVCHEIE 01
#define EXTERN 02
#define STATIC 04

sau
enum {CUVCHEIE = 01, EXTERN = 02, STATIC = 04}

Numerele (01, 02, 04) trebuie să fie puteri ale lui doi. Anumite expresii apar
frecvent:

indicatori |= EXTERN | STATIC;

setează la 1 biţii EXTERN şi STATIC din indicatori.

indicatori &= ~ (EXTERN | STATIC)

care est tot una cu:


indicatori = indicatori & (~EXTERN & ~STATIC)

setează la 0 biţii EXTERN şi STATIC din indicatori

if ((indicatori & (EXTERN | STATIC)) == 0)

este adevărată dacă ambii biţi (EXTERN şi STATIC) din indicatori au valoarea 0.

Deşi aceste expresii sunt bine puse la punct, ca alternativă, limbajul C oferă posibilitatea de a defini şi a accesa
direct câmpuri din interiorul unui cuvânt, în loc de a folosi operatori logici pe biţi. Un câmp de biţi, sau pe
scurt: câmp, este un set de biţi alăturaţi din cadrul unei unităţi din spaţiul de stocare, definită prin implementare,
pe care o vom numi un „cuvânt“.

Sintaxa definirii şi accesării unui câmp de biți este bazată pe structuri. Spre exemplu, tabela de simboluri
definite cu ajutorul lui #define de mai sus ar putea fi înlocuită cu definiţia a trei câmpuri:
struct {
unsigned int este_cuvcheie: 1;
unsigned int este_extern : 1;
unsigned int este_static : 1;
} indicatori;
6
Acest cod defineşte o variabilă numită indicatori care conţine 3 câmpuri de câte 1 bit. Numărul care urmează
după caracterul două puncte : reprezintă dimensiunea câmpului în biţi. Câmpurile sunt declarate de tipul
unsigned int pentru a asigura faptul că sunt mărimi pozitive. Referirea individuală la câmpuri se face la fel ca
pentru alţi membri ai unei structuri:
indicatori.este_cuvcheie
indicatori.este_extern
Câmpurile se comportă ca nişte întregi mici şi pot face parte din expresii aritmetice la fel ca orice alţi întregi.

Astfel, exemplele anterioare pot fi scrise într-un mod mai natural astfel:
indicatori.este_extern = indicatori.este_static = 1; /* pentru a seta biţii la valoarea 1 */
indicatori.este_extern = indicatori.este_static = 0; /* pentru a seta biții la valoarea 0 */
if(indicatori.este_extern == 0 && indicatori.este_static == 0) /* pentru a evalua biții */
Câmpurile nu au nevoie de nume; câmpurile fără nume (doar un caracter două puncte şi dimensiunea) sunt
folosite pentru umplerea spaţiului liber. Valoarea specială 0 a dimensiunii poate fi folosită pentru a forţa
alinierea la marginea următorului cuvânt.

Câmpurile nu pot fi declarate decât ca fiind de tipul int. Pentru portabilitate, specificaţi în mod explicit signed
sau unsigned. Câmpurile nu sunt tablouri şi nu au adrese, deci operatorul & nu li se poate aplica.

Aplicație rezolvată 4. Să se scrie un program care memorează ora, ziua, luna și anul unui eveniment folosind
două variante: o structură clasică și un câmp de biți. Să se afișeze spațiul ocupat în memorie de cele două tipuri
de date.
#include <stdio.h>

struct camp_de_biti {
unsigned int ora: 5; /* 0..24 deci 0..31: 5 biti */
unsigned int zi : 5; /* 0..31 deci 0..31: 5 biti */
unsigned int luna : 4; /* 0..12 deci 0..15: 4 biti */
int an : 15;
/* -15.000(iHr)..15.000(d.Hr) deci 0..16383: 14 biti + 1 bit de semn = 15 biti */
} ;

struct structura_clasica {
unsigned int ora;
unsigned int zi;
unsigned int luna;
int an;
} ;

main()
{
printf("marime in octeti camp de biti = %d\n", sizeof(struct camp_de_biti));
printf("marime in octeti structura clasica = %d\n", sizeof(struct structura_clasica));

return 0;
}
Observații:
• Pentru struct camp_de biti membrul ora are maxim 5 biți pentru că ora poate fi între 0 și 24, iar pe 5
biți se reprezintă numerele între 0 și 31;
• Pentru struct camp_de biti membrul zi are maxim 5 biți pentru că zi într-o lună poate fi între 0 și 31,
iar pe 5 biți se reprezintă numerele între 0 și 31;
• Pentru struct camp_de biti membrul luna are maxim 4 biți pentru că luna poate fi între 1 și 12, iar pe 4
biți se reprezintă numerele între 0 și 16;

7
• Pentru struct camp_de biti membrul an are maxim 15 biți pentru că am considerat anul între 15.000
î.Hr. și 15.000 d.Hr. folosind semnul – pentru anii î.Hr. deci fără semn anul poate fi între 0 și 15.000, iar pe
14 biți se reprezintă numerele între 0 și 16383, adăugând și bitul de semn obținem 15 biți;
• Pentru struct camp_de biti se ocupă: 5 + 5 + 4 + 15 = 29 biți, un int are 4 octeți = 32 biți deci 3 biți
rămân neocupați, sizeof(struct camp_de_biti) va afișa 4. Comparativ cu varianta cu struct clasic,
care ocupă 16 octeți, varianta cu câmp de biți este mult mai eficientă ca spațiu ocupat în memorie.

Aplicație rezolvată 5. Modificați programul anterior care memorează ora, ziua, luna și anul unui eveniment
folosind două variante: o structură clasică și un câmp de biți, astfel încât programul să citească și să afișeze
ora, ziua, luna și anul unui eveniment în cele două variante.
Observație: Atenție
la citirea membrilor
câmpului de biți
cărora operatorul &
nu li se poate
aplica, deci nu pot
apare în instrucțiuni
scanf().

#include <stdio.h>

struct camp_de_biti {
unsigned int ora: 5;
unsigned int zi : 5;
unsigned int luna : 4;
int an : 15;
} ;

struct structura_clasica {
unsigned int ora;
unsigned int zi;
unsigned int luna;
int an;
} ;

main()
{
struct camp_de_biti e1;
unsigned int temp;
int temp_an;
struct structura_clasica e2;

printf("Ora, ziua, luna si anul evenimentului cu o structura camp de biti\n");


printf("ora = "); scanf("%d", &temp); e1.ora = temp;
printf("zi = "); scanf("%d", &temp); e1.zi = temp;
printf("luna = "); scanf("%d", &temp); e1.luna = temp;
printf("an = "); scanf("%d", &temp_an); e1.an = temp_an;
printf("ora = %d , ziua = %d, luna = %d, ", e1.ora, e1.zi, e1.luna);
printf(e1.an<0?"anul = %d i.Hr.\n":"anul = %d d.Hr.\n", abs(e1.an));

printf("\nOra, ziua, luna si anul evenimentului cu o structura clasica\n");


printf("ora = "); scanf("%d", &e2.ora);
printf("zi = "); scanf("%d", &e2.zi);
printf("luna = "); scanf("%d", &e2.luna);
printf("an = "); scanf("%d", &e2.an);
printf("ora = %d , ziua = %d, luna = %d, ", e2.ora, e2.zi, e2.luna);
printf(e2.an<0?"anul = %d i.Hr.\n":"anul = %d d.Hr.\n", abs(e2.an));

return 0;
}

8
Aplicație propusă 5. Scrieți un program care să memoreze secunda, minutul, ora, ziua, luna și anul unui
eveniment folosind un câmp de biți.

REZOLVĂRI

Aplicație propusă 1. Folosind typedef creați un nou nume octet pentru tipul de dată unsigned char. Scrieți
un program care sa citească și să afișeze o variabilă de tipul octet.
#include <stdio.h>
main()
{
typedef unsigned char Octet;
Octet c;

printf("introduceti un caracter : ");


c = getchar();

printf("caracterul introdus : %c\n", c);

return 0;
}

Aplicație propusă 2. Scrieți un program care citește notele la cele două subiecte de la examenul de PCLP ale
unui student și calculează media studentului la proba scrisă a examenului de PCLP. Se va folosi typedef
pentru a da numele mai specific: nota tipului int si medie tipului float.
#include <stdio.h>
main()
{
typedef int Nota;
typedef float Media;

Nota nota_subiect1_pclp, nota_subiect2_pclp;


Media nota_examen_pclp;

printf("nota la primul subiect la PCLP : ");


scanf("%d", &nota_subiect1_pclp);
printf("nota la al 2-lea subiect la PCLP : ");
scanf("%d", &nota_subiect2_pclp);

nota_examen_pclp = nota_subiect1_pclp + nota_subiect2_pclp;


nota_examen_pclp = nota_examen_pclp/2;

printf("\nnota examen scris PCLP : %5.2f\n", nota_examen_pclp);

return 0;
}

Aplicație propusă 3. Scrieți un program care să declare o variabilă x de tip uniune cu trei cîmpuri ca mai jos:
union nume {
int i;
float f;
char s[100];
}x;

și să folosească variabila xtip pentru a ţine evidenţa tipului memorat curent în x, conform modelului:
if (xtip == INTREG)
printf("%d\n", x.i);

9
else if (xtip == REAL)
printf(”%f\n", x.f);
else if (xtip == SIR)
printf(“%s\n", x.s);
else
printf("eroare\n");

#include <stdio.h>

enum tip {INTREG, REAL, SIR};

union nume {
int i;
float f;
char s[100];
};

int main()
{
union nume x;
enum tip xtip;

while(1){
printf("\n\nCe doriti sa cititi 0(int), 1(float), 2(sir), 3(iesire)?");
scanf("%d%*c", &xtip);

if (xtip == INTREG){
printf("introduceti un numar intreg = ");
scanf("%d", &x.i);
printf("ati introdus numarul intreg = %d\n", x.i);
}
else if (xtip == REAL){
printf("introduceti un numar real = ");
scanf("%g", &x.f);
printf("ati introdus numarul real = %g\n", x.f);
}
else if (xtip == SIR){
printf("introduceti un sir de caractere = ");
fgets(x.s, 100, stdin);
printf("ati introdus sirul = %s\n", x.s);
}
else
break;
}

return 0;
}

Aplicație propusă 4. Rescrieți aplicația de mai sus folosind pointeri pentru a accesa membrii uniuni:
union nume *pu;
#include <stdio.h>

enum tip {INTREG, REAL, SIR};

union nume {
int i;
float f;
char s[100];
};

int main()
{
union nume a, *pu = &a;
enum tip xtip;

while(1){
10
printf("\n\nCe doriti sa cititi 0(int), 1(float), 2(sir), 3(iesire)?");
scanf("%d%*c", &xtip);

if (xtip == INTREG){
printf("introduceti un numar intreg = ");
scanf("%d", &pu->i);
printf("ati introdus numarul intreg = %d\n", pu->i);
}
else if (xtip == REAL){
printf("introduceti un numar real = ");
scanf("%g", &pu->f);
printf("ati introdus numarul real = %g\n", pu->f);
}
else if (xtip == SIR){
printf("introduceti un sir de caractere = ");
fgets(pu->s, 100, stdin);
printf("ati introdus sirul = %s\n", pu->s);
}
else
break;
}

return 0;
}

Aplicație propusă 5. Scrieți un program care să memoreze secunda, minutul, ora, ziua, luna și anul unui
eveniment folosind un câmp de biți.
#include <stdio.h>

struct eveniment {
unsigned int ora: 5;
unsigned int min: 6; /* 0..60 deci 0..63: 6 biti */
unsigned int sec: 6; /* 0..60 deci 0..63: 6 biti */
unsigned int zi : 5;
unsigned int luna : 4;
int an : 15;
} ;

main()
{
struct eveniment e;
unsigned int temp;
int temp_an;

printf("Secunda, minutul, ora, ziua, luna si anul evenimentului\n");


printf("secunda = "); scanf("%d", &temp); e.sec = temp;
printf("minutul = "); scanf("%d", &temp); e.min = temp;
printf("ora = "); scanf("%d", &temp); e.ora = temp;
printf("zi = "); scanf("%d", &temp); e.zi = temp;
printf("luna = "); scanf("%d", &temp); e.luna = temp;
printf("an = "); scanf("%d", &temp_an); e.an = temp_an;
printf("secunda = %d, minutul = %d, ora = %d , ziua = %d, luna = %d, ", e.sec, e.min,
e.ora, e.zi, e.luna);
printf(e.an < 0 ? "anul = %d i.Hr.\n" : "anul = %d d.Hr.\n", abs(e.an));

return 0;
}

11

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