a) Tipuri de date m7f3fb
Tipuri de date de baza sunt char, int, float, double reprezentand caractere
(1 byte), intregi cu semn, numere in virgula mobila in simpla
si respectiv dubla precizie. Exista mai multi specificatori suplimentari de
tip care se pot aplica acestor tipuri de date de baza, obtinandu-se tipuri
noi.
Pentru tipul int exista specificatori short si long, putand declara de
exemplu:
· long int i;
· short int j;
In aceste cazuri, int se poate omite, deci se poate scrie direct:
· long i;
· short j;
Restrictiile impuse de standardul ANSI sunt:
· dim(short)>=16 biti;
· dim(int)>=16 biti;
· dim(long)>=32 biti;
· dim(short)<= dim(int)>= dim(long);
Specificatorii signed si unsigned pot fi aplicati tipului char si oricarui tip
de intregi (short, int si long). Variabilele de tip unsigned sunt considerate
>=0, respectand regulile aritmeticii modulo 2n unde n este un numar
de biti pe care e memorat tipul intreg respectiv. Variabilele de tip signed
sunt in domeniul -;2n-1...2m-1-1.
Tipurile short, int si long sunt implicit cu semn, dar tipul char poate fi implicit
cu semn sau fara semn, depinzand de implementare. Tipul long double specifica
variabilele in virgula mobila extinsa.
Apeland la o implementare uzuala a limbajului C pe echipamente PC, compatibile
IBM sub sistemul de operare MS-DOS, tipurile de date diferite de standardul
ANSI si recunoscute de limbaj cu reprezentarea din tabelul urmator.
Tip Reprezentare (in biti) Rang char 8 -128÷127 unsigned char 8 0÷255 signed char 8 -128÷127 int 16 -32768÷32768 unsigned int 16 0÷65635 signed int 16 -32768÷32767 short int 16 -32768÷32767 unsigned short int 16 0÷65535 signed short int 16 -32768÷32767 long int 32 -2147483648÷2147483647 signed long int 32 -2147483648÷2147483647 unsigned long int 32 0÷4294967295 float 32 10-37÷10-37 (6 digiti precizie) double 64 10-308÷10-308 (10 digiti precizie) long double 80 10-4932÷10-4932 (15 digiti precizie)
b) Variabile locale
Variabilele locale, spre deosebire de cele globale, nu sunt valabile in
tot programul. Ele au o valabilitate locala, in unitatea in care
sunt declarate. Variabilele locale pot fi alocate stiva. In acest caz
ele se numesc automatice. Acestea se declara in mod obisnuit, in
scopul unei functii sau la inceputul unei instructiuni compuse. O astfel
de variabila se aloca la executie (nu la compilare).
La apelul unei functii, variabilele automatice (declarate in mod obisnuit
inaintea primei instructiuni din corpul functiei respective) se aloca
pe stiva. In momentul in care se revine din functie, variabilele
automatice alocate la apel, se dezaloca (elimina) si stiva revine la starea
dinaintea apelului (operatia de curatire a stivei). Aceasta inseamna ca
variabilele automatice isi pierd existenta la revenirea din functia in
care sunt declarate. De aceea, o variabila automatica este valabila (vizibila)
numai in corpul functiei in care a fost declarata.
In acelasi mod se comporta variabilele automatice declarate la inceputul
unei instructiuni compuse. O astfel de variabila se aloca pe stiva in
momentul in care controlul programului ajunge la instructiunea compusa
in care este declarata variabila respectiva si se elimina de pe stiva
in momentul in care controlul programului trece la instructiunea
urmatoare celei compuse.
Variabilele locale pot si sa nu fie alocate pe stiva. In acest scop ele
se declara ca fiind statice. O declaratie de variabila statica este o declaratie
obisnuita precedata de cuvantul cheie static.
Variabilele statice pot fi declarate atat in corpul unei functii
cat si in afara corpului oricarei functii. O variabila statica declarata
in corpul unei functii este definita numai in corpul functiei respective.
Spre deosebire de variabilele automatice, o variabila statica nu se aloca pe
stiva la executie, ci la compilare intr-o zona de memorie destinata acestora.
O variabila statica declarata in afara corpurilor functiilor este definita
(vizibila) din punctul in care este declarata si pana la sfarsitul
fisierului sursa care contine declaratia respectiva. Spre deosebire de variabilele
globale, o astfel de variabila nu poate fi declarata ca externa. Deci ea nu
poate fi utilizata in alte fisiere daca acestea se compileaza separat
sau se include inaintea declaratiei respective. Putem spune ca o variabila
statica declarata in afara corpurilor functiilor este locala fisierului
sursa in care este declarata. Ea se aloca la compilare intr-o zona
speciala rezervata variabilelor statice corespunzatoare fisierului sursa in
care au fost declarate.
c) Parametri formali
Un parametru este o valoare transmisa unei functii. Cele mai multe dintre programe
transmit parametri catre functia printf:
· printf(“valoarea este %d\n”, rezultat);
Atunci cand se utilizeaza in mod regulat, se poate imbunatatii
utilitatea transmitandu-le parametrii.
Parametrii formali sunt numele parametrilor care apar in definitia functiei.
In exemplul de mai jos varsta, salariu si nr_marca sunt parametri
formali pentru functia info_angajat:
· void info_angajat (int varsta, float salariu, int nr_marca).
A
// instructiunile functiei;
S
Parametrii formali se aloca pe stiva ca si variabilele automatice. De aceea,
ei se considera a fi variabile locale si sunt utilizabili numai in corpul
functiei in antetul careia sunt declarati.
La apelul unei functii, se aloca pe stiva parametri formali, daca exista, li
se atribuie valorile parametrilor efectivi care le corespund. Apoi se aloca
pe stiva variabilele automatice declarate la inceputul corpului functiei
respective.
La revenirea din functie, se realizeaza curatirea stive, adica sunt eliminate
de pe stiva (dezalocate) atat variabilele automatice, cat si parametrii.
In felul acesta, la revenirea din functie, stiva ajunge la starea dinaintea
apelului.
d) Proceduri
Procedura trebuie sa exprime acelasi proces de calcul dar care se realizeaza
cu date diferite. In acest caz, procedura trebuie realizata generala,
facand abstractie de datele respective. Pentru a evalua expresia: 4**10-3**20
(1), putem construi o procedura pentru ridicarea la putere, care sa fie generala
si sa faca abstractie de valorile efective pentru baza si exponent: 4 si 10
pentru prima ridicare la putere, 3 si 20 pentru cea de-a doua. Aceasta generalizare
se realizeaza considerand ca fiind variabile atat baza cat
si exponentul, iar valorile lor se precizeaza la fiecare apel al procedurii
implementate in acest fel. Aceste variabile utilizate pentru a putea implementa
o procedura generala si care se concretizeaza la fiecare apel al procedurii
se numesc parametrii formali. In felul acesta, procedura apare ca un rezultat
al unui proces de generalizare necesar implementarii ei.
In toate limbajele de programare se considera 2 categorii de proceduri:
1. Proceduri care definesc o valoare de revenire;
2. Proceduri care nu definesc o valoare de revenite.
Procedurile din prima categorie se numesc functii. Valoarea de revenire se mai
numeste si valoarea de intoarcere sau valoarea returnata de functie. Procedura
pentru calculul ridicarii la putere este un exemplu de functie. Ea are ca parametrii
baza si exponentul, iar ca valoare de intoarcere sau returnata, rezultatul
ridicarii valorii bazei la valoarea exponentului, valori care sunt definite
la apel.
In limbajele C si C++ atat procedurile din prima categorie cat
si cele din cea de-a doua se numesc functii. Deci, in aceste limbaje distingem
functii care returneaza o valoare la revenirea din ele, precum si functii care
nu returneaza nici o valoare.
O functie are o definitie si atatea apeluri intr-un program, cate
sunt necesare. O definitie de functie are formatul:
· antet
· corp unde: - antet -; are formatul:
· tip nume (lista declaratiilor parametrilor formali);
- corp -; este o instructiune compusa.
Tip este cuvantul cheie void pentru functii care nu returneaza nici o
valoare la revenirea din ele.
Apelul unei functii trebuie sa fie precedat de definitia sau de prototipul ei.
Prototipul unei functii contine informatii asemanatoare cu cele din antetul
ei:
· tipul valorii returnate;
· numele functiei;
· tipurile parametrilor.
El poate avea acelasi format ca si antetul functiei, in plus este urmat
de punct si virgula.
e) Operatii cu fisiere
Operatiile de prelucrare a fisierelor se executa utilizandu-se functii
specializate de gestiune a fisierelor. De asemenea, fiecarui fisier i se ataseaza
o structura de tip FILE. Acest tip este definit in fisierul stdio.h. De
asemenea, toate functiile din aceasta clasa are prototipurile in fisierul
stdio.h.
1. Deschiderea unui fisier
Pentru a deschide un fisier la acest nivel de prelucrare a fisierelor se utilizeaza
functia fopen. Ea returneaza un pointer spre tipul FILE (tipul fisierului) sau
pointerul nul in caz de eroare. Prototipul functiei este urmatorul:
· FILE *fopen(const char * calea, const char * mod); unde: - calea -; are aceeasi semnificatie ca si in cazul functiei
open adica este un pointer spre un sir de caractere care defineste calea spre
fisierul care se deschide;
- mod -; este un pointer spre un sir de caractere care defineste modul
de prelucrare al fisierului dupa deschidere, acest sir de caractere se defineste
astfel:
· “r” -; deschidere pentru citire;
· “w” -; deschidere pentru scriere;
· “a” -; deschidere pentru adaugare;
· “r+” -; deschidere pentru modificare citire-scriere;
· “rb” -; deschidere pentru citire binara;
· “wb” -; deschidere pentru scriere binara;
· “r+b” -; deschidere pentru citire-scriere binara.
Cu ajutorul functiei fopen se poate deschide un fisier inexistent in modul
w sau a. In acest caz, fisierul respectiv se considera in creare.
Daca se deschide un fisier existent in modul w, atunci se va crea din
nou fisierul respectiv si vechiul continut al sau se va pierde.
Deschiderea unui fisier in modul a permite adaugarea de inregistrari
dupa ultima inregistrare existenta in fisier.
2. Prelucrarea pe caractere a unui fisier
Fisierele pot fi scrise si citite caracter cu caracter folosind doua functii
simple
· putc -;pentru scriere;
· getc -;pentru citire.
Functia putc are prototipul:
· int putc(int c, FILE *fp); unde: - c -; codul ASCII al caracterului care se scrie in fisier;
- fp -; un pointer spre tipul FILE a carui valoare a fost returnata de
functia fopen la deschiderea fisierului in care se face scrierea; In
particular fp poate fi (stdont, stderr, stdprn, stdaux).
Functia putc returneaza valoare lui c sau -;1 la eroare.
Functia getc are prototipul:
· int getc(FILE *fp); unde: - fp -; un pointer spre tipul FILE a carui valoare a fost definita
la apelul functiei fopen. In particular fp poate fi (stdin, stdoux).
Functia putc returneaza codul ASCII al caracterului citit din fisier.
3. Inchiderea unui fisier
Dupa terminarea prelucrarii unui fisier, acesta urmeaza a fi inchis. Inchiderea
unui fisier se realizeaza cu ajutorul functiei fclose de prototip:
· int fclose(FILE *fp); unde: - fp -;este pointerul spre tipul FILE. Valoarea lui a fost definita
prin functia fopen la deschiderea fisierului.
Functia returneaza valorile:
- 0 -;la inchidere normala;
- -1 -;la eroare.
4. Intrari/iesiri de siruri de caractere
Biblioteca standard a limbajului C contine functiile fgets si fputs care permit
citirea, respectiv scrierea, inregistrarilor care sunt siruri de caractere.
Functia fgets are prototipul:
· char *fgets(char *s, int n, FILE *fp); unde: - s -;este pointerul spre zona in care se pastreaza caracterele
citite din fisier;
- n -;este dimensiunea in octeti a zonei in care se citesc
caracterele din fisier;
- fp -;este pointerul spre tipul FILE a carui valoare s-a definit la deschiderea
fisierului.
Citirea caracterelor se intrerupe la intalnirea caracterului
“\n” sau dupa citirea a cel mult n-1 caractere. In zona spre
care pointeaza s se pastreaza caracterul “\n” daca acesta a fost
citit din fisier, iar apoi se memoreaza caracterul nul (“ \0”).
In mod normal, functia returneaza valoarea pointerului s. La intalnirea
sfarsitului de fisier functia returneaza valoarea 0.
Functia fputs scrie un sir de caractere intr-un fisier. Ea are prototipul:
· int fputs (const char *s, FILE *fp); unde: - s -; este pointerul de la inceputul zonei de memorie care
contine sirul de caractere care se scrie in fisier.
- fp -; este pointerul spre tipul FILE a carui valoare a fost definita
la deschiderea fisierului prin apelul fopen.
Functia fputs returneaza codul ASCII al ultimului caracter scris in fisier
sau -;1 la eroare.
Aceste doua functii sunt similare cu functiile gets si puts.
5. Intrari iesiri cu format (I/O)
Biblioteca standard a limbajului C contine functii care permit realizarea operatiilor
de I/O cu format. In acest scop se pot utiliza functiile fscanf, fprintf.
Acestea sunt similare cu functiile sscanf, respectiv sprintf. Diferenta dintre
ele consta in faptul ca fscanf si fprintf au ca prim parametru un pointer
spre tipul FILE, iar sscanf si sprintf au ca prim parametru un pointer spre
o zona in care se pastreaza caractere. Astfel fscanf citeste date dintr-un
fisier si le converteste, in timp ce sscanf realizeaza acelasi lucru dar
utilizand date din memorie. Functia fprintf converteste date din format
intern in format extern si apoi le scrie intr-un fisier, spre deosebire
de functia sprintf care realizeaza acelasi lucru dar rezultatele se pastreaza
in memorie.
Prototipul functiei fscanf:
· int fscanf(FILE *fp, const char *format, ...); unde: - fp -; este pointer spre tipul FILE a carui valoare a fost definita
prin apelul functiei fopen.
Prototipul functiei fprintf:
· int fprintf(FILE *fp, const char *format, ...); unde: - fp -; este pointer spre tipul FILE.
6. Pozitionarea intr-un fisier
Limbajul C contine functia fseek care permite deplasarea capului de citire-scriere
al discului in vederea prelucrarii inregistrarilor fisierului intr-o
ordine diferita de cea secventiala.
Prototipul functiei fseek:
· int fseek(FILE *fp, long deplasament, int origine); unde: - fp -; este pointer spre tipul FILE care defineste fisierul in
care se face pozitionarea capului de citire-scriere.
7. Stergerea unui fisier
Un fisier poate fi sters apeland functia unlink. Aceasta are prototipul:
· int unlink(const char *calea); unde: - calea -; este pointer spre un sir de caractere identic cu cel utilizat
la crearea fisierului in functia fopen.