Sunteți pe pagina 1din 180

Theory without practice is useless; practice without theory is blind

Roger Bacon
Limbajul C a fost creat la nceputul anilor '70 de ctre Brian
!ernig"am #i $ennis % Ritc"ie de la Bell Laboratories &e' (erse)* fiind
ini+ial destinat scrierii unei pr+i din sistemul de operare ,ni-. Lucrarea
/"e C 0rogramming Language a celor doi autori* aprut n mai multe
1ersiuni* a rmas cartea de referin+ n domeniu* impunnd un standard
minimal pentru orice implementare.
Caracteristicile distincti1e ale limbajului au fost clar definite de la
nceput* ele pstrndu2se n toate de31oltrile ulterioare4
5 portabilitate ma-im;
5 structurare;
5 posibilitatea efecturii opera+iilor la ni1elul ma#inii cu pstrarea
caracteristicilor unui limbaj e1oluat.
6cest manual este structurat pe 78 capitole astfel nct elementele
limbajului C s fie pre3entate ntr2o manier unitar. 0rimul capitol face o
scurt introducere #i pre3int patru programe C. ,rmtoarele nou capitole
descriu elementele limbajului C. Capitolele unspre3ece #i doispre3ece trec n
re1ist func+iile cele mai des utili3ate definite n biblioteca standard*
mpreun cu cte1a programe demonstrati1e. 6u fost selectate doar func+iile
definite de mai multe standarde 9n primul rnd 6&:; C<* pentru a garanta o
portabilitate ct mai mare.
6cest manual a fost conceput pentru a ser1i ca document care s poat
fi consultat de programatori n elaborarea proiectelor* #i nu pentru a fi
memorat. %anualul nu este o introducere n limbajul C; se presupune c
cititorul este familiari3at cu4
5 concepte de ba3 referitoare la programare4 1ariabile* instruc+iuni de
atribuire* de control al e-ecu+iei* apeluri de func+ii;
5 repre3entarea informa+iei n calculator a 1alorilor ntregi* n 1irgul
mobil* a codurilor 6:C;;;
5 opera+ii de intrare = ie#ire.
$eoarece a1em con1ingerea c cea mai bun e-plica+ie este un program
func+ional* majoritatea e-emplelor din acest manual se regsesc n fi#iere
surs C care pot fi rulate pe orice mediu de programare C #i sub orice sistem
de operare.
Ca o ultim obser1a+ie amintim recomandarea fcut de n#i#i creatorii
limbajului4 cea mai bun metod de n1+are este practica.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?
1. Generaliti asupra limbajului C
1.1. Introducere
Limbajul C este un limbaj de programare uni1ersal* caracteri3at
printr2o e-primare concis* un control modern al flu-ului e-ecu+iei*
structuri de date* #i un bogat set de operatori.
Limbajul C nu este un limbaj de ni1el foarte nalt #i nu este
speciali3at pentru un anumit domeniu de aplica+ii. 6bsen+a
restric+iilor #i generalitatea sa l fac un limbaj mai con1enabil #i mai
eficient dect multe alte limbaje mai puternice.
Limbajul C permite scrierea de programe bine structurate*
datorit construc+iilor sale de control al flu-ului4 grupri de
instruc+iuni* luri de deci3ii 9if<* cicluri cu testul de terminare
naintea ciclului 9while* for< sau dup ciclu 9do< #i selec+ia unui
ca3 dintr2o mul+ime de ca3uri 9switch<.
Limbajul C permite lucrul cu pointeri #i are o aritmetic de
adrese puternic.
Limbajul C nu are opera+ii care prelucrea3 direct obiectele
compuse cum snt #irurile de caractere* mul+imile* listele sau
masi1ele* considerate fiecare ca o entitate. Limbajul C nu pre3int
facilit+i de alocare a memoriei altele dect defini+ia static sau
disciplina de sti1 relati1 la 1ariabilele locale ale func+iilor. @n
sfr#it* limbajul C nu are facilit+i de intrare2ie#ire #i nici metode
directe de acces la fi#iere. /oate aceste mecanisme de ni1el nalt snt
reali3ate prin func+ii e-plicite.
$e#i limbajul C este* a#adar* un limbaj de ni1el relati1 sc3ut* el
este un limbaj agreabil* e-presi1 #i elastic* care se pretea3 la o gam
larg de programe. C este un limbaj restrns #i se n1a+ relati1 u#or*
iar subtilit+ile se re+in pe msur ce e-perien+a n programare cre#te.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A
1.2. Primele programe
@n aceast sec+iune snt pre3entate #i e-plicate patru programe cu
scopul de a asigura un suport de ba3 pentru pre3entrile din
capitolele urmtoare.
0rin tradi+ie primul program C este un mic e-emplu din lucrarea
de1enit clasic 5 /"e C programming language* de Brian
!ernig"am #i $ennis % Ritc"ie.
#include <stdio.h>
main() {
printf("Hello, world\n");
return 0;

6cest program afi#ea3 un mesaj de salut.


0rima linie indic faptul c se folosesc func+ii de intrare = ie#ire*
#i descrierea modului de utili3are 9numele* tipul argumentelor* tipul
1alorii returnate etc< a acestora se afl n fi#ierul cu numele
stdio.h .
6 doua linie declar func+ia main care 1a con+ine instruc+iunile
programului. @n acest ca3 singura instruc+iune este un apel al func+iei
printf care afi#ea3 un mesaj la terminal. %esajul este dat ntre
g"ilimele #i se termin cu un caracter special ne'2line 9!\n!<.
;nstruc+iunea return pred controlul sistemului de operare la
terminarea programului #i comunic acestuia codul 0 pentru
terminare. 0rin con1en+ie aceast 1aloare semnific terminarea
normal a programului 2 adic nu au aprut erori n prelucrarea
datelor.
Corpul func+iei main apare ntre acolade.
6l doilea program a#teapt de la terminal introducerea unor
numere ntregi nenule #i determin suma lor. @n momentul n care se
introduce o 1aloare 3ero* programul afi#ea3 suma calculat.
#include <stdio.h>
main() {
int s,n;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B
s " 0;
do {
scanf("#d",$n);
s %" n;
while (n&"0);
printf("#d\n",s);
return 0;

@n cadrul func+iei main se declar dou 1ariabile s #i n care 1or


memora 1alori ntregi. Cariabila s 9care 1a pstra suma numerelor
introduse< este ini+iali3at cu 1aloarea 0.
@n continuare se repet o sec1en+ de dou instruc+iuni* prima
fiind o opera+ie de intrare #i a doua o adunare.
0rimul argument al func+iei scanf 2 formatul de introducere
"#d" 2 indic faptul c se a#teapt introducerea unei 1alori ntregi n
format 3ecimal de la terminal 9consol<. 6l doilea argument indic
unde se 1a depune n memorie 1aloarea citit; de aceea este necesar
s se preci3e3e adresa 1ariabilei n 9cu ajutorul operatorului $<.
@n a doua instruc+iune la 1aloarea 1ariabilei s se adun 1aloarea
1ariabilei n. Dperatorul %" are semnifica+ia adun la.
6ceast sec1en+ se repet 9do< ct timp 9while< 1aloarea
introdus 9n< este nenul. Dperatorul &" are semnifica+ia diferit de.
@n final func+ia printf afi#ea3 pe terminal valoarea 1ariabilei
s n format 3ecimal.
6l treilea program a#teapt de la terminal introducerea unei
1alori naturale n* dup care mai a#teapt introducerea a n 1alori reale
9dubl preci3ie<4 a
0
* a
'
* ...* a
n'
. @n continuare se parcurge aceast
list #i se determin produsul 1alorilor strict po3iti1e. @n final
programul afi#ea3 produsul calculat.
#include <stdio.h>
main() {
int n,i;
dou(le a)'00*, p;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E
scanf("#d",$n);
for (i"0; i<n; i%%)
scanf("#lf",$a)i*);
p " ';
for (i"0; i<n; i%%)
if (a)i*>0)
p +" a)i*;
printf("#lf\n",p);
return 0;

@n cadrul func+iei main se declar dou 1ariabile n #i i care 1or


memora 1alori ntregi. Cariabila n pstrea3 numrul de 1alori reale
din lista a. :e declar de asemenea un tablou unidimensional a care
1a memora 700 de 1alori de tip real 9dubl preci3ie<* #i o 1ariabil p
care 1a memora produsul cerut.
:e cite#te de la terminal o 1aloare n. @n continuare se introduc
1alorile reale a
i
9i = 0* '* ...* n'<. Formatul de introducere "#lf"
indic faptul c se a#teapt introducerea unei 1alori reale de la
terminal* care 1a fi depus la loca+ia de memorie asociat 1ariabilei
a
i
. @n locul construc+iei $a)i* se poate folosi forma ec"i1alent
a%i.
0entru a introduce toate 1alorile a
i
se efectuea3 un ciclu for*
n cadrul cruia 1ariabila i 9care controlea3 ciclul< ia toate 1alorile
ntre 0 9inclusi1< #i n 9e-clusi1< cu pasul '. /recerea la urmtoarea
1aloare a 1ariabilei i se face cu ajutorul operatorului %%.
@n continuare 1ariabila p* care 1a memora produsul 1alorilor
cerute* se ini+iali3ea3 cu '. Fiecare 1aloare a
i
este 1erificat
9instruc+iunea if< dac este strict po3iti1 #i n ca3 afirmati1 este
nmul+it cu 1aloarea p. Dperatorul +" are semnifica+ia nmulete
cu.
6l patrulea program este o ilustrare a unor probleme legate de
capacitatea repre3entrilor 1alorilor de tip ntreg #i 1irgul mobil.
#include <stdio.h>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7
int main() {
short ,,i;
float a,(,c,u,-,w;
i"./0; ,"i+i;
printf("#hd\n",,);
a"'.0/1234; ("'.0/1235;
c"a+a6(+(;
u"a+a; -"(+(; w"u6-;
printf("#f #f\n",c,w);
if (c""w) return 0;
else return ';

Cariabila ,* care ar trebui s memore3e 1aloarea B7E00* are tipul


ntreg scurt 9short<* pentru care domeniul de 1alori este restrns la
5?87EG ?87E7. 6stfel c 1aloarea 7770000700000000
98<
9n 3ecimal
B7E00<* n repre3entare ntreag cu semn este de fapt 57H?E.
6l doilea set de opera+ii necesit o anali3 mai atent; e-plica+iile
snt 1alabile pentru programe care rulea3 pe ar"itecturi ;ntel.
Cariabila c* care ar trebui s memore3e 1aloarea 8AE7?B7 9re3ultatul
corect<* 1a a1ea 1aloarea 8AE7?BE* deoarece tipul float are
re3er1ate pentru mantis doar 8A de cifre binare. Re3ultatul este
foarte apropiat de cel corect deoarece re3ultatele intermediare se
pstrea3 n regi#trii coprocesorului matematic cu preci3ie ma-im.
6bia la memorare se efectuea3 trunc"ierea* de unde re3ult 1aloarea
afi#at.
Cu totul altfel stau lucrurile n ca3ul celui de al treilea set de
opera+ii. 6ici re3ultatele intermediare snt memorate de fiecare dat
cu trunc"iere n 1ariabile de tip float. @n final se calculea3 #i
diferen+a dintre cele dou 1alori trunc"iate* de unde re3ult 1aloarea
7E77787E.
@nainte de terminare se 1erific dac 1alorile c #i w snt egale. @n
ca3 afirmati1 se comunic sistemului de operare un cod 0 9terminare
normal<. @n ca3 contrar se comunic un cod 7 9terminare anormal<.
Rula+i acest program pe diferite sisteme de calcul #i obser1a+i
care este re3ultatul.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G
1.3. Meta-limbajul i setul de caractere
%eta2limbajul care ser1e#te la descrierea formal a sinta-ei
limbajului C este simplu.
Categoriile sintactice sau no+iunile care trebuie definite snt
urmate de simbolul ''.
$efini+iile alternati1e de categorii snt listate pe linii separate.
$ac o linie nu este suficient* se trece la linia urmtoare* aliniat la
un tab fa+ de linia precedent.
,n simbol op+ional* terminal sau neterminal este indicat prin
adugarea imediat dup el a configura+iei de caractere <opt>.
:etul de caractere al limbajului C este un subset al setului de
caractere 6:C;;* format din4
5 8E litere mici
a b c d e f g " i j I l m n o p J r s t u 1 ' - ) 3
5 8E litere mari
6 B C $ K F L M ; ( ! L % & D 0 N R : / , C O P Q
5 70 cifre
0 7 8 ? A B E 7 G H
5 ?0 simboluri speciale
Blanc R S T U V ' 9 < W + * . = 4 ; < = > X Y Z [ \ > ] ^ _ `
5 E simboluri negrafice
Zn* Zt* Zb* Zr* Zf* Za
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H
2. !nitile le"icale ale limbajului C
@n limbajul C e-ist #ase tipuri de unit+i le-icale4 identificatori*
cu1inte2c"eie* constante* #iruri* operatori #i separatori.
2.1. Identi#icatori
,n identificator este o succesiune de litere #i cifre dintre care
primul caracter este n mod obligatoriu o liter. :e admit #i litere
mari #i litere mici dar ele se consider caractere distincte. Liniu+a de
subliniere > este considerat ca fiind liter. $eci alfabetul peste care
snt defini+i identificatorii este urmtorul4
A = <a*...*3*6*...*Q*0*...*H*>>
2.2. Cu$inte c%eie
Cu1intele c"eie snt identificatori re3er1a+i limbajului. Ki au o
semnifica+ie bine determinat #i nu pot fi utili3a+i dect a#a cum cere
sinta-a limbajului. Cu1intele2c"eie se scriu obligatoriu cu litere mici.
6ceste cu1inte snt 9fiecare mediu de programare C poate folosi #i
alte cu1inte re3er1ate<4
int re7ister if const
char auto else -oid
float e8tern for switch
dou(le static while case
lon7 struct do default
short union continue return
unsi7ned t9pedef (rea, si:eof
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70
2.3. Constante
@n limbajul C e-ist urmtoarele tipuri de constante4 ntreg
93ecimal* octal* "e-a3ecimal<* ntreg lung e-plicit* flotant* caracter*
simbolic.
Constante &ntregi
D constant ntreag const dintr2o succesiune de cifre.
D constant octal este o constant ntreag care ncepe cu 0
9cifra 3ero<* #i este format cu cifre de la 0 la 3.
D constant "e-a3ecimal este o constant ntreag precedat de
08 sau 0; 9cifra 0 #i litera 8<. Cifrele "e-a3ecimale includ literele de
la < la = #i de la a la f cu 1alori de la '0 la '1.
@n orice alt ca3* constanta ntreag este o constant 3ecimal.
Exemplu4 constanta 3ecimal 0' poate fi scris ca 003 n octal #i
08'f sau 0;'= n "e-a3ecimal.
D constant ntreag este generat pe un cu1nt 9doi sau patru
octe+i* dac sistemul de calcul este pe 7E sau ?8 de bi+i<.
D constant 3ecimal a crei 1aloare dep#e#te pe cel mai mare
ntreg cu semn repre3entabil pe un cu1nt scurt 97E bi+i< se consider
de tip lon7 #i este generat pe A octe+i.
D constant octal sau "e-a3ecimal care dep#e#te pe cel mai
mare ntreg fr semn repre3entabil pe un cu1nt scurt se consider
de asemenea de tip lon7.
D constant ntreag de1ine negati1 dac i se aplic operatorul
unar de negati1are a6a.
Constante de tip e"plicit
D constant ntreag 3ecimal* octal sau "e-a3ecimal* urmat
imediat de litera l sau > este o constant lung. 6ceasta 1a fi
generat n calculator pe A octe+i.
Exemplu4 '.0>.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77
D constant ntreag 3ecimal urmat imediat de litera u sau ?
este o constant de tip ntreg fr semn. Litera u sau ? poate fi
precedat de litera l sau >.
Exemplu4 '.0lu.
Constante #lotante
D constant flotant const dintr2o parte ntreag* un punct
3ecimal* o parte frac+ionar* litera e sau @ #i op+ional* un e-ponent
care este un ntreg cu semn. 0artea ntreag #i partea frac+ionar snt
constituite din cte o succesiune de cifre. @ntr2o constant flotant* att
partea ntreag ct #i partea frac+ionar pot lipsi dar nu ambele; de
asemenea poate lipsi punctul 3ecimal sau litera e #i e-ponentul* dar
nu deodat 9#i punctul #i litera e #i e-ponentul<.
Exemplu4 '.0./12e3 sau 0.'.e0
Drice constant flotant se consider a fi n preci3ie e-tins.
Constante caracter
D constant caracter const dintr2un singur caracter scris ntre
apostrofuri* de e-emplu !8!. Caloarea unei constante caracter este
1aloarea numeric a caracterului* n setul de caractere al
calculatorului. $e e-emplu n setul de caractere 6:C;; caracterul
3ero sau !0! are 1aloarea /5 n 3ecimal* total diferit de 1aloarea
numeric 3ero.
Constantele caracter particip la opera+iile aritmetice ca #i oricare
alte numere. $e e-emplu* dac 1ariabila c con+ine 1aloarea 6:C;; a
unei cifre* atunci prin instruc+iunea4
c " c 6 !0! ;
aceast 1aloare se transform n 1aloarea efecti1 a cifrei.
6numite caractere negrafice #i caractere grafice ! 9apostrof< #i \
9bacIslas"< pot fi repre3entate ca #i constante caracter cu ajutorul a#a
numitor sec1en+e de e1itare. :ec1en+ele de e1itare ofer de altfel #i
un mecanism general pentru repre3entarea caracterelor mai greu de
introdus n calculator #i a oricror configura+ii de bi+i. 6ceste
sec1en+e de e1itare snt4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78
\n ne'2line \r carriage return \\ bacIslas"
\t tab ori3ontal \f form feed \! apostrof
\( bacIspace \a semnal sonor \" g"ilimele
\ddd configura+ie de bi+i 9ddd<
6ceste sec1en+e* de#i snt formate din mai multe caractere* ele
repre3int n realitate un singur caracter. :ec1en+a !\ddd! unde ddd
este un #ir de 7 pn la ? cifre octale* generea3 pe un octet 1aloarea
caracterului dorit sau a configura+iei de bi+i dorite* date de #irul ddd.
Exemplu4 sec1en+a !\0/0! 1a genera caracterul spa+iu.
,n ca3 special al acestei construc+ii este sec1en+a !\0! care
indic caracterul A?>>* care este caracterul cu 1aloarea 3ero. !\0!
este scris deseori n locul lui 0 pentru a sublinia natura de caracter a
unei anumite e-presii.
Cnd caracterul care urmea3 dup un bacIslas" nu este unul
dintre cele specificate* bacIslas"2ul este ignorat. 6tragem aten+ia c
toate caracterele setului 6:C;; snt po3iti1e* dar o constant caracter
specificat printr2o sec1en+ de e1itare poate fi #i negati1* de
e-emplu !\033! are 1aloarea 6'.
Constante simbolice
D constant simbolic este un identificator cu 1aloare de
constant. Caloarea constantei poate fi orice #ir de caractere introdus
prin construc+ia #define 91e3i capitolul G<.
Exemplu4 #define B<; '000
$up ntlnirea acestei construc+ii compilatorul 1a nlocui toate
apari+iile constantei simbolice B<; cu 1aloarea '000.
&umele constantelor simbolice se scriu de obicei cu litere mari
9fr a fi obligatoriu<.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?
2.'. (iruri
,n #ir este o succesiune de caractere scrise ntre g"ilimele* de
e-emplu "<CDE".
L"ilimelele nu fac parte din #ir; ele ser1esc numai pentru
delimitarea #irului. Caracterul " 9g"ilimele< poate aprea ntr2un #ir
dac se utili3ea3 sec1en+a de e1itare \". @n interiorul unui #ir pot fi
folosite #i alte sec1en+e de e1itare pentru constante caracter* de
asemenea poate fi folosit caracterul \ 9bacIslas"< la sfr#itul unui
rnd pentru a da posibilitatea continurii unui #ir pe mai multe linii*
situa+ie n care caracterul \ nsu#i 1a fi ignorat.
0entru #irul de caractere se mai folose#te denumirea constant #ir
sau constant de tip #ir.
Cnd un #ir apare ntr2un program C* compilatorul creea3 un
masi1 de caractere care con+ine caracterele #irului #i plasea3 automat
caracterul A?>> 9!\0!< la sfr#itul #irului* astfel ca programele care
operea3 asupra #irurilor s poat detecta sfr#itul acestora. 6ceast
repre3entare nseamn c* teoretic* nu e-ist o limit a lungimii unui
#ir* iar programele trebuie s parcurg #irul* anali3ndu2l pentru a2i
determina lungimea. :e admit #i #iruri de lungime 3ero.
/e"nic* un #ir este un masi1 ale crui elemente snt caractere. Kl
are tipul masi1 de caractere #i clasa de memorie static 91e3i
sec+iunea ?.7<. ,n #ir este ini+iali3at cu caracterele date 91e3i
sec+iunea B.A<.
La alocare* memoria fi3ic cerut este cu un octet mai mare dect
numrul de caractere scrise ntre g"ilimele* datorit adugrii
automate a caracterului null la sfr#itul fiecrui #ir.
Exemplu. Func+ia strlen(s) returnea3 lungimea #irului de
caractere s* e-clu3nd caracterul terminal null.
int strlen(char s)*) {
=W returnea3 lungimea #irului W=
int i;
i"0;
while (s)i*&"!\0!)
%%i;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A
return i;

6tragem aten+ia asupra diferen+ei dintre o constant caracter #i un


#ir care con+ine un singur caracter. "8" nu este acela#i lucru cu !8!.
!8! este un singur caracter* folosit pentru a genera pe un octet
1aloarea numeric a literei x* din setul de caractere al calculatorului.
"8" este un #ir de caractere* care n calculator se repre3int pe doi
octe+i* dintre care primul con+ine un caracter 9litera x<* iar al doilea
caracterul A?>> care indic sfr#itul de #ir.
2.). *peratori
Limbajul C pre3int un numr mare de operatori care pot fi
clasifica+i dup di1erse criterii. K-ist operatori unari* binari #i
ternari* operatori aritmetici* logici* operatori pe bi+i etc.
@ntr2un capitol separat 1om pre3enta clasele de operatori care
corespund la diferite ni1ele de prioritate.
2.+. ,eparatori
,n separator este un caracter sau un #ir de caractere care separ
unit+ile le-icale ntr2un program scris n C.
:eparatorul cel mai frec1ent este a#a numitul spa+iu alb 9blanc<
care con+ine unul sau mai multe spa+ii* tab2uri* ne'2line2uri sau
comentarii.
6ceste construc+ii snt eliminate n fa3a de anali3a le-ical a
compilrii.
$m mai jos lista separatorilor admi#i n limbajul C.
( ) 0arante3ele mici ncadrea3 lista de argumente ale unei
func+ii sau delimitea3 anumite pr+i n cadrul e-presiilor
aritmetice etc
{ 6coladele ncadrea3 instruc+iunile compuse* care
constituie corpul unor instruc+iuni sau corpul func+iilor
) * 0arante3ele mari ncadrea3 dimensiunile de masi1 sau
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B
indicii elementelor de masi1
" " L"ilimelele ncadrea3 un #ir de caractere
! ! 6postrofurile ncadrea3 un singur caracter sau o sec1en+
de e1itare
; 0unct #i 1irgula termin o instruc+iune
F+ :las" asterisc nceput de comentariu
+F 6sterisc slas" sfr#it de comentariu
,n comentariu este un #ir de caractere care ncepe cu caracterele
F+ #i se termin cu caracterele +F.
,n comentariu poate s apar oriunde ntr2un program* unde
poate aprea un blanc #i are rol de separator; el nu influen+ea3 cu
nimic semnifica+ia programului* scopul lui fiind doar o documentare
a programului.
&u se admit comentarii imbricate.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E
3. -ariabile
D 1ariabil este un obiect de programare cruia i se atribuie un
nume.
Cariabilele ca #i constantele snt elemente de ba3 cu care
operea3 un program scris n C.
Cariabilele se deosebesc dup denumire #i pot primi diferite
1alori. &umele 1ariabilelor snt identificatori. &umele de 1ariabile se
scriu de obicei cu litere mici 9fr a fi obligatoriu<.
Cariabilele n limbajul C snt caracteri3ate prin dou atribute4
clas de memorie #i tip.
6ceste dou atribute i snt atribuite unei 1ariabile prin
intermediul unei declara+ii. $eclara+iile listea3 1ariabilele care
urmea3 a fi folosite* stabilesc clasa de memorie* tipul 1ariabilelor #i
e1entual 1alorile ini+iale* dar despre declara+ii 1om discuta n
capitolul B.
3.1. Clase de memorie
Limbajul C pre3int patru clase de memorie4 automatic* e-tern*
static* registru.
-ariabile automatice
Cariabilele automatice snt 1ariabile locale fiecrui bloc
9sec+iunea E.8< sau func+ii 9capitolul 7<. Kle se declar prin
specificatorul de clas de memorie auto sau implicit prin conte-t. D
1ariabil care apare n corpul unei func+ii sau al unui bloc pentru care
nu s2a fcut nici o declara+ie de clas de memorie se consider
implicit de clas auto.
D 1ariabil auto este actuali3at la fiecare intrare n bloc #i se
distruge n momentul cnd controlul a prsit blocul. Kle nu #i re+in
1alorile de la un apel la altul al func+iei sau blocului #i trebuie
ini+iali3ate la fiecare intrare. $ac nu snt ini+iali3ate* con+in 1alori
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77
re3iduale. &ici o func+ie nu are acces la 1ariabilele auto din alt
func+ie. @n func+ii diferite pot e-ista 1ariabile locale cu acelea#i nume*
fr ca 1ariabilele s aib 1reo legtur ntre ele.
-ariabile e"terne
Cariabilele e-terne snt 1ariabile cu caracter global. Kle se
definesc n afara oricrei func+ii #i pot fi apelate prin nume din
oricare func+ie care intr n alctuirea programului.
@n declara+ia de defini+ie aceste 1ariabile nu necesit specificarea
nici unei clase de memorie.
La ntlnirea unei defini+ii de 1ariabil e-tern compilatorul aloc
#i memorie pentru aceast 1ariabil.
@ntr2un fi#ier surs domeniul de defini+ie #i ac+iune al unei
1ariabile e-terne este de la locul de declara+ie pn la sfr#itul
fi#ierului.
6ceste 1ariabile e-ist #i #i pstrea3 1alorile de2a lungul
e-ecu+iei ntregului program.
0entru ca o func+ie s poat utili3a o 1ariabil e-tern* numele
1ariabilei trebuie fcut cunoscut func+iei printr2o declara+ie.
$eclara+ia poate fi fcut fie e-plicit prin utili3area specificatorului
e-tern* fie implicit prin conte-t.
$ac defini+ia unei 1ariabile e-terne apare n fi#ierul surs
naintea folosirii ei ntr2o func+ie particular* atunci nici o declara+ie
ulterioar nu este necesar* dar poate fi fcut.
$ac o 1ariabil e-tern este referit ntr2o func+ie nainte ca ea
s fie definit* sau dac este definit ntr2un fi#ier surs diferit de
fi#ierul n care este folosit* atunci este obligatorie o declara+ie e-tern
pentru a lega apari+iile 1ariabilelor respecti1e.
$ac o 1ariabil e-tern este definit ntr2un fi#ier surs diferit de
cel n care ea este referit* atunci o singur declara+ie e-tern dat n
afara oricrei func+ii este suficient pentru toate func+iile care
urmea3 declara+iei.
Func+iile snt considerate n general 1ariabile e-terne afar de
ca3ul cnd se specific altfel.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7G
Cariabilele e-terne se folosesc adeseori n locul listelor de
argumente pentru a comunica date ntre func+ii* c"iar dac func+iile
snt compilate separat.
-ariabile statice
Cariabilele statice se declar prin specificatorul de clas de
memorie static. 6ceste 1ariabile snt la rndul lor de dou feluri4
interne #i e-terne.
Cariabilele statice interne snt locale unei func+ii #i se definesc n
interiorul unei func+ii* dar spre deosebire de 1ariabilele auto* ele #i
pstrea3 1alorile tot timpul e-ecu+iei programului. Cariabilele statice
interne nu snt create #i distruse de fiecare dat cnd func+ia este
acti1at sau prsit; ele ofer n cadrul unei func+ii o memorie
particular permanent pentru func+ia respecti1.
6lte func+ii nu au acces la 1ariabilele statice interne proprii unei
func+ii.
Kle pot fi declarate #i implicit prin conte-t; de e-emplu #irurile
de caractere care apar n interiorul unei func+ii cum ar fi argumentele
func+iei printf 91e3i capitolul 77< snt 1ariabile statice interne.
Cariabilele statice e-terne se definesc n afara oricrei func+ii #i
orice func+ie are acces la ele. 6ceste 1ariabile snt ns globale numai
pentru fi#ierul surs n care ele au fost definite. &u snt recunoscute
n alte fi#iere.
@n conclu3ie* 1ariabila static este e-tern dac este definit n
afara oricrei func+ii #i este static intern dac este definit n
interiorul unei func+ii.
@n general* func+iile snt considerate obiecte e-terne. K-ist ns
#i posibilitatea s declarm o func+ie de clas static. 6ceasta face
ca numele func+iei s nu fie recunoscut n afara fi#ierului n care a
fost declarat.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7H
-ariabile registru
D 1ariabil registru se declar prin specificatorul de clas de
memorie re7ister. Ca #i 1ariabilele auto ele snt locale unui
bloc sau func+ii #i 1alorile lor se pierd la ie#irea din blocul sau func+ia
respecti1. Cariabilele declarate re7ister indic compilatorului c
1ariabilele respecti1e 1or fi folosite foarte des. $ac este posibil*
1ariabilele re7ister 1or li plasate de ctre compilator n regi#trii
rapi3i ai calculatorului* ceea ce conduce la programe mai compacte #i
mai rapide.
Cariabile re7ister pot fi numai 1ariabilele automatice sau
parametrii formali ai unei func+ii. 0ractic e-ist cte1a restric+ii
asupra 1ariabilelor re7ister care reflect realitatea "ard'are2ului
de ba3. 6stfel4
numai cte1a 1ariabile din fiecare func+ie pot fi pstrate n regi#tri
9de obicei 8 sau ?<; declara+ia register este ignorat pentru celelalte
1ariabile;
numai tipurile de date int* char #i pointer snt admise;
nu este posibil referirea la adresa unei 1ariabile re7ister.
3.2. .ipuri de $ariabile
Limbajul C admite numai cte1a tipuri fundamentale de 1ariabile4
caracter* ntreg* flotant.
.ipul caracter
D 1ariabil de tip caracter se declar prin specificatorul de tip
char. Qona de memorie alocat unei 1ariabile de tip char este de
un octet. Ka este suficient de mare pentru a putea memora orice
caracter al setului de caractere implementate pe calculator.
$ac un caracter din setul de caractere este memorat ntr2o
1ariabil de tip char* atunci 1aloarea sa este egal cu codul ntreg al
caracterului respecti1. bi alte cantit+i pot fi memorate n 1ariabile de
tip char* dar implementarea este dependent de sistemul de calcul.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
80
Drdinul de mrime al 1ariabilelor caracter este ntre 6'.5 #i
'.3. Caracterele setului 6:C;; snt toate po3iti1e* dar o constant
caracter specificat printr2o sec1en+ de e1itare poate fi #i negati1*
de e-emplu !\033! are 1aloarea 6'. 6cest lucru se ntmpl atunci
cnd aceast constant apare ntr2o e-presie* moment n care se
con1erte#te la tipul int prin e-tensia bitului cel mai din stnga din
octet 9datorit modului de func+ionare a instruc+iunilor
calculatorului<.
.ipul &ntreg
Cariabilele ntregi po3iti1e sau negati1e pot fi declarate prin
specificatorul de tip int. Qona de memorie alocat unei 1ariabile
ntregi poate fi de cel mult trei dimensiuni.
Rela+ii despre dimensiune snt furni3ate de calificatorii short*
lon7 #i unsi7ned* care pot fi aplica+i tipului int.
Calificatorul short se refer totdeauna la numrul minim de
octe+i pe care poate fi repre3entat un ntreg* n ca3ul nostru 8.
Calificatorul lon7 se refer la numrul ma-im de octe+i pe care
poate fi repre3entat un ntreg* n ca3ul nostru A.
/ipul int are dimensiunea natural sugerat de sistemul de
calcul. :cara numerelor ntregi repre3entabile n ma#in depinde de
asemenea de sistemul de calcul4 un ntreg poate lua 1alori ntre
60.325 #i 0.323 9sisteme de calcul pe 7E bi+i< sau ntre
6.'/3/502/5 #i .'/3/502/3 9sisteme de calcul pe ?8 de bi+i<.
Calificatorul unsi7ned alturi de declara+ia de tip int
determin ca 1alorile 1ariabilelor astfel declarate s fie considerate
ntregi fr semn.
&umerele de tipul unsigned respect legile aritmeticii modulo 8
n
*
unde n este numrul de bi+i din repre3entarea unei 1ariabile de tip
int. &umerele de tipul unsi7ned snt totdeauna po3iti1e.
$eclara+iile pentru calificatori snt de forma4
short int 8;
lon7 int 9;
unsi7ned int :;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
87
Cu1ntul int poate fi omis n aceste situa+ii.
.ipul #lotant /$irgul mobil0
Cariabilele flotante pot fi n simpl preci3ie #i atunci se declar
prin specificatorul de tip float sau n dubl preci3ie #i atunci se
declar prin specificatorul dou(le. %ajoritatea sistemelor de calcul
admit #i repre3entarea n preci3ie e-tins; o 1ariabil n preci3ie
e-tins se declar prin specificatorul lon7 dou(le.
.ipul void /tip nepreci1at0
,n pointer poate fi declarat de tip -oid. @n aceast situa+ie
pointerul nu poate fi folosit pentru indirectare 9dereferen+iere< fr un
cast e-plicit* #i aceasta deoarece compilatorul nu poate determina
mrimea obiectului pe care pointerul l indic.
int 8;
float r;
-oid +p " $8; =W p indic pe - W=
int main() {
+(int +) p " .;
p " $r; =W p indic pe r W=
+(float +)p " '.';

$ac o func+ie este declarat de tip -oid* aceasta nu 1a returna o


1aloare4
-oid hello(char +name) {
printf("Hello, #s.",name);

.ipuri deri$ate
@n afar de tipurile aritmetice fundamentale* e-ist* n principiu* o
clas infinit de tipuri deri1ate* construite din tipurile fundamentale
n urmtoarele moduri4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
88
5 masive de T pentru masi1e de obiecte de un tip dat T* unde T este
unul dintre tipurile admise;
5 funcii care returneaz T pentru func+ii care returnea3 obiecte de
un tip dat T;
5 pointer la T pentru pointeri la obiecte de un tip dat T;
5 structuri pentru un #ir de obiecte de tipuri diferite;
5 reuniuni care pot con+ine obiecte de tipuri diferite* tratate ntr2o
singur 3on de memorie.
@n general aceste metode de construire de noi tipuri de obiecte
pot fi aplicate recursi1. 6mnunte despre tipurile deri1ate snt date n
sec+iunea B.?.
3.3. *biecte i $alori-st&nga
6lte dou no+iuni folosite n descrierea limbajului C snt obiectul
#i valoarea-stna.
,n obiect este con+inutul unei 3one de memorie.
D valoare-stna este o e-presie care se refer la un obiect. ,n
e-emplu e1ident de valoare-stna este un identificator. K-ist
operatori care produc 1alori2stnga4 de e-emplu* dac E este o
e-presie de tip pointer* atunci +E este o e-presie 1aloare2stnga care
se refer la obiectul pe care2l indic E. &umele valoare-stna 9n
limba engle3 left value< a fost sugerat din faptul c n e-presia de
atribuire E7 c E8 operandul stng E7 trebuie s fie o e-presie
valoare-stna. @n paragraful de descriere a operatorilor se 1a indica
dac operan3ii snt valori-stna sau dac re3ultatul opera+iei este o
valoare-stna.
3.'. Con$ersii de tip
,n numr mare de operatori pot cau3a con1ersia 1alorilor unui
operand de la un tip la altul. $ac ntr2o e-presie apar operan3i de
diferite tipuri* ei snt con1erti+i la un tip comun dup un mic numr
de reguli. @n general se fac automat numai con1ersiile care an sens*
de e-emplu4 din ntreg n flotant* ntr2o e-presie de forma f%i.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8?
K-presii care nu au sens* ca de e-emplu un numr flotant ca indice*
nu snt admise.
Caractere i &ntregi
,n caracter poate aprea oriunde unde un ntreg este admis. @n
toate ca3urile 1aloarea caracterului este con1ertit automat ntr2un
ntreg. $eci ntr2o e-presie aritmetic tipul char #i int pot aprea
mpreun. 6ceasta permite o fle-ibilitate considerabil n anumite
tipuri de transformri de caractere. ,n astfel de e-emplu este func+ia
atoi descris n sec+iunea 7.B care con1erte#te un #ir de cifre n
ec"i1alentul lor numeric.
K-presia4
s)i* 6 !0!
produce 1aloarea numeric a caracterului 9cifr< memorat n 6:C;;.
6tragem aten+ia c atunci cnd o 1ariabil de tip char este
con1ertit la tipul int* se poate produce un ntreg negati1* dac bitul
cel mai din stnga al octetului con+ine 7. Caracterele din setul de
caractere 6:C;; nu de1in niciodat negati1e* dar anumite configura+ii
de bi+i memorate n 1ariabile de tip caracter pot aprea ca negati1e
prin e-tensia la tipul int.
Con1ersia tipului int n char se face cu pierderea bi+ilor de
ordin superior.
@ntregii de tip short snt con1erti+i automat la int. Con1ersia
ntregilor se face cu e-tensie de semn; ntregii snt totdeauna cantit+i
cu semn.
,n ntreg lon7 este con1ertit la un ntreg short sau char prin
trunc"iere la stnga; surplusul de bi+i de ordin superior se pierde.
Con$ersii #lotante
/oate opera+iile aritmetice n 1irgul mobil se e-ecut n
preci3ie e-tins. Con1ersia de la float la int se face prin
trunc"ierea pr+ii frac+ionare. Con1ersia de la int la float este
acceptat.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8A
2ntregi #r semn
@ntr2o e-presie n care apar doi operan3i* dintre care unul
unsi7ned iar cellalt un ntreg de orice alt tip* ntregul cu semn
este con1ertit n ntreg fr semn #i re3ultatul este un ntreg fr
semn.
Cnd un int trece n unsi7ned* 1aloarea sa este cel mai mic
ntreg fr semn congruent cu ntregul cu semn 9modulo 8
7E
sau 8
?8
<.
@ntr2o repre3entare la complementul fa+ de 8 9deci pentru numere
negati1e<* con1ersia este conceptual* nu e-ist nici o sc"imbare
real a configura+iei de bi+i.
Cnd un ntreg fr semn este con1ertit la lon7* 1aloarea
re3ultatului este numeric aceea#i ca #i a ntregului fr semn* astfel
con1ersia nu face altce1a dect s adauge 3erouri la stnga.
Con$ersii aritmetice
$ac un operator aritmetic binar are doi operan3i de tipuri
diferite* atunci tipul de ni1el mai sc3ut este con1ertit la tipul de
ni1el mai nalt nainte de opera+ie. Re3ultatul este de tipul de ni1el
mai nalt. ;erar"ia tipurilor este urmtoarea4
5 char < short < int < lon7;
5 float < dou(le < lon7 dou(le;
5 tip ntreg cu semn < tip ntreg fr semn;
5 tip ntreg < 1irgul mobil.
Con$ersii prin atribuire
Con1ersiile de tip se pot face prin atribuire; 1aloarea membrului
drept este con1ertit la tipul membrului stng* care este tipul
re3ultatului.
Con$ersii logice
K-presiile rela+ionale de forma i<G #i e-presiile logice legate
prin operatorii $$ #i HH snt definite ca a1nd 1aloarea 7 dac snt
ade1rate #i 0 dac snt false.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8B
6stfel atribuirea4
d " (c>"!0!) $$ (c<"!4!);
l face pe d egal cu 7 dac c este cifr #i egal cu 0 n ca3 contrar.
Con$ersii e"plicite
$ac con1ersiile de pn aici le2am putea considera implicite*
e-ist #i con1ersii e-plicite de tipuri pentru orice e-presie. 6ceste
con1ersii se fac prin construc+ia special numit cast de forma4
(nume-tip) expresie
@n aceast construc+ie expresie este con1ertit la tipul specificat
dup regulile preci3ate mai sus. %ai precis aceasta este ec"i1alent
cu atribuirea e-presiei respecti1e unei 1ariabile de un tip specificat* #i
aceast nou 1ariabil este apoi folosit n locul ntregii e-presii. $e
e-emplu* n e-presia4
sIrt((dou(le)n)
se con1erte#te n la dou(le nainte de a se transmite func+iei sIrt.
&otm ns c* con+inutul real al lui n nu este alterat. Dperatorul
cast are aceea#i preceden+ ca #i oricare operator unar.
3"presia constant
D e-presie constant este o e-presie care con+ine numai
constante. 6ceste e-presii snt e1aluate n momentul compilrii #i nu
n timpul e-ecu+iei; ele pot fi astfel utili3ate n orice loc unde sinta-a
cere o constant* ca de e-emplu4
#define B<;>JA@ '000
char line)B<;>JA@%'*;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8E
'. *peratori i e"presii
Limbajul C pre3int un numr mare de operatori* caracteri3a+i
prin diferite ni1ele de prioritate sau preceden+.
@n acest capitol descriem operatorii n ordinea descresctoare a
preceden+ei lor. Dperatorii descri#i n acela#i paragraf au aceea#i
preceden+. Com specifica de fiecare dat dac asociati1itatea este la
stnga sau la dreapta.
K-presiile combin 1ariabile #i constante pentru a produce 1alori
noi #i le 1om introduce pe msur ce 1om pre3en+a operatorii.
'.1. 3"presii primare
Expresie-primar4
identificator
constant
ir
(expresie)
expresie-primar )expresie*
expresie-primar (list-expresii<opt>)
valoare-stna . identificator
expresie-primar 6> identificator
!ist-expresii4
expresie
list-expresii, expresie
,n identificator este o expresie-primar* cu condi+ia c el s fi
fost declarat corespun3tor. /ipul su este specificat n declara+ia sa.
$ac tipul unui identificator este masiv de ...* atunci 1aloarea
expresiei-identificator este un pointer la primul obiect al masi1ului*
iar tipul e-presiei este pointer la .... %ai mult* un identificator de
masi1 nu este o e-presie valoare-stna.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
87
La fel* un identificator declarat de tip funcie care
returneaz """* care nu apare pe po3i+ie de apel de func+ie este
con1ertit la pointer la funcie care returneaz """.
D constant este o expresie-primar. /ipul su poate fi int*
lon7 sau dou(le. Constantele caracter snt de tip int* constantele
flotante snt de tip lon7 dou(le.
,n #ir este o expresie-primar. /ipul su original este masiv de
caractere* dar urmnd acelea#i reguli descrise mai sus pentru
identificatori* acesta este modificat n pointer la caracter #i
re3ultatul este un pointer la primul caracter al #irului. K-ist cte1a
e-cep+ii n anumite ini+iali3ri 91e3i paragraful B.A<.
D e-presie ntre parante3e rotunde este o expresie-primar* al
crei tip #i 1aloare snt identice cu cele ale e-presiei din interiorul
parante3elor 9e-presia din parante3e poate fi #i o valoare-stna<.
D expresie-primar urmat de o e-presie ntre parante3e ptrate
este o expresie-primar. :ensul intuiti1 este de inde-are. $e obicei
expresia-primar are tipul pointer la """* expresia-indice are tipul
int* iar re3ultatul are tipul .... D e-presie de forma E7)E8* este
identic 9prin defini+ie< cu +((E7)%(E8))* unde + este operatorul
de indirectare.
,n apel de func+ie este o expresie-primar. Ka const dintr2o
expresie-primar urmat de o perec"e de parante3e rotunde* care
con+in o list-expresii separate prin 1irgule. !ista-expresii constituie
argumentele reale ale func+iei; aceast list poate fi #i 1id. Expresia-
primar trebuie s fie de tipul funcie care returneaz """* iar
re3ultatul apelului de func+ie 1a fi de tipul ....
@naintea apelului* oricare argument de tip float este con1ertit la
tipul dou(le* oricare argument de tip char sau short este
con1ertit la tipul int. &umele de masi1e snt con1ertite n pointeri la
nceputul masi1ului. &ici o alt con1ersie nu se efectuea3 automat.
$ac este necesar pentru ca tipul unui argument actual s
coincid cu cel al argumentului formal* se 1a folosi un cast 91e3i
sec+iunea ?.A<.
:nt permise apeluri recursi1e la orice func+ie.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8G
D valoare-stna urmat de un punct #i un identificator este o
expresie-primar. #aloarea-stna denume#te o structur sau o
reuniune 91e3i capitolul 70< iar identificatorul denume#te un membru
din structur sau reuniune. Re3ultatul este o valoare-stna care se
refer la membrul denumit din structur sau reuniune.
D expresie-primar urmat de o sgeat 9constituit dintr2o
liniu+ #i semnul > urmat de un identificator este o expresie-
primar. 0rima e-presie trebuie s fie un pointer la o structur sau
reuniune* iar identificatorul trebuie s fie numele unui membru din
structura sau reuniunea respecti1. Re3ultatul este o valoare-stna
care se refer la membrul denumit din structura sau reuniunea ctre
care indic e-presia pointer.
K-presia E7>E8 este identic din punctul de 1edere al
re3ultatului cu (+E7). E8
$escriem n continuare operatorii limbajului C mpreun cu
e-presiile care se pot constitui cu ace#ti operatori.
'.2. *peratori unari
/o+i operatorii unari au aceea#i preceden+* iar e-presiile unare se
grupea3 de la dreapta la stnga.
Expresie-unar4
+ expresie
$ valoare-stna
expresie
& expresie
K expresie
%% valoare-stna
66 valoare-stna
valoare-stna %%
valoare-stna 66
(nume-tip) expresie
si:eof (nume-tip)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8H
Dperatorul unar + este operatorul de indirectare. K-presia care2l
urmea3 trebuie s fie un pointer* iar re3ultatul este o 1aloare2stnga
care se refer la obiectul ctre care indic e-presia. $ac tipul
e-presiei este pointer la """ atunci tipul re3ultatului este .... 6cest
operator tratea3 operandul su ca o adres* face acces la ea #i i
ob+ine con+inutul.
Exemplu4 instruc+iunea 9 " +p8; atribuie lui 9 con+inutul
adresei ctre care indic p8.
Dperatorul unar $ este operatorul de ob+inere a adresei unui
obiect sau de ob+inere a unui pointer la obiectul respecti1. Dperandul
este o valoare-stna iar re3ultatul este un pointer la obiectul referit
de valoarea-stna. $ac tipul valorii-stna este ... atunci tipul
re3ultatului este pointer la """.
Exemplu. Fie 8 o 1ariabil de tip int #i p8 un pointer creat ntr2
un anumit fel 91e3i capitolul H<. 6tunci prin instruc+iunea
p8 " $8;
se atribuie 1ariabilei de tip pointer la int p8 adresa 1ariabilei 8;
putem spune acum c p8 indic spre 8. :ec1en+a4
p8 " $8; 9 " +p8;
este ec"i1alent cu
9 " 8;
Dperatorul $ poate fi aplicat numai la 1ariabile #i la elemente de
masi1. Construc+ii de forma $(8%') #i $0 nu snt admise. $e
asemenea nu se admite ca 1ariabila s fie de clas re7ister.
Dperatorul unar $ ajut la transmiterea argumentelor de tip
adres n func+ii.
Dperatorul unar 6 este operatorul de negati1are. Dperandul su
este o e-presie* iar re3ultatul este negati1area operandului. @n acest
ca3 snt aplicate con1ersiile aritmetice obi#nuite. &egati1area unui
ntreg de tip unsigned se face sc3nd 1aloarea sa din 8
n
* unde n este
numrul de bi+i re3er1a+i tipului int.
Dperatorul unar & este operatorul de negare logic. Dperandul
su este o e-presie* iar re3ultatul su este 7 sau 0 dup cum 1aloarea
operandului este 0 sau diferit de 3ero. /ipul re3ultatului este int.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?0
6cest operator este aplicabil la orice e-presie de tip aritmetic sau la
pointeri.
Dperatorul unar K 9tilda< este operatorul de complementare la
unu. Kl con1erte#te fiecare bit 7 la 0 #i in1ers. Kl este un operator
logic pe bi+i.
Dperandul su trebuie s fie de tip ntreg. :e aplic con1ersiile
aritmetice obi#nuite.
Dperatorul unar %% este operatorul de incrementare. Dperandul
su este o 1aloare2stnga. Dperatorul produce incrementarea
operandului cu 7. 6cest operator pre3int un aspect deosebit deoarece
el poate fi folosit ca un operator prefi- 9naintea 1ariabilei4 %%n< sau
ca un operator postfi- 9dup 1ariabil4 n%%<. @n ambele ca3uri efectul
este incrementarea lui n. $ar e-presia %%n incrementea3 pe n
nainte de folosirea 1alorii sale* n timp ce n%% incrementea3 pe n
dup ce 1aloarea sa a fost utili3at. 6ceasta nseamn c n conte-tul
n care se urmre#te numai incrementarea lui n* oricare construc+ie
poate fi folosit* dar ntr2un conte-t n care #i 1aloarea lui n este
folosit %%n #i n%% furni3ea3 dou 1alori distincte.
Exemplu4 dac n este B* atunci
8 " n%% ; atribuie lui 8 1aloarea B
8 " %%n ; atribuie lui 8 1aloarea E
@n ambele ca3uri n de1ine E.
Re3ultatul opera+iei nu este o valoare-stna* dar tipul su este
tipul valorii-stna.
Dperatorul unar 66 este operatorul de decrementare. 6cest
operator este analog cu operatorul %% doar c produce decrementarea
cu 7 a operandului.
Dperatorul (nume-tip) este operatorul de con1ersie de tip. 0rin
nume-tip n+elegem unul dintre tipurile fundamentale admise n C.
Dperandul acestui operator este o expresie. Dperatorul produce
con1ersia 1alorii expresiei la tipul denumit. 6ceast construc+ie se
nume#te cast.
Dperatorul si:eof furni3ea3 dimensiunea n octe+i a
operandului su. 6plicat unui masi1 sau structuri* re3ultatul este
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?7
numrul total de octe+i din masi1 sau structur. $imensiunea se
determin n momentul compilrii* din declara+iile obiectelor din
e-presie. :emantic* aceast e-presie este o constant ntreag care se
poate folosi n orice loc n care se cere o constant. Cea mai frec1ent
utili3are o are n comunicarea cu rutinele de alocare a memoriei sau
rutinele ;=D sistem.
Dperatorul si:eof poate fi aplicat #i unui nume-tip ntre
parante3e. @n acest ca3 el furni3ea3 dimensiunea n octe+i a unui
obiect de tipul indicat.
Construc+ia si:eof(nume-tip) este luat ca o unitate* astfel c
e-presia
si:eof(nume-tip)6.
este acela#i lucru cu
(si:eof(nume-tip))6.
'.3. *peratori multiplicati$i
Dperatorii multiplicati1i + F #i # snt operatori aritmetici
binari #i se grupea3 de la stnga la dreapta.
Expresie-multiplicativ4
expresie + expresie
expresie F expresie
expresie # expresie
Dperatorul binar + indic nmul+irea. Dperatorul este asociati1*
dar n e-presiile n care apar mai mul+i operatori de nmul+ire* ordinea
de e1aluare nu se specific. Compilatorul rearanjea3 c"iar #i un
calcul cu parante3e. 6stfel a+((+c) poate fi e1aluat ca (a+()+c.
6ceasta nu implic diferen+e* dar dac totu#i se dore#te o anumit
ordine* atunci se 1or introduce 1ariabile temporare.
Dperatorul binar F indic mpr+irea. Cnd se mpart dou
numere ntregi po3iti1e* trunc"ierea se face spre 3ero; dac unul
dintre operan3i este negati1 atunci trunc"ierea depinde de sistemul de
calcul.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?8
Dperatorul binar # furni3ea3 restul mpr+irii primei e-presii la
cea de a doua. Dperan3ii nu pot fi de tip float. Restul are totdeauna
semnul dempr+itului. /otdeauna (aF()+(%a#( este egal cu a
9dac ( este diferit de 0<. :nt e-ecutate con1ersiile aritmetice
obi#nuite.
'.'. *peratori aditi$i
Dperatorii aditi1i % #i 6 snt operatori aritmetici binari #i se
grupea3 de la stnga la dreapta. :e e-ecut con1ersiile aritmetice
obi#nuite*
Expresie-aditiv4
expresie % expresie
expresie 6 expresie
Dperatorul binar % produce suma operan3ilor si. Kl este
asociati1 #i e-presiile care con+in mai mul+i operatori pot fi rearanjate
la fel ca n ca3ul operatorului de nmul+ire.
Dperatorul binar 6 produce diferen+a operan3ilor si.
'.). *peratori de deplasare
Dperatorii de deplasare << #i >> snt operatori logici pe bi+i.
Ki se grupea3 de la stnga la dreapta.
Expresie-deplasare4
expresie << expresie
expresie >> expresie
Dperatorul << produce deplasarea la stnga a operandului din
stnga cu un numr de po3i+ii binare dat de operandul din dreapta.
Dperatorul >> produce deplasarea la dreapta a operandului din
stnga cu un numr de po3i+ii binare dat de operandul din dreapta.
@n ambele ca3uri se e-ecut con1ersiile aritmetice obi#nuite
asupra operan3ilor* fiecare dintre ei trebuind s fie de tip ntreg.
Dperandul din dreapta este con1ertit la int; tipul re3ultatului este
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
??
cel al operandului din stnga. Re3ultatul este nedefinit dac operandul
din dreapta este negati1 sau mai mare sau egal cu lungimea
obiectului* n bi+i. 6stfel 1aloarea e-presiei E7<<E8 este E7
9interpretat ca #i configura+ie de bi+i< deplasat la stnga cu E8
po3i+ii bit; bi+ii elibera+i de1in 3ero. K-presia E7>>E8 este E7
deplasat la dreapta cu E8 po3i+ii binare. $eplasarea la dreapta este
logic 9bi+ii elibera+i de1in 0< dac E7 este de tip unsigned; altfel ea
este aritmetic 9bi+ii elibera+i de1in copii ale bitului semn<.
Exemplu4 8<<. deplasea3 pe 8 la stnga cu 8 po3i+ii* bi+ii
elibera+i de1in 0; aceasta este ec"i1alent cu multiplicarea lui 8 cu A.
'.+. *peratori relaionali
Dperatorii rela+ionali <* >* <"* >" se grupea3 de la stnga la
dreapta.
Expresie-relaional4
expresie < expresie
expresie > expresie
expresie <" expresie
expresie >" expresie
Dperatorii < 9mai mic<* > 9mai mare<* <" 9mai mic sau egal< #i
>" 9mai mare sau egal< produc 1aloarea 0 dac rela+ia specificat este
fals #i 7 dac ea este ade1rat.
/ipul re3ultatului este int. :e e-ecut con1ersiile aritmetice
obi#nuite. 6ce#ti operatori au preceden+a mai mic dect operatorii
aritmetici* astfel c e-presia i<86' se consider i<(86') a#a dup
cum ne a#teptam.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?A
'.4. *peratori de egalitate
Expresie-ealitate4
expresie "" expresie
expresie &" expresie
Dperatorii "" 9egal cu< #i &" 9diferit de< snt analogi cu operatorii
rela+ionali* dar preceden+a lor este mai mic. 6stfel a<( "" c<d
este 7* dac a<( #i c<d au aceea#i 1aloare de ade1r.
'.5. *peratorul I pe bii
Expresie-$%4
expresie $ expresie
Dperatorul $ este operatorul $% logic pe bi+i. Kl este asociati1 #i
e-presiile care con+in operatorul $ pot fi rearanjate. Re3ultatul este
func+ia logic $% pe bi+i aplicat operan3ilor si. Dperatorul se
aplic numai la operan3i de tipuri ntregi. Legea dup care
func+ionea3 este4
V 0 7
0 0 0
7 0 7
Dperatorul $ este deseori folosit pentru a masca o anumit
mul+ime de bi+i4 de e-emplu4
c " n $ 0'33;
pune pe 3ero to+i bi+ii afar de ultimii 7 bi+i de ordin inferior ai lui n*
fr a afecta con+inutul lui n.
'.6. *peratorul SAU-exclusiv pe bii
Expresie-&A'-exclusiv4
expresie L expresie
Dperatorul L este operatorul &A'-exclusiv logic pe bi+i. Kl este
asociati1 #i e-presiile care2l con+in pot fi rearanjate. Re3ultatul este
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?B
func+ia logic &A'-exclusiv pe bi+i aplicat operan3ilor si.
Dperatorul se aplic numai la operan3i de tipuri ntregi. Legea dup
care func+ionea3 este4
L
0 7
0 0 7
7 7 0
'.17. *peratorul SAU-inclusiv pe bii
Expresie-&A'-inclusiv4
expresie H expresie
Dperatorul H este operatorul &A'-inclusiv logic pe bi+i. Kl este
asociati1 #i e-presiile care2l con+in pot fi rearanjate. Re3ultatul este
func+ia logic &A'-inclusiv pe bi+i aplicat operan3ilor si.
Dperatorul se aplic numai la operan3i de tipuri ntregi. Legea dup
care func+ionea3 este4
H
0 7
0 0 7
7 7 7
Dperatorul H este folosit pentru a po3i+iona bi+i; de e-emplu4
8 " 8 H B<MN;
pune pe 7 to+i bi+ii din 8 care corespund la bi+i po3i+iona+i pe 7 din
B<MN. :e efectuea3 con1ersiile aritmetice obi#nuite.
'.11. *peratorul I-logic
Expresie-$%-loic4
expresie $$ expresie
Dperatorul $$ este operatorul $%-loic #i el se grupea3 de la
stnga la dreapta. Re3ultatul este 7 dac ambii operan3i snt diferi+i de
3ero #i 0 n rest. :pre deosebire de operatorul $% pe bi+i $* operatorul
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?E
$%-loic $$ garantea3 o e1aluare de la stnga la dreapta; mai mult* al
doilea operand nu este e1aluat dac primul operand este 0.
Dperan3ii nu trebuie s aib n mod obligatoriu acela#i tip* dar
fiecare trebuie s aib unul dintre tipurile fundamentale sau pointer.
Re3ultatul este totdeauna de tip int.
'.12. *peratorul SAU-logic
Expresie-&A'-loic4
expresie HH expresie
Dperatorul HH este operatorul &A'-loic #i el se grupea3 de la
stnga la dreapta. Re3ultatul este 7 dac cel pu+in unul dintre operan3i
este diferit de 3ero #i 0 n rest.
:pre deosebire de operatorul &A'-inclusiv pe bi+i H* operatorul
&A'-loic HH garantea3 o e1aluare de la stnga la dreapta; mai mult*
al doilea operand nu este e1aluat dac 1aloarea primului operand este
diferit de 3ero.
Dperan3ii nu trebuie s aib n mod obligatoriu acela#i tip* dar
fiecare trebuie s aib unul dintre tipurile fundamentale sau pointer.
Re3ultatul este totdeauna de tip int.
'.13. *peratorul condiional
Expresie-condiional4
expresie O expresie 4 expresie
Dperatorul condi+ional O este un operator ternar. 0rima e-presie
se e1aluea3 #i dac ea este diferit de 3ero sau ade1rat* re3ultatul
este 1aloarea celei de2a doua e-presii* altfel re3ultatul este 1aloarea
e-presiei a treia. $e e-emplu e-presia4
: " (a>() O a P (;
calculea3 ma-imul dintre a #i ( #i l atribuie lui :. :e e1aluea3 mai
nti prima e-presie a>(. $ac ea este ade1rat se e1aluea3 a doua
e-presie #i 1aloarea ei este re3ultatul opera+iei* aceast 1aloare se
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?7
atribuie lui :. $ac prima e-presie nu este ade1rat atunci : ia
1aloarea lui (.
K-presia condi+ional poate fi folosit peste tot unde sinta-a cere
o e-presie.
$ac este posibil* se e-ecut con1ersiile aritmetice obi#nuite
pentru a aduce e-presia a doua #i a treia la un tip comun; dac ambele
e-presii snt pointeri de acela#i tip* re3ultatul are #i el acela#i tip;
dac numai o e-presie este un pointer* cealalt trebuie sa fie
constanta 0* iar re3ultatul este de tipul pointerului. @ntotdeauna numai
una dintre e-presiile a doua #i a treia este e1aluat.
$ac f este flotant #i n ntreg* atunci e-presia
(h>0)O f P n
este de tip double indiferent dac n este po3iti1 sau negati1.
0arante3ele nu snt necesare deoarece preceden+a operatorului OP
este mai mic* dar ele pot fi folosite pentru a face e-presia
condi+ional mai 1i3ibil.
'.1'. *peratori de atribuire
K-ist mai mul+i operatori de atribuire* care se grupea3 to+i de la
dreapta la stnga. Dperandul stng este o 1aloare2stnga* operandul
drept este o e-presie. /ipul e-presiei de atribuire este tipul
operandului stng.
Re3ultatul este 1aloarea memorat n operandul stng dup ce
atribuirea a a1ut loc. Cele dou pr+i ale unui operator de atribuire
compus snt unit+i le-icale 9simboluri< distincte.
Expresie-atribuire4
valoare-stna " expresie
valoare-stna op" expresie
unde op poate fi unul din operatorii %* 6* +* F* #* <<* >>* $* L* H.
@ntr2o atribuire simpl cu "* 1aloarea e-presiei nlocuie#te pe cea
a obiectului referit de valoare-stna. $ac ambii operan3i au tip
aritmetic* atunci operandul drept este con1ertit la tipul operandului
stng nainte de atribuire.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?G
K-presiile de forma E7 op" E8 se interpretea3 ca fiind
ec"i1alente cu e-presiile de forma E7 " E7 op E8; totu#i E7 este
e1aluat o singur dat.
Exemplu4 e-presia 8 +" 9%' este ec"i1alent cu
8 " 8 + (9%') #i nu cu 8 " 8 + 9 % '
0entru operatorii %" #i 6"* operandul stng poate fi #i un pointer*
n care ca3 operandul din dreapta este con1ertit la ntreg 91e3i
capitolul H<. /o+i operan3ii din dreapta #i to+i operan3ii din stnga care
nu snt pointeri trebuie s fie de tip aritmetic.
6tribuirea prescurtat este a1antajoas n ca3ul cnd n membrul
stng a1em e-presii complicate* deoarece ele se e1aluea3 o singur
dat.
'.1). *peratorul $irgul
Expresie-virul4
expresie , expresie
D perec"e de e-presii separate prin 1irgul se e1aluea3 de la
stnga la dreapta #i 1aloarea e-presiei din stnga se neglijea3. /ipul
#i 1aloarea re3ultatului snt cele ale operandului din dreapta. 6ce#ti
operatori se grupea3 de la stnga la dreapta. @n conte-tele n care
1irgula are un sens special* 9de e-emplu ntr2o list de argumente
reale ale unei func+ii #i lista de ini+iali3are<* operatorul 1irgul descris
aici poate aprea numai n parante3e. $e e-emplu func+ia4
f(a,(t"0,t%.),c)
are trei argumente* dintre care al doilea are 1aloarea B. K-presia
acestui argument este o e-presie 1irgul. @n calculul 1alorii lui se
e1aluea3 nti e-presia din stnga #i se ob+ine 1aloarea ? pentru t*
apoi cu aceast 1aloare se e1aluea3 a doua e-presie #i se ob+ine t=B.
0rima 1aloare a lui t se pierde.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
?H
'.1+. Precedena i ordinea de e$aluare
/abelul de la sfr#itul acestei sec+iuni constituie un re3umat al
regulilor de preceden+ #i asociati1itate ale tuturor operatorilor.
Dperatorii din aceea#i linie au aceea#i preceden+; liniile snt
scrise n ordinea descresctoare a preceden+ei* astfel de e-emplu
operatorii +* F #i # au to+i aceea#i preceden+* care este mai mare
dect aceea a operatorilor % #i 6.
$up cum s2a men+ionat deja* e-presiile care con+in unul dintre
operatorii asociati1i sau comutati1i 9+* %* $* L* H< pot fi rearanjate de
compilator c"iar dac con+in parante3e. @n cele mai multe ca3uri
aceasta nu produce nici o diferen+; n ca3urile n care o asemenea
diferen+ ar putea aprea pot fi utili3ate 1ariabile temporare e-plicite*
pentru a for+a ordinea de e1aluare.
Limbajul C* ca #i multe alte limbaje* nu specific n ce ordine snt
e1alua+i operan3ii unui operator. $e e-emplu ntr2o instruc+iune de
forma4
8 " f() % 7();
f poate fi e1aluat nainte sau dup e1aluarea lui 7; dac f sau 7
alterea3 o 1ariabil e-tern de care cealalt depinde* 8 poate
depinde de ordinea de e1aluare. $in nou re3ultate intermediare
trebuie memorate n 1ariabile temporare pentru a asigura o sec1en+
particular.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A0
Dperator 6sociati1itate
() )* 6> .
stnga la dreapta
& %% 66 6 (tip) + $ si:eof dreapta la stnga
+ F #
stnga la dreapta
% 6
stnga la dreapta
<< >>
stnga la dreapta
< <" > >"
stnga la dreapta
"" &"
stnga la dreapta
$
stnga la dreapta
L
stnga la dreapta
H
stnga la dreapta
$$
stnga la dreapta
HH
stnga la dreapta
OP
dreapta la stnga
" op" dreapta la stnga
,
stnga la dreapta
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A7
). 8eclaraii
$eclara+iile se folosesc pentru a specifica interpretarea pe care
compilatorul trebuie s o dea fiecrui identificator.
(eclaraie4
specificator-declaraie lista-declarator<opt>;
&pecificator-declaraie4
specificator-tip specificator-declaraie<opt>
specificator-clas-memorie specificator-declaraie<opt>
&pecificator-tip4
char
short
int
lon7
unsi7ned
float
dou(le
-oid
specificator-structur-sau-reuniune
t9pedef-nume
&pecificator-clas-memorie4
auto
static
e8tern
re7ister
const
t9pedef
!ista-declarator4
declarator-cu-iniializare
declarator-cu-iniializare* lista-declarator
(eclarator-cu-iniializare4
declarator iniializator<opt>
(eclarator4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A8
identificator
(declarator)
+ declarator
declarator ()
declarator )expresie-constant<opt>*
$eclara+iile listea3 toate 1ariabilele care urmea3 a fi folosite
ntr2un program. D declara+ie specific tipul* clasa de memorie #i
e1entual 1alorile ini+iale pentru una sau mai multe 1ariabile de
acela#i tip. $eclara+iile se fac sau n afara oricrei func+ii sau la
nceputul unei func+ii naintea oricrei instruc+iuni.
&u orice declara+ie re3er1 #i memorie pentru un anumit
identificator* de aceea deosebim4
declara+ia de defini+ie a unei 1ariabile* care se refer la locul
unde este creat 1ariabila #i unde i se aloc memorie;
declara+ia de utili3are a unei 1ariabile* care se refer la locul
unde numele 1ariabilei este declarat pentru a anun+a propriet+ile
1ariabilei care urmea3 a fi folosit.
).1. ,peci#icatori de clas de memorie
:pecificatorii de clas de memorie snt4
auto static e8tern re7ister
const t9pedef
:pecificatorul t9pedef nu re3er1 memorie #i este denumit
specificator de clas de memorie numai din moti1e sintactice; el 1a
fi discutat n capitolul 70.
:emnifica+ia diferitelor clase de memorie a fost discutat deja n
paragraful ?.7.
$eclara+iile cu specificatorii auto* static #i re7ister
determin #i re3er1area unei 3one de memorie corespun3toare.
$eclara+ia cu specificatorul e8tern presupune o defini+ie e-tern
pentru identificatorii da+i* unde1a n afara func+iei sau fi#ierului n
care ei snt declara+i.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A?
@ntr2o declara+ie poate s apar cel mult un specificator de clas
de memorie. $ac specificatorul de clas lipse#te din declara+ie* el se
consider implicit auto n interiorul unei func+ii #i defini+ie e-tern n
afara func+iei. K-cep+ie fac func+iile care nu snt niciodat
automatice. $e e-emplu liniile4
int sp;
dou(le -al)B<;Q<>*;
care apar ntr2un program n afara oricrei func+ii* definesc
1ariabilele e-terne sp de tip int #i -al de tip masi1 de dou(le.
Kle determin alocarea memoriei #i ser1esc de asemenea ca declara+ii
ale acestor 1ariabile n tot restul fi#ierului surs. 0e de alt parte
liniile4
e8tern int sp;
e8tern dou(le -al)*;
declar pentru restul fi#ierului surs c 1ariabilele sp #i -al snt
e-terne* sp este de tip int #i -al este un masi1 de dou(le #i c
ele au fost definite n alt parte* unde li s2a alocat #i memorie. $eci
aceste declara+ii nu creea3 aceste 1ariabile #i nici nu le aloc
memorie.
).2. ,peci#icatori de tip
:pecificatorii de tip snt4
char short int lon7 unsi7ned
float dou(le -oid
specificator-structur-sau-reuniune
t9pedef2nume
Cu1intele lon7* short #i unsi7ned pot fi considerate #i ca
adjecti1e; urmtoarele combina+ii snt acceptate4
short int
lon7 int
unsi7ned int
unsi7ned lon7 int
lon7 dou(le
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AA
@ntr2o declara+ie se admite cel mult un specificator de tip* cu
e-cep+ia combina+iilor amintite mai sus. $ac specificatorul de tip
lipse#te din declara+ie* el se consider implicit int.
:pecificatorii de structuri #i reuniuni snt pre3enta+i n
sec+iunea 70.H* iar declara+iile cu t9pedef n sec+iunea
70.70.
).3. 8eclaratori
!ista-declarator care apare ntr2o declara+ie este o succesiune de
declaratori separa+i prin 1irgule* fiecare dintre ei putnd a1ea un
ini+iali3ator.
$eclaratorii din lista-declarator snt identificatorii care trebuie
declara+i.
Fiecare declarator este considerat ca o afirma+ie care* atunci cnd
apare o construc+ie de aceea#i form cu declaratorul* produce un
obiect de tipul #i de clasa de memorie indicat. Fiecare declarator
con+ine un singur identificator. Lruparea declaratorilor este la fel ca
#i la e-presii.
$ac declaratorul este un identificator simplu* atunci el are tipul
indicat de specificatorul din declara+ie.
,n declarator ntre parante3e este tot un declarator* dar legtura
declaratorilor complec#i poate fi alterat de parante3e.
: considerm acum o declara+ie de forma4
T (7
unde T este un specificator de tip 9ca de e-emplu int< #i (7 un
declarator. : presupunem c aceast declara+ie face ca identificatorul
s aib tipul ...T unde ... este 1id dac (7 este un identificator
simplu 9a#a cum tipul lui 8 n int 8 este int<. $ac (7 are forma4
+(
atunci tipul identificatorului pe care2l con+ine acest declarator este
pointer la T.
$ac (7 are forma4
(()
atunci identificatorul pe care2l con+ine are tipul funcie care
returneaz T.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AB
$ac (7 are forma4
()expresie-constant* sau ()*
atunci identificatorul pe care2l con+ine are tipul masiv de T.
@n primul ca3 e-presia constant este o e-presie a crei 1aloare
este determinabil la compilare #i al crei tip este int. Cnd mai
mul+i identificatori masiv de T snt adiacen+i* se creea3 un masi1
multidimensional; e-presiile constante care specific marginile
masi1elor pot lipsi numai pentru primul membru din sec1en+.
6ceast omisiune este util cnd masi1ul este e-tern #i defini+ia real
care aloc memoria este n alt parte 91e3i sec+iunea B.7<. 0rima
e-presie constant poate lipsi de asemenea cnd declaratorul este
urmat de ini+iali3are. @n acest ca3 dimensiunea este calculat la
compilare din numrul elementelor ini+iale furni3ate.
,n masi1 poate fi construit din obiecte de unul dintre tipurile de
ba3* din pointeri* din reuniuni sau structuri* sau din alte masi1e
9pentru a genera un masi1 multidimensional<.
&u toate posibilit+ile admise de sinta-a de mai sus snt permise.
Restric+iile snt urmtoarele4 func+iile nu pot returna masi1e*
structuri* reuniuni sau func+ii* de#i ele pot returna pointeri la astfel de
obiecte; nu e-ist masi1e de func+ii* dar pot fi masi1e de pointeri la
func+ii. $e asemenea* o structur sau reuniune nu poate con+ine o
func+ie* dar ea poate con+ine un pointer la func+ie. $e e-emplu*
declara+ia
int i, +ip, f(), +fip(), (+pfi)();
declar un ntreg i* un pointer ip la un ntreg* o func+ie f care
returnea3 un ntreg* o func+ie fip care returnea3 un pointer la un
ntreg* un pointer pfi la o func+ie care returnea3 un ntreg. 0re3int
interes compararea ultimilor doi declaratori.
Construc+ia +fip() este +(fip())* astfel c declara+ia
sugerea3 apelul func+iei fip #i apoi utili3nd indirectarea prin
intermediul pointerului se ob+ine un ntreg.
@n declaratorul (+pfi)()* parante3ele e-terne snt necesare
pentru arta c indirectarea printr2un pointer la o func+ie furni3ea3 o
func+ie* care este apoi apelat; ea returnea3 un ntreg.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AE
$eclara+iile de 1ariabile pot fi e-plicite sau implicite prin
conte-t. $e e-emplu declara+iile4
int a,(,c;
char d, m)'00*;
specific un tip #i o list de 1ariabile. 6ici clasa de memorie nu este
declarat e-plicit* ea se deduce din conte-t. $ac declara+ia este
fcut n afara oricrei func+ii atunci clasa de memorie este e8tern;
dac declara+ia este fcut n interiorul unei func+ii atunci implicit
clasa de memorie este auto.
Cariabilele pot fi distribuite n declara+ii n orice mod; astfel
listele le mai sus pot fi scrise #i sub forma4
int a;
int (;
int c;
char d;
char m)'00*;
6ceasta ultim form ocup mai mult spa+iu dar este mai
con1enabil pentru adugarea unui comentariu pentru fiecare
declara+ie sau pentru modificri ulterioare.
).'. Modi#icatorul const
Caloarea unei 1ariabile declarate cu acest modificator nu poate fi
modificat.
:inta-a4
const nume-variabil " valoare ;
nume-funcie (...* const tip +nume-variabil* ...)
@n prima 1ariant* modificatorul atribuie o 1aloare ini+ial unei
1ariabile care nu mai poate fi ulterior modificat de program. $e
e-emplu*
const int -irsta " 04;
Drice atribuire pentru 1ariabila -irsta 1a genera o eroare de
compilare.
6ten+ieR D 1ariabil declarat cu const poate fi indirect
modificat prin intermediul unui pointer4
int +p " $-irsta;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A7
+p " 01;
@n a doua 1ariant modificatorul const este folosit mpreun
cu un parametru pointer ntr2o list de parametri ai unei func+ii.
Func+ia nu poate modifica 1ariabila pe care o indic pointerul4
int printf (const char +format, ...);
).). Iniiali1are
,n declarator poate specifica o 1aloare ini+ial pentru
identificatorul care se declar. ;ni+iali3atorul este precedat de semnul
" #i const dintr2o e-presie sau o list de 1alori incluse n acolade.
%niializator4
expresie
{list-iniializare
!ist-iniializare4
expresie
list-iniializare, list-iniializare
{list-iniializare
/oate e-presiile dintr2un iniializator pentru 1ariabile statice sau
e-terne trebuie s fie e-presii constante 91e3i sec+iunea ?.A< sau
e-presii care se reduc la adresa unei 1ariabile declarate anterior*
posibil offset2ul unei e-presii constante. Cariabilele de clas auto sau
register pot fi ini+iali3ate cu e-presii oarecare* nu neaprat e-presii
constante* care implic constante sau 1ariabile declarate anterior sau
c"iar func+ii.
@n absen+a ini+iali3rii e-plicite* 1ariabilele statice #i e-terne snt
ini+iali3ate implicit cu 1aloarea 0. Cariabilele auto #i register au 1alori
ini+iale nedefinite 9re3iduale<.
0entru 1ariabilele statice #i e-terne* ini+iali3area se face o singur
dat* n principiu nainte ca programul s nceap s se e-ecute.
0entru 1ariabilele auto #i re7ister* ini+iali3area este fcut
la fiecare intrare n func+ie sau bloc.
$ac un ini+iali3ator se aplic unui scalar 9un pointer sau un
obiect de tip aritmetic< el const dintr2o singur e-presie* e1entual n
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AG
acolade. Caloarea ini+ial a obiectului este luat din e-presie; se
efectuea3 acelea#i opera+ii ca n ca3ul atribuirii.
0entru ini+iali3area masi1elor #i masi1elor de pointeri 1e3i
sec+iunea H.G. 0entru ini+iali3area structurilor 1e3i sec+iunea 70.?.
$ac masi1ul sau structura con+ine sub2masi1e sau sub2structuri
regula de ini+iali3are se aplic recursi1 la membrii masi1ului sau
structuri.
).+. Nume-tip
@n cele e-puse mai sus furni3area unui nume-tip a fost necesar n
dou conte-te4
pentru a specifica con1ersii e-plicite de tip prin intermediul unui
cast 91e3i sec+iunea ?.A<;
ca argument al lui si:eof 91e3i sec+iunea A.8<.
,n nume-tip este n esen+ o declara+ie pentru un obiect de acest
tip* dar care omite numele obiectului.
)ume-tip4
specificator-tip declarator-abstract
(eclarator-abstract4
vid
(declarator-abstract)
+declarator-abstract
declarator-abstract()
declarator-abstract)expresie-constant<opt>*
0entru a e1ita ambiguitatea* n construc+ia4
(declarator-abstract)
declaratorul abstract se presupune a nu fi 1id. Cu aceast restric+ie*
este posibil s identificm n mod unic locul ntr2un declarator-
abstract* unde ar putea aprea un identificator* dac aceast
construc+ie a fost un declarator ntr2o declara+ie. 6tunci tipul denumit
este acela#i ca #i tipul identificatorului ipotetic. $e e-emplu4
int
int+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AH
int +)0*
int(+))0*
int +( )
int(+)()
denume#te respecti1 tipurile int* pointer la ntre* masiv de ?
pointeri la ntrei* pointer la un masiv de ? ntrei* funcie care
returneaz pointer la ntre #i pointer la o funcie care returneaz
ntre.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B0
+. Instruciuni
@ntr2un program scris n limbajul C instruc+iunile se e-ecut
sec1en+ial* n afar de ca3ul n care se indic altfel.
;nstruc+iunile pot fi scrise cte una pe o linie pentru o li3ibilitate
mai bun* dar nu este obligatoriu.
+.1. Instruciunea expresie
Cele mai multe instruc+iuni snt instruc+iuni expresie. D e-presie
de1ine instruc+iune dac ea este urmat de punct #i 1irgul.
Format4
expresie;
$e obicei instruc+iunile expresie snt atribuiri sau apeluri de
func+ie; de e-emplu4
8 " 0;
printf(...);
@n limbajul C punct #i 1irgula este un terminator de instruc+iune
#i este obligatoriu.
+.2. Instruciunea compus sau blocul
;nstruc+iunea compus este o grupare de declara+ii #i instruc+iuni
nc"ise ntre acolade. Kle au fost introduse cu scopul de a folosi mai
multe instruc+iuni acolo unde sinta-a cere o instruc+iune.
;nstruc+iunea compus sau blocul snt ec"i1alente sintactic cu o
singur instruc+iune.
Format4
%nstruciune-compus4
{ list-declaratori<opt> list-instruciuni<opt>
!ist-declaratori4
declaraie
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B7
declaraie list-declaratori
!ist-instruciuni4
instruciune
instruciune list-instruciuni
$ac anumi+i identificatori din lista-declaratori au fost declara+i
anterior* atunci declara+ia e-terioar este sal1at pe durata blocului*
dup care #i reia sensul su.
Drice ini+iali3are pentru 1ariabile auto #i re7ister se
efectuea3 la fiecare intrare n bloc. ;ni+iali3rile pentru 1ariabilele
static se e-ecut numai o singur dat cnd programul ncepe s
se e-ecute.
,n bloc se termin cu o acolad dreapt care nu este urmat
niciodat de punct #i 1irgul.
+.3. Instruciunea condiional
:inta-a instruc+iunii condi+ionale admite dou formate4
if (expresie)
instruciune27
if (expresie)
instruciune27
else instruciune28
;nstruc+iunea condi+ional se folose#te pentru a lua deci3ii. @n
ambele ca3uri se e1aluea3 e-presia #i dac ea este ade1rat 9deci
diferit de 3ero< se e-ecut instruc+iune27. $ac e-presia este fals
9are 1aloarea 3ero< #i instruc+iunea if are #i parte de else atunci se
e-ecut instruc+iune28.
,na #i numai una dintre cele dou instruc+iuni se e-ecut.
$eoarece un if testea3 pur #i simplu 1aloarea numeric a unei
e-presii* se admite o prescurtare #i anume4
if (expresie)
n loc de4
if (expresie &" 0)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B8
$eoarece partea else a unei instruc+iuni if este op+ional*
e-ist o ambiguitate cnd un else este omis dintr2o sec1en+ de if
imbricat. 6ceasta se re3ol1 asociind else cu ultimul if care nu
are else.
Exemplu4
if (n>0)
if (a>()
: " a;
else
: " (;
0artea else apar+ine if2ului din interior. $ac nu dorim acest
lucru atunci folosim acoladele pentru a for+a asocierea4
if (n>0) {
if (a>()
: " a;

else
: " (;
;nstruc+iunea condi+ional admite #i construc+ia else2if de forma4
if (expresie27)
instruciune27
else if (expresie28)
instruciune28
else if (expresie2?)
instruc+iune2?
else
instruciune2A
6ceast sec1en+ de if se folose#te frec1ent n programe* ca
mod de a e-prima o deci3ie multipl.
K-presiile se e1aluea3 n ordinea n care apar; dac se ntlne#te
o e-presie ade1rat* atunci se e-ecut instruc+iunea asociat cu ea #i
astfel se termin ntregul lan+.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B?
Dricare instruc+iune poate fi o instruc+iune simpl sau un grup de
instruc+iuni ntre acolade.
d ;nstruc+iunea dup ultimul else se e-ecut n ca3ul n care nici
o e-presie nu a fost ade1rat.
$ac n acest ca3 nu e-ist nici o ac+iune e-plicit de fcut*
atunci partea
else instruciune2A
poate s lipseasc.
Func+ia (inar9 din sec+iunea 7.B este un e-emplu de deci3ie
multipl de ordinul ?.
0ot e-ista un numr arbitrar de construc+ii4
else if (expresie)
instruciune
grupate ntre un if ini+ial #i un else final.
@ntotdeauna un else se leag cu ultimul if ntlnit.
+.'. Instruciunea while
Format4
while (expresie)
instruciune
;nstruc+iunea se e-ecut repetat atta timp ct 1aloarea e-presiei
este diferit de 3ero. /estul are loc naintea fiecrei e-ecu+ii a
instruc+iunii. 0rin urmare ciclul este urmtorul4 se testea3 condi+ia
din parante3e dac ea este ade1rat* deci e-presia din parante3e are
o 1aloare diferit de 3ero* se e-ecut corpul instruc+iunii while* se
1erific din nou condi+ia* dac ea este ade1rat se e-ecut din nou
corpul instruc+iunii. Cnd condi+ia de1ine fals* adic 1aloarea
e-presiei din parante3e este 3ero* se face un salt la instruc+iunea de
dup corpul instruc+iunii while* deci instruc+iunea while se
termin.
+.). Instruciunea do
Format4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BA
do instruciune while
(expresie);
;nstruc+iunea se e-ecut repetat pn cnd 1aloarea e-presiei
de1ine 3ero. /estul are loc dup fiecare e-ecu+ie a instruc+iunii.
+.+. Instruciunea for
Format4
for (expresie27<opt>; expresie28<opt>; expresie2?<opt>)
instruciune
6ceast instruc+iune este ec"i1alent cu4
expresie27;
while (expresie28) {
instruciune;
expresie2?;

Expresie27 constituie ini+iali3area ciclului #i se e-ecut o singur


dat naintea ciclului. Expresie28 specific testul care controlea3
ciclul. Kl se e-ecut naintea fiecrei itera+ii. $ac condi+ia din test
este ade1rat atunci se e-ecut corpul ciclului* dup care se e-ecut
expresie2?* care const de cele mai multe ori n modificarea 1alorii
1ariabilei de control al ciclului. :e re1ine apoi la ree1aluarea
condi+iei. Ciclul se termin cnd condi+ia de1ine fals.
Dricare dintre e-presiile instruc+iunii for sau c"iar toate pot lipsi.
$ac lipse#te expresie28* aceasta implic faptul c clau3a
while este ec"i1alent cu '"ile 97<* ceea ce nseamn o condi+ie
totdeauna ade1rat. 6lte omisiuni de e-presii snt pur #i simplu
eliminate din e-pandarea de mai sus.
;nstruc+iunile while #i for permit un lucru demn de
obser1at #i anume* ele e-ecut testul de control la nceputul ciclului
#i naintea intrrii n corpul instruc+iunii.
$ac nu este nimic de fcut* nu se face nimic* cu riscul de a nu
intra niciodat n corpul instruc+iunii.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BB
+.4. Instruciunea switch
;nstruc+iunea switch este o deci3ie multipl special #i
determin transferul controlului unei instruc+iuni sau unui bloc de
instruc+iuni dintr2un #ir de instruc+iuni n func+ie de 1aloarea unei
e-presii.
Format4
switch (expresie) instruciune
K-presia este supus la con1ersiile aritmetice obi#nuite dar
re3ultatul e1alurii trebuie s fie de tip int.
Fiecare instruc+iune din corpul instruc+iunii s'itc" poate fi
etic"etat cu una sau mai multe prefi-e case astfel4
case expresie-constantP
unde e-presie2constant trebuie s fie de tip int.
0oate e-ista de asemenea cel mult o instruc+iune etic"etat cu
defaultP
Cnd o instruc+iune switch se e-ecut* se e1aluea3 e-presia
din parante3e #i 1aloarea ei se compar cu fiecare constant din
fiecare case.
$ac se gse#te o constant case egal cu 1aloarea e-presiei*
atunci se e-ecut instruc+iunea care urmea3 dup case2ul respecti1.
$ac nici o constant case nu este egal cu 1aloarea e-presiei #i
dac e-ist un prefi- default* atunci se e-ecut instruc+iunea de
dup el* altfel nici o instruc+iune din switch nu se e-ecut.
0refi-ele case #i default nu alterea3 flu-ul de control* care
continu printre astfel de prefi-e.
0entru ie#irea din switch se folose#te instruc+iunea (rea,
91e3i sec+iunea E.G< sau return 91e3i sec+iunea E.70<.
$e obicei instruc+iunea care constituie corpul unui switch este
o instruc+iune compus. La nceputul acestei instruc+iuni pot aprea #i
declara+ii* dar ini+iali3area 1ariabilelor automatice #i registru este
inefecti1.
na " n( " nc " 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BE
while (c"s)i%%*)
switch (c) {
case !0!P
case !'!P
case !.!P
case !0!P
case !/!P
case !1!P
case !2!P
case !R!P
case !5!P
case !4!P
nc)c6!0!*%%;
(rea,;
case ! !P
case !\r!P
case !\t!P
n(%%;
(rea,;
defaultP
na%%;
(rea,;

printf("cifreP ");
for (i"0; i<'0; i%%)
printf(" #d",nc)i*);
printf("\nspatii al(eP #d, alteleP #d\n",
n(,na);
@n acest e-emplu se parcurg toate caracterele dintr2un #ir* se
numr cifrele* spa+iile albe #i alte caractere #i se afi#ea3 aceste
numere nso+ite de comentarii.
;nstruc+iunea while este cea care asigur parcurgerea #irului
pn la sfr#it. 0entru fiecare caracter se e-ecut corpul instruc+iunii
while care const dintr2o singur instruc+iune switch.
:e e1aluea3 e-presia ntreag din parante3e 9n ca3ul nostru
caracterul c< #i se compar 1aloarea sa cu toate constantele2case. @n
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
B7
momentul cnd a1em egalitate se ncepe e-ecu+ia de la case2ul
respecti1.
6fi#area re3ultatelor se face prin intermediul instruc+iunii
for #i a func+iei printf 91e3i capitolul 77<.
+.5. Instruciunea break
Format4
(rea,;
6ceast instruc+iune determin terminarea celei mai interioare
instruc+iuni while* do* for sau switch care o con+ine. Controlul
trece la instruc+iunea care urmea3 dup instruc+iunea astfel
terminat.
+.6. Instruciunea continue
Format4
continue;
6ceast instruc+iune determin trecerea controlului la por+iunea
de continuare a ciclului celei mai interioare instruc+iuni while* do
sau for care o con+ine* adic la sfr#itul ciclului #i reluarea
urmtoarei itera+ii a ciclului. @n while #i do se continu cu testul*
iar n for se continu cu expresie-?.
%ai precis n fiecare dintre instruc+iunile4
while (...) {
...
continP;

for (...) {
...
continP;

do {
...
continP;
while (...);
dac apare o instruc+iune continue aceasta este ec"i1alent cu un
salt la etic"eta contin. $up continP urmea3 o instruc+iune
1id 91e3i sec+iunea E.77<.
0or+iunea de program din e-emplul urmtor prelucrea3 numai
elementele po3iti1e ale unui masi1.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BG
for (i"0; i<n; i%%) {
if (a)i*<0) =W sare peste elementele negati1e W=
continue;
... =W prelucrea3 elementele po3iti1e W=

+.17. Instruciunea return
D instruc+iune return permite ie#irea dintr2o func+ie #i
transmiterea controlului apelantului func+iei. D func+ie poate returna
1alori apelantului su* prin intermediul unei instruc+iuni return.
Formate4
return;
return expresie;
@n primul ca3 1aloarea returnat nu este definit. @n al doilea ca3
1aloarea e-presiei este returnat apelantului func+iei. $ac se cere*
e-presia este con1ertit* ca ntr2o atribuire* la tipul func+iei n care ea
apare.
+.11. Instruciunea $id
Format4
;
;nstruc+iunea 1id este util pentru a introduce o etic"et naintea
unei acolade drepte* ntr2o instruc+iune compus* sau pentru a
introduce un corp nul ntr2o instruc+iune de ciclare care cere corp al
instruc+iunii* ca de e-emplu while sau for.
Exemplu4
for (nc"0; s)nc*&"0; %%nc) ;
6ceast instruc+iune numr caracterele unui #ir. Corpul lui for
este 1id* deoarece tot lucrul se face n partea de test #i actuali3are dar
sinta-a lui for cere un corp al instruc+iunii. ;nstruc+iunea 1id
satisface acest lucru.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
BH
4. 9unciile i structura unui program
Func+iile snt elementele de ba3 ale unui program scris n C;
orice program* de orice dimensiune* const din una sau mai multe
func+ii* care specific opera+iile care trebuie efectuate.
D func+ie ofer un mod con1enabil de ncapsulare a anumitor
calcule ntr2o cutie neagr care poate fi utili3at apoi fr a a1ea grija
con+inutului ei. Func+iile snt ntr2ade1r singurul mod de a face fa+
comple-it+ii programelor mari. Func+iile permit desfacerea
programelor mari n unele mici #i dau utili3atorului posibilitatea de a
de31olta programe* folosind ceea ce al+ii au fcut deja n loc s o ia
de la nceput.
Limbajul C a fost conceput s permit definirea de func+ii
eficiente #i u#or de mnuit. @n general e bine s concepem programe
constituite din mai multe func+ii mici dect din pu+ine func+ii de
dimensiuni mari. ,n program poate fi mpr+it n mai multe fi#iere
surs n mod con1enabil* iar fi#ierele surs pot fi compilate separat.
%ai precis* un program C const dintr2o sec1en+ de defini+ii
e-terne. 6cestea snt defini+ii de func+ii #i de date. :inta-a defini+iilor
e-terne este aceea#i ca #i a tuturor declara+iilor.
4.1. 8e#iniia #unciilor
:inta-a defini+iei unei func+ii este urmtoarea4
(efiniia-funciei4
tip-funcie<opt> nume-funcie(lista-parametri) corp-funcie
!ista-parametri4
declaraie-parametru
declaraie-parametru, lista-parametri
*orpul-funciei4
instruciune-compus
$intre specificatorii de clas de memorie numai e8tern #i
static snt admi#i. ,n declarator de func+ie este similar cu un
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E0
declarator pentru funcie care returneaz """ cu e-cep+ia c el
listea3 parametrii formali ai func+iei care se define#te.
$up cum se obser1* diferitele pr+i pot s lipseasc; o func+ie
minim este4
dumm9() {
func+ia care nu face nimic. 6ceast func+ie poate fi util n programe*
+innd locul unei alte func+ii n de31oltarea ulterioar a programului.
&umele func+iei poate fi precedat de un tip* dac func+ia
returnea3 altce1a dect o 1aloare ntreag 91e3i sec+iunea 7.8<.
&umele func+iei poate fi de asemenea precedat de clasa de
memorie e8tern sau static. $ac nici un specificator de clas de
memorie nu este pre3ent* atunci func+ia este automat declarat
e-tern* deoarece n C nu se admite ca o func+ie s fie definit n
interiorul altei func+ii.
$eclara+ia unei func+ii se face implicit la apari+ia ei. :e
interpretea3 ca func+ie orice identificator nedeclarat anterior #i urmat
de o parante3 a(a. 0entru a e1ita surpri3e neplcute datorit
neconcordan+ei dintre tipurile de parametri aceast practic nu este
recomandat.
$m mai jos un e-emplu de func+ie complet definit4
int ma8(int a, int (, int c) {
int m;
m " (a>() O a P (;
return (m>c) O m P c;

6ceast func+ie determin ma-imul dintre ? numere date4


int este un specificator de tip care indic faptul c func+ia ma-
returnea3 o 1aloare ntreag;
ma8(int a, int (, int c) este declara+ia func+iei #i a
parametrilor formali;
{ . . . este corpul func+iei.
: ilustrm mecanismul definirii unei func+ii scriind func+ia
putere power(m,n) care ridic un ntreg m la o putere ntreag
po3iti1 n. 6stfel 1aloarea lui power(.,1) este ?8. 6ceast func+ie
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E7
desigur nu este complet* deoarece calculea3 numai puteri po3iti1e
de ntregi mici.
0re3entm mai jos func+ia power #i un program principal care
o apelea3* pentru a putea 1edea #i structura unui program.
power(int 8, int n) {
int i, p;
p " ';
for (i"'; i<"n; %%i)
p " p + 8;
return p;

main() {
int i;
for (i"0; i<'0; %%i)
printf(" #d #d\n", i, power(.,i),
power(60,i));

Func+ia power este apelat n programul principal de dou ori.


Fiecare apel transmite func+iei dou argumente.
Re3ultatul este afi#at de func+ia de bibliotec printf 91e3i
capitolul 77<.
&umele func+iei este urmat obligatoriu de parante3e* c"iar dac
lista parametrilor este 1id.
@n general numele func+iei este ales dup dorin+a utili3atorului.
/otu#i n fiecare program trebuie s e-iste o func+ie cu numele impus
main; orice program #i ncepe e-ecu+ia cu func+ia main. Celelalte
func+ii snt apelate din interiorul func+iei main. ,nele dintre func+iile
apelate snt definite n acela#i program* altele snt con+inute ntr2o
bibliotec de func+ii.
Comunicarea ntre func+ii se face prin argumente #i 1alori
returnate de func+ii. Comunicarea ntre func+ii poate fi fcut #i prin
intermediul 1ariabilelor e-terne.
D func+ie poate fi declarat #i static. @n acest ca3 ea poate fi
apelat numai din fi#ierul unde a fost definit.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E8
Func+iile n C pot fi folosite recursi1* deci o func+ie se poate
apela pe ea ns#i fie direct* fie indirect.
@n general ns recursi1itatea nu face economie de memorie*
deoarece trebuie men+inut o sti1 cu 1alorile de prelucrat.
4.2. :pelul #unciilor
@n limbajul C orice func+ie este apelat prin numele ei* urmat de
lista real a argumentelor* nc"is ntre parante3e.
$ac ntr2o e-presie numele func+iei nu este urmat imediat de o
parante3 a(a* adic func+ia nu apare pe po3i+ia de apel de func+ie
atunci nu se reali3ea3 imediat apelul func+iei respecti1e ci se
generea3 un pointer la func+ie 91e3i sec+iunea H.77<.
4.3. ;e$enirea din #uncii
Re1enirea dintr2o func+ie se face prin intermediul unei
instruc+iuni return.
Caloarea pe care o func+ie o calculea3 poate fi returnat prin
instruc+iunea return* care dup cum am 13ut are dou formate4
return;
return expresie;
Ca argument poate aprea orice e-presie admis n C. Func+ia
returnea3 1aloarea acestei e-presii func+iei apelante.
D func+ie nu returnea3 n mod obligatoriu o 1aloare. D
instruc+iune return* fr e-presie ca parametru* cau3ea3 numai
transferul controlului func+iei apelante nu #i o 1aloare util.
La rndul su func+ia apelant poate ignora 1aloarea returnat.
$e obicei o func+ie returnea3 o 1aloare de tip ntreg. $ac se
dore#te ca func+ia s returne3e un alt tip* atunci numele tipului trebuie
s precead numele func+iei* iar programul trebuie s con+in o
declara+ie a acestei func+ii att n fi#ierul n care func+ia este definit
ct #i n fi#ierul unde func+ia este apelat.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E?
0entru a e1ita orice confu3ie se recomand ca tipul 1alorii
returnate de func+ie s fie ntotdeauna preci3at* iar dac dorim n mod
e-pres ca func+ia s nu returne3e o 1aloare s folosim tipul -oid.
$e e-emplu* func+ia atof(s) din biblioteca asociat
compilatorului con1erte#te #irul s de cifre n 1aloarea sa n dubl
preci3ie. Com declara func+ia sub forma4
dou(le atof(char s)*);
sau mpreun cu alte 1ariabile de tip dou(le4
dou(le sum, atof(char s)*);
Func+iile nu pot returna masi1e* structuri* reuniuni sau func+ii.
$ac o func+ie returnea3 o 1aloare de tip char* nu este ne1oie
de nici o declara+ie de tip din cau3a con1ersiilor implicite. /otdeauna
tipul char este con1ertit la int n e-presii.
4.'. :rgumentele #unciei i transmiterea
parametrilor
D metod de a comunica datele ntre func+ii este prin argumente.
0arante3ele mici care urmea3 dup numele func+iei nc"id lista
argumentelor.
@n limbajul C argumentele func+iilor snt transmise prin 1aloare.
6ceasta nseamn c n C func+ia apelat prime#te 1alorile
argumentelor sale ntr2o copie particular de 1ariabile temporare 9n
realitate pe sti1<.
Func+ia apelat nu poate altera dect 1ariabilele sale particulare*
adic copiile temporare.
6pelul prin 1aloare este o posibilitate* dar nu #i o obligati1itate.
6pelul prin 1aloare conduce la programe mai compacte cu mai pu+ine
1ariabile e-terne* deoarece argumentele pot fi tratate ca 1ariabile
locale* #i care pot fi modificate con1enabil n rutina apelat.
Ca e-emplu* pre3entm o 1ersiune a func+iei putere care face u3
de acest fapt4
power(int 8, int n) {
int p;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EA
for (p"'; n>0; 66n)
p " p + 8;
return p;

6rgumentul n este utili3at ca o 1ariabil temporar #i este


decrementat pn de1ine 3ero; astfel nu este ne1oie de nc o
1ariabil i. Drice opera+ii s2ar face asupra lui n n interiorul func+iei*
ele nu au efect asupra argumentului pentru care func+ia a fost apelat.
$ac totu#i se dore#te alterarea efecti1 a unui argument al
func+iei apelante* acest lucru se reali3ea3 cu ajutorul pointerilor sau
a 1ariabilelor declarate e-terne.
@n ca3ul pointerilor* func+ia apelant trebuie s furni3e3e adresa
1ariabilei de modificat 9te"nic printr2un pointer la aceast 1ariabil<*
iar func+ia apelat trebuie s declare argumentul corespun3tor ca
fiind un pointer. Referirea la 1ariabila de modificat se face prin
adresare indirect 91e3i capitolul H<.
0rintre argumentele func+iei pot aprea #i nume de masi1e. @n
acest ca3 1aloarea transmis func+iei este n realitate adresa de
nceput a masi1ului 9elementele masi1ului nu snt copiate<. 0rin
inde-area acestei 1alori func+ia poate a1ea acces #i poate modifica
orice element din masi1.
4.). 9uncii cu numr $ariabil de parametri
0entru func+iile cu numr 1ariabil de parametri standardul 6&:;
define#te o construc+ie special ... * numit elips. 6cesta este de
e-emplu ca3ul func+iilor de citire #i scriere cu format
9familiile ...scanf #i ...printf 2 a se 1edea capitolul 77<. @n acest ca3*
parametrii fic#i snt 1erifica+i la compilare* iar cei 1ariabili snt
transmi#i ca #i cnd nu ar e-ista prototip de func+ie.
0entru simplitatea e-punerii am pstrat con1en+iile definite de
standardele mai 1ec"i ale limbajului* pstrate #i de standardul 6&:;
C. D func+ie poate fi declarat fr nici un parametru* compilatorul
deducnd de aici c func+ia respecti1 poate a1ea oric+i parametri de
orice tip. &u se recomand totu#i o asemenea practic deoarece este
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EB
posibil s se cree3e confu3ii care conduc la erori n e-ecu+ia
programelor* erori care se corectea3 foarte greu n ca3ul programelor
mari.
4.+. 3"emple de #uncii i programe
7. 6cest e-emplu este un program de cutare #i imprimare a
tuturor liniilor dintr2un te-t care con+in o anumit configura+ie de
caractere* de e-emplu cu1ntul engle3esc "the". :tructura de ba3 a
acestui program este4
while (mai e-ist linii surs)
if (linia con+ine configura+ia de caractere)
imprim linia
@n scopul scrierii acestui program 1om scrie trei func+ii. Func+ia
7etline cite#te o linie din te-tul surs #i returnea3 lungimea ei.
6ceast func+ie are dou argumente. 6rgumentul s indic numele
masi1ului unde se 1a citi linia* iar argumentul lim repre3int
lungimea ma-im a unei linii care poate fi citit.
Func+ia inde8 caut configura+ia de caractere dorit n interiorul
liniei #i furni3ea3 po3i+ia sau inde-ul n #irul s* unde ncepe #irul t*
sau 7 dac linia nu con+ine #irul t. 6rgumentele func+iei snt s care
repre3int adresa #irului de studiat #i t care repre3int configura+ia
cutat.
Func+ia care reali3ea3 afi#area este printf din bibliotec.
0rogramul care reali3ea3 structura de mai sus este4
#define B<;>JA@ '000
#define @S= 6'
7etline(char s)*, int lim) {
=W cite#te o linie n s; returnea3 lungimea W=
int c, i;
i " 0;
while (66lim>0 $$ (c"7etchar())&" @S= $$
c&"!\n!)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EE
s)i%%*"c;
if (c""!\n!) s)i%%*"c;
s)i*"!\0!;
return i;

inde8(char s)*, char t)*) {


=W returnea3 po3i+ia din #irul s unde ncepe #irul t* sau 7 W=
int i,G,,;
for (i"0; s)i*&"!\0!; i%%) {
for (G"i, ,"0; t),*&"!\0! $$
s)G*""t),*; G%%, ,%%)
;
if (t),*""!\0!)
return i;

return 6';

main() {
=W imprim toate liniile care con+in cu1ntul the W=
char line )B<;>JA@*;
while (7etline(line, B<;>JA@)>0)
if (inde8(line,"the")>"0)
printf("#s",line);

8. Func+ia atof con1erte#te un #ir de cifre din formatul 6:C;;


ntr2un numr flotant n preci3ie dubl.
dou(le atof(char s)*) {
=W con1erte#te #irul s n dubl preci3ie W=
dou(le -al, power;
int i, si7n;
for (i"0; s)i*""! ! HH s)i*""!\n! HH
s)i*""!\t!; i%%) ; =W sare peste spa+ii albe W=
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
E7
si7n " ';
if (s)i*""!%! HH s)i*""!6!)
si7n " (s)i%%*""!%!) O ' P 6';
for (-al"0; s)i*>"!0! $$ s)i*<"!4!; i%%)
-al " '0 + -al % s)i* 6 !0!;
if (s)i*"" !.!) =W punct 3ecimal W=
i%%;
for (power"'; s)i*>"!0! $$ s)i*<"!4!; i%%)
{
-al " '0 + -al %s)i* 6 !0!P
power +" '0;

return si7n + -al F power;

?. Func+ia atoi con1erte#te un #ir de cifre n ec"i1alentul lor


numeric ntreg.
atoi(char s)*) { =W con1erte#te #irul s la un ntreg W=
int i,n;
n " 0;
for (i"0; s)i*>"!0! $$ s)i*<"!4!; i%%)
n " '0 + n %s)i* 6 !0!;
return n;

A. Func+ia lower con1erte#te literele mari din setul de caractere


6:C;; n litere mici. $ac lo'er prime#te un caracter care nu este o
liter mare atunci l returnea3 nesc"imbat.
lower(int c) {
if (c>"!<! $$ c<"!T!)
return c % !a! 6 !<!;
else
return c;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EG
B. Func+ia (inar9 reali3ea3 cutarea 1alorii 8 ntr2un masi1
sortat -* care are n elemente.
(inar9(int 8, int -)*, int n) {
=W caut 8 n -
0
* -
'
* ...* -
n6'
W=
int low, hi7h, mid;
low " 0;
hi7h " n 6 ';
while (low<"hi7h) {
mid " (low % hi7h) F .;
if (8 < -)mid*)
hi7h " mid 6 ';
else if (8 > -)mid*)
low " mid % ';
else =W s2a gsit o intrare W=
return(mid);

return 6';

Func+ia returnea3 po3i+ia lui 8 9un numr ntre 0 #i n7<* dac 8


apare n - sau 7 altfel.
K-emplul ilustrea3 o deci3ie tripl* dac 8 este mai mic* mai
mare sau egal cu elementul din mijlocul #irului -)mid*.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EH
5. <iniile de control ale compilatorului
Limbajul C ofer o facilitate de e-tensie a limbajului cu ajutorul
unui preprocesor de macro2opera+ii simple. Folosirea liniilor de
forma4
#define
#include
este cea mai u3ual metod pentru e-tensia limbajului* caracterul a#a
9die3< indicnd faptul c aceste linii 1or fi tratate de ctre preprocesor.
Liniile precedate de caracterul a#a au o sinta- independent de restul
limbajului #i pot aprea oriunde n fi#ierul surs* a1nd efect de la
punctul de defini+ie pn la sfr#itul fi#ierului.
5.l. 2nlocuirea simbolurilor= substituii macro
D defini+ie de forma4
#define identificator ir-simboluri
determin ca preprocesorul s nlocuiasc toate apari+iile ulterioare
ale identificatorului cu ir-simboluri dat 9ir-simboluri nu se termin
cu a;a deoarece n urma substitu+iei identificatorului cu acest #ir ar
aprea prea multe caractere a;a<.
$ir-simboluri sau te-tul de nlocuire este arbitrar. @n mod normal
el este tot restul liniei ce urmea3 dup identificator. D defini+ie ns
poate fi continuat pe mai multe linii* introducnd ca ultim caracter n
linia de continuat caracterul a\a 9bacIslas"<.
,n identificator care este subiectul unei linii #define poate fi
redefinit ulterior n program printr2o alt linie #define. @n acest
ca3* prima defini+ie are efect numai pn la defini+ia urmtoare.
:ubstitu+iile nu se reali3ea3 n ca3ul n care identificatorii snt
ncadra+i ntre g"ilimele. $e e-emplu fie defini+ia4
#define <>=< '
Driunde 1a aprea n programul surs identificatorul 6LF6 el 1a
fi nlocuit cu constanta 7* cu e-cep+ia unei situa+ii de forma4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70
printf("<>=<");
n care se 1a tipri c"iar te-tul 6LF6 #i nu constanta 7* deoarece
identificatorul este ncadrat ntre g"ilimele.
6ceast facilitate este deosebit de 1aloroas pentru definirea
constantelor simbolice ca n4
#define R<CMJT@ '00
int ta()R<CMJT@*;
deoarece ntr2o e1entual modificare a dimensiunii tabelului ta( se
1a modifica doar o singur linie n fi#ierul surs. D linie de forma4
#define identif(identif27*...* identif2n) ir-simboluri
n care nu e-ist spa+iu ntre primul identificator #i caracterul a(a este
o defini+ie pentru o macro2opera+ie cu argumente* n care te-tul de
nlocuire 9ir-simboluri< depinde de modul n care se apelea3 macro2
ul respecti1. Ca un e-emplu s definim o macro2opera+ie numit ma8
n felul urmtor4
#define ma8(a,() ((a)>(() O (a) P (())
atunci linia dintr2un program surs4
8 " ma8(p%I,r%s);
1a fi nlocuit cu4
8 " ((p%I)>(r%s) O (p%I) P (r%s));
6ceast macro2defini+ie furni3ea3 o funcie maximum care se
e-pandea3 n cod* n loc s se reali3e3e un apel de func+ie. 6cest
macro 1a ser1i pentru orice tip de date* nefiind ne1oie de diferite
tipuri de func+ii ma-imum pentru diferite tipuri de date* a#a cum este
necesar n ca3ul func+iilor propriu23ise.
$ac se e-aminea3 atent e-pandarea lui ma8 se pot obser1a
anumite probleme ce pot genera erori* #i anume4 e-presiile fiind
e1aluate de dou ori* n ca3ul n care ele con+in opera+ii ce generea3
efecte colaterale 9apelurile de func+ii* operatorii de incrementare< se
pot ob+ine re3ultate total eronate.
$e asemenea* trebuie a1ut mare grij la folosirea parante3elor
pentru a face sigur ordinea e1alurii dorite. $e e-emplu macro2
opera+ia sIuare(8) definit prin4
#define sIuare(8) 8+8
care se apelea3 n programul surs sub forma4
: " sIuare(:%');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77
1a produce un re3ultat* altul dect cel scontat* datorit priorit+ii mai
mari a operatorului + fa+ de cea a operatorului %.
5.2. Includerea #iierelor
D linie de forma4
#include "nume-fiier"
reali3ea3 nlocuirea liniei respecti1e cu ntregul con+inut al fi#ierului
nume2fi#ier. Fi#ierul denumit este cutat n primul rnd n directorul
fi#ierului surs curent #i apoi ntr2o succesiune de locuri standard*
cum ar fi biblioteca ;+D standard asociat compilatorului. 6lternati1*
o linie de forma4
#include <nume-fiier>
caut fi#ierul nume2fi#ier numai n biblioteca standard #i nu n
directorul fi#ierului surs.
$eseori* o linie sau mai multe linii* de una sau ambele forme apar
la nceputul fiecrui fi#ier surs pentru a include defini+ii comune
9prin declara+ii #define #i declara+ii e-terne pentru 1ariabilele
globale<.
Facilitatea de includere a unor fi#iere ntr2un te-t surs este
deosebit de util pentru gruparea declara+iilor unui program mare. Ka
1a asigura faptul c toate fi#ierele surs 1or primi acelea#i defini+ii #i
declara+ii de 1ariabile* n felul acesta eliminndu2se un tip particular
de erori. $ac se modific un fi#ier inclus printr2o linie #include*
toate fi#ierele care depind de el trebuie recompilate.
5.3. Compilarea condiionat
D linie de control a compilatorului de forma4
#if expresie-constant
1erific dac e-presia constant este e1aluat la o 1aloare diferit de
3ero.
D linie de control de forma4
#ifdef identificator
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78
1erific dac identificatorul a fost subiectul unei linii de control de
forma #define.
D linie de control de forma4
#ifndef identificator
1erific dac identificatorul este nedefinit n preprocesor.
/oate cele trei forme de linii de control precedente pot fi urmate
de un numr arbitrar de linii care* e1entual* pot s con+in o linie de
control forma4
#else
#i apoi de o linie de control de forma4
#endif
$ac condi+ia supus 1erificrii este ade1rat* atunci orice linie
ntre #else #i #endif este ignorat. $ac condi+ia este fals atunci
toate liniile ntre testul de 1erificare #i un #else sau n lipsa unui
#else pn la #endif snt ignorate.
/oate aceste construc+ii pot fi imbricate.
5.'. !tili1area dircti$elor de compilare
0re3entm n continuare un e-emplu didactic de utili3are a
directi1elor de compilare n de31oltarea unor proiecte.
:e cite#te de la tastatur o perec"e de numere naturale p #i I. :
se determine dac fiecare din cele dou numere este prim sau nu* #i
s se calcule3e cel mai mare di1i3or comun.
: re3ol1m aceast problem folosind dou fi#iere surs. 0rimul
con+ine func+ia main #i apelea3 dou func+ii4 eprim #i cmmdc. 6l
doilea fi+ier implementea3 cele dou func+ii.
0re3entm mai nti un fi#ier "eader 9numere.h< care con+ine
defini+iile celor dou func+ii.
#ifndef UAumereUH
#define UAumereUH
unsi7ned eprim(unsi7ned n);
unsi7ned cmmdc(unsi7ned p, unsi7ned I);
#endif
Fi#ierul surs princ.c este foarte scurt.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?
#include <stdio.h>
#include "numere.h"
static -oid citire(unsi7ned +n) {
scanf("#u",n);
if (eprim(+n))
printf("#u e prim\n",+n);
else
printf("#u nu e prim\n",+n);

int main() {
unsi7ned p,I,,;
citire($p);
citire($I);
,"cmmdc(p,I);
printf("DmmdcP #u\n",,);
return 0;

Fi#ierul surs numere.c este pre3entat n continuare.


#include "numere.h"
unsi7ned eprim(unsi7ned n) {
unsi7ned i,a,r;
if (n""0) return 0;
if (n</) return ';
if ((n$')""0) return 0;
for (i"0; ; i%".) {
r"n#i;
if (r""0) return 0;
a"nFi;
if (a<"i) return ';

unsi7ned cmmdc(unsi7ned p, unsi7ned I) {


while ((p>0) $$ (I>0))
if (p>I) p#"I;
else I#"p;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A
if (p""0) return I;
else return p;

0entru a ob+ine un program e-ecutabil din aceste dou fi#iere se


poate utili3a o singur comand de compilare4
*c princ.c numere.c opiuni2de2compilare
unde *c este numele compilatorului folosit 9e-emplu4 (cc* 7cc<.
Dp+iunile de compilare 9atunci cnd snt necesare< snt specifice
mediului de programare folosit.
0roiectele 5 programe de dimensiuni mari 5 snt compuse de cele
mai multe ori din module care se elaborea3 #i se pun la punct
separat. ,neori pot fi identificate func+ii care pre3int un interes
general mai mare* #i care pot fi utili3ate n elaborarea unor tipuri de
aplica+ii foarte di1erse. 6cestea snt de31oltate separat #i* dup ce au
fost puse la punct n totalitate* se depun ntr2o bibliotec de func+ii n
format obiect. @n momentul n care acestea snt incluse n proiecte nu
se mai pierde timp cu compilarea modulelor surs. @n sc"imb
modulele care le apelea3 au ne1oie de modul cum snt descrise
aceste func+ii* #i acesta se pstrea3 n fi#iere "eader.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B
6. Pointeri i masi$e
,n pointer este o 1ariabil care con+ine adresa unei alte 1ariabile.
0ointerii snt foarte mult utili3a+i n programe scrise n C* pe de o
parte pentru c uneori snt unicul mijloc de a e-prima un calcul* iar
pe de alt parte pentru c ofer posibilitatea scrierii unui program mai
compact #i mai eficient dect ar putea fi ob+inut prin alte ci.
6.1. Pointeri i adrese
$eoarece un pointer con+ine adresa unui obiect* cu ajutorul lui
putem a1ea acces* n mod indirect* la acea 1ariabil 9obiect<.
: presupunem c 8 este o 1ariabil de tip ntreg #i p8 un pointer
la aceast 1ariabil. 6tunci aplicnd operatorul unar $ lui 8*
instruc+iunea4
p8 " $8;
atribuie 1ariabilei p8 adresa 1ariabilei 8; n acest fel spunem c p8
indic 9pointea3< spre 8.
;n1ers* dac p8 con+ine adresa 1ariabilei 8* atunci
instruc+iunea4
9 " +p8;
atribuie 1ariabilei 9 con+inutul loca+iei pe care o indic p8.
K1ident toate 1ariabilele care snt implicate n aceste instruc+iuni
trebuie declarate. 6ceste declara+ii snt4
int 8,9;
int +p8;
$eclara+iile 1ariabilelor 8 #i 9 snt deja cunoscute. $eclara+ia
pointerului p8 este o noutate. 6 doua declara+ie indic faptul c o
combina+ie de forma +p8 este un ntreg* iar 1ariabila p- care apare n
conte-tul +p8 este ec"i1alent cu un pointer la o 1ariabil de tip
ntreg. @n locul tipului ntreg poate aprea oricare dintre tipurile
admise n limbaj #i se refer la obiectele pe care le indic p8.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E
0ointerii pot aprea #i n e-presii* ca de e-emplu n e-presia
urmtoare4
9 " +p8 % ';
unde 1ariabilei 9 i se atribuie con+inutul 1ariabilei 8 plus '.
;nstruc+iunea4
d " sIrt((dou(le)+p8);
are ca efect con1ertirea con+inutului 1ariabilei 8 pe care o indic p8
n tip dou(le #i apoi depunerea rdcinii ptrate a 1alorii astfel
con1ertite n 1ariabila d.
Referiri la pointeri pot aprea de asemenea #i n partea stng a
atribuirilor. $ac* de e-emplu* p8 indic spre 8* atunci4
+p8 " 0;
atribuie 1ariabilei 8 1aloarea 3ero* iar4
+p8 %" ';
incrementea3 con+inutul 1ariabilei 8 cu '* ca #i n e-presia4
(+p8)%%;
@n acest ultim e-emplu parante3ele snt obligatorii deoarece* n
lipsa lor* e-presia ar incrementa pe p8 n loc de con+inutul 1ariabilei
pe care o indic 9operatorii unari +* %% au aceea#i preceden+ #i snt
e1alua+i de la dreapta spre stnga<.
6.2 Pointeri i argumente de #uncii
$eoarece n limbajul C transmiterea argumentelor la func+ii se
face prin 1aloare 9#i nu prin referin+<* func+ia apelat nu are
posibilitatea de a altera o 1ariabil din func+ia apelant. 0roblema
care se pune este cum procedm dac totu#i dorim s sc"imbm un
argumentX
$e e-emplu* o rutin de sortare poate sc"imba ntre ele dou
elemente care nu respect ordinea dorit* cu ajutorul unei func+ii
swap. Fie func+ia swap definit astfel4
swap(int 8, int 9) { =W gre#it W=
int temp;
temp " 8;
8 " 9;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77
9 " temp;

Func+ia swap apelat prin swap(a,() nu 1a reali3a ac+iunea


dorit deoarece ea nu poate afecta argumentele a #i ( din rutina
apelant.
K-ist ns o posibilitate de a ob+ine efectul dorit* dac func+ia
apelant transmite ca argumente pointeri la 1alorile ce se doresc
intersc"imbate. 6tunci n func+ia apelant apelul 1a fi4
swap($a,$();
iar forma corect a lui swap este4
swap(int +p8, int +p9) {=W intersc"imb Wp- #i Wp) W=
int temp;
temp " +p8;
+p8 " +p9;
+p9 " temp;

6.3. Pointeri i masi$e


@n limbajul C e-ist o strns legtur ntre pointeri #i masi1e.
Drice opera+ie care poate fi reali3at prin indicarea masi1ului poate fi
de asemenea fcut prin pointeri* care* n plus* conduce #i la o
accelerare a opera+iei. $eclara+ia4
int a)'0*;
define#te un masi1 de dimensiune 70* care repre3int un bloc de 70
obiecte consecuti1e numite a)0** ... a)4*. &ota+ia a)i* repre3int
al i2lea element al masi1ului sau elementul din po3i+ia i+'* ncepnd
cu primul element. $ac pa este un pointer la un ntreg declarat sub
forma4
int +pa;
atunci atribuirea4
pa " $a)0*;
ncarc 1ariabila pa cu adresa primului element al masi1ului a.
6tribuirea4
8 " +pa;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7G
copia3 con+inutul lui a)0* n 8.
$ac pa indic un element particular al unui masi1 a* atunci prin
defini+ie pa%i indic un element cu i po3i+ii dup elementul pe care
l indic pa* dup cum pa6i indic un element cu i po3i+ii nainte
de cel pe care indic pa. 6stfel* dac 1ariabila pa indic pe a)0*
atunci +(pa%i) se refer la con+inutul lui a)i*.
6ceste obser1a+ii snt ade1rate indiferent de tipul 1ariabilelor
din masi1ul a.
@ntreaga aritmetic cu pointeri are n 1edere faptul c e-presia
pa%i nseamn de fapt nmul+irea lui i cu lungimea elementului pe
care l indic pa #i adunarea apoi la pa* ob+inndu2se astfel adresa
elementului de indice i al masi1ului.
Coresponden+a dintre inde-area ntr2un masi1 #i aritmetica de
pointeri este foarte strns. $e fapt* o referire la un masi1 este
con1ertit de compilator ntr2un pointer la nceputul masi1ului.
Kfectul este c un nume de masi1 este o e-presie pointer* deoarece
numele unui masi1 este identic cu numele elementului de indice 3ero
din masi1.
6tribuirea4
pa " $a)0*;
este identic cu4
pa " a;
$e asemenea* e-presiile a)i* #i +(a%i) snt identice. 6plicnd
operatorul V la ambele pr+i ob+inem $a)i* identic cu a%i. 0e de
alt parte* dac pa este un pointer* e-presiile pot folosi acest pointer
ca un indice4 pa)i* este identic cu +(pa%i). 0e scurt orice
e-presie de masi1 #i indice poate fi scris ca un pointer #i un
deplasament #i in1ers* c"iar n aceea#i instruc+iune.
K-ist ns o singur diferen+ ntre un nume de masi1 #i un
pointer la nceputul masi1ului. ,n pointer este o 1ariabil* deci
pa " a #i pa%% snt instruc+iuni corecte. $ar un nume de masi1
este o constant #i deci construc+ii de forma a " pa* a%% sau
p " $a snt ilegale.
Cnd se transmite unei func+ii un nume de masi1* ceea ce se
transmite de fapt este adresa primului element al masi1ului. 6#adar*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7H
un nume de masi1* argument al unei func+ii* este n realitate un
pointer* adic o 1ariabil care con+ine o adres. Fie de e-emplu
func+ia strlen care calculea3 lungimea #irului s4
strlen(char +s) { =W returnea3 lungimea #irului W=
int n;
for (n"0; +s&"!\0!; s%%)
n%%;
return n;

;ncrementarea lui s este legal deoarece s este o 1ariabil


pointer. s%% nu afectea3 #irul de caractere din func+ia care apelea3
pe strlen* ci numai copia adresei #irului din func+ia strlen.
Kste posibil s se transmit unei func+ii* ca argument* numai o
parte a unui masi1* printr2un pointer la nceputul sub2masi1ului
respecti1. $e e-emplu* dac a este un masi1* atunci4
f($a).*)
f(a%.)
transmit func+iei f adresa elementului a).** deoarece $a).* #i
a%. snt e-presii pointer care* ambele* se refer la al treilea element
al masi1ului a. @n cadrul func+iei f argumentul se poate declara astfel4
f(int arr)*) {
sau
f(int +arr) {
$eclara+iile int arr)* #i int +arr snt ec"i1alente*
op+iunea pentru una din aceste forme depin3nd de modul n care 1or
fi scrise e-presiile n interiorul func+iei.
6.'. :ritmetica de adrese
$ac p este un pointer* atunci p %" i incrementea3 pe p
pentru a indica cu i elemente dup elementul pe care l indic n
prealabil p. 6ceast construc+ie #i altele similare snt cele mai simple
#i comune formule ale aritmeticii de adrese* care constituie o
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G0
caracteristic puternic a limbajului C. : ilustrm cte1a din
propriet+ile aritmeticii de adrese scriind un alocator rudimentar de
memorie. Fie rutina alloc(n) care returnea3 un pointer p la o
3on de n caractere consecuti1e care 1or fi folosite de rutina apelant
pentru memorarea unui #ir de caractere. Fie rutina free(p) care
eliberea3 o 3on ncepnd cu adresa indicat de pointerul p pentru a
putea fi refolosit mai tr3iu. Qona de memorie folosit de rutinele
alloc #i free este o sti1 func+ionnd pe principiul ultimul intrat
primul ie#it* iar apelul la free trebuie fcut n ordine in1ers cu
apelul la alloc. : considerm c func+ia alloc 1a gestiona sti1a
ca pe elementele unui masi1 pe care l 1om numi alloc(uf. Com
mai folosi un pointer la urmtorul element liber din masi1* pe care2l
1om numi allocp. Cnd se apelea3 rutina alloc pentru n
caractere* se 1erific dac e-ist suficient spa+iu liber n masi1ul
alloc(uf. $ac da* alloc 1a returna 1aloarea curent a lui
allocp* adic adresa de nceput a blocului cerut* dup care 1a
incrementa pe allocp cu n pentru a indica urmtoarea 3on liber.
free(p) actuali3ea3 allocp cu 1aloarea p* dac p indic n
interiorul lui alloc(uf.
#define A?>> 0
=W 1aloarea pointerului pentru semnali3area erorii W=
#define <>>SDMJT@ '000
=W dimensiunea spa+iului disponibil W=
static char alloc(uf )<>>SDMJT@*;
=W memoria pentru alloc W=
static char +allocp " alloc(uf;
=W urmtoarea po3i+ie liber W=
char +alloc(int n) {
=W returnea3 pointer la n caractere W=
if (allocp%n<"alloc(uf%<>>SDMJT@) {
allocp %" n; =W dimensiunea satisfcut W=
return allocp6n; =W 1ec"ea 1aloare W=

else
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G7
return A?>>; =W nu este spa+iu suficient W=

free(char +p) { =W eliberea3 memoria indicat de p W=


if (p>"alloc(uf $$ p<alloc(uf%<>>SDMJT@)
allocp " p;

/estul if (allocp%n<"alloc(uf%<>>SDMJT@)
1erific dac e-ist spa+iu suficient pentru satisfacerea cererii de
alocare a n caractere. $ac cererea poate fi satisfcut* alloc re1ine
cu un pointer la 3ona de n caractere consecuti1e. $ac nu* alloc
trebuie s semnale3e lipsa de spa+iu pe care o face returnnd 1aloarea
constantei simbolice A?>>. Limbajul C garantea3 c nici un pointer
care indic corect o dat nu 1a con+ine 3ero* prin urmare o re1enire
cu 1aloarea 3ero poate fi folosit pentru semnalarea unui e1eniment
anormal 9n ca3ul nostru* lipsa de spa+iu<. 6tribuirea 1alorii 3ero unui
pointer este deci un ca3 special.
Dbser1m de asemenea c 1ariabilele alloc(uf #i allocp
snt declarate static cu scopul ca ele s fie locale numai fi#ierului
surs care con+ine func+iile alloc #i free.
K-emplul de mai sus demonstrea3 cte1a din facilit+ile
aritmeticii de adrese 9pointeri<. @n primul rnd* pointerii pot fi
compara+i n anumite situa+ii. $ac p #i I snt pointeri la membri
unui acela#i masi1* atunci rela+iile <* <"* >* >"* ""* &" snt
1alide. Rela+ia p<I* de e-emplu* este ade1rat dac p indic un
element mai apropiat de nceputul masi1ului dect elementul indicat
de pointerul I. Comparrile ntre pointeri pot duce ns la re3ultate
impre1i3ibile* dac ei se refer la elemente apar+innd la masi1e
diferite.
:e obser1 c pointerii #i ntregii pot fi aduna+i sau sc3u+i.
Construc+ia de forma4
p%n
nseamn adresa celui de2al n2lea element dup cel indicat de p*
indiferent de tipul elementului pe care l indic p. Compilatorul C
alinia3 1aloarea lui n conform dimensiunii elementelor pe care le
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G8
indic p* dimensiunea fiind determinat din declara+ia lui p 9scara de
aliniere este 7 pentru char* 8 pentru int etc<.
$ac p #i I indic elemente ale aceluia#i masi1* p6I este
numrul elementelor dintre cele pe care le indic p #i I. : scriem o
alt 1ersiune a func+iei strlen folosind aceast ultim obser1a+ie4
strlen(char +s) { =W returnea3 lungimea unui #ir W=
char +p;
p " s;
while (+p &" !\0!)
p%%;
return p6s;

@n acest e-emplu s rmne constant cu adresa de nceput a


#irului* n timp ce p a1ansea3 la urmtorul caracter de fiecare dat.
$iferen+a p6s dintre adresa ultimului element al #irului #i adresa
primului element al #irului indic numrul de elemente.
@n afar de opera+iile binare men+ionate 9adunarea sau scderea
pointerilor cu ntregi #i scderea sau compararea a doi pointeri<*
celelalte opera+ii cu pointeri snt ilegale. &u este permis adunarea*
nmul+irea* mpr+irea sau deplasarea pointerilor* dup cum nici
adunarea lor cu constante de tip dou(le sau float.
:nt admise de asemenea incrementrile #i decrementrile
precum #i alte combina+ii ca de e-emplu +%%p #i +66p.
6.). Pointeri la caracter i #uncii
D constant #ir* de e-emplu4
"Cuna dimineata"
este un masi1 de caractere* care n repre3entarea intern este terminat
cu caracterul !\0!* astfel nct programul poate depista sfr#itul lui.
Lungimea acestui #ir n memorie este astfel cu 7 mai mare dect
numrul de caractere ce apar efecti1 ntre g"ilimelele de nceput #i
sfr#it de #ir.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G?
Cea mai frec1ent apari+ie a unei constante #ir este ca argument
la func+ii* ca3 n care accesul la ea se reali3ea3 prin intermediul unui
pointer.
@n e-emplul4
printf("Cuna dimineata\n");
func+ia printf prime#te de fapt un pointer la masi1ul de caractere.
@n prelucrarea unui #ir de caractere snt implica+i numai pointeri*
limbajul C neoferind nici un operator care s trate3e #irul de caractere
ca o unitate de informa+ie.
Com pre3enta cte1a aspecte legate de pointeri #i masi1e
anali3nd dou e-emple. : considerm pentru nceput func+ia
strcp9(s,t) care copia3 #irul t peste #irul s. D prim 1ersiune
a programului ar fi urmtoarea4
strcp9(char s)*, char t)*) {=W copia3 t peste s W=
int t;
i " 0;
while ((s)i*"t)i*) &" !\0!)
i%%;

D a doua 1ersiune cu ajutorul pointerilor este urmtoarea4


strcp9(char +s, char +t) {
=W 1ersiune cu pointeri W=
while ((+s%%"+t%%) &" !\0!) ;

6ceast 1ersiune cu pointeri modific prin incrementare pe s #i t


n partea de test. Caloarea lui +t%% este caracterul indicat de
pointerul t* nainte de incrementare. &ota+ia postfi- %% asigur c t
1a fi modificat dup depunerea con+inutului indicat de el* la 1ec"ea
po3i+ie a lui s* dup care #i s se incrementea3. Kfectul este c se
copia3 caracterele #irului t n #irul s pn la caracterul terminal
!\0! inclusi1.
6m mai putea face o obser1a+ie legat de redundan+a comparrii
cu caracterul !\0!* redundan+ care re3ult din structura
instruc+iunii while.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GA
bi atunci forma cea mai prescurtat a func+iei strcp9(s,t)
este4
strcp9(char +s, char +t) {
while (+s%% " +t%%) ;

: considerm* ca al doilea e-emplu* func+ia strcmp(s,t)


care compar caracterele #irurilor s #i t #i returnea3 o 1aloare
negati1* 3ero sau po3iti1* dup cum #irul s este le-icografic mai
mic* egal sau mai mare ca #irul t. Caloarea returnat se ob+ine prin
scderea caracterelor primei po3i+ii n care s #i t difer.
D prim 1ersiune a func+iei strcmp(s,t) este
urmtoarea4
strcmp(char s, char t) {=W compar #irurile s #i t W=
int i;
i " 0;
while (s)i*""t)i*)
if (s)i%%*""!\0!)
return 0;
return s)i*6t)i*;

Cersiunea cu pointeri a aceleia#i func+ii este4


strcmp(char +s, char +t) {
for (; +s""+t; s%%,t%%)
if (+s""!\0!)
return 0;
return +s6+t;

@n final pre3entm func+ia strsa- care copia3 un #ir dat prin


argumentul ei ntr2o 3on ob+inut printr2un apel la func+ia alloc.
Ka returnea3 un pointer la #irul copiat sau A?>>* dac nu mai e-ist
suficient spa+iu pentru memorarea #irului.
char +strsa-(char +s) { =W copia3 #irul s W=
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GB
char +p;
p " alloc(strlen(s)%');
if (p&"A?>>)
strcp9(p,s);
return p;

6.+. Masi$e multidimensionale


Limbajul C ofer facilitatea utili3rii masi1elor
multidimensionale* de#i n practic ele snt folosite mai pu+in dect
masi1ele de pointeri.
: considerm problema con1ersiei datei* de la 3i din lun* la 3i
din an #i in1ers* +innd cont de faptul c anul poate s fie bisect sau
nu. $efinim dou func+ii care s reali3e3e cele dou con1ersii.
Func+ia da9UofU9ear con1erte#te 3iua #i luna n 3iua anului #i
func+ia monthUda9 con1erte#te 3iua anului n lun #i 3i.
6mbele func+ii au ne1oie de aceea#i informa+ie #i anume un tabel
cu numrul 3ilelor din fiecare lun. $eoarece numrul 3ilelor din
lun difer pentru anii bisec+i de cele pentru anii nebisec+i este mai
u#or s considerm un tabel bidimensional n care prima linie s
corespund numrului de 3ile ale lunilor pentru anii nebisec+i* iar a
doua linie s corespund numrului de 3ile pentru anii bisec+i. @n felul
acesta nu trebuie s +inem o e1iden+ n timpul calculului a ceea ce se
ntmpl cu luna februarie. 6tunci masi1ul bidimensional care
con+ine informa+iile pentru cele dou func+ii este urmtorul4
static int da9Uta().*)'0* " {
{0,0',.5,0',00,0',00,0',0',00,0',00,0',
{0,0',.4,0',00,0',00,0',0',00,0',00,0'
;
%asi1ul da9Uta( trebuie s fie declarat e-tern pentru a putea fi
folosit de ambele func+ii.
@n limbajul C* prin defini+ie* un masi1 cu dou dimensiuni este n
realitate un masi1 cu o dimensiune ale crui elemente snt masi1e. $e
aceea indicii se scriu sub forma )i*)G* n loc de )i,G** cum se
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GE
procedea3 n cele mai multe limbaje. ,n masi1 bidimensional poate
fi tratat n acela#i fel ca #i n celelalte limbaje* n sensul c elementele
snt memorate pe linie* adic indicele cel mai din dreapta 1aria3 cel
mai rapid.
,n masi1 se ini+iali3ea3 cu ajutorul unei liste de ini+iali3atori
nc"i#i ntre acolade; fiecare linie a unui masi1 bidimensional se
ini+iali3ea3 cu ajutorul unei subliste de ini+iali3atori. @n ca3ul
e-emplului nostru* masi1ul da9Uta( ncepe cu o coloan 3ero*
pentru ca numerele lunilor s fie ntre 7 #i 78 #i nu ntre 0 #i 77*
aceasta pentru a nu face modificri n calculul indicilor.
bi atunci func+iile care reali3ea3 con1ersiile cerute de e-emplul
nostru snt4
da9UofU9ear (int 9ear, int month, int da9)
{ =W 3iua anului din lun #i 3i W=
int i, leap;
leap " (9ear#/""0) $$ (9ear#'00&"0) HH
(9ear#/00""0);
for (i"'; i<month; i%%)
da9 %" da9Uta()leap*)i*;
return da9;

$eoarece 1ariabila leap poate lua ca 1alori numai 3ero sau unu
dup cum e-presia4
(9ear#/""0) $$ (9ear#'00&"0) HH
(9ear#/00""0)
este fals sau ade1rat* ea poate fi folosit ca indice de linie n
tabelul da9Uta( care are doar dou linii n e-emplul nostru.
monthUda9(int 9ear, int 9earda9,
int +pmonth, int +pda9) {
int i,leap;
leap " (9ear#/""0) $$ (9ear#'00&"0) HH
(9ear#/00""0);
for (i"'; 9earda9>da9Uta()leap*)i*; i%%)
9earda9 6" da9Uta()leap*)i*;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
G7
+pmonth " i;
+pda9 " 9earda9;

$eoarece aceast ultim func+ie returnea3 dou 1alori*


argumentele lun #i 3i 1or fi pointeri.
Exemplu4 monthUda9('45/,2',$m,$d) 1a ncrca pe m cu
?* iar pe d cu 7 9adic 7 martie<.
$ac un masi1 bidimensional trebuie transmis unei func+ii*
declara+ia argumentelor func+iei trebuie s includ dimensiunea
coloanei. $imensiunea liniei nu este necesar s apar n mod
obligatoriu* deoarece ceea ce se transmite de fapt este un pointer la
masi1e de cte 7? ntregi* n ca3ul e-emplului nostru. 6stfel* dac
masi1ul da9Uta( trebuie transmis unei func+ii f* atunci declara+ia
lui f poate fi4
f(int (+da9Uta())'0*)
unde declara+ia (+da9Uta())'0*) indic faptul c argumentul lui
f este un pointer la un masi1 de 7? ntregi.
@n general deci* un masi1 d2dimensional a)i*)G*...)p* de
rangul i+G+...+p este un masi1 d7 2 dimensional de rangul
G+,+...+p ale crui elemente* fiecare* snt masi1e d8 2
dimensionale de rang ,+...+p ale crui elemente* fiecare* snt
masi1e d? 2 dimensionale #.a.m.d. Dricare dintre e-presiile a)i**
a)i*)G*...* a)i*)G*... )p* pot aprea n e-presii. 0rima are
tipul masi1* ultima are tipul int* de e-emplu* dac masi1ul este de
tipul int. Com mai re1eni asupra acestei probleme cu detalii.
6.4. Masi$e de pointeri i pointeri la pointeri
$eoarece pointerii snt 1ariabile* are sens no+iunea de masi1 de
pointeri. Com ilustra modul de lucru cu masi1e de pointeri pe un
e-emplu.
: scriem un program care s sorte3e le-icografic liniile de
lungimi diferite ale unui te-t* linii care spre deosebire de ntregi nu
pot fi comparate sau sc"imbate printr2o singur opera+ie.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GG
$ac memorm liniile te-tului una dup alta ntr2un masi1 lung
de caractere 9gestionat de func+ia alloc<* atunci fiecare linie poate
fi accesibil cu ajutorul unui pointer la primul ei caracter. 0ointerii
tuturor liniilor* la rndul lor* pot fi memora+i sub forma unui masi1.
6tunci dou linii de te-t pot fi comparate transmi+nd pointerii lor
func+iei strcmp. $ac dou linii care nu respect ordinea trebuie s
fie sc"imbate* se sc"imb doar pointerii lor din masi1ul de pointeri #i
nu te-tul efecti1 al liniilor.
0rocesul de sortare l 1om reali3a n trei pa#i4
7< se citesc toate liniile te-tului de la intrare;
8< se sortea3 liniile n ordine le-icografic;
?< se tipresc liniile sortate n noua ordine.
Com scrie programul prin func+iile sale* fiecare func+ie reali3nd
unul din cei trei pa#i de mai sus. D rutin principal 1a controla cele
trei func+ii. Ka are urmtorul cod4
#define >JA@M '00 =W nr ma-im de linii de sortat W=
main() { =W sortea3 liniile de la intrare W=
char +lineptr)>JA@M*; =W pointeri la linii W=
int nlines; =W nr linii intrare citite W=
if ((nlines"readlines(lineptr,>JA@M))>"0)
{
sort(lineptr,nlines);
writelines(lineptr,nlines);

else printf
("Jntrarea prea mare pentru sort\n");

Cele ? func+ii care reali3ea3 ntregul proces snt4 readlines*


sort #i writelines.
Rutina de intrare readlines trebuie s memore3e caracterele
fiecrei linii #i s construiasc un masi1 de pointeri la liniile citite.
/rebuie* de asemenea* s numere liniile din te-tul de la intrare*
deoarece aceast informa+ie este necesar n procesul de sortare #i de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GH
imprimare. @ntruct func+ia de intrare poate prelucra numai un numr
finit de linii de intrare* ea poate returna un numr ilegal* cum ar fi 7*
spre a semnala c numrul liniilor de intrare este prea mare pentru
capacitatea de care dispune.
6tunci func+ia readlines care cite#te liniile te-tului de la
intrare este urmtoarea4
#define B<;>@A '000
#define A?>> 0
#define @S= 6'
readlines(char +lineptr)*, int ma8lines) {
=W cite#te liniile W=
int len,nlines;
char +p,+alloc(),line)B<;>@A*;
nlines " 0;
while ((len"7etline(line,B<;>@A))>0)
if (nlines>"ma8lines)
return 6';
else if ((p"alloc(len))""A?>>)
return 6';
else {
line)len6'* " !\0!;
strcp9(p,line);
lineptr)nlines%%* " p;

return nlines;

;nstruc+iunea line)len6'* " !\0!; #terge caracterul


<LF> de la sfr#itul fiecrei linii ca s nu afecte3e ordinea n care snt
sortate liniile #i depune n locul lui caracterul !\0! ca marc de
sfr#it de #ir.
Rutina care tipre#te liniile n noua lor ordine este
writelines #i are urmtorul cod4
writelines(char +lineptr)*, int nlines) {
=W scrie liniile sortate W=
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H0
int i;
for (i"0; i<nlines; i%%)
printf("#s\n",lineptr)i*);

$eclara+ia nou care apare n aceste programe este4


char +lineptr)>JA@M*;
care indic faptul c lineptr este un masi1 de >JA@M elemente*
fiecare element al masi1ului fiind un pointer la un caracter. 6stfel
lineptr)i* este un pointer la un caracter* iar WlineptrYi[ permite
accesul la caracterul respecti1.
$eoarece lineptr este el nsu#i un masi1* care se transmite ca
argument func+iei writelines* el 1a fi tratat ca un pointer 91e3i
sec+iunea H.?< #i atunci func+ia writelines mai poate fi scris #i
astfel4
writelines(char +lineptr)*, int nlines) {
while (66nlines>"0)
printf("#s\n",+lineptr%%);

@n func+ia printf* lineptr indic ini+ial prima linie de


imprimat; fiecare incrementare a1ansea3 pe +lineptr la
urmtoarea linie de imprimat* n timp ce nlines se mic#orea3
dup fiecare tiprire a unei linii cu 7.
Func+ia care reali3ea3 sortarea efecti1 a liniilor se ba3ea3 pe
algoritmul de njumt+ire #i are urmtorul cod4
#define A?>> 0
#define >JA@M '00 =W nr ma-im de linii de sortat W=
sort(char +-)*, int n) {
=W sortea3 #irurile -
0
* -
'
* ... -
n6'
n ordine cresctoare W=
int 7ap,i,G;
char +temp;
for (7ap"nF.; 7ap>0; 7apF".)
for (i"7ap; i<n; i%%)
for (G"i67ap; G>"0; G6"7ap) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H7
if (strcmp(-)G*,-)G%7ap*)<"0)
(rea,;
temp " -)G*;
-)G* " -)G%7ap*;
-)G%7ap* " temp;

$eoarece fiecare element al masi1ului - 9care este de fapt


masi1ul lineptr< este un pointer la primul caracter al unei linii*
1ariabila temp 1a fi #i ea un pointer la un caracter* deci opera+iile de
atribuire din ciclu dup 1ariabila G snt admise #i ele reali3ea3
rein1ersarea pointerilor la linii dac ele nu snt n ordinea cerut.
: re+inem deci urmtoarele lucruri legate de masi1e #i pointeri.
$e cte ori apare ntr2o e-presie un identificator de tip masi1 el este
con1ertit ntr2un pointer la primul element al masi1ului. 0rin
defini+ie* operatorul de inde-are )* este interpretat astfel nct
E7)E8* este identic cu +((E7)%(E8)). $ac E7 este un masi1* iar
E8 un ntreg* atunci E7)E8* se refer la elementul de indice E8 al
masi1ului E7.
D regul corespun3toare se aplic #i masi1elor multi2
dimensionale. $ac E7 este un masi1 d2dimensional* de rangul
i+G+...+,* atunci ori de cte ori e7 apare ntr2o e-presie* e7 1a fi
con1ertit ntr2un pointer la un masi1 d7 2 dimensional de rangul
G+...+,* ale crui elemente snt masi1e. $ac operatorul + se
aplic acestui pointer* re3ultatul este masi1ul d7 2 dimensional* care
se 1a con1erti imediat ntr2un pointer la un masi1 d8 2 dimensional
#.a.m.d. Ra+ionamentul se poate aplica n mod inducti1 pn cnd* n
final* ca urmare a aplicrii operatorului + se ob+ine ca re3ultat un
ntreg* de e-emplu* dac masi1ul a fost declarat de tipul int.
: considerm* de e-emplu* masi1ul4
int 8)0*)1*;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H8
8 este un masi1 de ntregi* de rangul ?WB. Cnd 8 apare ntr2o
e-presie* el este con1ertit ntr2un pointer la 9primul din cele trei<
masi1e de B ntregi.
@n e-presia 8)i** care este ec"i1alent cu e-presia +(8%i)* 8
este con1ertit ntr2un pointer la un masi1* ale crui elemente snt la
rndul lor masi1e de B elemente; apoi i se con1erte#te la tipul 8* adic
indicele i se nmul+e#te cu lungimea elementului pe care l indic 8
9adic B ntregi< #i apoi re3ultatele se adun. :e aplic operatorul +
pentru ob+inerea masi1ului i 9de B ntregi< care la rndul lui este
con1ertit ntr2un pointer la primul ntreg din cei cinci.
:e obser1 deci c primul indice din declara+ia unui masi1 nu
joac rol n calculul adresei.
6.5. Iniiali1area masi$elor i masi$elor de
pointeri
;ni+iali3atorul unei 1ariabile declarate masi1 const dintr2o list
de ini+iali3atori separa+i prin 1irgul #i nc"i#i ntre acolade*
corespun3tori tuturor elementelor masi1ului. Ki snt scri#i n ordinea
cresctoare a indicilor masi1ului. $ac masi1ul con+ine sub2masi1e
atunci regula se aplic recursi1 membrilor masi1ului. $ac n lista de
ini+iali3are e-ist mai pu+ini ini+iali3atori dect elementele masi1ului*
restul elementelor neini+iali3ate se ini+iali3ea3 cu 3ero. &u se admite
ini+iali3area unui masi1 de clas cu automatic.
6coladele { #i se pot omite n urmtoarele situa+ii4
5 dac ini+iali3atorul ncepe cu o acolad stng 9{<* atunci lista de
ini+iali3atori* separa+i prin 1irgul* 1a ini+iali3a elementele masi1ului;
nu se accept s e-iste mai mul+i ini+iali3atori dect numrul
elementelor masi1ului;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H?
5 dac ns ini+iali3atorul nu ncepe cu acolad stng 9{<* atunci se
iau din lista de ini+iali3atori at+ia ini+iali3atori c+i corespund
numrului de elemente ale masi1ului* restul ini+iali3atorilor 1or
ini+iali3a urmtorul membru al masi1ului* care are ca parte 9sub2
masi1< masi1ul deja ini+iali3at.
,n masi1 de caractere poate fi ini+iali3at cu un #ir* ca3 n care
caracterele succesi1e ale #irului ini+iali3ea3 elementele masi1ului.
Exemple4
7< int 8)* " {',0,1;
6ceast declara+ie define#te #i ini+iali3ea3 pe 8 ca un masi1
unidimensional cu trei elemente* n ciuda faptului c nu s2a specificat
dimensiunea masi1ului. 0re3en+a ini+iali3atorilor nc"i#i ntre acolade
determin dimensiunea masi1ului.
8< $eclara+ia
int 9)/*)0*"{
{',0,1,
{.,/,2,
{0,1,3,
;
este o ini+iali3are complet nc"is ntre acolade. Calorile 7*?*B
ini+iali3ea3 prima linie a masi1ului 9)0* #i anume pe 9)0*)0**
9)0*)'** 9)0*).*. @n mod analog urmtoarele dou linii
ini+iali3ea3 pe 9)'* #i 9).*. $eoarece ini+iali3atorii snt mai
putini dect numrul elementelor masi1ului* linia 9)0* se 1a
ini+iali3a cu 3ero* respecti1 elementele 9)0*)0** 9)0*)'** 9)0*
).* 1or a1ea 1alorile 3ero.
?< 6cela#i efect se poate ob+ine din declara+ia4
int 9)/*)0* " {',0,1,.,/,2,0,1,3;
unde ini+iali3atorul masi1ului 9 ncepe cu acolada stng n timp ce
ini+iali3atorul pentru masi1ul 9)0* nu* fapt pentru care primii trei
ini+iali3atori snt folosi+i pentru ini+iali3area lui 9)0** restul
ini+iali3atorilor fiind folosi+i pentru ini+iali3area masi1elor 9)'* #i
respecti1 9).*.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HA
A< $eclara+ia4
int 9)/*)0* " {
{',{.,,{0,,{/
;
ini+iali3ea3 masi1ul 9)0* cu 97*0*0<* masi1ul 9)'* cu 98*0*0<*
masi1ul 9).* cu 9?*0*0< #i masi1ul 9)/* cu 9A*0*0<.
B< $eclara+ia4
static char ms7)* " "@roare de sinta8a";
ini+iali3ea3 elementele masi1ului de caractere ms7 cu caracterele
succesi1e ale #irului dat.
@n ceea ce pri1e#te ini+iali3area unui masi1 de pointeri s
considerm urmtorul e-emplu.
Fie func+ia monthUname care returnea3 un pointer la un #ir de
caractere care indic numele unei luni a anului. Func+ia dat con+ine
un masi1 de #iruri de caractere #i returnea3 un pointer la un astfel de
#ir* cnd ea este apelat.
Codul func+iei este urmtorul4
char +monthUname(int n) {
=W returnea3 numele lunii a n2a W=
static char +name)* " {
"luna ile7ala", "ianuarie",
"fe(ruarie", "martie", "aprilie",
"mai", "iunie", "iulie", "au7ust",
"septem(rie", "octom(rie", "noiem(rie",
"decem(rie"

return ((n<') HH (n>'.)) O name)0* P
name)n* ;

@n acest e-emplu* name este un masi1 de pointeri la caracter* al


crui ini+iali3ator este o list de #iruri de caractere. Compilatorul
aloc o 3on de memorie pentru memorarea acestor #iruri #i
generea3 cte un pointer la fiecare din ele pe care apoi i introduce n
masi1ul name. $eci name)i* 1a con+ine un pointer la #irul de
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HB
caractere a1nd indice i al ini+iali3atorului. $imensiunea masi1ului
name nu este necesar a fi specificat deoarece compilatorul o
calculea3 numrnd ini+iali3atorii furni3a+i #i o completea3 n
declara+ia masi1ului.
6.6. Masi$e de pointeri i masi$e
multidimensionale
6desea se creea3 confu3ii n ceea ce pri1e#te diferen+a dintre un
masi1 bidimensional #i un masi1 de pointeri. Fie date declara+iile4
int a)'0*)'0*;
int +()'0*;
@n aceast declara+ie a este un masi1 de ntregi cruia i se aloc
spa+iu pentru toate cele 700 de elemente* iar calculul indicilor se face
n mod obi#nuit pentru a a1ea acces la oricare element al masi1ului.
0entru masi1ul (* declara+ia aloc spa+iu numai pentru 3ece
pointeri* fiecare trebuind s fie ncrcat cu adresa unui masi1 de
ntregi.
0resupunnd c fiecare pointer indic un masi1 de 3ece elemente
nseamn c ar trebui alocate nc o sut de loca+ii de memorie pentru
elementele masi1elor.
@n aceast accep+iune* folosirea masi1elor a #i ( poate fi similar
n sensul c a)1*)1* #i ()1*)1** de e-emplu* se refer ambele la
unul #i acela#i ntreg 9dac fiecare element ()i* este ini+iali3at cu
adresa masi1ului a)i*<.
6stfel* masi1ul de pointeri utili3ea3 mai mult spa+iu de memorie
dect masi1ele bidimensionale #i pot cere un pas de ini+iali3are
e-plicit. $ar masi1ele de pointeri pre3int dou a1antaje* #i anume4
accesul la un element se face cu adresare indirect* prin intermediul
unui pointer* n loc de procedura obi#nuit folosind nmul+irea #i apoi
adunarea* iar al doilea a1antaj const n aceea c dimensiunea
masi1elor pointate poate fi 1ariabil. 6cest lucru nseamn c un
element al masi1ului de pointeri ( poate indica un masi1 de 3ece
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HE
elemente* altul un masi1 de dou elemente #i altul de e-emplu poate
s nu indice nici un masi1.
Cu toate c problema pre3entat n acest paragraf am descris2o n
termenii ntregilor* ea este cel mai frec1ent utili3at n memorarea
#irurilor de caractere de lungimi diferite 9ca n func+ia monthUname
pre3entat mai sus<.
6.17. :rgumentele unei linii de comand
@n sistemul de calcul care admite limbajul C trebuie s e-iste
posibilitatea ca n momentul e-ecu+iei unui program scris n acest
limbaj s i se transmit acestuia argumente sau parametri prin linia de
comand. Cnd un program este lansat n e-ecu+ie #i func+ia main
este apelat* apelul 1a con+ine dou argumente. 0rimul argument
9numit con1en+ional ar7c< repre3int numrul de argumente din
linia de comand care a lansat programul. 6l doilea argument 9ar7-<
este un pointer la un masi1 de pointeri la #iruri de caractere care
con+in argumentele* cte unul pe #ir.
: ilustrm acest mod dinamic de comunicare ntre utili3ator #i
programul su printr2un e-emplu.
Fie programul numit pri care dorim s imprime la terminal
argumentele lui luate din linia de comand* imprimarea fcndu2se pe
o linie* iar argumentele imprimate s fie separate prin spa+ii.
Comanda4
pri succes cole7i
1a a1ea ca re3ultat imprimarea la terminal a te-tului
succes colei
0rin con1en+ie* ar7-)0* este un pointer la numele pri al
programului apelat* astfel c ar7c* care specific numrul de
argumente din linia de comand este cel pu+in 7.
@n e-emplul nostru* ar7c este ?* iar ar7-)0** ar7-)'* #i
ar7-).* snt pointeri la "pri"* "succes" #i respecti1
"cole7i". 0rimul argument real este ar7-)'* iar ultimul este
ar7-)ar7c6'*. $ac ar7c este 7* nseamn c linia de comand
nu are nici un argument dup numele programului.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
H7
6tunci programul pri are urmtorul cod4
main(int ar7c, char +ar7-)*) {
=W tipre#te argumentele W=
int i;
for (i"'; i<ar7c; i%%)
printf("#s##c",ar7-)i*,(i<ar7c6')O
! !P!\n!);

$eoarece ar7- este un pointer la un masi1 de pointeri* e-ist


mai multe posibilit+i de a scrie acest program. : mai scriem dou
1ersiuni ale acestui program.
main(int ar7c, char +ar7-)*) {
=W 1ersiunea a doua W=
while (66ar7c>0)
printf("#s#c",+%%ar7-,(ar7->')O
! !P!\n!);

$eoarece ar7- este un pointer la un masi1 de pointeri*


incrementndu2l* (%%ar7-)* el 1a pointa la ar7-)'* n loc de
ar7-)0*. Fiecare incrementare succesi1 po3i+ionea3 pe ar7- la
urmtorul argument* iar +ar7- este pointerul la argumentul #irului
respecti1. @n acela#i timp ar7c este decrementat pn de1ine 3ero*
moment n care nu mai snt argumente de imprimat.
6lternati14
main(int ar7c, char +ar7-) *) {
=W 1ersiunea a treia W=
while (66ar7c>0)
printf((ar7c>')O "#s "P"#s\n",+%%ar7-);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HG
6ceast 1ersiune arat c argumentul func+iei printf poate fi o
e-presie ca oricare alta* cu toate c acest mod de utili3are nu este
foarte frec1ent.
Ca un al doilea e-emplu* s reconsiderm programul din
sec+iunea 7.B* care imprim fiecare linie a unui te-t care con+ine un
#ir specificat de caractere 9sc"em<.
$orim acum ca aceast sc"em s poat fi modificat dinamic*
de la e-ecu+ie la e-ecu+ie. 0entru aceasta o specificm printr2un
argument n linia de comand.
bi atunci programul care caut sc"ema dat de primul argument
al liniei de comand este4
#define B<;>JA@ '000
main(int ar7c, char +ar7-) *) {
=W gse#te sc"ema din primul argument W=
char line)B<;>JA@*;
if (ar7c&".)
printf(">inia de comanda eronata\n");
else
while (7etline(line,B<;>JA@)>0)
if (inde8(line,ar7-)'*)>"0)
printf("#s",line);

unde linia de comand este de e-emplu4 "find lim(aG" n care


"find" este numele programului* iar "lim(aG" este sc"ema
cutat. Re3ultatul 1a fi imprimarea tuturor liniilor te-tului de intrare
care con+in cu1ntul "lim(aG".
: elaborm acum modelul de ba3* legat de linia de comand #i
argumentele ei.
: presupunem c dorim s introducem n linia de comand dou
argumente op+ionale4 unul care s tipreasc toate liniile cu e-cep+ia
acelora care con+in sc"ema* #i al doilea care s precead fiecare linie
tiprit cu numrul ei de linie.
D con1en+ie pentru programele scrise n limbajul C este ca
argumentele dintr2o linie de comand care ncep cu un semn ' 6' s
introduc un parametru op+ional. $ac alegem* de e-emplu* 68
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HH
pentru a indica cu e-cep+ia #i 6n pentru a cere numrarea
liniilor* atunci comanda4
find 68 6n la
a1nd intrarea4
la miezul stinselor lumini
s-a,un victorios-
la temelii- la rdcini-
la mduv- la os"
1a produce tiprirea liniei a doua* precedat de numrul ei* deoarece
aceast linie nu con+ine sc"ema "la".
6rgumentele op+ionale snt permise n orice ordine n linia de
comand. 6nali3area #i prelucrarea argumentelor unei linii de
comand trebuie efectuat n func+ia principal main* ini+iali3nd n
mod corespun3tor anumite 1ariabile. Celelalte func+ii ale
programului nu 1or mai +ine e1iden+a acestor argumente.
Kste mai comod pentru utili3ator dac argumentele op+ionale snt
concatenate* ca n comanda4
find 68n la
Caracterele !8! respecti1 !n! indic doar absen+a sau pre3en+a
acestor op+iuni 9s'itc"< #i nu snt tratate din punct de 1edere al
1alorii lor.
Fie programul care caut sc"ema "la" n liniile de la intrare #i
le tipre#te pe acelea* care nu con+in sc"ema* precedate de numrul
lor de linie. 0rogramul tratea3 corect* att prima form a liniei de
comand ct #i a doua.
#define B<;>JA@ '000
main(int ar7c, char +ar7-)*) {
=W caut sc"ema W=
char line)B<;>JA@*, +s;
lon7 line0;
int e8cept, num(er;
line0 " 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
700
num(er " 0;
while (66ar7c>0 $$ (+%%ar7-))0*""!6!)
for (s"ar7-)0*%'; +s&"!\0!; s%%)
switch(+s) {
case !8!P e8cept " '; (rea,;
case !n!P num(er " '; (rea,;
defaultP
printf
("findP optiune ile7ala #c\n",
+s);
ar7c " 0;
(rea,;

if (ar7c&"')
printf
("Au e8ista ar7umente sau schema\n");
else
while (7etline(line,B<;>JA@)>0) {
line0%%;
if ((inde8(line,+ar7-)>"0)&"e8cept)
{
if (num(er)
printf("#dP",line0);
printf("#s",line);

$ac nu e-ist erori n linia de comand* atunci la sfr#itul


primului ciclu '"ile ar7c trebuie s fie 7* iar +ar7- con+ine adresa
sc"emei. +%%ar7- este un pointer la un #ir argument* iar (+%
%ar7-))0* este primul caracter al #irului. @n aceast ultim
e-presie parante3ele snt necesare deoarece fr ele e-presia
nseamn +%%(ar7-)0*) ceea ce este cu totul altce1a 9#i gre#it<4 al
doilea caracter din numele programului. D alternati1 corect pentru
(+%%ar7-)0*) este ++%%ar7-.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
707
6.11. Pointeri la #uncii
@n limbajul C o func+ie nu este o 1ariabil* dar putem defini un
pointer la o func+ie* care apoi poate fi prelucrat* transmis unor alte
func+ii* introdus ntr2un masi1 #i a#a mai departe. Relati1 la o func+ie
se pot face doar dou opera+ii4 apelul ei #i considerarea adresei ei.
$ac numele unei func+ii apare ntr2o e-presie* fr a fi urmat
imediat de o parante3 stng* deci nu pe po3i+ia unui apel la ea*
atunci se generea3 un pointer la aceast func+ie. 0entru a transmite o
func+ie unei alte func+ii* ca argument* se poate proceda n felul
urmtor4
int f();
7(f);
unde func+ia f este un argument pentru func+ia 7. $efini+ia func+iei 7
1a fi4
7(int(+funcpt) ()) {
(+funcpt)();

Func+ia f trebuie declarat e-plicit n rutina apelant 9int


f();<* deoarece apari+ia ei n 7(f) nu a fost urmat de parante3
stng a(a. @n e-presia 7(f) f nu apare pe po3i+ia de apel de func+ie.
@n acest ca3* pentru argumentul func+iei 7 se generea3 un pointer la
func+ia f. $eci 7 apelea3 func+ia f printr2un pointer la ea.
$eclara+iile din func+ia 7 trebuie studiate cu grij.
int (+funcpt)();
spune c funcpt este un pointer la o func+ie care returnea3 un
ntreg. 0rimul set de parante3e este necesar* deoarece fr el
int +funcpt();
nseamn c funcpt este o func+ie care returnea3 un pointer la un
ntreg* ceea ce este cu totul diferit fa+ de sensul primei e-presii.
Folosirea lui funcpt n e-presia4
(+funcpt)();
indic faptul c funcpt este un pointer la o func+ie* +funcpt este
func+ia* iar (+funcpt)() este apelul func+iei.
D form ec"i1alent simplificat de apel este urmtoarea4
funcpt();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
708
Ca un e-emplu* s considerm procedura de sortare a liniilor de
la intrare* descris n sec+iunea H.7* dar modificat n sensul ca dac
argumentul op+ional 6n apare n linia de comand* atunci liniile se
1or sorta nu le-icografic ci numeric* liniile con+innd grupe de
numere.
D sortare const adesea din trei pr+i4 o comparare care determin
ordinea oricrei perec"i de elemente* un sc"imb care in1ersea3
ordinea elementelor implicate #i un algoritm de sortare care face
comparrile #i in1ersrile pn cnd elementele snt aduse n ordinea
cerut. 6lgoritmul de sortare este independent de opera+iile de
comparare #i in1ersare* astfel nct transmi+nd diferite func+ii de
comparare #i in1ersare func+iei de sortare* elementele de intrare se
pot aranja dup diferite criterii.
Compararea le-icografic a dou linii se reali3ea3 prin func+iile
strcmp #i swap. %ai a1em ne1oie de o rutin numcmp care s
compare dou linii pe ba3a 1alorilor numerice #i care s returne3e
aceia#i indicatori ca #i rutina strcmp.
$eclarm aceste trei func+ii n func+ia principal main* iar
pointerii la aceste func+ii i transmitem ca argumente func+iei sort*
care la rndul ei 1a apela aceste func+ii prin intermediul pointerilor
respecti1i.
Func+ia principal main 1a a1ea atunci urmtorul cod4
#define >JA@M '00 =W nr ma-im de linii de sortat W=
main (int ar7c, char +ar7-)*) {
char +lineptr)>JA@M*; =W pointeri la linii te-t W=
int nlines; =W numr de linii citite W=
int strcmp(), numcmp(); =W func+ii de comparare W=
int swap (); =W func+ia de in1ersare W=
int numeric;
numeric " 0; =W 7 dac sort numeric W=
if (ar7c>' $$ ar7-)'*)0*""!6! $$
ar7-)'*)'*""!n!)
numeric " ';
if ((nlines"readlines(lineptr,>JA@M))>"0)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70?
{
if (numeric)
sort(lineptr,nlines,numcmp,swap);
else
sort(lineptr,nlines,strcmp,swap);
writelines (lineptr,nlines);

else
printf
("Ar de linii de intrare prea mare\n");

@n apelul func+iei sort* argumentele strcmp* numcmp #i


swap snt adresele func+iilor respecti1e. $eoarece ele au fost
declarate func+ii care returnea3 un ntreg* operatorul a$a nu este
necesar s precead numele func+iilor* compilatorul fiind cel care
gestionea3 transmiterea adreselor func+iilor.
Func+ia sort care aranjea3 liniile n ordinea cresctoare
se 1a modifica astfel4
sort(char +-)*, int n, int (+comp)(),
int (+e8ch)()) { =W sortea3 -
0
* -
'
* ... * -
n'
W=
int 7ap,i,G;
for (7ap"nF.; 7ap>0; 7apF".)
for (i"7ap; i<n; i%%)
for (G"i67ap; G>"0; G6"7ap) {
if (comp(-)G*,-)G%7ap*)<"0)
(rea,;
e8ch(-%G,-%G%7ap);

: studiem declara+iile din aceast func+ie.


int(+comp)(), (+e8ch)();
indic faptul c comp #i e8ch snt pointeri la func+ii care returnea3
un ntreg 9primul set de parante3e este necesar<.
if (comp(-)G*,-)G%7ap*)<"0)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70A
nseamn apelul func+iei comp 9adic strcmp sau numcmp<*
deoarece comp este un pointer la func+ie* +comp este func+ia* iar
comp(-)G*,-)G%7ap*)
este apelul func+iei.
e8ch(-%G,-%G%7ap)
este apelul func+iei swap* de in1ersare a dou linii* in1ersare care
reali3ea3 intersc"imbarea adreselor liniilor implicate 91e3i sec+iunea
H.8<. Func+ia numcmp este urmtoarea4
numcmp(char +s', char +s.) {
=W compar s' #i s. numeric W=
dou(le atof(),-',-.;
-' " atof(s');
-. " atof(s.);
if (-'<-.)
return 6';
else
if (-'>-.)
return ';
else
return 0;

0entru ca programul nostru s fie complet s mai pre3entm #i


codul func+iei swap* care sc"imb ntre ei pointerii a dou linii.
swap(char +p8)*, char +p9)*) {
char +temp;
temp " +p8;
+p8 " +p9;
+p9 " temp;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70B
17. ,tructuri i reuniuni
D structur este o colec+ie de una sau mai multe 1ariabile* de
acela#i tip sau de tipuri diferite* grupate mpreun sub un singur
nume pentru a putea fi tratate mpreun 9n alte limbaje* structurile se
numesc articole<.
:tructurile ajut la organi3area datelor complicate* n special n
programele mari* deoarece permit unui grup de 1ariabile legate s fie
tratate ca o singur entitate. Com ilustra n acest capitol modul de
utili3are a structurilor.
17.1. 3lemente de ba1
: re1enim asupra rutinei de con1ersie a datei pre3entat n
capitolul H.
D dat const din 3i* lun #i an* e1entual numrul 3ilei din an #i
numele lunii. 6ceste cinci 1ariabile pot fi grupate ntr2o singur
structur astfel4
struct date {
int da9;
int month;
int 9ear;
int 9earda9;
char monUname)/*;
;
Cu1ntul c"eie struct introduce o declara+ie de structur care
este o list de declara+ii nc"ise n acolade.
Cu1ntul struct poate fi urmat op+ional de un nume* numit
marcaj de structur sau etic"et de structur* cum este n e-emplul
nostru numele date. 6cest marcaj denume#te acest tip de structur
#i poate fi folosit n continuare ca o prescurtare pentru declara+ia de
structur detaliat creia i este asociat.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70E
Klementele sau 1ariabilele men+ionate ntr2o structur se numesc
membri ai structurii. ,n membru al structurii sau o etic"et #i o
1ariabil oarecare* nemembru* pot a1ea acela#i nume fr a genera
conflicte* deoarece ele 1or fi ntotdeauna deosebite una de alta din
conte-t.
6colada dreapt care nc"eie o list de membri ai unei structuri
poate fi urmat de o list de 1ariabile* la fel ca #i n ca3ul tipurilor de
ba3. $e e-emplu4
struct {. . . 8,9,:;
este din punct de 1edere sintactic analog cu4
int 8,9,:;
n sensul c fiecare declara+ie declar pe 8* 9 #i : ca 1ariabile de
tipul numit 9structur n primul ca3 #i ntreg n al doilea< #i cau3ea3
alocarea de spa+iu pentru ele.
D declara+ie de structur care nu este urmat de o list de
1ariabile nu aloc memorie; ea descrie numai un #ablon* o form de
structur. $ac structura este marcat sau etic"etat* atunci marcajul
ei poate fi folosit mai tr3iu pentru definirea unor alte 1ariabile de tip
structur* cu acela#i #ablon ca structura marcat. $e e-emplu* fiind
dat declara+ia4
struct date d;
ea define#te 1ariabila d* ca o structur de acela#i fel 9#ablon< ca
structura date.
D structur e-tern sau static poate fi ini+iali3at* ata#nd dup
defini+ia ei o list de ini+iali3atori pentru componente* de e-emplu4
struct date d " {/,3,'45/,'51,"iulie";
,n membru al unei structuri este referit printr2o e-presie de
forma4
nume-structur.membru
n care operatorul membru de structur a.a leag numele membrului
de numele structurii. Ca e-emplu fie atribuirea4
leap " (d.9ear#/""0) $$ (d.9ear#'00&"0)
HH (d.9ear#/00""0);
sau 1erificarea numelui lunii4
if (strcmp(d.monUname,"au7ust")""0) ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
707
:tructurile pot fi imbricate; o nregistrare de stat de plat* de
e-emplu* poate fi de urmtoarea form4
struct person {
char name)A<B@MJT@*;
char address)<EVMJT@*;
lon7 :ipcode;
lon7 ssUnum(er;
dou(le salar9;
struct date (irthdate;
struct date hiredate;
;
:tructura person con+ine dou structuri de #ablon date.
$eclara+ia4
struct person emp;
define#te #i aloc o structur cu numele emp de acela#i #ablon ca #i
person. 6tunci4
emp.(irthdate.month
se refer la luna de na#tere. Dperatorul de membru de structur a.a
este asociati1 de la stnga la dreapta.
17.2. ,tructuri i #uncii
K-ist un numr de restric+ii asupra structurilor n limbajul C.
:ingurele opera+ii care se pot aplica unei structuri snt accesul la un
membru al structurii #i considerarea adresei ei cu ajutorul
operatorului $. 6cest lucru implic faptul c structurile nu pot fi
atribuite sau copiate ca entit+i #i c ele nu pot fi transmise ca
argumente la func+ii #i nici returnate din func+ii. :tructurile de clas
automatic* ca #i masi1ele de aceea#i clas* nu pot fi ini+iali3ate; pot fi
ini+iali3ate numai structurile e-terne #i statice* regulile de ini+iali3are
fiind acelea#i ca pentru masi1e.
0ointerii la structuri nu se supun ns acestor restric+ii* moti1
pentru care structurile #i func+iile pot coe-ista #i conlucra prin
intermediul pointerilor.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70G
Ca un e-emplu* s rescriem programul de con1ersie a datei* care
calculea3 3iua anului* din lun #i 3i.
da9UofU9ear(struct date +pd) {
=W calculul 3ilei anului W=
int i, da9, leap;
da9 " pd6>da9;
leap " (pd6>9ear#/""0) $$
(pd6>9ear#'00&""0) HH
(pd6>9ear#/00""0);
for (i"'; i<pd6>month; i%%)
da9 %" da9Uta()leap*)i*;
return da9;

$eclara+ia4
struct date + pd;
indic faptul c pd este un pointer la o structur de #ablonul lui date.
&ota+ia4
pd6>9ear
indic faptul c se refer membrul S9earS al acestei structuri. @n
general* dac p este un pointer la o structur p6>membru-structur
se refer la un membru particular 9operatorul a6>a se formea3 din
semnul minus urmat de semnul mai mare<.
$eoarece pd este pointer la o structur* membrul )ear poate fi de
asemenea referit prin4
(+pd).9ear
&ota+ia S6>S se impune ca un mod con1enabil de prescurtare. @n
nota+ia (+pd).9ear* parante3ele snt necesare deoarece preceden+a
operatorului membru de structur a.a este mai mare dect cea a
operatorului +.
6mbii operatori a.a #i a6>a snt asociati1i de la stnga la dreapta*
astfel nct4
p6>I6>membru
emp.(irthdate.month
snt de fapt4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
70H
(p6>I)6>membru
(emp.(irthdate).month
Dperatorii a6>a #i a.a ai structurilor* mpreun cu () pentru
listele de argumente #i )* pentru inde-are se gsesc n 1rful listei de
preceden+ 91e3i sec+iunea A.7E<* fiind din acest punct de 1edere
foarte apropia+i. 6stfel* fiind dat declara+ia4
struct {
int 8;
int +9; +p;
unde p este un pointer la o structur* atunci e-presia4
%%p6>8
incrementea3 pe 8* nu pointerul p* deoarece operatorul a6>a are o
preceden+ mai mare dect a%%a. 0arante3ele pot fi folosite pentru a
modifica ordinea operatorilor dat de preceden+a. 6stfel4
(%%p)6>8
incrementea3 mai nti pe p #i apoi accesea3 elementul 8* din
structura nou pointat.
@n e-presia (p%%)6>8 se accesea3 mai nti 8* apoi se
incrementea3 pointerul p.
@n mod analog* +p6>9 indic con+inutul adresei pe care o indic
9. K-presia +p6>9%% accesea3 mai nti ceea ce indic 9 #i apoi
incrementea3 pe 9. K-presia (+p6>9)%% incrementea3 ceea ce
indic 9. K-presia +p%%6>9 accesea3 ceea ce indic 9 #i apoi
incrementea3 pointerul p.
17.3. Masi$e de structuri
:tructurile snt n mod special utile pentru tratarea masi1elor de
1ariabile legate prin conte-t. 0entru e-emplificare 1om considera un
program care numr intrrile fiecrui cu1nt c"eie dintr2un te-t.
0entru aceasta a1em ne1oie de un masi1 de #iruri de caractere* pentru
pstrarea numelor cu1intelor c"eie #i un masi1 de ntregi pentru a
memora numrul apari+iilor. D posibilitate este de a folosi dou
masi1e paralele ,e9word #i ,e9count declarate prin4
char +,e9word)AN@WM*;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
770
int ,e9count)AN@WM*;
respecti1 unul de pointeri la #iruri de caractere #i cellalt de ntregi.
Fiecrui cu1nt c"eie i corespunde perec"ea4
char +,e9word;
int ,e9count;
astfel nct putem considera cele dou masi1e ca fiind un masi1 de
perec"i. 6tunci* declara+ia de structur4
struct ,e9 {
char +,e9word;
int ,e9count;
,e9ta()AN@WM*;
define#te un masi1 ,e9ta( de structuri de acest tip #i aloc memorie
pentru ele. Fiecare element al masi1ului ,e9ta( este o structur de
acela#i #ablon ca #i structura ,e9.
$efini+ia masi1ului ,e9ta( poate fi scris #i sub forma4
struct ,e9 {
char +,e9word;
int ,e9count;
;
struct ,e9 ,e9ta()AN@WM*;
$eoarece masi1ul de structuri ,e9ta( con+ine* n ca3ul nostru*
o mul+ime constant de cu1inte c"eie* este mai u#or de ini+iali3at o
dat pentru totdeauna c"iar n locul unde este definit. ;ni+iali3area
structurilor este o opera+ie analoag cu ini+iali3area unui masi1 n
sensul c defini+ia este urmat de o list de ini+iali3atori nc"i#i n
acolade.
6tunci ini+iali3area masi1ului de structuri ,e9ta( 1a fi
urmtoarea4
struct ,e9 {
char + ,e9word;
int ,e9count;
,e9ta()* " {
"(rea,",0,
"case",0,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
777
"char",0,
=W ... W=
"while",0;
;ni+iali3atorii snt perec"i care corespund la membrii structurii.
;ni+iali3area ar putea fi fcut #i inclu3nd ini+iali3atorii fiecrei
structuri din masi1 n acolade ca n4
{"(rea,",0,{"case",0....
dar parante3ele interioare nu snt necesare dac ini+iali3atorii snt
1ariabile simple sau #iruri de caractere #i dac to+i ini+iali3atorii snt
pre3en+i.
Compilatorul 1a calcula* pe ba3a ini+iali3atorilor* dimensiunea
masi1ului de structuri ,e9ta( moti1 pentru care* la ini+iali3are* nu
este necesar indicarea dimensiunii masi1ului.
0rogramul de numrare a cu1intelor c"eie ncepe cu definirea
masi1ului de structuri ,e9ta(. Rutina principal main cite#te
te-tul de la intrare prin apel repetat la o func+ie 7etword* care
e-trage din intrare cte un cu1nt la un apel. Fiecare cu1nt este apoi
cutat n tabelul ,e9ta( cu ajutorul unei func+ii de cutare
(inar9* descris n sec+iunea 7.B. Lista cu1intelor c"eie trebuie s
fie n ordine cresctoare pentru ca func+ia (inar9 s lucre3e corect.
$ac cu1ntul cercetat este un cu1nt c"eie atunci func+ia (inar9
returnea3 numrul de ordine al cu1ntului n tabelul cu1intelor c"eie*
altfel returnea3 7.
#define B<;XSVE .0
(inar9(char +word, struct ,e9 ta()*,
int n) {
int low,hi7h,mid,cond;
low " 0;
hi7h " n 6 ';
while (low<"hi7h) {
mid "(low % hi7h) F .;
if (
(cond"strcmp(word,ta()mid*.,e9word))
<0)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
778
hi7h " mid 6 ';
else
if (cond>0) low " mid % ';
else
return mid;

return 6';

main() { =W numr cu1intele c"eie W=


int n,t;
char word)B<;XSVE*;
while ((t"7etword(word,B<;XSVE))&"@S=)
if (t"">@RR@V)
if (
(n"(inar9(word,,e9ta(,AN@WM))
>"0)
,e9ta()n*.,e9count%%;
for (n"0; n<AN@WM; n%%)
if (,e9ta()n*.,e9count>0)
printf("#/d #s\n",
,e9ta()n*.,e9count,
,e9ta()n*.,e9word);

@nainte de a scrie func+ia 7etword este suficient s spunem c


ea returnea3 constanta simbolic >@RR@V de fiecare dat cnd
gse#te un cu1nt n te-tul de intrare #i copia3 cu1ntul n primul ei
argument.
Cantitatea AN@WM este numrul cu1intelor c"eie din ,e9ta(
9dimensiunea masi1ului de structuri<. $e#i putem calcula acest numr
manual* este mai simplu #i mai sigur s2o facem cu calculatorul* mai
ales dac lista cu1intelor c"eie este supus modificrilor. D
posibilitate de a calcula AN@WM cu calculatorul este de a termina
lista ini+iali3atorilor cu un pointer A?>> #i apoi prin ciclare pe
,e9ta( s detectm sfr#itul lui. 6cest lucru este mai mult dect
necesar deoarece dimensiunea masi1ului de structuri este perfect
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77?
determinat n momentul compilrii. &umrul de intrri se determin
mpr+ind dimensiunea masi1ului la dimensiunea structurii ,e9.
Dperatorul si:eof descris n sec+iunea A.8 furni3ea3
dimensiunea n octe+i a argumentului su.
@n ca3ul nostru* numrul cu1intelor c"eie este dimensiunea
masi1ului ,e9ta( mpr+it la dimensiunea unui element de masi1.
6cest calcul este fcut ntr2o linie #define pentru a da o 1aloare
identificatorului AN@WM4
#define AN@WM (si:eof(,e9ta() F
si:eof(struct ,e9))
: re1enim acum la func+ia 7etword. 0rogramul pe care2l 1om
da pentru aceast func+ie este mai general dect este necesar n
aplica+ia noastr* dar nu este mult mai complicat.
Func+ia 7etword cite#te cu1ntul urmtor din te-tul de intrare*
printr2un cu1nt n+elegndu2se fie un #ir de litere #i cifre* cu primul
caracter liter* fie un singur caracter. Func+ia returnea3 constanta
simbolic >@RR@V dac a gsit un cu1nt* @S= dac a detectat
sfr#itul fi#ierului sau caracterul nsu#i* dac el nu a fost alfabetic.
7etword(char +w, int lim) {=W cite#te un cu1nt W=
int t;
while (66lim>0) {
t " t9pe(+w%%"7etchar());
if (t""@S=)
return @S=;
if (t&">@RR@V $$ t&"EJYJR)
(rea,;

+(w6') " !\0!;
return >@RR@V;

Func+ia 7etword apelea3 func+ia t9pe pentru identificarea


tipului fiecrui caracter citit la intrare cu ajutorul func+iei 7etchar.
Cersiunea func+iei t9pe pentru caractere 6:C;; este4
t9pe(int c) { =W returnea3 tipul caracterului W=
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77A
if (c>"!a! $$ c<"!:! HH c>"!<! $$ c<"!T!)
return >@RR@V;
if (c>"!0! $$ c<"!4!)
return EJYJR;
return c;

Constantele simbolice >@RR@V #i EJYJR pot a1ea orice 1aloare


care nu 1ine n contradic+ie cu caracterele nealfabetice #i KDF. Calori
posibile pot fi4
#define >@RR@V !a!
#define EJYJR !0!
17.'. Pointeri la structuri
0entru a ilustra modul de corelare dintre pointeri #i masi1ele de
structuri* s rescriem programul de numrare a cu1intelor c"eie dintr2
un te-t* de data aceasta folosind pointeri* n loc de indici de masi1.
$eclara+ia e-tern a masi1ului de structuri ,e9ta( nu necesit
modificri* n timp ce func+iile main #i (inar9 da. 0re3entm* n
continuare* aceste func+ii modificate.
#define B<;XSVE .0
struct ,e9 +(inar9(char +word, struct ,e9
ta()*, int n) {
=W caut cu1nt W=
int cond;
struct ,e9 + low;
struct ,e9 +hi7h;
struct ,e9 +mid;
low " $ta()0*;
hi7h " $ta()n6'*;
while (low<"hi7h) {
mid " low % (hi7h6low) F .;
if ((cond"strcmp(word,mid6>,e9word))<0)
hi7h " mid 6 ';
else if (cond>0)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77B
low " mid % ';
else return mid;

return A?>>;

main() {=W numr cu1intele c"eie* 1ersiune cu pointeri W=


int t;
char word)B<;XSVE*;
struct ,e9 +(inar9(), +p;
while ((t"7etword(word.B<;XSVE))&"@S=)
if (t"">@RR@V)
if ((p"(inar9(word,,e9ta(,AN@WM))
&" A?>>)
p6>,e9count%%;
for (p",e9ta(; p<,e9ta(%AN@WM; p%%)
if (p6>,e9count>0)
printf("#/d #s\n",p6>,e9count,
p6>,e9word);

: obser1m cte1a lucruri importante n acest e-emplu. @n


primul rnd* declara+ia func+iei (inar9 trebuie s indice c ea
returnea3 un pointer la o structur de acela#i #ablon cu structura
,e9* n loc de un ntreg. 6cest lucru este declarat att n func+ia
principal main ct #i n func+ia (inar9. $ac (inar9 gse#te un
cu1nt n structura ,e9* atunci returnea3 un pointer la el; dac nu27
gse#te* returnea3 A?>>. @n func+ie de aceste dou 1alori returnate*
func+ia main semnalea3 gsirea cu1ntului prin incrementarea
cmpului ,e9count corespun3tor cu1ntului sau cite#te urmtorul
cu1nt.
@n al doilea rnd* toate opera+iile de acces la elementele masi1ului
de structuri ,e9ta( se fac prin intermediul pointerilor. 6cest lucru
determin o modificare semnificati1 n func+ia (inar9. Calculul
elementului mijlociu nu se mai poate face simplu prin4
mid " (low % hi7h) F .
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77E
deoarece adunarea a doi pointeri este o opera+ie ilegal* nedefinit.
6ceast instruc+iune trebuie modificat n4
mid " low % (hi7h6low) F .
care face ca mid s pointe3e elementul de la jumtatea distan+ei
dintre low #i hi7h.
: mai obser1m ini+iali3area pointerilor low #i hi7h* care este
perfect legal* deoarece este posibil ini+iali3area unui pointer cu o
adres a unui element deja definit.
@n func+ia main a1em urmtorul ciclu4
for(p",e9ta(; p<,e9ta(%AN@WM; p%%)...
$ac p este un pointer la un masi1 de structuri* orice opera+ie
asupra lui p +ine cont de dimensiunea unei structuri* astfel nct p%%
incrementea3 pointerul p la urmtoarea structur din masi1* adunnd
la p dimensiunea corespun3toare a unei structuri. 6cest lucru nu
nseamn c dimensiunea structurii este egal cu suma dimensiunilor
membrilor ei deoarece din cerin+e de aliniere a unor membri se pot
genera goluri ntr2o structur.
@n sfr#it* cnd o func+ie returnea3 un tip complicat #i are o list
complicat de argumente* ca n4
struct ,e9 +(inar9(char +word, struct ,e9
ta(, int n)
func+ia poate fi mai greu 1i3ibil #i detectabil cu un editor de te-te.
$in acest moti1* se poate opta #i pentru urmtoarea form4
struct ,e9 +(inar9(word,ta(,n)
char +word; struct ,e9 ta(; int n;
unde nainte de acolada de desc"idere se preci3ea3 tipul fiecrui
parametru.
6lege+i forma care 1 con1ine #i care 1i se pare mai sugesti1.
17.). ,tructuri auto-re#erite
: considerm problema mai general* a numrului apari+iilor
tuturor cu1intelor dintr2un te-t de intrare. $eoarece lista cu1intelor
nu este cunoscut dinainte* n2o putem sorta folosind algoritmul de
cutare binar* ca n paragraful precedent. &u putem utili3a nici o
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
777
cutare liniar pentru fiecare cu1nt* pe msura apari+iei lui pentru a
1edea dac a mai fost pre3ent sau nu* pentru c timpul de e-ecu+ie al
programelor ar cre#te ptratic cu numrul cu1intelor de la intrare.
,n mod de a organi3a datele pentru a lucra eficient cu o list de
cu1inte arbitrare este de a pstra mul+imea de cu1inte* tot timpul
sortat* plasnd fiecare nou cu1nt din intrare pe o po3i+ie
corespun3toare* relati1 la intrrile anterioare. $ac am reali3a acest
lucru prin deplasarea cu1intelor ntr2un masi1 liniar* programul ar
dura* de asemenea* foarte mult. $e aceea* pentru re3ol1area eficient
a acestei probleme 1om folosi o structur de date numit arbore binar.
Fiecare nod al arborelui 1a repre3enta un cu1nt distinct din
intrare #i 1a con+ine urmtoarea informa+ie4
2 un pointer la cu1nt;
2 un contor pentru numrul de apari+ii;
2 un pointer la descendentul stng al cu1ntului;
2 un pointer la descendentul drept al cu1ntului. &ici un nod al
arborelui nu 1a a1ea mai mult dect doi descenden+i dar poate a1ea un
descendent sau c"iar nici unul.
6rborele se construie#te astfel nct pentru orice nod* sub2
arborele stng al su con+ine numai cu1intele care snt mai mici dect
cu1ntul din nod* iar sub2arborele drept con+ine numai cu1inte* care
snt mai mari dect cu1ntul din nod* compararea fcndu2se din punct
de 1edere le-icografic.
0entru a #ti dac un cu1nt nou din intrare e-ist deja n arbore se
porne#te de la nodul rdcin #i se compar noul cu1nt cu cu1ntul
memorat n nodul rdcin. $ac ele coincid se incrementea3
contorul de numrare a apari+iilor pentru nodul rdcin #i se 1a citi
un nou cu1nt din intrare.
$ac noul cu1nt din intrare este mai mic dect cu1ntul memorat
n nodul rdcin* cutarea continu cu descendentul stng* altfel se
in1estig"ea3 descendentul drept. $ac nu e-ist nici un descendent
pe direc+ia cerut* noul cu1nt nu e-ist n arbore #i 1a fi inserat pe
po3i+ia descendentului corespun3tor. :e obser1 c acest proces de
cutare este recursi1* deoarece cutarea din fiecare nod utili3ea3 o
cutare ntr2unul dintre descenden+ii si.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77G
0rin urmare se impune de la sine ca rutinele de inserare n arbore
#i de imprimare s fie recursi1e.
Re1enind la descrierea unui nod* el apare ca fiind o structur cu
patru componente4
struct tnode { =W nodul de ba3 W=
char +word; =W pointer la cu1nt W=
int count; =W numrtor de apari+ii W=
struct tnode +left; =W descendent stng W=
struct tnode +ri7ht; =W descendent drept W=
;
6ceast declara+ie recursi1 a unui nod este perfect legal*
deoarece o structur nu poate con+ine ca #i component o intrare a ei
ns#i dar poate con+ine un pointer la o structur de acela#i #ablon cu
ea.
$eclara+ia4
struct tnode +left;
declar pe left ca fiind un pointer la structur 9nod< #i nu o
structur ns#i.
@n program 1om folosi rutinele 7etword* pentru citirea unui
cu1nt din intrare* alloc pentru re3er1area de spa+iu necesar
memorrii unui cu1nt #i alte cte1a rutine pe care le cunoa#tem deja.
Rutina principal main cite#te prin intermediul rutinei get'ord un
cu1nt* #i l plasea3 n arbore prin rutina tree.
#define B<;XSVE .0
main() { =W contori3are apari+ii cu1inte W=
struct tnode +root, +tree();
char word)B<;XSVE*;
int t;
root " A?>>;
while ((t"7etword(word,B<;XSVE))&"@S=)
if (t"">@RR@V)
root " tree(root,word);
treeprint(root);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77H
Rutina main gestionea3 fiecare cu1nt din intrare ncepnd cu
cel mai nalt ni1el al arborelui 9rdcina<. La fiecare pas* cu1ntul din
intrare este comparat cu cu1ntul asociat rdcinii #i este apoi
transmis n jos* fie descendentului stng* fie celui drept* printr2un apel
recursi1 la rutina tree. @n acest proces* cu1ntul fie e-ist deja*
unde1a n arbore* ca3 n care contorul lui de numrare a apari+iilor se
incrementea3* fie cutarea continu pn la ntlnirea unui pointer
A?>>* ca3 n care nodul trebuie creat #i adugat arborelui. Cnd se
creea3 un nod nou* rutina tree returnea3 un pointer la el* care
apoi este introdus n nodul de origine 9adic n nodul al crui
descendent este noul nod< n cmpul left sau ri7ht dup cum
noul cu1nt este mai mic sau mai mare fa+ de cu1ntul origine.
Rutina tree* care returnea3 un pointer la o structur de #ablon
tnode are urmtorul cod4
struct tnode +tree(struct tnode +p,
char +w) { =W introduce cu1ntul ' n nodul p W=
struct tnode +talloc(int n);
char +strsa-(char +s);
int cond;
if (p""A?>>) { =W a sosit un nou cu1nt W=
p " talloc(); =W creea3 un nod nou W=
p6>word " strsa-(w);
p6>count " ';
p6>left " p6>ri7ht " A?>>;

else
if ((cond"strcmp(w,p6>word))""0)
p6>count%%;
else
if (cond<0) =W noul cu1nt mai mic W=
p6>left " tree(p6>left,w);
else =W noul cu1nt mai mare W=
p6>ri7ht " tree(p6>ri7ht,w);
return p;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
780

%emoria pentru noul nod se aloc de ctre rutina talloc* care


este o adaptare a rutinei alloc* pe care am 13ut2o deja. Ka
returnea3 un pointer la un spa+iu liber* n care se poate nscrie noul
nod al arborelui. Com discuta rutina talloc mai tr3iu. &oul cu1nt
se copia3 n acest spa+iu cu ajutorul rutinei strsa-* care returnea3
un pointer la nceputul cu1ntului* contorul de apari+ii se ini+iali3ea3
la 7 #i pointerii ctre cei doi descenden+i se fac A?>>. 6ceast parte
de cod se e-ecut numai cnd se adaug un nou nod.
Rutina treeprint tipre#te arborele astfel nct pentru fiecare
nod se imprim sub2arborele lui stng* adic toate cu1intele mai mici
dect cu1ntul curent* apoi cu1ntul curent #i la sfr#it sub2arborele
drept* adic toate cu1intele mai mari dect cu1ntul curent. Rutina
treeprint este una din cele mai tipice rutine recursi1e.
treeprint(struct tnode +p) {
=W tipre#te arborele p recursi1 W=
if (p&"A?>>) {
treeprint(p6>left);
printf("#1d #s\n",p6>count,p6>word);
treeprint(p6>ri7ht);

Kste important de re+inut faptul c n algoritmul de cutare n


arbore* pentru a ajunge la un anumit nod* se parcurg toate nodurile
precedente* pe ramura respecti1 9stng sau dreapt<* ncepnd
ntotdeauna cu nodul rdcin. $up fiecare ie#ire din rutina tree*
din cau3a recursi1it+ii* se parcurge acela#i drum* de data aceasta de
la nodul gsit spre rdcina arborelui* refcndu2se to+i pointerii
drumului parcurs.
$ac considera+i ca nu a+i n+eles suficient de bine recursi1itatea*
desena+i21 un arbore #i imprima+i2l cu ajutorul rutinei treeprint*
a1nd grij s memora+i fiecare ie#ire din tree #i treeprint.
D obser1a+ie legat de acest e-emplu4 dac arborele este
nebalansate* adic cu1intele nu sosesc n ordine aleatoare din punct
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
787
de 1edere le-icografic* atunci timpul de e-ecu+ie al programului
poate de1eni foarte mare. Ca3ul limit n acest sens este acela n care
cu1intele de la intrare snt deja n ordine* 9cresctoare sau
descresctoare<* ca3 n care programul nostru simulea3 o cutare
liniar ntr2un mod destul de costisitor.
: ne oprim pu+in asupra alocrii de memorie. Cu toate c se
aloc diferite tipuri de obiecte* este de preferat s e-iste un singur
alocator de memorie ntr2un program. Relati1 la acest alocator de
memorie se pun doua probleme4 n primul rnd cum poate satisface el
condi+iile de aliniere ale obiectelor de un anumit tip 9de e-emplu
ntregii trebuie aloca+i la adrese pare<; n al doilea rnd cum se poate
declara c alocatorul returnea3 pointeri la tipuri diferite de obiecte.
Cerin+ele de aliniere pot fi n general re3ol1ate cu u#urin+ pe
seama unui spa+iu care se pierde* dar care este nesemnificati1 ca
dimensiune. $e e-emplu* alocatorul alloc returnea3 totdeauna un
pointer la o adres par. @n ca3ul n care cererea de alocare poate fi
satisfcut #i de o adres impar 9pentru #iruri de caractere* de
e-emplu< se pierde un caracter.
@n ceea ce pri1e#te declararea tipului alocatorului alloc 9adic a
tipului de obiect pe care l indic pointerul returnat de alloc<* un
foarte bun procedeu n limbajul C este de a declara c func+ia alloc
returnea3 un pointer la c"ar #i apoi s con1ertim e-plicit acest
pointer la tipul dorit printr2un cast. 6stfel dac p este declarat n
forma4
char +p;
atunci4
(struct tnode +)p;
con1erte#te pe p dintr2un pointer la char ntr2un pointer la o
structur de #ablon tnode* dac el apare ntr2o e-presie. bi atunci* o
1ersiune a alocatorului talloc poate fi urmtoarea4
struct tnode +talloc() {
char +alloc();
return (struct tnode +) alloc
(si:eof(struct tnode));

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
788
17.+. Cutare &n tabele
D alt problem legat de definirea #i utili3area structurilor este
cutarea n tabele. Cnd se ntlne#te de e-emplu* o linie de forma4
#define W@M '
simbolul W@M #i te-tul de substitu+ie 7 se memorea3 ntr2o tabel.
%ai tr3iu* ori de cte ori te-tul W@M 1a aprea n instruc+iuni* el se 1a
nlocui cu constanta 7.
Crearea #i gestionarea tabelelor de simboluri este o problem de
ba3 n procesul de compilare. K-ist dou rutine principale care
gestionea3 simbolurile #i te-tele lor de substitu+ie. 0rima*
install(s,t) nregistrea3 simbolul s #i te-tul de substitu+ie t
ntr2o tabel* s #i t fiind #iruri de caractere. 6 doua* loo,up(s)
caut #irul s n tabel #i returnea3 fie un pointer la locul unde a fost
gsit* fie A?>> dac #irul s nu figurea3 n tabel.
6lgoritmul folosit pentru crearea #i gestionarea tabelei de
simboluri este o cutare pe ba3 de "as"ing. Fiecrui simbol i se
calculea3 un cod "as" astfel4 se adun codurile 6:C;; ale
caracterelor simbolului #i se ia restul pro1enit din mpr+irea
numrului ob+inut din adunare #i dimensiunea tabelului. 6stfel*
fiecrui simbol i se asocia3 un cod "as" H care 1erific rela+ia4
0<"H<08'00 9n "e-a3ecimal<
Codul "as" astfel ob+inut 1a fi folosit apoi ca un indice ntr2o
tabel de pointeri. ,n element al acestei tabele 9masi1< indic
nceputul unui lan+ de blocuri care descriu simboluri cu acela#i cod
"as". $ac un element al tabelei este A?>> nseamn c nici un
simbol nu are 1aloarea respecti1 de "as"ing.
,n bloc dintr2un lan+ indicat de un element al tabelei este o
structur care con+ine un pointer la simbol* un pointer la te-tul de
substitu+ie #i un pointer la urmtorul bloc din lan+. ,n pointer A?>>
la urmtorul bloc din lan+ indic sfr#itul lan+ului.
bablonul unei structuri 9nod< este urmtorul4
struct nlist {
char +name;
char +def;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78?
struct nlist +ne8t;= W urmtoarea intrare n lan+ W=
;
/abelul de pointeri care indic nceputurile lan+ului de blocuri ce
descriu simboluri de acela#i cod "as" este4
#define H<MHMJT@ 08'00
static struct nlist +hashta()H<MHMJT@*;
6lgoritmul de "as"ing pe care2l pre3entm nu este cel mai bun
posibil* dar are meritul de a fi e-trem de simplu4
hash(char +s) {
=W formea3 1aloarea "as" pentru #irul s W=
int hash-al;
for (hash-al"0; +s&"!\0!;)
hash-al %" +s%%;
return hash-al # H<MHMJT@;

6lgoritmul de "as"ing produce un indice n masi1ul de pointeri


hashta(. @n procesul de cutare a unui simbol* dac el e-ist* el
trebuie s fie n lan+ul de blocuri care ncepe la adresa con+inut de
elementul din hashta( cu indicele respecti1.
Cutarea n tabela de simboluri hashta( se reali3ea3 cu
func+ia loo,up. $ac simbolul cutat este pre3ent unde1a n lan+*
func+ia returnea3 un pointer la el; altfel returnea3 A?>>.
struct nlist +loo,up(char +s) {
=W caut #irul s n hashta( W=
struct nlist +np;
for (np"hashta()hash(s)*; np&"A?>>;
np"np6>ne8t)
if (strcmp(s,np6>name)""0)
return np; =W s2a gsit s W=
return A?>>; =W nu s2a gsit s W=

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78A
Rutina install folose#te func+ia loo,up pentru a determina
dac simbolul nou care trebuie introdus n lan+ este deja pre3ent sau
nu. $ac mai e-ist o defini+ie anterioar pentru acest simbol* ea
trebuie nlocuit cu defini+ia nou. 6ltfel* se creea3 o intrare nou
pentru acest simbol* care se introduce la nceputul lan+ului. Func+ia
install returnea3 A?>>* dac din anumite moti1e nu e-ist
suficient spa+iu pentru crearea unui bloc unu.
struct nlist +install(char +name, char
+def) { =W scrie 9nume* def< n hta( W=
struct nlist +np, +loo,up();
char +strsa-(), +alloc();
int hash-al;
if ((np"loo,up(name))""A?>>) { =W nu s2a gsit W=
np " (struct nlist+)alloc(si:eof(+np));
if (np""A?>>)
return A?>>; =W nu e-ist spa+iu W=
if ((np6>name"strsa-(name))""A?>>)
return A?>>;
hash-al " hash(np6>name);
np6>ne8t " hashta()hash-al*;
hashta()hash-al* " np;

else =W nodul e-ist deja W=
free(np6>def); =W eliberea3 defini+ia 1ec"e W=
if ((np6>def"strsa-(def))""A?>>)
return A?>>;
return np;

$eoarece apelurile la func+iile alloc #i free pot aprea n


orice ordine #i deoarece alinierea contea3* 1ersiunea simpl a
func+iei alloc* pre3entat n capitolul H nu este adec1at aici. @n
biblioteca standard e-ist func+ii de alocare fr restric+ii* care se
apelea3 implicit sau e-plicit de ctre utili3ator dintr2un program
scris n C pentru a ob+ine spa+iul de memorie necesar. $eoarece #i
alte ac+iuni dintr2un program pot cere spa+iu de memorie ntr2o
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78B
manier asincron* spa+iul de memorie gestionat de func+ia alloc
poate s fie necontiguu. 6stfel* spa+iul liber de memorie este pstrat
sub forma unui lan+ de blocuri libere* fiecare bloc con+innd o
dimensiune* un pointer la urmtorul bloc #i spa+iul liber propriu23is.
Blocurile snt pstrate n ordinea cresctoare a adreselor iar* ultimul
bloc* de adresa cea mai mare* indic primul bloc* prin pointerul lui la
blocul urmtor din lan+* astfel nct lan+ul este circular.
Cnd se lansea3 o cerere* se e-aminea3 lista spa+iului liber* pn
se gse#te un bloc suficient de mare pentru cererea respecti1. $ac
blocul are e-act dimensiunea cerut* el se eliberea3 din lan+ul
blocurilor libere #i este returnat utili3atorului. $ac blocul este mai
mare se descompune* astfel nct partea cerut se transmite
utili3atorului* iar partea rmas se introduce napoi n lista de spa+iu
liber. $ac nu se gse#te un bloc suficient de mare pentru cererea
lansat se caut un alt bloc de memorie.
Kliberarea unei 3one de memorie prin intermediul rutinei free
cau3ea3* de asemenea* o cutare n lista de spa+iu liber* pentru a gsi
locul corespun3tor de inserare a blocului de memorie eliberat. $ac
blocul de memorie eliberat este adiacent cu un bloc din lista de spa+iu
liber la orice parte a sa* el este alipit la acel bloc* crendu2se un bloc
mai mare* astfel ca memoria s nu de1in prea fragmentat.
$eterminarea adiacen+ei este u#urat de faptul c lista de spa+iu liber
se pstrea3 n ordinea cresctoare a adreselor de memorie.
K-emplul de utili3are a acestor func+ii ini+iali3ea3 elementele
masi1ului hashta( cu A?>>. @n continuare se a#teapt de la
tastatur introducerea unui nume #i a unei defini+ii pentru acest nume.
$ac numele introdus nu e-ist n lista hashta( atunci se afi#ea3
un mesaj corespun3tor* altfel se afi#ea3 1ec"ea defini+ie care este
apoi nlocuit de noua defini+ie introdus.
main() {
char num)00*,def)00*;
int i;
struct nlist +np;
for (i"0; i<H<MHMJT@; i%%)
hashta()i* " A?>>;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78E
do {
7etword(num); 7etword(def);
if ((np"loo,up(num))""A?>>)
printf("Aew name\n");
else
printf("Sld definitionP #s\n",
np6>def);
install(num,def);
while (');

17.4. C&mpuri
,n cmp se define#te ca fiind o mul+ime de bi+i consecuti1i dintr2
un cu1nt sau ntreg. 6dic din moti1e de economie a spa+iului de
memorie* este util mpac"etarea unor obiecte ntr2un singur cu1nt
ma#in. ,n ca3 frec1ent de acest tip este utili3area unui set de flaguri*
fiecare pe un bit* pentru tabela de simboluri a unui compilator.
Fiecare simbol dintr2un program are anumite informa+ii asociate
lui* cum snt de e-emplu* clasa de memorie* tipul* dac este sau nu
cu1nt c"eie #.a.m.d. Cel mai compact mod de a codifica aceste
informa+ii este folosirea unui set de flaguri* de cte un bit* ntr2un
singur ntreg sau caracter.
%odul cel mai u3ual pentru a face acest lucru este de a defini un
set de m#ti* fiecare masc fiind corespun3toare po3i+iei bitului m
interiorul caracterului sau cu1ntului. $e e-emplu4
#define N@WXSVE 0'
#define @;R@VA<> 0.
#define MR<RJD 0/
definesc m#tile N@WXSVE* @;R@VA<> #i MR<RJD care se refer la
bi+ii 0* 7 #i respecti1 8 din caracter sau cu1nt. 6tunci accesarea
acestor bi+i se reali3ea3 cu ajutorul opera+iilor de deplasare* mascare
#i complementare* descri#i ntr2un capitol anterior. &umerele trebuie
s fie puteri ale lui 8.
K-presii de forma4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
787
fla7s H " @;R@VA<> H MR<RJD;
apar frec1ent #i ele setea3 bi+ii 7 #i 8 din caracterul sau ntregul
fla7s 9n e-emplul nostru<
n timp ce e-presia4
fla7s $" (@;R@VA<> H MR<RJD);
selectea3 bi+ii 7 #i 8 din flags.
K-presia4
if (fla7s $ (@;R@VA<> H MR<RJD)) ...
este ade1rat cnd cel pu+in unul din bi+ii 7 sau 8 din flags este unu.
K-presia4
if (&(fla7s $ (@;R@VA<> H MR<RJD))) ...
este ade1rat cnd bi+ii 7 #i 8 din flags snt ambii 3ero.
Limbajul C ofer aceste e-presii* ca o alternati1* pentru
posibilitatea de a defini #i de a accesa bi+ii dintr2un cu1nt* n mod
direct* folosind operatorii logici pe bi+i.
:inta-a defini+iei cmpului #i a accesului la el se ba3ea3 pe
structuri. $e e-emplu construc+iile #define din e-emplul de mai
sus pot fi nlocuite prin definirea a trei cmpuri4
struct {
unsi7ned isU,e9wordP ';
unsi7ned isUe8ternalP';
unsi7ned isUstaticP ';
fla7s;
6ceast construc+ie define#te 1ariabila fla7s care con+ine ?
cmpuri* fiecare de cte un bit. &umrul care urmea3 dup aPa
repre3int lungimea cmpului n bi+i. Cmpurile snt declarate
unsi7ned pentru a sublinia c ele snt cantit+i fr semn. 0entru a
ne referi la un cmp indi1idual din 1ariabila fla7s folosim o nota+ie
similar cu nota+ia folosit pentru membrii structurilor.
fla7s.isU,e9word
fla7s.isUstatic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78G
Cmpurile se comport ca ni#te ntregi mici fr semn #i pot
participa n e-presii aritmetice ca orice al+i ntregi. 6stfel* e-presiile
anterioare pot fi scrise mai natural sub forma urmtoare4
fla7s.isUe8tern " fla7s.isUstatic " ';
pentru setarea bi+ilor 7 #i 8 din 1ariabila fla7s*
fla7s.isUe8tern " fla7s.isUstatic " 0;
pentru #tergerea bi+ilor* iar4
if (fla7s.isUe8tern""0 $$
fla7s.isUstatic""0)
pentru testarea lor.
,n cmp nu trebuie s dep#easc limitele unui cu1nt. @n ca3
contrar* cmpul se alinia3 la limita urmtorului cu1nt. Cmpurile nu
necesit s fie denumite. ,n cmp fr nume* descris numai prin
caracterul aPa #i lungimea lui n bi+i este folosit pentru a re3er1a
spa+iu n 1ederea alinierii urmtorului cmp. Lungimea 3ero a unui
cmp poate fi folosit pentru for+area alinierii urmtorului cmp la
limita unui nou cu1nt* el fiind presupus a con+ine tot cmpuri #i nu
un membru obi#nuit al structuri* deoarece n acest ultim ca3* alinierea
se face n mod automat. &ici un cmp nu poate fi mai lung dect un
cu1nt. Cmpurile se atribuie de la dreapta la stnga.
Cmpurile nu pot constitui masi1e* nu au adrese* astfel nct
operatorul '$' nu se poate aplica asupra lor.
17.5. ;euniuni
D reuniune este o 1ariabil care poate con+ine* la momente
diferite* obiecte de diferite tipuri #i dimensiuni; compilatorul este cel
care +ine e1iden+a dimensiunilor #i aliniamentului.
Reuniunile ofer posibilitatea ca mai multe tipuri diferite de date
s fie tratate ntr2o singur 3on de memorie* fr a folosi n program
1reo informa+ie dependent de ma#in.
: relum e-emplul tabelei de simboluri a unui compilator*
presupunnd c constantele pot fi de tip int* float sau #iruri de
caractere.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
78H
Caloarea unei constante particulare trebuie memorat ntr2o
1ariabil de tip corespun3tor* cu toate c este mai con1enabil* pentru
gestiunea tabelei de simboluri* ca 1aloarea s fie memorat n aceea#i
3on de memorie* indiferent de tipul ei #i s ocupe aceea#i cantitate
de memorie. 6cesta este scopul unei reuniuni4 de a furni3a o singur
1ariabil care s poat con+ine oricare dintre 1alorile unor tipuri de
date. Ca #i n ca3ul cmpurilor* sinta-a defini+iei #i accesului la o
reuniune se ba3ea3 pe structuri. Fie defini+ia4
union uUta7. { int i-al;
float f-al;
char +p-al;
u-al;
Cariabila u-al 1a fi suficient de mare ca s poat pstra pe cea
mai mare dintre cele trei tipuri de componente. Dricare dintre tipurile
de mai sus poate fi atribuit 1ariabilei u-al #i apoi folosit n e-presii
n mod corespun3tor* adic tipul n u-al este tipul ultim atribuit.
,tili3atorul este cel care +ine e1iden+a tipului curent memorat ntr2o
reuniune.
:intactic* membrii unei reuniuni snt accesibili printr2o
construc+ie de forma4
nume-reuniune. membru
sau
pointer-la-reuniune6>membru
$ac 1ariabila ut9pe este utili3at pentru a +ine e1iden+a tipului
curent memorat n u-al* atunci fie urmtorul cod4
if (ut9pe""JAR)
printf ("#d\n",u-al.i-al);
else if (ut9pe"" =>S<R)
printf("#f\n",u-al.f-al);
else if (ut9pe""MRVJAY)
printf("#s\n",u-al.p-al);
else
printf("tip incorect #d in ut9pe\n",
ut9pe);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?0
Reuniunile pot aprea n structuri #i masi1e #i in1ers. :inta-a
pentru accesarea unui membru al unei reuniuni* dintr2o structur* sau
in1ers este identic cu cea pentru structurile imbricate. 0e e-emplu*
n masi1ul de structuri s9mta()AMWB* definit de4
struct {
char + name;
int fla7s;
int ut9pe;
union {
int i-al;
float f-al;
char +p-al;
u-al;
s9mta()AMWB*;
1ariabila i-al se refer prin4
s9mta()i*.u-al.i-al
iar primul caracter al #irului pointat de p-al prin4
+s9mta()i*.u-al.p-al
$e fapt* o reuniune este o structur n care to+i membrii au
deplasamentul 3ero* structura fiind suficient de mare pentru a putea
pstra pe cel mai mare membru. 6linierea este corespun3toare
pentru toate tipurile reuniunii. Ca #i la structuri* singurele opera+ii
permise cu reuniuni snt accesul la un membru al reuniunii #i
considerarea adresei ei.
Reuniunile nu pot fi atribuite* transmise la func+ii sau returnate
de ctre acestea. 0ointerii la reuniuni pot fi folosi+i n mod similar cu
pointerii la structuri.
17.6. 8eclaraii de structuri> reuniuni i c&mpuri
$eoarece specificatorii de structuri* reuniuni #i cmpuri au
aceea#i form 1om pre3enta sinta-a lor general n acest paragraf.
&pecificator-structur-sau-reuniune4
struct-sau-union { lista-declaraiilor
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?7
struct-sau-union identificator { lista-declaraiilor
struct-sau-union identificator
&truct-sau-union4
struct
union
Lista2declara+iilor este o sec1en+ de declara+ii pentru membrii
structurii sau reuniunii.
!ista-declaraiilor4
declaraie-structur
declaraie-structur, lista-declaraiilor
(eclaraie-structur4
specificator-tip, lista-declarator;
!ista-declarator4
declarator-structur
declarator-structur, lista-declarator
@n mod obi#nuit* un declarator2structur este c"iar un declarator
pentru un membru al structurii sau reuniunii. ,n membru al structurii
poate fi constituit dintr2un numr specificat de bi+i* ca3 n care a1em
de2a face cu un cmp. Lungimea lui se separ de nume prin caracterul
aPa 6tunci4
(eclarator-structur4
declarator
declarator P expresie-constant
P expresie-constant
@ntr2o structur fiecare membru care nu este un cmp ncepe la o
adres corespun3toare tipului su. 6stfel ntr2o structur pot e-ista
3one fr nume neutili3ate* re3ultate din moti1e de aliniere.
Limbajul C nu introduce restric+ii pri1ind tipurile obiectelor care
pot fi declarate cmpuri.
,n specificator2structur2sau2reuniune de forma a doua declar
un identificator ca fiind etic"eta 9marcajul< structurii sau reuniunii.
6tunci o declara+ie ulterioar poate folosi forma a treia a unui
specificator2structur2sau2reuniune.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?8
Ktic"etele de structuri permit definirea structurilor auto2referite;
de asemenea permit ca partea de declara+ie a corpului structurii s fie
dat o singur dat #i folosit de mai multe ori. Kste inter3is
declararea recursi1 a unei structuri sau reuniuni* dar o structur sau
o reuniune poate con+ine un pointer la ea.
$ou structuri pot partaja o sec1en+ ini+ial comun de membri;
adic acela#i membru poate aprea n dou structuri diferite dac el
are acela#i tip n ambele structuri #i dac to+i membri preceden+i lui
snt identici n cele dou structuri.
17.17. Typedef
Limbajul C ofer o facilitate numit t)pedef pentru a crea noi
nume de tipuri de date. :pecificatorul de tip t)pedef2nume are
sinta-a4
typedef-nume4
declarator
@ntr2o declara+ie implicnd t9pedef fiecare identificator care
apare ca parte a unui declarator de1ine sintactic ec"i1alent cu
cu1ntul c"eie re3er1at pentru tipul asociat cu identificatorul. $e
e-emplu* declara+ia4
t9pedef int >@AYRH;
l face pe >@AYRH sinonim cu int. /ipul >@AYRH poate fi folosit
ulterior n declara+ii n acela#i mod ca #i tipul int.
>@AYRH len, ma8len;
>@AYRH +len7th)*;
@n mod similar* declara+ia4
t9pedef char +MRVJAY;
l face pe MRVJAY sinonim cu char+* adic pointer la caracter* care
apoi poate fi utili3at n declara+ii de tipul4
MRVJAY p, lineptr)>JA@M*, alloc();
:e obser1 c tipul care se declar prin t9pedef apare pe
po3i+ia numelui de 1ariabil nu imediat dup cu1ntul re3er1at
t9pedef. :intactic t9pedef este sinonim cu clasele de memorie
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7??
e8tern* static etc* dar nu re3er1 memorie pentru 1ariabilele
respecti1e.
Ca un e-emplu mai complicat s relum declara+ia unui nod al
unui arbore* de data aceasta folosind t9pedef pentru a crea un nou
nume pentru un tip structur 91e3i sec+iunea 70.B<.
t9pedef struct tnode {
char +word; =W pointer la te-t W=
int count; =W numr apari+ii W=
struct tnode +left; =W descendent stng W=
struct tnode +ri7ht; =W descendent drept W=
RV@@ASE@, +RV@@ZRV;
6ceast declara+ie creea3 dou nume noi de tipuri* numite
RV@@ASE@* care este o structur #i RV@@ZRV* care este un pointer la
o structur. 6tunci rutina talloc poate fi scris sub forma4
RV@@ZRV talloc() {
char +alloc();
return (RV@@ZRV)alloc(si:eof(RV@@ASE@)));

/rebuie subliniat faptul c declara+ia t9pedef nu creea3 noi


tipuri n nici un ca3; ea adaug doar sinonime pentru anumite tipuri
de date* deja e-istente. Cariabilele declarate n acest fel au e-act
acelea#i propriet+i ca #i cele declarate e-plicit. $e fapt* t9pedef se
aseamn cu #define* cu e-cep+ia faptului c n timp ce #define
este tratat de preprocesor* t9pedef este tratat de ctre compilator.
$e e-emplu4
t9pedef int(+Z=J)();
creea3 numele Z=J pentru pointer la o funcie care returneaz un
ntre* tip care poate fi folosit ulterior ntr2un conte-t de tipul4
Z=J strcmp, numcmp, swap;
n programul de sortare din capitolul H.
K-ist dou moti1e principale care impun folosirea declara+iilor
t9pedef. 0rimul este legat de problemele de portabilitate. Cnd se
folosesc declara+ii t9pedef pentru tipuri de date care snt
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?A
dependente de ma#in* atunci pentru o compilare pe un alt sistem de
calcul este necesar modificarea doar a acestor declara+ii nu #i a
datelor din program.
6l doilea const n faptul c prin crearea de noi nume de tipuri se
ofer posibilitatea folosirii unor nume mai sugesti1e n program* deci
o mai rapid n+elegere a programului.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?B
11. Intrri ? ieiri
@ntruct limbajul C nu a fost de31oltat pentru un sistem particular
de operare #i datorit faptului c s2a dorit reali3area unei portabilit+i
ct mai mari* att a unui compilator C* ct #i a programelor scrise n
acest limbaj* el nu posed facilit+i de intrare = ie#ire.
K-ist totu#i un sistem de intrare = ie#ire 9sistemul ;=D< constituit
dintr2un numr de subprograme care reali3ea3 func+ii de intrare =
ie#ire pentru programe scrise n C* dar care nu fac parte din limbajul
C. 6ceste subprograme se gsesc n biblioteca C.
:copul acestui capitol este de a descrie cele mai utili3ate
subprograme de intrare = ie#ire #i interfa+a lor cu programele scrise n
limbajul C.
11.1. Intrri i ieiri standard= #iiere
:istemul ;=D ofer utili3atorului trei Sfi#iereS standard de lucru.
Cu1ntul fi#ier a fost pus ntre g"ilimele* deoarece limbajul nu
define#te acest tip de dat #i pentru c fi#ierele repre3int mai
degrab ni#te flu-uri de intrare = ie#ire standard puse la dispo3i+ia
utili3atorului. 6ceste fi#iere snt4
5 fi#ierul standard de intrare 9stdin<;
5 fi#ierul standard de ie#ire 9stdout<;
5 fi#ierul standard de afi#are a mesajelor 9stderr<.
/oate aceste trei fi#iere snt sec1en+iale #i n momentul e-ecu+iei
unui program C snt implicit definite #i desc"ise.
stdin #i stdout snt asociate n mod normal terminalului de
la care a fost lansat programul n e-ecu+ie. :istemul ;=D permite
redirectarea acestor fi#iere pe alte periferice sau nc"iderea lor dup
lansarea programului. Redirectarea fi#ierului stdin se specific prin
construc+ia4
<specificator-fiier
n linia de comand prin care a fost lansat programul.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?E
Redirectarea fi#ierului stdout se specific prin construc+ia4
>specificator-fiier
n linia de comand prin care a fost lansat programul.
Redirectarea fi#ierului stdout pe un alt periferic* n scopul
efecturii unei opera+ii de adugare 9append< se specific prin
construc+ia 4
>>specificator-fiier
stderr este ntotdeauna asociat terminalului de la care a fost
lansat programul n e-ecu+ie #i nu poate fi redirectat.
0entru a se putea face o referire la aceste fi#iere orice program C
trebuie s con+in fi#ierul stdio.h* care se include printr2o linie de
forma4
#include <stdio.h>
dac acest fi#ier se afl n biblioteca standard.
0entru claritatea #i li3ibilitatea programelor scrise n C* ct #i
pentru crearea unei imagini sugesti1e asupra lucrului cu fi#iere* n
fi#ierul de defini+ii standard stdio.h s2a definit un nou nume de tip
de dat #i anume =J>@ care este o structur. 0entru a referi un fi#ier*
este necesar o declara+ie de forma4
=J>@ +fp;
unde fp 1a fi numele de dat cu care se 1a referi fi#ierul n orice
opera+ie de intrare = ie#ire asociat. ;at cte1a informa+ii pstrate de
structura =J>@4
5 un identificator de fi#ier pe care sistemul de operare l asocia3
flu-ului pe durata prelucrrii; acesta poate fi aflat cu ajutorul func+iei
fileno;
5 adresele 3onelor tampon asociate; po3i+ia curent n aceste 3one;
5 indicatorii de sfr#it de fi#ier #i de eroare;
5 alte informa+ii.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?7
11.2. :ccesul la #iiere= desc%idere i &nc%idere
&ume
fopen 2 desc"ide un flu-
$eclara+ie
=J>@ +fopen(const char +path,
const char +mode);
$escriere
Func+ia fopen desc"ide fi#ierul al crui nume este un #ir indicat
de path #i i asocia3 un flu-.
6rgumentul mode indic un #ir care ncepe cu una din sec1en+ele
urmtoare4
r desc"ide un fi#ier pentru citire;
r+ desc"ide pentru citire #i scriere;
w trunc"ia3 fi#ierul la lungime 3ero sau creea3 un fi#ier pentru
scriere;
w+ desc"ide pentru adugare la sfr#it* n citire #i scriere; fi#ierul este
creat dac nu e-ist* altfel este trunc"iat;
a desc"ide pentru adugare la sfr#it* n scriere; fi#ierul este creat
dac nu e-ist;
a+ desc"ide pentru adugare la sfr#it* n citire #i scriere; fi#ierul este
creat dac nu e-ist;
$up desc"idere* n primele patru ca3uri indicatorul po3i+iei n
flu- este la nceputul fi#ierului* n ultimele dou la sfr#itul acestuia.
birul mode include de asemenea litera b 9desc"ide un fi#ier
binar< sau t 9desc"ide un fi#ier te-t< fie pe ultima po3i+ie fie pe cea
din mijloc.
Dpera+iile de citire #i scriere pot alterna n ca3ul flu-urilor read =
'rite n orice ordine. : re+inem c standardul 6&:; C cere s e-iste
o func+ie de po3i+ionare ntre o opera+ie de intrare #i una de ie#ire* sau
ntre o opera+ie de ie#ire #i una de intrare* cu e-cep+ia ca3ului cnd o
opera+ie de citire detectea3 sfr#itul de fi#ier. 6ceast opera+ie poate
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?G
fi inefecti1 2 cum ar fi fsee,(flu8, 0>, M@@NUD?V) apelat
cu scop de sincroni3are.
Calori returnate
@n ca3 de succes se returnea3 un pointer de tip =J>@. @n ca3 de
eroare se returnea3 A?>> #i 1ariabila global errno indic codul
erorii.
&ume
fclose 2 nc"ide un flu-
$eclara+ie
int fclose( =J>@ +flu8);
$escriere
Func+ia fclose nc"ide fi#ierul asociat flu-ului flu8. $ac
flu8 a fost desc"is pentru ie#ire* orice date aflate n 3one tampon
snt scrise n fi#ier n prealabil cu un apel fflush.
Calori returnate
@n ca3 de succes se returnea3 0. @n ca3 de eroare se returnea3
@S= #i 1ariabila global errno indic codul erorii.
&ume
tmpfile 2 creea3 un fi#ier temporar
$eclara+ie
=J>@ +tmpfile();
$escriere
Func+ia tmpfile generea3 un nume unic de fi#ier temporar.
6cesta este desc"is n mod binar pentru scriere = citire 9"wb+"<.
Fi#ierul 1a fi #ters automat la nc"idere sau la terminarea
programului.
Caloare returnat
Func+ia returnea3 un descriptor de flu- n ca3 de succes* sau
A?>> dac nu poate fi generat un nume unic de fi#ier sau dac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7?H
fi#ierul nu poate fi desc"is. @n ca3 de eroare 1ariabila global errno
indic codul erorii.
&ume
fflush 2 for+ea3 scrierea n flu-
$eclara+ie
int fflush(=J>@ +flu8);
$escriere
Func+ia fflush for+ea3 o scriere a tuturor datelor aflate n 3one
tampon ale flu-ului flu8. Flu-ul rmne desc"is.
Calori returnate
@n ca3 de succes se returnea3 0. @n ca3 de eroare se returnea3
@S= #i 1ariabila global errno indic codul erorii.
&ume
fseek* ftell* rewind 2 repo3i+ionea3 un flu-
$eclara+ie
int fsee,(=J>@ +flu8, lon7 offset,
int reper);
lon7 ftell(=J>@ +flu8);
-oid rewind(=J>@ +flu8);
$escriere
Func+ia fsee, setea3 indicatorul de po3i+ie pentru fi#ierul
asociat flu-ului flu8. &oua po3i+ie* dat n octe+i* se ob+ine adunnd
offset octe+i la po3i+ia specificat de reper. $ac reper este
M@@NUM@R* M@@NUD?V* sau M@@NU@AE* offset este relati1 la
nceputul fi#ierului* po3i+ia curent a indicatorului* respecti1 sfr#itul
fi#ierului. Func+ia fsee, #terge indicatorul de sfr#it de fi#ier.
Func+ia ftell ob+ine 1aloarea curent a indicatorului de po3i+ie
pentru fi#ierul asociat flu-ului flu8.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A0
Func+ia rewind po3i+ionea3 indicatorul de po3i+ie pentru
fi#ierul asociat flu-ului flu8 la nceputul fi#ierului. Kste ec"i1alent
cu4
(-oid)fsee,(flu8, 0>, M@@NUM@R)
cu completarea c func+ia rewind #terge #i indicatorul de eroare al
flu-ului.
Calori returnate
Func+ia rewind nu returnea3 nici o 1aloare. @n ca3 de succes*
fsee, returnea3 0* #i ftell returnea3 offset2ul curent. @n ca3 de
eroare se returnea3 @S= #i 1ariabila global errno indic codul
erorii.
11.3. Citire i scriere #r #ormat
&ume
fgets 2 cite#te un #ir de caractere dintr2un flu- te-t
$eclara+ie
char +f7ets(char +s, int si:e, =J>@ +flu8);
$escriere
Func+ia f7ets cel mult si:e6' caractere din flu8 #i le
memorea3 n 3ona indicat de s. Citirea se opre#te la detectarea
sfr#itului de fi#ier sau ne'2line. $ac se cite#te caracterul ne'2line
acesta este memorat n s. $up ultimul caracter se memorea3 null.
6peluri ale acestei func+ii pot fi combinate cu orice apeluri ale
altor func+ii de intrare din bibliotec 9fscanf* de e-emplu< pentru
un acela#i flu- de intrare.
Calori returnate
Func+ia returnea3 adresa s n ca3 de succes* sau A?>> n ca3 de
eroare sau la ntlnirea sfr#itului de fi#ier dac nu s2a citit nici un
caracter.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A7
&ume
fputs 2 scrie un #ir de caractere ntr2un flu- te-t
$eclara+ie
int fputs(const char +s, =J>@ +flu8);
$escriere
Func+ia fputs scrie #irul s n flu- fr caracterul terminator
null.
6peluri ale acestei func+ii pot fi combinate cu orice apeluri ale
altor func+ii de ie#ire din bibliotec 9fprintf* de e-emplu< pentru
un acela#i flu- de ie#ire.
Calori returnate
Func+ia returnea3 o 1aloare non2negati1 n ca3 de succes* sau
@S= n ca3 de eroare.
&ume
fread* fwrite 2 intrri = ie#iri pentru flu-uri binare
$eclara+ie
unsi7ned fread(-oid +ptr, unsi7ned si:e,
unsi7ned nel, =J>@ +flu8);
unsi7ned fwrite(const -oid +ptr, unsi7ned
si:e, unsi7ned nel, =J>@ +flu8);
$escriere
Func+ia fread cite#te nel elemente* fiecare a1nd mrimea
si:e octe+i* din flu-ul indicat de flu8* #i le memorea3 n 3ona
indicat de ptr.
Func+ia fwrite scrie nel elemente* fiecare a1nd mrimea
si:e octe+i* din flu-ul indicat de flu8* pe care le ia din 3ona
indicat de ptr.
Calori returnate
Func+iile returnea3 numrul de elemente citite sau scrise cu
succes 9#i nu numrul de caractere<. $ac apare o eroare sau se
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A8
ntlne#te sfr#itul de fi#ier* 1aloarea returnat este mai mic dect
nel 9posibil 3ero<.
11.'. Citire cu #ormat
&ume
scanf* fscanf* sscanf 2 citire cu format
$eclara+ie
int scanf(const char +format, ...);
int fscanf(=J>@ +flu8, const char +format,
...);
int sscanf(const char +str, const char
+format, ...);
$escriere
Familia de func+ii scanf scanea3 intrarea n concordan+ cu #irul
de caractere format dup cum se descrie mai jos. 6cest format
poate con+ine specificatori de con1ersie; re3ultatele unor astfel de
con1ersii 9dac se efectuea3< se memorea3 prin intermediul
argumentelor pointer. Func+ia scanf cite#te #irul de intrare din
flu-ul standard stdin* fscanf din flu8* #i sscanf din #irul
indicat de str.
Fiecare argument pointer trebuie s corespund n ordine ca tip
cu fiecare specificator de con1ersie 9dar a se 1edea suprimarea mai
jos<. $ac argumentele nu snt suficiente comportamentul
programului este impre1i3ibil. /oate con1ersiile snt introduse de
caracterul %. birul format poate con+ine #i alte caractere. :pa+ii albe
9blanc* tab* sau ne'2line< din #irul format se potri1esc cu orice spa+iu
alb n orice numr 9inclusi1 nici unul< din #irul de intrare. Drice alte
caractere trebuie s se potri1easc e-act. :canarea se opre#te atunci
cnd un caracter din #irul de intrare nu se potri1e#te cu cel din format.
:canarea se opre#te de asemenea atunci cnd o con1ersie nu se mai
poate efectua 9a se 1edea mai jos<.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A?
Con1ersii
$up caracterul % care introduce o con1ersie poate urma un
numr de caractere indicatori* dup cum urmea34
* :uprim atribuirea. Con1ersia care urmea3 se face n mod
obi#nuit* dar nu se folose#te nici un argument pointer; re3ultatul
con1ersiei este pur #i simplu abandonat.
h Con1ersia este de tip dioux sau n #i argumentul asociat este un
pointer la short 9n loc de int<.
l Con1ersia este de tip dioux sau n #i argumentul asociat este un
pointer la lon7 9n loc de int<* sau con1ersia este de tip efg #i
argumentul asociat este un pointer la dou(le 9n loc de
float<.
L Con1ersia este de tip efg #i argumentul asociat este un pointer la
lon7 dou(le.
@n completare la ace#ti indicatori poate e-ista o mrime w
ma-im op+ional pentru cmp* e-primat ca un ntreg 3ecimal* ntre
caracterul % #i cel de con1ersie* #i naintea indicatorului. $ac nu este
dat o mrime ma-im se folose#te mrimea implicit infinit 9cu o
e-cep+ie la con1ersia de tip c<; n ca3 contrar se scanea3 cel mult un
numr de w caractere n timpul con1ersiei. @nainte de a ncepe o
con1ersie* majoritatea con1ersiilor ignor spa+iile albe; acestea nu
snt contori3ate n mrimea cmpului.
:nt disponibile urmtoarele con1ersii4
% 0otri1ire cu un caracter %. Cu alte cu1inte* %% n #irul format
trebuie s se potri1easc cu un caracter %. &u se efectuea3 nici o
con1ersie #i nici o atribuire.
d 0otri1ire cu un ntreg 3ecimal 9e1entual cu semn<; argumentul
asociat trebuie s fie un pointer la int.
i 0otri1ire cu un ntreg 9e1entual cu semn<; argumentul asociat
trebuie s fie un pointer la int. Caloarea ntreag este citit n
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7AA
ba3a 7E dac ncepe cu 08 sau 0;* n ba3a G dac ncepe cu 0* #i
n ba3a 70 n ca3 contrar. :nt folosite numai caracterele care
corespund ba3ei respecti1e.
o 0otri1ire cu un ntreg octal fr semn; argumentul asociat trebuie
s fie un pointer la unsi7ned.
u 0otri1ire cu un ntreg 3ecimal fr semn; argumentul asociat
trebuie s fie un pointer la unsi7ned.
x 0otri1ire cu un ntreg "e-a3ecimal fr semn; argumentul asociat
trebuie s fie un pointer la unsi7ned.
f 0otri1ire cu un numr n 1irgul mobil 9e1entual cu semn<;
argumentul asociat trebuie s fie un pointer la float.
e*g Kc"i1alent cu f.
s 0otri1ire cu o sec1en+ de caractere diferite de spa+iu alb;
argumentul asociat trebuie s fie un pointer la char* #i 3ona
trebuie s fie suficient de mare pentru a putea primi toat
sec1en+a #i caracterul terminator null. birul de intrare se termin
la un spa+iu alb sau la atingerea mrimii ma-ime a cmpului
9prima condi+ie ntlnit<.
c 0otri1ire cu o sec1en+ de caractere de mrime w 9dac aceasta
este specificat; prin lips se ia w=7<; argumentul asociat trebuie
s fie un pointer la char* #i 3ona trebuie s fie suficient de mare
pentru a putea primi toat sec1en+a 9nu se adaug terminator
null<. &u se ignor ca de obicei spa+iile albe din fa+. 0entru a
ignora mai nti spa+iile albe se indic un spa+iu e-plicit n format.
[ 0otri1ire cu o sec1en+ ne1id de caractere din setul specificat de
caractere acceptate; argumentul asociat trebuie s fie un pointer
la char* #i 3ona trebuie s fie suficient de mare pentru a putea
primi toat sec1en+a #i caracterul terminator null. &u se ignor ca
de obicei spa+iile albe din fa+. birul de intrare 1a fi format din
caractere aflate n 9sau care nu se afl n< setul specificat n
format; setul este definit de caracterele aflate ntre [ #i . :etul
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7AB
e-clude acele caractere dac primul caracter dup [ este !.
0entru a include caracterul n set* acesta trebuie s fie primul
caracter dup [ sau !; caracterul aflat n orice alt po3i+ie
nc"ide setul. Caracterul " are #i el un rol special4 plasat ntre
dou alte caractere adaug toate celelalte caractere aflate n
inter1alul respecti1 la set. 0entru a include caracterul " acesta
trebuie s fie ultimul caracter nainte de . $e e-emplu* "#
)L*0646*" semnific setul orice caracter cu excepia * #
pn la $* i ". birul se termin la apari+ia unui caracter care nu
se afl 9sau* dac se preci3ea3 !* care se afl< n set sau dac se
atinge mrimea ma-im specificat.
p 0otri1ire cu o 1aloare pointer 9a#a cum se afi#ea3 cu %p n
printf<; argumentul asociat trebuie s fie un pointer la pointer.
n &u se prelucrea3 nimic din #irul de intrare; n sc"imb* numrul
de caractere consumate pn la acest punct din #irul de intrare
este memorat la argumentul asociat* care trebuie s fie un pointer
la int.
Calori returnate
Func+iile returnea3 numrul de 1alori atribuite* care poate fi mai
mic dect numrul de argumente pointer* sau c"iar 3ero* n ca3ul n
care apar nepotri1iri ntre format #i #irul de intrare. Qero indic faptul
c* c"iar dac a1em un #ir de intrare disponibil* nu s2a efectuat nici o
con1ersie 9#i atribuire<; aceast situa+ie apare atunci cnd un caracter
din #irul de intrare este in1alid* cum ar fi un caracter alfabetic pentru
o con1ersie %d. Caloarea @S= este returnat dac apare un eroare
nainte de prima con1ersie* cum ar fi detectarea sfr#itului de fi#ier.
$ac o eroare sau un sfr#it de fi#ier apare dup ce o con1ersie a
nceput* se returnea3 numrul de con1ersii efectuate cu succes.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7AE
11.). ,criere cu #ormat
&ume
printf* fprintf* sprintf 2 scriere cu format
$eclara+ie
int printf(const char +format, ...);
int fprintf(=J>@ +flu8, const char
+format, ...);
int sprintf(char +str, const char +format,
...);
$escriere
Func+iile din familia printf generea3 o ie#ire n concordan+ cu
format dup cum se descrie mai jos. Func+ia printf afi#ea3 ie#irea
la flu-ul standard stdout; fprintf scrie ie#irea la flu8;
sprintf scrie ie#irea n #irul de caractere str.
6ceste func+ii generea3 ie#irea sub controlul #irului format care
specific cum se con1ertesc argumentele pentru ie#ire.
birul de formatare
birul format este un #ir de caractere* printre care se pot afla 3ero
sau mai multe directi1e4 caractere obi#nuite 9diferite de %< care snt
copiate a#a cum snt n flu-ul de ie#ire* #i specifica+ii de con1ersie*
fiecare dintre ele re3ultnd din ncrcarea a 3ero sau mai multe
argumente. Fiecare specifica+ie de con1ersie este introdus de
caracterul % #i se termin cu un specificator de con1ersie. @ntre
acestea pot fi 9n aceast ordine< 3ero sau mai mul+i indicatori* o
mrime minim a cmpului op+ional* o preci3ie op+ional #i un
modificator op+ional de lungime.
6rgumentele trebuie s corespund n ordine cu specificatorii de
con1ersie. 6cestea snt folosite n ordinea dat* unde fiecare caracter
* #i fiecare specificator de con1ersie solicit urmtorul argument.
$ac argumentele nu snt suficiente comportamentul programului
este impre1i3ibil.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7A7
Caractere indicatori
Caracterul % este urmat de 3ero* unul sau mai mul+i indicatori4
% Caloarea numeric se con1erte#te n format alternati1. 0entru
con1ersii de tip o* primul caracter al #irului de ie#ire este 3ero
9prin prefi-are cu 0 dac 1aloarea nu este 3ero<. 0entru con1ersii
de tip x #i &* o 1aloare nenul este prefi-at cu 08 9sau 0;
pentru con1ersii de tip &<. 0entru con1ersii de tip e* '* f* (* g #i
)* re3ultatul 1a con+ine ntotdeauna punctul 3ecimal* c"iar dac
nu apare partea frac+ionar 9n mod normal punctul 3ecimal apare
n aceste con1ersii numai dac e-ist #i partea frac+ionar<.
0entru con1ersii de tip g #i ) 3erourile finale nu snt eliminate
a#a cum se procedea3 n mod normal. 0entru alte con1ersii
re3ultatul este nedefinit.
# Caloarea numeric este con1ertit cu 3erouri la stnga. 0entru
con1ersii de tip d* i* o* u* x* &* e* '* f* (* g #i )* 1aloarea
con1ertit este completat cu 3erouri la stnga n loc de blanc.
$ac apar indicatorii # #i " mpreun* indicatorul # este ignorat.
$ac pentru o con1ersie numeric 9d* i* o* u* x* &< este dat o
preci3ie* indicatorul # este ignorat. 0entru alte con1ersii
re3ultatul este nedefinit.
" Caloarea con1ertit este aliniat la stnga 9implicit alinierea se
face la dreapta<. Cu e-cep+ia con1ersiilor de tip n* 1aloarea
con1ertit este completat la dreapta cu blanc* n loc s fie
completat la stnga cu blanc sau 3ero. $ac apar indicatorii # #i
" mpreun* indicatorul # este ignorat.
&p 9spa+iu< @n ca3ul unui re3ultat al unei con1ersii cu semn* naintea
unui numr po3iti1 sau #ir 1id se pune un blanc.
+ :emnul 9% sau 6< este plasat naintea numrului generat de o
con1ersie cu semn. ;mplicit semnul este folosit numai pentru
numere negati1e. $ac apar indicatorii + #i &p mpreun*
indicatorul &p este ignorat.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7AG
L+imea cmpului
,n #ir de cifre 3ecimale 9cu prima cifr nenul< specific o l+ime
minim pentru cmp. $ac 1aloarea con1ertit are mai pu+ine
caractere dect l+imea specificat* 1a fi completat cu spa+ii la stnga
9sau dreapta* dac s2a specificat aliniere la stnga<. @n locul unui
numr 3ecimal se poate folosi + pentru a specifica faptul c l+imea
cmpului este dat de argumentul urmtor* care trebuie s fie de tip
int. D 1aloare negati1 pentru l+ime este considerat un indicator "
urmat de o 1aloare po3iti1 pentru l+ime. @n nici un ca3 nu se 1a
trunc"ia cmpul; dac re3ultatul con1ersiei este mai mare dect
l+imea cmpului* cmpul este e-pandat pentru a con+ine re3ultatul
con1ersiei.
0reci3ia
0reci3ia 9op+ional< este dat de caracterul . urmat de un #ir de
cifre 3ecimale. @n locul #irului de cifre 3ecimale se poate scrie *
pentru a specifica faptul c preci3ia este dat de argumentul urmtor*
care trebuie s fie de tip int. $ac preci3ia este dat doar de .* sau
dac preci3ia este negati1* atunci aceasta se consider 3ero. 0reci3ia
d numrul minim de cifre care apar pentru con1ersii de tip d* i* o*
u* x* &* numrul de cifre care apar dup punctul 3ecimal pentru
con1ersii de tip e* '* f* (* numrul ma-im de cifre semnificati1e
pentru con1ersii de tip g #i )* sau numrul ma-im de caractere
generate pentru con1ersii de tip s.
%odificator de lungime
@n acest ca3 prin con1ersie ntreag n+elegem con1ersie de tip d*
i* o* u* x* &.
h Con1ersia ntreag care urmea3 corespunde unui argument
short sau unsi7ned short* sau urmtoarea con1ersie de tip
n corespunde unui argument de tip pointer la short.
l Con1ersia ntreag care urmea3 corespunde unui argument
lon7 sau unsi7ned lon7* sau urmtoarea con1ersie de tip n
corespunde unui argument de tip pointer la lon7.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7AH
L ,rmtoarea con1ersie de tip e* '* f* g sau ) corespunde unui
argument lon7 dou(le.
:pecificator de con1ersie
,n caracter care specific tipul con1ersiei care se 1a face.
:pecificatorii de con1ersie #i semnifica+ia lor snt4
d*i
6rgumentul de tip int este con1ertit la nota+ia 3ecimal cu
semn. 0reci3ia* dac este dat* d numrul minim de cifre care
trebuie s apar; dac 1aloarea con1ertit necesit mai pu+ine
cifre* aceasta este completat la stnga cu 3erouri. 0reci3ia
implicit este 7. $ac 1aloarea 0 este afi#at cu preci3ie e-plicit
0* ie#irea este 1id.
o*u*x*&
6rgumentul de tip unsi7ned este con1ertit la nota+ie octal
fr semn 9o<* 3ecimal fr semn 9u<* sau "e-a3ecimal fr
semn 9x #i &<. Literele a(cdef se folosesc pentru con1ersii de
tip x; literele <CDE@= pentru con1ersii de tip &. 0reci3ia* dac
este dat* d numrul minim de cifre care trebuie s apar; dac
1aloarea con1ertit necesit mai pu+ine cifre* aceasta este
completat la stnga cu 3erouri. 0reci3ia implicit este 7. $ac
1aloarea 0 este afi#at cu preci3ie e-plicit 0* ie#irea este 1id.
e*'
6rgumentul de tip flotant este rotunjit #i con1ertit n stil
Y6[d.dddefdd unde a1em o cifr nainte de punctul 3ecimal #i
numrul de cifre dup acesta este egal cu preci3ia; dac aceasta
lipse#te se consider E; dac preci3ia este 3ero* punctul 3ecimal
nu apare. D con1ersie de tip ' folose#te litera @ 9n loc de e<
pentru a introduce e-ponentul. K-ponentul are ntotdeauna cel
pu+in dou cifre; dac 1aloarea este 3ero* e-ponentul este 00.
f*(
6rgumentul de tip flotant este rotunjit #i con1ertit n nota+ie
3ecimal n stil Y6[ddd.ddd* unde numrul de cifre dup punctul
3ecimal este egal cu preci3ia specificat. $ac preci3ia lipse#te se
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B0
consider E; dac preci3ia este e-plicit 3ero* punctul 3ecimal nu
apare. $ac punctul 3ecimal apare* cel pu+in o cifr apare
naintea acestuia.
g*)
6rgumentul de tip flotant este con1ertit n stil f sau e 9sau '
pentru con1ersii de tip )<. 0reci3ia specific numrul de cifre
semnificati1e. $ac preci3ia lipse#te se consider E; dac preci3ia
este 3ero se consider 7. :tilul e este folosit dac e-ponentul
re3ultat n urma con1ersiei este mai mic dect A ori mai mare
sau egal cu preci3ia. Qerourile finale snt eliminate din partea
frac+ionar a re3ultatului; punctul 3ecimal apare numai dac este
urmat de cel pu+in o cifr.
c 6rgumentul de tip int este con1ertit la unsi7ned char #i se
scrie caracterul re3ultat.
s 6rgumentul de tip const char + este un pointer la un #ir de
caractere. Caracterele din #ir snt scrise pn la 9fr a include<
caracterul terminator null; dac preci3ia este specificat* nu se
scrie un numr mai mare dect cel specificat. $ac preci3ia este
dat* nu e ne1oie de caracterul null; dac preci3ia nu este
specificat* sau dac este mai mare dect mrimea #irului* #irul
trebuie s con+in un caracter terminator null.
p 6rgumentul de tip pointer este scris n "e-a3ecimal; formatul este
specific sistemului de calcul.
n &umrul de caractere scrise pn n acest moment este memorat
la argumentul de tip int +. &u se face nici o con1ersie.
% :e scrie un caracter #. &u se face nici o con1ersie. :pecifica+ia
complet este %%.
Caloare returnat
Func+iile returnea3 numrul de caractere generate 9nu se include
caracterul terminator null pentru sprintf<.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B7
11.+. .ratarea erorilor
&ume
perror 2 afi#ea3 un mesaj de eroare sistem
$eclara+ie
-oid perror(const char +s);
#include <errno.h>
const char +s9sUerrlist)*;
int s9sUnerr;
$escriere
Rutina perror afi#ea3 un mesaj la ie#irea standard de eroare*
care descrie ultima eroare ntlnit la ultimul apel sistem sau func+ie
de bibliotec. %ai nti se afi#ea3 argumentul s* apoi 1irgula #i
blanc* #i n final mesajul de eroare #i ne'2line. :e recomand 9mai
ales pentru depanare< ca argumentul s s includ numele func+iei n
care a aprut eroarea. Codul erorii se ia din 1ariabila e-tern errno.
Lista global de erori s9sUerrlist)* inde-at cu errno
poate fi folosit pentru a ob+ine mesajul de eroare fr ne'2line.
,ltimul indice de mesaj din list este s9sUnerr6'. :e recomand
o aten+ie deosebit n ca3ul accesului direct la list deoarece unele
coduri noi de eroare pot lipsi din s9sUerrlist)*.
$ac un apel sistem e#uea3 1ariabila errno indic codul erorii.
6ceste 1alori pot fi gsite n <errno.h>. Func+ia perror ser1e#te
la afi#area acestui cod de eroare ntr2o form li3ibil. $ac un apel
terminat cu eroare nu este imediat urmat de un apel perror*
1aloarea 1ariabilei errno se poate pierde dac nu e sal1at.
&ume
clearerr* feof* ferror 2 1erific #i resetea3 starea
flu-ului
$eclara+ie
-oid clearerr(=J>@ +flu8);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B8
int feof(=J>@ +flu8);
int ferror(=J>@ +flu8);
int fileno( =J>@ +flu8);
$escriere
Func+ia clearerr #terge indicatorii de sfr#it de fi#ier #i eroare
ai flu-ului.
Func+ia feof testea3 indicatorul de sfr#it de fi#ier al flu-ului*
#i returnea3 non23ero dac este setat. 6cesta este setat dac o
opera+ie de citire a detectat sfr#itul de fi#ier.
Func+ia ferror testea3 indicatorul de eroare al flu-ului* #i
returnea3 non23ero dac este setat. 6cesta este setat dac o opera+ie
de citire sau scriere a detectat o eroare 9datorat de e-emplu
"ard'are2ului<.
Func+iile de citire 9cu sau fr format< nu fac distinc+ie ntre
sfr#it de fi#ier #i eroare* astfel c trebuie apelate func+iile feof #i
ferror pentru a determina cau3a.
Func+ia fileno e-aminea3 argumentul flu8 #i returnea3
descriptorul asociat de sistemul de operare acestui flu-.
:tenie@ Kste foarte frec1ent folosirea incorect a func+iei feof
pentru a testa dac s2a ajuns la sfr#itul fi#ierului. &u se recomand n
nici un ca3 acest stil de programare4
#define >MJV 50
char lin)>MJV*;
=J>@ +fi,+fo;
fi"fopen(nume-fiier-intrare,"rt");
fo"fopen(nume-fiier-ieire,"wt");
while (&feof(fi)) { =W gre#itR W=
f7ets(lin,>MJV,fi);
fputs(lin,fo);

fclose(fi); fclose(fo);
@n aceast sec1en+* dac #i ultima linie a fi#ierului te-t de intrare
este terminat cu ne'2line* aceasta 1a fi scris de dou ori n fi#ierul
de ie#ire. $e ceX $up ce se cite#te ultima linie nc nu este
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B?
po3i+ionat indicatorul de sfr#it de fi#ier* deci func+ia f7ets
returnea3 succes. La reluarea ciclului se ncearc un nou f7ets #i
abia acum se depistea3 sfr#itul de fi#ier* fapt marcat n 3ona
re3er1at flu-ului fi. 6stfel con+inutul tabloului lin rmne
nemodificat #i este scris a doua oar n fi#ierul de ie#ire. 6bia la o
nou reluare a ciclului func+ia feof ne spune c s2a depistat sfr#itul
de fi#ier.
@n acest manual snt pre3entate mai multe programe care
efectuea3 diferite prelucrri asupra unor fi#iere te-t. 0entru
simplitate toate programele presupun c nu apar erori la citire sau la
scriere.
11.4. *peraii cu directoare
Func+iile de parcurgere a cataloagelor de fi#iere descrise n
aceast sec+iune 9opendir* readdir* closedir< snt definite de
mai multe medii de programare C 9Borland* atcom* Cisual C* L&,
Linu-<* precum #i de standardul 0D:;O. 6ceste func+ii snt descrise
n <dirent.h>.
Func+iile de redenumire #i #tergere a unor fi#iere snt descrise n
<stdio.h>.
&ume
opendir 2 desc"ide un director
$eclara+ie
EJV +opendir(const char +nume);
$escriere
Func+ia opendir desc"ide un flu- pentru directorul cu numele
nume* #i returnea3 un pointer la flu-ul desc"is. Flu-ul este
po3i+ionat pe prima intrare din director.
Caloare returnat
Func+ia returnea3 un pointer la flu- n ca3 de succes* sau A?>>
n ca3 de eroare #i 1ariabila global errno indic codul erorii.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7BA
Cte1a erori posibile
@<DD@M 6cces inter3is
@ASREJV nume nu este un director
&ume
readdir 2 cite#te un director
$eclara+ie
struct dirent +readdir(EJV +dir);
$escriere
Func+ia readdir returnea3 un pointer la o structur de tip
dirent care repre3int urmtoarea intrare din directorul indicat de
flu-ul dir. Returnea3 A?>> dac s2a depistat sfr#itul de director
sau dac a aprut o eroare.
:tructura de tip dirent con+ine un cmp char dUname)*.
,tili3area altor cmpuri din structur reduce portabilitatea
programelor.
Caloare returnat
Func+ia returnea3 un pointer la o structur de tip dirent* sau
A?>> dac s2a depistat sfr#itul de director sau dac a aprut o
eroare.
&ume
closedir 2 nc"ide un director
$eclara+ie
int closedir(EJV +dir);
$escriere
Func+ia closedir nc"ide flu-ul dir.
Caloare returnat
Func+ia returnea3 0 n ca3 de succes sau @S= n ca3 de eroare.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7BB
&ume
rename 2 redenume#te un fi#ier
remove 2 #terge un fi#ier
$eclara+ie
int rename(const char +old, const char
+new);
int remo-e(const char +name);
$escriere
Func+ia rename sc"imb numele unui fi#ier din old n new.
$ac a fost preci3at un periferic n new* acesta trebuie s coincid cu
cel din old. $irectoarele din old #i new pot s fie diferite* astfel c
rename poate fi folosit pentru a muta un fi#ier dintr2un director n
altul. &u se permit specificatori generici 9'ildcards<.
Func+ia remo-e #terge fi#ierul specificat prin name.
Caloare returnat
@n ca3 de succes se returnea3 0. @n ca3 de eroare se returnea3
@S= #i 1ariabila global errno indic codul erorii.
11.5. Programe demonstrati$e
0rimele trei programe primesc ca parametri n linia de comand
numele fi#ierelor pe care le 1or prelucra. ,ltimul program prime#te
ca parametru n linia de comand numele directorului al crui
con+inut 1a fi afi#at.
7< $eterminarea mrimii unui fi#ier
#include <stdio.h>
=J>@ +f;
int main(int ac, char ++a-) {
if (ac&".) {
fputs("?n ar7ument&\n",stderr);
return ';

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7BE
f " fopen(a-)'*,"r(");
if (&f) {
perror("@roare la deschidere");
return ';

fsee,(f,0,M@@NU@AE);
fprintf(stderr,"=ile #s, si:e #ld\n",
ftell(f));
fclose(f);
return 0;

8< Copierea unui fi#ier


Func+iile f7ets #i fputs se folosesc pentru flu-uri desc"ise n
mod te-t. Cum se utili3ea3 pentru copierea unui fi#ier te-tX
#include <stdio.h>
#define >MJV 50
char lin)>MJV*;
=J>@ +fi, +fo;
int main(int ac, char ++a-) {
if (ac&"0) {
fputs("Eoua ar7umente&\n",stderr);

fi"fopen(a-)'*,"rt"); fo"fopen(a-).*,"wt");
if (&fi HH &fo) {
perror("@roare la deschidere");
return ';

while (f7ets(lin,>MJV,fi))
fputs(lin,fo);
fclose(fi); fclose(fo);
return 0;

Func+iile fread #i fwrite se folosesc pentru flu-uri desc"ise


n mod binar. Cum se utili3ea3 pentru copierea unui fi#ier binarX
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7B7
#include <stdio.h>
#define >TSA 50
char :on)>TSA*;
=J>@ +fi, +fo;
int ,;
int main(int ac, char ++a-) {
if (ac&"0) {
fputs("Eoua ar7umente&\n",stderr);
return ';

fi"fopen(a-)'*,"r(");
fo"fopen(a-).*,"w(");
if (&fi HH &fo) {
perror("@roare la deschidere");
return ';

while (,"fread(:on,',>TSA,fi))
fwrite(:on,',,,fo);
fclose(fi); fclose(fo);
return 0;

?< 0relucrarea unui fi#ier te-t


0rogramul pre3entat n continuare cite#te un fi#ier te-t care
con+ine pe fiecare linie un #ir de caractere 9fr spa+ii< #i trei 1alori
ntregi* #i afi#ea3 pe terminal numele pe 78 po3i+ii aliniat la stnga #i
media aritmetic a celor trei 1alori ntregi.
#include <stdio.h>
=J>@ +fi;
char num)'0*;
int a,(,c;
dou(le m;
int main(int ac, char ++a-) {
if (ac&".) {
fputs("?n ar7ument&\n",stderr);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7BG
return ';

fi"fopen(a-)'*,"rt");
if (&fi) {
perror("@roare la deschidere");
return ';

while (fscanf(fi,"#s #d #d #d",
num,$a,$(,$c)&"@S=) {
m"(a%(%c)F0.0;
printf("#6'.s#2..lf\n",num,m);

fclose(fi);
return 0;

A< 6fi#area con+inutului unui director


#include <dirent.h>
#include <stdio.h>
EJV +dir;
struct dirent +ent;
int main(int ac, char ++a-) {
if (ac&".) {
printf("?n parametru\n");
return ';

dir " opendir(a-)'*);
if (&dir) {
perror("@roare open dir");
return ';

while (ent"readdir(dir))
printf("#s\n",ent6>dUname);
return 0;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7BH
12. :lte rutine din biblioteca standard
@n acest capitol snt descrise func+ii care re3ol1 probleme legate
de alocarea dinamic a memoriei* sortare #i cutare* clasificare*
opera+ii cu blocuri de memorie #i #iruri de caractere* func+ii
matematice.
12.1. :locarea dinamic a memoriei
&ume
calloc* malloc* realloc 2 aloc memoria n mod
dinamic
free 2 eliberea3 memoria alocat n mod dinamic
$eclara+ie
#include <stdli(.h>
-oid +calloc(unsi7ned nel, unsi7ned si:e);
-oid +malloc(unsi7ned si:e);
-oid +realloc(-oid +ptr, unsi7ned si:e);
-oid free(-oid +ptr);
$escriere
Func+ia calloc aloc memorie pentru un tablou de nel
elemente* fiecare de mrime si:e octe+i #i returnea3 un pointer la
memoria alocat. Con+inutul memoriei este pus la 3ero.
Func+ia malloc aloc si3e octe+i #i returnea3 un pointer la
memoria alocat. Con+inutul memoriei nu este #ters.
Func+ia free eliberea3 spa+iul de memorie indicat de ptr* care
trebuie s fi fost returnat de un apel anterior malloc* calloc sau
realloc. @n ca3 contrar* sau dac a e-istat deja un apel anterior
free(ptr)* comportamentul programului este impre1i3ibil.
Func+ia realloc sc"imb mrimea blocului de memorie indicat
de ptr la si:e octe+i. Con+inutul rmne nesc"imbat la mrimea
minim dintre mrimea 1ec"e #i cea nou; noul spa+iu de memorie
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E0
care este e1entual alocat este neini+iali3at. $ac ptr este A?>>
apelul este ec"i1alent cu malloc(si:e); dac si:e este egal cu
3ero apelul este ec"i1alent cu free(ptr). Cu e-cep+ia ca3ului cnd
ptr este A?>>* acesta trebuie s fi fost returnat de un apel precedent
malloc* calloc sau realloc.
Calori returnate
0entru calloc #i malloc 1aloarea returnat este un pointer la
memoria alocat* care este aliniat n mod corespun3tor pentru orice
tip de 1ariabile* sau A?>> dac nu e-ist suficient memorie
continu.
Func+ia free nu returnea3 nimic.
Func+ia realloc returnea3 un pointer la noua 3on de
memorie alocat* care este aliniat n mod corespun3tor pentru orice
tip de 1ariabile* #i poate fi diferit de ptr* sau poate fi A?>> dac nu
e-ist suficient memorie continu sau dac 1aloarea si:e este
egal cu 0. $ac realloc e#uea3* blocul original rmne neatins 2
nu este nici eliberat nici mutat.
12.2. ,ortare i cutare
&ume
*sort 2 sortea3 un tablou
bsearch 2 cutare binar ntr2un tablou sortat
$eclara+ie
#include <stdli(.h>
-oid Isort(-oid +(ase, unsi7ned nel,
unsi7ned si:e, int (+comp)
(const -oid +, const -oid +));
-oid +(search(const -oid +,e9, const -oid
+(ase, unsi7ned nel, unsi7ned si:e, int
(+comp)(const -oid +, const -oid +));
$escriere
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E7
Func+ia Isort sortea3 un tablou de nel elemente* fiecare de
mrime si:e. 6rgumentul (ase indic spre nceputul tabloului.
Klementele tabloului snt sortate n ordine cresctoare n
concordan+ cu func+ia de comparare referit de comp* apelat cu
dou argumente care indic spre obiectele ce se compar. Func+ia de
comparare trebuie s returne3e un ntreg mai mic dect* egal cu* sau
mai mare dect 3ero dac primul argument este considerat a fi mai
mic dect* egal cu* respecti1 mai mare dect al doilea. $ac cele dou
elemente comparate snt egale* ordinea n tabloul sortat este
nedefinit.
Func+ia (search caut ntr2un tablou de nel elemente* fiecare
de mrime si:e* un membru care coincide cu obiectul indicat de
,e9. 6rgumentul (ase indic spre nceputul tabloului.
Con+inutul tabloului trebuie s fie sortat cresctor n concordan+
cu func+ia de comparare referit de comp* apelat cu dou argumente
care indic spre obiectele ce se compar. Func+ia de comparare
trebuie s returne3e un ntreg mai mic dect* egal cu* sau mai mare
dect 3ero dac primul argument este considerat a fi mai mic dect*
egal cu* respecti1 mai mare dect al doilea.
Caloare returnat
Func+ia (search returnea3 un pointer la un membru al
tabloului care coincide cu obiectul indicat de ,e9* sau A?>> dac nu
se gse#te nici un membru. $ac e-ist mai multe elemente care
coincid cu ,e9* poate fi returnat oricare element cu aceast
proprietate.
12.3. ;utine de clasi#icare
&ume
isalnum* isalpha* isascii* iscntrl* isdigit*
isgraph* islower* isprint* ispunct* isspace*
isupper* isxdigit 2 rutine de clasificare
tolower 2 con1ersie n liter mic
toupper 2 con1ersie n liter mare
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E8
$eclara+ie
#include <ct9pe.h>
int isalnum(int c); int islower(int c);
int isalpha(int c); int isprint(int c);
int isascii(int c); int ispunct(int c);
int iscntrl(int c); int isspace(int c);
int isdi7it(int c); int isupper(int c);
int is7raph(int c); int is8di7it(int c);
int tolower(int c); int toupper(int c);
$escriere
0rimele 78 func+ii 1erific dac c* care trebuie s fie o 1aloare de
tip unsi7ned char sau @S=* se afl n una din clasele de caractere
enumerate mai sus.
isalnum
Cerific dac c este alfanumeric; este ec"i1alent cu
(isalpha(c) HH isdi7it(c)).
isalpha
Cerific dac c este alfabetic; este ec"i1alent cu (isupper(c)
HH islower(c)).
isascii
Cerific dac c este o 1aloare pe 7 bi+i din setul de caractere
6:C;;.
iscntrl
Cerific dac c este un caracter de control.
isdi7it
Cerific dac c este o cifr 9ntre 0 #i H<.
is7raph
Cerific dac c este un caracter afi#abil cu e-cep+ia spa+iului.
islower
Cerific dac c este o liter mic.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E?
isprint
Cerific dac c este un caracter afi#abil inclusi1 spa+iu.
ispunct
Cerific dac c este un caracter diferit de spa+iu #i non2
alfanumeric.
isspace
Cerific dac c este un spa+iu alb.
isupper
Cerific dac c este o liter mare.
is8di7it
Cerific dac c este o cifr "e-a3ecimal din setul 0 7 8 ? A B E 7
G H a b c d e f 6 B C $ K F.
tolower
Con1erte#te caracterul c* dac este o liter* la litera mic
corespun3toare.
toupper
Con1erte#te caracterul c* dac este o liter* la litera mare
corespun3toare.
Caloare returnat
Caloarea returnat de func+iile is... este nenul dac caracterul c
se afl n clasa testat* #i 3ero n ca3 contrar.
Caloarea returnat de func+iile to... este litera con1ertit dac
caracterul c este o liter* #i nedefinit n ca3 contrar.
12.'. *peraii cu blocuri de memorie
0entru majoritatea func+iilor din aceast categorie compilatorul
e-pandea3 codul acestora folosind instruc+iuni pe #iruri de caractere.
$eclara+iile acestor func+ii se ob+in cu
#include <strin7.h>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7EA
&ume
memcpy 2 copia3 o 3on de memorie
$eclara+ie
-oid +memcp9(-oid +dest, const -oid +src,
unsi7ned n);
-oid +memmo-e(-oid +dest, const -oid +src,
unsi7ned n);
$escriere
Func+ia memcp9 copia3 n octe+i din 3ona de memorie src n
3ona de memorie dest. Qonele de memorie nu trebuie s se
suprapun. $ac e-ist acest risc se utili3ea3 memmo-e.
Caloare returnat
Func+iile returnea3 un pointer la dest.
&ume
memcmp 2 compar dou 3one de memorie
$eclara+ie
int memcmp(const -oid +s', const -oid +s.,
unsi7ned n);
$escriere
Func+ia memcmp compar primii n octe+i ai 3onelor de memorie
s' #i s..
Caloare returnat
Returnea3 un ntreg mai mic dect* egal cu* sau mai mare dect
3ero dac s' este mai mic dect* coincide* respecti1 este mai mare
dect s..
&ume
memset 2 umple o 3on de memorie cu o constant pe un
octet
$eclara+ie
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7EB
-oid +memset(-oid +s, int c, unsi7ned n);
$escriere
Func+ia memset umple primii n octe+i ai 3onei de memorie
indicat de s cu constanta c pe un octet.
Caloare returnat
Func+ia returnea3 un pointer la 3ona de memorie s.
&ume
memchr 2 caut n memorie un caracter
$eclara+ie
-oid +memchr(const -oid +s, int c,
unsi7ned n);
$escriere
Func+ia memchr caut caracterul c n primii n octe+i de memorie
indica+i de s. Cutarea se opre#te la primul octet care are 1aloarea c
9interpretat ca unsi7ned char<.
Caloare returnat
Func+ia returnea3 un pointer la octetul gsit sau A?>> dac
1aloarea nu e-ist n 3ona de memorie.
12.). *peraii cu iruri de caractere
0entru majoritatea func+iilor din aceast categorie compilatorul
e-pandea3 codul acestora folosind instruc+iuni pe #iruri de caractere.
$eclara+iile acestor func+ii se ob+in cu
#include <strin7.h>
&ume
strlen 2 calculea3 lungimea unui #ir
$eclara+ie
unsi7ned strlen(const char +s);
$escriere
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7EE
Func+ia strlen calculea3 lungimea #irului s* fr a include
caracterul terminator null.
Caloare returnat
Func+ia returnea3 numrul de caractere din s.
&ume
strcpy* strncpy 2 copia3 un #ir de caractere
$eclara+ie
char +strcp9(char +dest, const char +src);
char +strncp9(char +dest, const char +src,
unsi7ned n);
$escriere
Func+ia strcp9 copia3 #irul indicat de src 9inclusi1
caracterul terminator null< n 3ona indicat de dest. birurile nu
trebuie s se suprapun* #i n plus 3ona dest trebuie s fie suficient
de mare pentru a primi copia.
Func+ia strncp9 este similar* cu e-cep+ia faptului c nu se
copia3 mai mult de n octe+i din src. 6stfel* dac caracterul
terminator null nu se afl n primii n octe+i din src* re3ultatul nu 1a
fi terminat cu null. @n ca3ul n care lungimea lui src este mai mic
dect n* restul octe+ilor din dest primesc 1aloarea null.
Caloare returnat
Func+iile returnea3 un pointer la #irul dest.
&ume
strdup 2 duplic un #ir
$eclara+ie
char +strdup(const char +s);
$escriere
Func+ia strdup returnea3 un pointer la un nou #ir care este un
duplicat al #irului s. %emoria pentru noul #ir se ob+ine cu malloc*
#i poate fi eliberat cu free.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7E7
Caloare returnat
Func+ia returnea3 un pointer la #irul duplicat* sau A?>> dac nu
e-ist memorie suficient disponibil.
&ume
strcat* strncat 2 concatenea3 dou #iruri
$eclara+ie
char +strcat(char +dest, const char +src);
char +strncat(char +dest, const char +src,
unsi7ned n);
$escriere
Func+ia strcat adaug #irul src la #irul dest suprascriind
caracterul null de la sfr#itul lui dest* #i la sfr#it adaug un caracter
terminator null. birurile nu trebuie s se suprapun* #i n plus #irul
dest trebuie s aib suficient spa+iu pentru a pstra re3ultatul.
Func+ia strncat este similar* cu e-cep+ia faptului c numai
primele n caractere din src se adaug la dest.
Caloare returnat
Func+iile returnea3 un pointer la #irul re3ultat dest.
&ume
strcmp 2 compar dou #iruri de caractere
$eclara+ie
int strcmp(const char +s', const char
+s.);
$escriere
Func+ia strcmp compar cele dou #iruri s' #i s..
Caloare returnat
Func+ia returnea3 un ntreg mai mic dect* egal cu* sau mai mare
dect 3ero dac s' este mai mic dect* coincide* respecti1 este mai
mare dect s..
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7EG
&ume
strchr* strrchr 2 locali3ea3 un caracter
$eclara+ie
char +strchr(const char +s, int c);
char +strrchr(const char +s, int c);
$escriere
Func+ia strchr returnea3 un pointer la prima apari+ie a
caracterului c n #irul s.
Func+ia strrchr returnea3 un pointer la ultima apari+ie a
caracterului c n #irul s.
Caloare returnat
Func+iile returnea3 un pointer la caracterul gsit sau A?>> dac
1aloarea nu a fost gsit.
&ume
strstr 2 locali3ea3 un sub#ir
$eclara+ie
char +strstr(const char +sir, const char
+su(s);
$escriere
Func+ia strstr gse#te prima apari+ie a sub#irului su(s n
#irul sir. Caracterul terminator null nu este luat n considerare.
Caloare returnat
Func+ia returnea3 un pointer la nceputul sub#irului* sau A?>>
dac sub#irul nu este gsit.
&ume
strspn* strcspn 2 caut un set de caractere ntr2un #ir
$eclara+ie
unsi7ned strspn(const char +s, const char
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7EH
+acc);
unsi7ned strcspn(const char +s, const char
+reG);
$escriere
Func+ia strspn calculea3 lungimea segmentului ini+ial din s
format n ntregime numai cu caractere din acc.
Func+ia strcspn calculea3 lungimea segmentului ini+ial din s
format n ntregime numai cu caractere care nu se gsesc n reG.
Calori returnate
Func+ia strspn returnea3 po3i+ia primului caracter din s care
nu se afl n acc.
Func+ia strcspn returnea3 po3i+ia primului caracter din s care
se afl n reG.
12.+. Aiblioteca matematic
7< Func+iile din prima categorie snt descrise n <stdli(.h>.
&ume
rand* srand 2 generarea numerelor pseudo2aleatoare
$eclara+ie
int rand(-oid);
-oid srand(unsi7ned int seed);
$escriere
Func+ia rand returnea3 un ntreg pseudo2aleator ntre 0 #i
V<AEUB<; 9pentru majoritatea mediilor de programare C aceast
constant este egal cu 1aloarea ma-im cu semn repre3entabil pe
un cu1nt al sistemului de calcul<.
Func+ia srand ini+iali3ea3 generatorul cu 1aloarea seed
pentru o nou sec1en+ de 1alori ntregi pseudo2aleatoare care 1or fi
returnate de rand. 6ceste sec1en+e se repet dac srand se apelea3
cu aceea#i 1aloare seed.
:e obi#nuie#te ca generatorul s fie ini+iali3at cu o 1aloare dat
de ceasul sistemului de calcul* ca n e-emplul de mai jos4
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
770
#include <time.h>
srand(time(A?>>));
Caloare returnat
Func+ia rand returnea3 o 1aloare ntre 0 #i V<AEUB<;.
Dbser1a+ie
@n lucrarea )umerical .ecipes in */ The Art of &cientific
*omputin 2 illiam M 0ress* Brian 0 Flanner)* :aul 6 /euIolsI)*
illiam / Cetterling = &e' PorI4 Cambridge ,ni1ersit) 0ress* 7HH0
97st ed* p 807<* se face urmtorul comentariu4
S$ac dori+i s genera+i o 1aloare aleatoare ntreag ntre 7 #i 70*
se recomand s folosi+i sec1en+a
G"'%(int)('0.0+rand()F(V<AEUB<;%'.0));
#i nu o sec1en+ de tipul
G"'%(int)('000000.0+rand())#'0;
care folose#te bi+ii de rang inferior.S
/ot n fi#ierul <stdli(.h> snt descrise #i urmtoarele func+ii4
int a(s(int i); 1aloare absolut
lon7 la(s(lon7 i); 1aloare absolut
int atoi(char +s); con1ersie din 6:C;; n ntreg
lon7 atol(char +s); con1ersie din 6:C;; n ntreg lung
dou(le atof(char +s); con1ersie din 6:C;; n dubl
preci3ie
8< Func+iile din a doua categorie snt descrise n fi#ierul
<math.h>.
dou(le fa(s(dou(le 8); 1aloare absolut
dou(le floor(dou(le 8); parte ntreag inferioar
dou(le ceil(dou(le 8); parte ntreag superioar
dou(le sIrt(dou(le 8);
x
dou(le sin(dou(le 8); sin9x<
dou(le cos(dou(le 8); cos9x<
dou(le tan(dou(le 8); tg9x<
dou(le asin(dou(le 8); arcsin9x<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
777
dou(le acos(dou(le 8); arccos9x<
dou(le atan(dou(le 8); arctg9x< n Y2F8*F8[
dou(le atan.(dou(le 9, dou(le 8);
arctg9y/x< n Y5*[
dou(le e8p(dou(le 8); e
x
dou(le lo7(dou(le 8); ln9x<
dou(le pow(dou(le 8, dou(le 9); x
y
dou(le sinh(dou(le 8); sin"9x<
dou(le cosh(dou(le 8); cos"9x<
dou(le tanh(dou(le 8); tg"9x<
dou(le lde8p(dou(le 8, int e); x 8
e
dou(le fmod(dou(le 8, dou(le 9); x modulo y
Func+ia fmod returnea3 o 1aloare f definit astfel4 x = a y + f
a este o 1aloare ntreag 9dat de xFy< #i 0 _f _ g y; f are semnul lui
x.
,rmtoarele dou func+ii returnea3 dou 1alori4 una este
1aloarea returnat de func+ie 9de tip dou(le<* #i cealalt returnat
prin intermediul unui argument de tip pointer la int respecti1
dou(le.
dou(le fre8p(dou(le 8, int +e);
Func+ia fre8p desparte 1aloarea x n dou pr+i4 o parte frac+ionar
normali3at 9f Y0.B*7<< #i un e-ponent e. $ac x este 0 atunci f=0 #i
e=0. Caloarea returnat este f.
dou(le modf(dou(le 8, dou(le +n);
Func+ia modf desparte 1aloarea x n dou pr+i4 o parte frac+ionar
subunitar f #i o parte ntreag n. Calorile f #i n au acela#i semn ca #i
x. Caloarea returnat este f.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
778
12.4. Programe demonstrati$e
7< 0rogramul pre3entat n continuare generea3 un #ir de n 1alori
ntregi aleatoare n inter1alul Y0*B7[ pe care le depune n tabloul ;
9alocat dinamic<* #i apoi le sortea3 cresctor. @n continuare se
generea3 , 1alori ntregi aleatoare pe care le caut n tabloul ;.
0entru fiecare cutare cu succes se afi#ea3 pe terminal 1aloarea
cutat #i po3i+ia n tablou.
Calorile n* , #i B se iau n aceast ordine din linia de comand.
#include <stdli(.h>
#include <stdio.h>
#include <time.h>
int cmp(const -oid +<, const -oid +C) {
return +(int +)<6+(int +)C;

int main(int ac, int ++a-) {


int +;,+p,B,n,,,i,-;
if (ac&"/) {
fputs("Rrei ar7umente&\n",stderr);
return ';

n"atoi(a-)'*); ,"atoi(a-).*);
B"atoi(a-)0*);
;"(int +)malloc(n+si:eof(int));
if (&;) return ';
srand(time(A?>>));
for (i"0; i<n; i%%)
;)i*"rand()#B;
Isort(;,n,si:eof(int),cmp);
for (i"0; i<,; i%%) {
-"rand()#B;
p"(int +)(search($-,;,n,si:eof(int),
cmp);
if (p)
printf("QalP #d ZosP #d\n",-,p6;);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77?
free(;);
return 0;

8< : relum al treilea e-emplu din capitolul precedent. :e cite#te


un fi#ier te-t care con+ine pe fiecare linie un nume 9#ir de caractere
fr spa+iu< #i trei 1alori reale 9note<. 0entru fiecare linie se
calculea3 media aritmetic a celor trei 1alori #i se determin dac
elementul este admis 9fiecare not este minimum B< sau respins 9cel
pu+in o not este sub B<. @n final se afi#ea3 liniile n ordinea
urmtoare4 mai nti elementele admise n ordinea descresctoare a
mediei* #i apoi elementele respinse n ordine alfabetic dup nume.
:e afi#ea3 doar numele* situa+ia 9<FV< #i media.
@n acest e-emplu punem n e1iden+ o modalitate comod de
selectare a membrilor unei structuri cu ajutorul macrourilor. %acroul
=ld selectea3 din 3ona referit de pointerul Z membrul f. $eoarece
pointerul Z 9care poate fi argumentul < sau C al func+iei comp< refer
o 3on de tip -oid* este necesar mai nti un cast pentru a preci3a
tipul concret al acesteia. %embrul f poate fi4 nm* ar* md* defini+i n
cadrul structurii de tip Mt@l.
$eoarece nu #tim de la nceput cte linii are fi#ierul de intrare*
sntem ne1oi+i s folosim urmtoarea strategie. La nceput alocm
pentru tabloul @l o 3on care s memore3e A< elemente. 0e msur
ce aceast 3on se completea3* la un moment dat numrul de linii
citite coincide cu A<. @n acest moment se aloc o 3on nou care s
poat memora un numr mai mare de elemente. $esigur* de fiecare
dat se 1a actuali3a mrimea spa+iului alocat.
#include <stdli(.h>
#include <strin7.h>
#include <stdio.h>
#define A< 0.
t9pedef struct {
char nm)'0*, ar;
float na, n(, nc, md;
Mt@l;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77A
#define =ld(Z,f) ((Mt@l +)Z)6>f
int comp(const -oid +<, const -oid +C) {
float w;
int d;
if (d"=ld(<,ar)6=ld(C,ar))
return d;
if (=ld(<,ar)""!<!) {
w"=ld(C,md)6=ld(<,md);
if (w>0) return ';
if (w<0) return 6';

return strcmp(=ld(<,nm),=ld(C,nm));

int main(int ac, char ++a-) {


int na,ne,i;
Mt@l +@l;
=J>@ +fi;
if (ac&".) {
fputs("?n ar7ument&\n",stderr);
return ';

fi"fopen(a-)'*,"rt");
if (&fi) {
perror("@roare la deschidere");
return ';

na"A<; ne"0;
@l"(Mt@l +)malloc(na+si:eof(Mt@l));
while (fscanf(fi,"#s #d #d #d",
@l)ne*.nm,$@l)ne*.na,$@l)ne*.n(,
$@l)ne*.nc)&"@S=) {
if ((@l)ne*.na>"1) $$ (@l)ne*.n(>"1) $$
(@l)ne*.nc>"1))
@l)ne*.ar"!<!;
else @l)ne*.ar"!V!;
@l)ne*.md"(@l)ne*.na%@l)ne*.n(%
@l)ne*.nc)F0.0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77B
ne%%;
if (ne""na) {
na%"A<;
@l"(Mt@l +)realloc(@l,na+
si:eof(Mt@l));


fclose(fi);
Isort(@l,ne,si:eof(Mt@l),comp);
for (i"0; i<ne; i%%)
printf("#6'.s #c#2..lf\n",
@l)i*.nm,@l)i*.ar,@l)i*.md);
free(@l);
return 0;

?< :e cite#te dintr2un fi#ier te-t o 1aloare natural n. ,rmtoarele


linii con+in n cu1inte* fiecare cu1nt a1nd acela#i numr de litere 9cel
mult 70<. : se afi#e3e cu1intele din fi#ier ordonate alfabetic.
0entru a memora lista de cu1inte folosim urmtoarea strategie. @n
loc s alocm pentru fiecare cu1nt 9#ir de caractere< citit o 3on nou
de memorie* alocm de la nceput o 3on n care s putem memora
toate cu1intele din list. 6ceast 3on 1a a1ea mrimea de (l%')+n
octe+i* unde l este lungimea fiecrui cu1nt 9numrul de litere<. $e ce
(l%')X pentru c trebuie s memorm #i caracterul terminator null.
61antaje4 memoria este utili3at mai eficient dac se aloc de la
nceput o 3on contigu de dimensiune mai mare* #i se reduce foarte
mult fragmentarea memoriei.
#include <stdli(.h>
#include <strin7.h>
#include <stdio.h>
int comp(const -oid +<, const -oid +C) {
return strcmp((char +)<,(char +)C);

int main(int ac, char ++a-) {


char +D,s)''*;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77E
int n,l,i;
=J>@ +fi;
if (ac&".) {
fputs("?n ar7ument&\n",stderr);
return ';

fi"fopen(a-)'*,"rt");
if (&fi) {
perror("@roare la deschidere");
return ';

fscanf(fi,"#d #s",n,s);
l"strlen(s);
D"(char +)malloc((l%')+n);
Mtrcp9(D,s);
for (i"'; i<n; i%%)
fscanf(fi,"#s",D%(l%')+i);
fclose(fi);
Isort(D,n,l%',comp);
for (i"0; i<n; i%%)
printf("#s\n",D%(l%')+i);
free(D);
return 0;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
777
Aibliogra#ie
Brian !ernig"am* $ennis % Ritc"ie 2 The * 0rorammin !anuae
0rentice2Mall :oft'are :eries* 7H7G
2 !imba,ul *; manual de proramare
;nstitutul de te"nic de calcul* Cluj2&apoca 7HGA
Merbert :c"ildt 2 1anual * complet
Kditura /eora* 7HHG
%anuale electronice
"ttp4=='''.programmingtutorials.com=c."tml
%ars"all Brain 2 %ntroduction to * 0rorammin
"ttp4==de1central.iftec".com=learning=tutorials=c2cpp=c=
:te1e :ummit 2 %ntroductory * 0rorammin *lass )otes
"ttp4=='''.esIimo.com=]scs=cclass=cclass."tml
:te1e :ummit 2 %ntermediate * 0rorammin *lass )otes
"ttp4=='''.esIimo.com=]scs=cclass=cclass."tml
Brian Bro'n 2 * 0rorammin
"ttp4=='''.cit.ac.n3=smac=cprogram=onlinet."tm
Brian Bro'n 2 An %ntroduction to * 0rorammin
"ttp4=='''.cit.ac.n3=smac=cprogram=default."tm
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77G
Cuprins
7. Leneralit+i asupra limbajului C . . . . . . . . . . . . . . . . . . . A
7.7. ;ntroducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A
7.8. 0rimele programe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B
7.?. %eta2limbajul #i setul de caractere . . . . . . . . . . . . . . . . . . . . H
8. ,nit+ile le-icale ale limbajului C . . . . . . . . . . . . . . . . 70
8.7. ;dentificatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.8. Cu1inte c"eie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.?. Constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.A. biruri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7A
8.B. Dperatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7B
8.E. :eparatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7B
?. Cariabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
?.7. Clase de memorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
?.8. /ipuri de 1ariabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
?.?. Dbiecte #i 1alori2stnga . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8?
?.A. Con1ersii de tip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8?
A. Dperatori #i e-presii . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A.7. K-presii primare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A.8. Dperatori unari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8H
A.?. Dperatori multiplicati1i . . . . . . . . . . . . . . . . . . . . . . . . . . . ?8
A.A. Dperatori aditi1i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ??
A.B. Dperatori de deplasare . . . . . . . . . . . . . . . . . . . . . . . . . . . . ??
A.E. Dperatori rela+ionali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?A
A.7. Dperatori de egalitate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?B
A.G. Dperatorul b; pe bi+i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?B
A.H. Dperatorul :6,2e-clusi1 pe bi+i . . . . . . . . . . . . . . . . . . . . ?B
A.70. Dperatorul :6,2inclusi1 pe bi+i . . . . . . . . . . . . . . . . . . . . ?E
A.77. Dperatorul b;2logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?E
A.78. Dperatorul :6,2logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?7
A.7?. Dperatorul condi+ional . . . . . . . . . . . . . . . . . . . . . . . . . . . ?7
A.7A. Dperatori de atribuire . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
77H
A.7B. Dperatorul 1irgul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?H
A.7E. 0receden+a #i ordinea de e1aluare . . . . . . . . . . . . . . . . . . . A0
B. $eclara+ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A8
B.7. :pecificatori de clas de memorie . . . . . . . . . . . . . . . . . . . A?
B.8. :pecificatori de tip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AA
B.?. $eclaratori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AB
B.A. %odificatorul const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A7
B.B. ;ni+iali3are . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AG
B.E. )ume-tip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AH
E. ;nstruc+iuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B7
E.7. ;nstruc+iunea expresie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B7
E.8. ;nstruc+iunea compus sau blocul . . . . . . . . . . . . . . . . . . . . B7
E.?. ;nstruc+iunea condi+ional . . . . . . . . . . . . . . . . . . . . . . . . . . B8
E.A. ;nstruc+iunea while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BA
E.B. ;nstruc+iunea do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BA
E.E. ;nstruc+iunea for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BB
E.7. ;nstruc+iunea switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . BE
E.G. ;nstruc+iunea (rea, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BG
E.H. ;nstruc+iunea continue . . . . . . . . . . . . . . . . . . . . . . . . . . BG
E.70. ;nstruc+iunea return . . . . . . . . . . . . . . . . . . . . . . . . . . . BH
E.77. ;nstruc+iunea 1id . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BH
7. Func+iile #i structura unui program . . . . . . . . . . . . . . . . E0
7.7. $efini+ia func+iilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E0
7.8. 6pelul func+iilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E?
7.?. Re1enirea din func+ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .E?
7.A. 6rgumentele func+iei #i transmiterea parametrilor . . . . . . . EA
7.B. Func+ii cu numr 1ariabil de parametri . . . . . . . . . . . . . . . . EB
7.E. K-emple de func+ii #i programe . . . . . . . . . . . . . . . . . . . . . EE
G. Liniile de control ale compilatorului . . . . . . . . . . . . . . . 70
G.l. @nlocuirea simbolurilor* substitu+ii macro . . . . . . . . . . . . . . 70
G.8. ;ncluderea fi#ierelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
G.?. Compilarea condi+ionat . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
G.A. ,tili3area directi1elor de compilare . . . . . . . . . . . . . . . . . . 7?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7G0
H. 0ointeri #i masi1e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7E
H.7. 0ointeri #i adrese . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7E
H.8 0ointeri #i argumente de func+ii . . . . . . . . . . . . . . . . . . . . . . 77
H.?. 0ointeri #i masi1e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7G
H.A. 6ritmetica de adrese . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G0
H.B. 0ointeri la caracter #i func+ii . . . . . . . . . . . . . . . . . . . . . . . . G?
H.E. %asi1e multidimensionale . . . . . . . . . . . . . . . . . . . . . . . . . GE
H.7. %asi1e de pointeri #i pointeri la pointeri . . . . . . . . . . . . . . GG
H.G. ;ni+iali3area masi1elor #i masi1elor de pointeri . . . . . . . . . H?
H.H. %asi1e de pointeri #i masi1e multidimensionale . . . . . . . . HE
H.70. 6rgumentele unei linii de comand . . . . . . . . . . . . . . . . . H7
H.77. 0ointeri la func+ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
70. :tructuri #i reuniuni . . . . . . . . . . . . . . . . . . . . . . . . . 70E
70.7. Klemente de ba3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70E
70.8. :tructuri #i func+ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70G
70.?. %asi1e de structuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770
70.A. 0ointeri la structuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77B
70.B. :tructuri auto2referite . . . . . . . . . . . . . . . . . . . . . . . . . . . 777
70.E. Cutare n tabele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78?
70.7. Cmpuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
70.G. Reuniuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78H
70.H. $eclara+ii de structuri* reuniuni #i cmpuri . . . . . . . . . . 7?7
70.70. R9pedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7??
77. ;ntrri = ie#iri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7?E
77.7. ;ntrri #i ie#iri standard; fi#iere . . . . . . . . . . . . . . . . . . . . 7?E
77.8. 6ccesul la fi#iere; desc"idere #i nc"idere . . . . . . . . . . . 7?G
77.?. Citire #i scriere fr format . . . . . . . . . . . . . . . . . . . . . . . 7A7
77.A. Citire cu format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7A?
77.B. :criere cu format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7A7
77.E. /ratarea erorilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7B8
77.7. Dpera+ii cu directoare . . . . . . . . . . . . . . . . . . . . . . . . . . . 7BA
77.G. 0rograme demonstrati1e . . . . . . . . . . . . . . . . . . . . . . . . 7BE
78. 6lte rutine din biblioteca standard . . . . . . . . . . . . . . 7E0
78.7. 6locarea dinamic a memoriei . . . . . . . . . . . . . . . . . . . . 7E0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7G7
78.8. :ortare #i cutare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7E7
78.?. Rutine de clasificare . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7E8
78.A. Dpera+ii cu blocuri de memorie . . . . . . . . . . . . . . . . . . . 7EA
78.B. Dpera+ii cu #iruri de caractere . . . . . . . . . . . . . . . . . . . . 7EE
78.E. Biblioteca matematic . . . . . . . . . . . . . . . . . . . . . . . . . . 770
78.7. 0rograme demonstrati1e . . . . . . . . . . . . . . . . . . . . . . . . . 77?
Bibliografie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
7G8

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