Sunteți pe pagina 1din 15

Tema 2. Funcii, expresii, operatori 2.1. Structura, prototipul i apelul funciilor 2.2.

Funcii de intrare: getch(), getche(),getchar(), gets() 2.3. Funcii de ieire: putch(), putchar(), puts() 2.4. Funciile de ieire printf() i sprintf() 2.5. Funciile de intrare scanf() i sscanf() 2.6. Expresii i operanzi 2.7. Operatori 2.8. Regula conversiilor implicite

2.1. Structura, prototipul i apelul funciilor O funcie const din antet i corp. Antetul conine informaii necesare compilatorului pentru a apela funcia: numele funciei, tipul rezultatului returnat de funcie, lista cu tipul i numele argumentelor funciei, parametrii formali. Formatul antetului este urmtorul: tip_returnat nume_funcie(lista cu tipul i numele parametrilor formali) tip_returnat este tipul rezultatului care va fi returnat de funcie n punctul programului de unde a fost apelat. nume_funcie este numele funciei, un identificator. Pentru funciile de bibliotec, numele sunt prestabilite. Pentru funciile proprii, programatorul alege numele. Lista cu tipul i numele parametrilor formali const din elemente separate prin virgul. Fiecare element este declaraia unui parametru formal. Lista se scrie n paranteze rotunde. Aceste paranteze sunt obligatoriii chiar, dac lista este vid, parantezele rmn goale. n continuare, dup numele oricrei funcii vom pune i parantezele rotunde, pentru a accentua c este vorba despre o funcie. Exemplu: int func1(int a, int b) este antetul funciei cu numele func1. Aceast funcie are 2 parametri formali cu numele a i b, ambii de tipul int. Funcia returneaz o valoare de tipul int. Dac funcia nu are parametri, adic lista respectiv este vid, atunci se scrie cuvntul void n loc de list. n acest caz, antetul funciei are forma: tip_returnat nume_funcie(void) Exemplu: char citeste(void) este antetul funciei cu numele citeste. Ea returneaz o valoare de tip char, i nu are argumente. n C o funcie poate returna ca rezultat nu mai mult de o valoare, adic sau una sau niciuna. n cazul cnd funcia nu returneaz nici un rezultat, atunci n loc de tip_returnat se scrie cuvntul void, iar antetul are forma: void nume_funcie(lista cu tipul i numele parametrilor formali) Exemplu: void tipar(int a, char b, long double c) este antetul funciei cu numele tipar. Ea nu returneaz nici un rezultat, are 3 argumente. n C este permis i antetul de forma:

tip_returnat nume_funcie( ) Aici lista argumentelor lipsete i n paranteze nu este scris nimic, sunt goale. n acest caz nu se tie nimic despre argumentele funciei. Compilatorul C trebuie s se descurce singur, dup contextul programului, dac sunt sau nu parametri. Exemplu: long f4( ) este antetul funciei cu numele f4 care returneaz o valoare long i nu se tie ci parametri are funcia. O funcie poate s nu aib argumente i nici s nu returneze vre-un rezultat. Exemplu: void f(void) Corpul funciei are formatul: { Declaraii date; Instruciuni; } Corpul poate conine declaraii de date, locale funciei, i instruciuni de prelucrare a datelor, inclusiv a celor transmise n funcie prin parametri. Exemplu: int add(int a, int b) { int c; c=a+b; return c; } Funcia add adun doi ntregi, transmii n funcie prin parametrii a i b, atribuie rezultatul sumei variabilei c i returneaz valoarea lui c. Dac o funcie returneaz o valoare, atunci corpul ei trebuie s conin cel puin o instruciune return, care va returna valoarea respectiv. Corpul poate conine i mai multe instruciuni return, n dependen de caz. n cazul cnd funcia nu returneaz nici-o valoare, instruciunea return nu este obligatorie. Atunci ieirea din funcia are loc dup execuia ultimei instruciuni a funciei. Dac logic ieirea din funcie poate surveni i pn la ultima instruciune, atunci n locul respectiv se scrie return. Exemplu: short divide(short a, short b) { if( b!=0 ) return a/b; else { printf(Nu se poate imparti la 0!); exit(); } } Funcia divide trebuie s mpart a la b. Dac b este diferit de 0, atunci vom obine rezultatul mpririi (care va fi un numr ntreg; partea fracionar, eventual, se va pierde). n cazul cnd b este 0, vom obine mesajul respectiv. Antetul mpreun cu corpul unei funcii reprezint definiia funciei respective. Funciile nu pot fi incluse una n alta. n definiia unei funcii nu poate fi definiia altei funcii. Orice funcie, apelat undeva n program, trebuie s aib definiia pn la primul apel. Uneori, acest lucru este incomod. Poate e mai comod ca funcia s fie elaborat mai trziu, dup scrierea programului ce conine apeluri ale funciei respective. n acest caz putem

folosi prototipul funciei. Scriem prototipul funciei nainte de primul ei apel, iar definiia funciei o vom scrie undeva mai departe, de obicei la sfritul programului. Important este ca primul apel al unei funciei s fie precedat de definiia sau prototipul ei. Prototipul funciei are formatul: tip_returnat nume_funcie(lista cu tipul i numele parametrilor formali); adic este numai antetul funciei dup care se pune punct i virgul. Prototipul conine informaiile necesare compilatorului pentru a verifica dac apelurile funciei sunt fcute corect. Pentru aceasta el trebuie s tie tipul returnat de funcie, numele ei i lista cu tipurile parametrilor. Pentru exemplele de mai sus, prototipurile vor fi: int func1(int a, int b); char citeste(void); void tipar(int a, char b, long double c); long f4( ); int add(int a, int b); short divide(short a, short b); n prototipul funciilor, numele pentru parametrii formali poate fi omis: int func1(int, int); void tipar(int, char, long double); int add(int, int); short divide(short, short); Dac un parametru formal este vector, atunci n prototip poate fi omis dimensiunea lui: int produs(int x[], int y[]); sau int produs(int [], int []); Dar, pentru un parametru formal cu 2 sau mai multe dimensiuni, n prototip se poate omite numai prima dimensiune: int nr_elem_pozitive(int a[][2][3]); sau int nr_elem_pozitive(int [][2][3]); Apelul unei funcii are formatul: nume_funcie(lista parametrilor actuali) Parametrii actuali sunt acele date, care trebuie transmise n funcie pentru a fi prelucrate. Ei se mai numesc parametri efectivi. Un parametru formal poate fi o constant, o variabil sau o expresie. Valoarea parametrilor actuali se transmite parametrilor formali respectivi. Numrul, ordinea i tipul parametrilor actuali trebuie s corespund cu parametrii formali. Exemple: add(2,13) este apelul funciei add(), rezultatul apelului va fi 15 (=2+13). int x=5, y=-10, z=add(2*x,y); Acest apel ne va da rezultatul 0 (suma produsului 2*5 cu numrul -10). divide(2,3) ne va da 0; divide(5,0) ne va da mesajul: Nu se poate imparti la 0! int x=7, z; z=add(x+3,x/3)+divide(x+5,9); va calcula valoarea expresiei (x+3)+(x/3)+(x+5)/9 i ne va da rezultatul 13.

2.2. Funcii de intrare C dispune de o mulime de funcii standard de intrare i ieire. Cu ele programul poate introduce i extrage date.

Funciile de intrare mai des folosite sunt: getch(), getche(), getchar(), gets(), scanf() .a. Aceste funcii citesc, adic introduc date de la intrarea standard, care este tastatura. Vom examina funciile getch(), getche(), getchar(), gets(). Funcia getch() Aceast funcie citete un caracter de la tastatur. La apelul ei, sistemul se oprete i ateapt ca utilizatorul s apese o tast. La apsarea unei taste ce corespunde unui caracter ASCII, codul ASCII respectiv se introduce direct n memorie, sistemul nu ateapt apsarea tastei Enter, ci continu execuia programului. Prototiul funciei este int getch(); i se afl n conio.h. Funcia nu are argumente, n paranteze nu se scrie nimic. Funcia returneaz codul ASCII al caracterului citit. Dac la apel se apsa o tast ce nu corespunde unui caracter ASCII, cum sunt tastele funcionale F1, F2 .a., atunci, la primul apel getch() returneaz valoarea 0, iar la al doilea apel returneaz un numr, care este codul ataat tastei respective. Caracterul apsat la solicitarea funciei getch() nu se vede, nu este afiat pe ecran. De aceea, se spune c getch() citete date fr ecou. Funcia getche() Este ca i getch(). Unica deosebire este c pe ecran este afiat caracterul care este apsat la tastatur. Funcia getchar() Introduce un caracter de la tastatur, dar prin buferul tastaturii, adic ateapt apsarea tastei Enter. n bufer pot fi mai multe caractere, cnd se apas Enter, se citete primul caracter din bufer. Funcia are declaraia int getchar(); n stdio.h, ea nu are parametri i returneaz codul ASCII al caracterului citit. La eroare, getchar() returneaz EOF (care, de regul, este valoarea -1). Funcia gets() Citete un ir de caractere de la tastatur. Prototipul char *gets(char *s); este definit n stdio.h. Funcia are un parametru care este adresa de nceput a locaiei de memorie unde se va pstra irul de caractere citit. Ea returneaz adresa de nceput a locaiei unde a fost pstrat irul citit. n caz de eroare, funcia returneaz valoarea constantei simbolice NULL, definit n stdio.h. De obicei, valoarea NULL este 0 i nu semnific nici o adres de memorie. Important este ca irul citit de la tastatur s ncap n locaia rezervat preventiv pentru el, inclusiv i caracterul \0 de cod 0, ce semnific sfritul irului.

2.3. Funcii de ieire Vom examina funciile de ieire: putch(), putchar(), puts(). Funcia putch() Extrage un caracter la ecran. Are prototipul int putch(int c); n conio.h ,extrage caracterul determinat de unicul parametru c, returneaz codul caracterului extras sau -1 n caz de eroare. Nu trece cursorul n linia urmtoare, el rmne imediat dup caracterul extras. Dac c este un caracter de control, atunci el este executat (\n, \t, \a, etc.). Funcia putchar() Extrage un caracter la ecran, are declaraia int putchar(int c); n stdio.h, extrage caracterul determinat de unicul parametru c, returneaz codul caracterului extras sau -1 la eroare. Dac c este un caracter de control, atunci el este executat (\n, \t, \a, etc.). Funcia puts()

Extrage un ir de caractere la ecran, are prototipul int puts(const char *s); n stdio.h, extrage din memorie la ecran irul de caracter determinat de unicul parametrul s, care este adresa de nceput a irului de extras. Extragerea ce face pn la ntlnirea caracterului nul, adic a codului 0. Returneaz numrul de caractere extrase sau -1 la eroare. Caracterele de control, ce se ntlnesc n ir, sunt executate (\n, \t, \a, etc.).

2.4. Funciile de ieire printf() i sprintf() Funcia printf() Este o funcie cu un numr variabil de argumente. Ea extrage la ecran date formatate, adic le extrage ntr-un format anumit. Are prototipul int printf(const char *f, p1, p2, ...); n stdio.h. Funcia returneaz numrul de caractere (octei) extrase sau -1 la eroare. Apelul funciei se face printr-o construcie de forma printf( control, p1,p2,...,pn ). Argumentele p1,p2,...,pn sunt expresii, valorile crora trebuie extrase. Aceste valori sunt convertite din formatul binar intern n format extern, pentru a fi afiate pe ecran. irul de caractere control conine texte i specificatori de format. Textele sunt extrase pe ecran, iar specificatorii de format determin cum trebuie convertite valorile p1,p2,...,pn din formatul intern n formatul extern. Pentru fiecare din expresiile p1,p2,...,pn, n irul control trebuie s fie un specificator de format. Dac numrul de specificatori de format este mai mare ca numrul valorilor de extras, atunci rezultatul este imprevizibil. Excesul de valori de extras, cel mai des, este ignorat. Fiecare valoare este scris n cmpul su de extragere. Lungimea cmpului de extragere este determinat implicit de valoarea care se extrage. Dar lungimea cmpului de extragere poate fi definit i explicit n specificatorul de format ce corespunde valorii de extras. Un specificator de format ncepe cu semnul % i se termin cu una sau dou litere speciale. ntre caracterul % i prima liter mai pot fi i urmtoarele caractere cu semnificaie prestabilit: Un semn (minus) opional, determin alinierea valorii extrase n stnga cmpului de extragere. Un semn + (plus) opional, determin c numrul va fi extras ntotdeauna cu semn. Un spaiu (o poziie liber) opional,dac primul caracter nu este un semn, atunci un spaiu va fi extras ca prefix. Un semn #, determin o scriere alternativ a valorii extrase: %#o prima cifr va fi 0, %#x sau %#X va aduga prefixul 0x sau 0X valorilor diferite de 0, pentru e,E,f,g,G i combinaiile lor cu h,l,L datele vor fi ntotdeauna cu punct zecimal, iar pentru g,G zerourile de la sfrit nu vor fi nlturate. Un ir de cifre zecimale opional, definete dimensiunea minim a cmpului n care se extrage valoarea respectiv. Dac valoarea de extras necesit mai multe poziii dect e artat n acest ir de cifre zecimale, atunci valoarea va fi extras pe numrul necesar de poziii, adic irul de cifre zecimale este ignorat. Dac e definit un cmp de extragere mai mare dect e necesar, atunci implicit valoarea este aliniat la dreapta cmpului de extragere, dac nu este semnul minus n faa irului de cifre respectiv. n acest caz, poziiile excesive rmn goale, sunt umplute cu spaii, iar dac irul de cifre ncepe cu cifra 0, atunci poziiile excesive sunt umplute cu cifre de 0. Semnul minus, n faa dimensiunii cmpului de extragere, determin alinierea valorii extrase n stnga cmpului. Dimensiunea cmpului poate fi specificat cu un semn * (asteric), atunci valoarea lui se ia din urmtorul argument, care trebuie s fie de tip int. Un punct zecimal urmat de un ir de cifre zecimale, toate opionale, determin precizia valorii extrase, adic numrul de cifre dup punctul zecimal, dac se extrage un numr real i numrul de caractere afiate, dac se extrage un ir de caractere. Pentru ntregi, precizia determin numrul minim de cifre ce vor fi extrase, se scriu zerouri n fa pentru a completa tot cmpul de extragere. Dac precizia este 0, atunci nu se extrage nici punctul zecimal. Precizia poate fi specificat cu un semn * (asteric), atunci valoarea ei se ia din urmtorul argument, care trebuie s fie de tip int.

Deci, un specificator de format are forma: %[-/+/spaiu][#][0][cifre][.cifre]liter[liter] , parantezele ptrate nseamn c elementul respectiv este opional. Literele cu semnificaie special n specificatorii de format sunt urmtoarele: %c este folosit pentru extragerea unui caracter; %d este folosit pentru extragerea n zecimal a unui ntreg cu semn, unei valori de tip int sau char; %i este folosit pentru extragerea n zecimal a unui ntreg cu semn, unei valori de tip int sau char; %u este folosit pentru extragerea n zecimal a unui ntreg fr semn, unei valori de tip unsigned int sau unsigned char; %o este folosit pentru extragerea n octal a unui ntreg fr semn, unei valori de tip unsigned int sau unsigned char; %x sau %X este folosit pentru extragerea n hexazecimal a unui ntreg fr semn, unei valori de tip unsigned int sau unsigned char; pentru %x se folosesc cifrele hexazecimale 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f iar pentru %X cifrele 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; %s este folosit pentru extragerea unui ir de caractere, tablou de tipul char; irul de extras este reprezentat n argumente prin numele tabloului de tip char sau este o constant ir de caractere, ambele reprezint adresa de nceput a irului de extras; sunt extrase caracterele irului pn la ntlnirea primului caracter de cod 0, caracterul nul; %f este folosit pentru extragerea unui numr de tip float sau double cu 6 cifre zecimale n format matematic: [-]ddd.zzzzzz, unde ddd este partea ntreag, iar zzzzzz partea fracionar din 6 cifre; %e sau %E este folosit pentru extragerea numerelor float sau double n format tiinific, cu exponent: [-]d.zzzzzz[e/E][+/-]rr, unde d este partea ntreag format dintr-o cifr, zzzzzz sunt 6 cifre dup punctul zecimal i rr este exponentul; %g sau %G este folosit pentru extragerea numerelor reale, alege dintre formatele e,E i f, formatul ce extrage valoarea pe un numr minim de caractere; %ld, %li, %lu, %lo, %lx, %lX extrage valori ntregi de tipul long respectiv; %hd, %hi, %hu, %ho, %hx, %hX extrage valori ntregi de tipul short respectiv; %lf, %le, %lE, %lg, %lG extrage valori reale de tipul double cu 6 cifre zecimale; %Lf, %Le, %LE, %Lg, %LG extrage valori reale de tipul long double cu 6 cifre zecimale. %% extrage caracterul %; %w, unde w este un caracter ce nu a fost enumerat mai sus, extrage caracterul respectiv. Funcia printf() nu poate fi folosit direct pentru scrierea datelor n fiiere. Pentru aceasta este funcia fprintf(). Funcia sprintf() Extrage date formatate, ca i funcia printf(), dar le extrage nu la ieirea standard, ci ntr-un ir de caractere. Are prototipul int sprintf(char *buffer, const char *f, p1, p2, ...); n stdio.h. Apelul funciei se face printr-o construcie de forma sprintf( s, control, p1,p2,...,pn ). Argumentele p1,p2,...,pn sunt expresii, valorile crora se extrag n irul de caractere s, dup convertirea lor din formatul intern n formatul extern, conform specificatorilor de format din parametrul control. n rest, funcia se comport ca i printf().

2.5. Funciile de intrare scanf() i sscanf()

Funcia scanf() Este o funcie cu un numr variabil de argumente. Ea citete, adic introduce, date de la tastatur n corespundere cu anumite formate. Are prototipul int scanf(const char *f, &p1, &p2, ...); n stdio.h. Funcia returneaz numrul de valori corect introduse, convertite i stocate n memorie, returneaz 0, dac nu a stocat nici-o valoare n memorie i returneaz -1 dac ncearc s citeasc EOF. Apelul funciei se face printr-o construcie de forma scanf( control, &p1,&p2,...,&pn ), unde p1,p2,...,pn sunt nume de variabile simple, iar &p1,&p2,...,&pn semnific adresele lor n memorie, unde vor fi stocate datele introduse de la tastatur. (Aici & semnific operaia adresa, &p este adresa de nceput unde este pstrat variabila p). Aceste valori sunt convertite din formatul extern n format intern, binar, pentru a fi stocate n memorie. irul de caractere control conine specificatori de format. Specificatorii de format determin cum trebuie convertite valorile introduse de la tastatur din formatul extern n formatul intern. Pentru fiecare specificator de format, din irul control, trebuie s fie introdus o valoare de tipul corespunztor de la tastatur. La apelul funciei scanf(), execuia programului se oprete i ateapt introducerea datelor de la tastatur. Programul va atepta pn vor fi introduse attea date, ci specificatori de format sunt n irul control. Dac se tasteaz mai multe date dect sunt necesare, atunci la apsarea tastei Enter, se vor citi numai numrul necesar de date. Datele tastate n plus vor fi ignorate (dar vor rmne n buferul tastaturii). Dup una sau mai multe date tastate, se apas Enter. Datele tastate sunt stocate n buferul tastaturii i numai dup apsarea tastei Enter ele sunt convertite n formatul intern i sunt stocate n locaiile determinate de adresele &p1,&p2,,&pn. Pentru o variabil ir de caractere s, n apelul scanf(), nu trebuie scris &s, ci numai s, deoarece numele s al irului de acum reprezint adresa de nceput a locaiei rezervate pentru ir. Un specificator de format ncepe cu semnul % i se termin cu una sau dou litere speciale. ntre caracterul % i prima liter mai pot fi i urmtoarele caractere cu semnificaie prestabilit: Un ir de cifre zecimale, determin numrul de caractere ce vor fi citite de la intrare pentru variabila curent; Un caracter * (asteric), citete valoarea curent de la tastatur, dar nu o stocheaz nicieri, n lista de adrese din scanf() pentru aceast valoare nu este indicat nici-o adres. n irul control, la apelul funciei scanf(), printre specificatorii de format, pot fi i texte opionale. Fiecare astfel de text trebuie s fie tastat (identic) la tastatur n locurile respective la tastarea datelor. Literele cu semnificaie special n specificatorii de format sunt urmtoarele: %c este folosit pentru introducerea unui caracter; %d este folosit pentru introducerea unui ntreg zecimal i conversia lui la tipul int; %i este folosit pentru introducerea unui ntreg zecimal i conversia lui la tipul int; %u este folosit pentru introducerea unui ntreg zecimal fr semn i conversia lui la tipul unsigned; %o este folosit pentru introducerea unui ntreg octal fr semn i conversia lui la tipul int; %x sau %X este folosit pentru introducerea unui ntreg hexazecimal fr semn i conversia lui la tipul int; pentru %x se folosesc cifrele hexazecimale 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f iar pentru %X cifrele 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; %s este folosit pentru introducerea unui ir de caractere, tablou de tipul char; %f este folosit pentru introducerea unui numr real i conversia lui la tipul float; %e sau %E este folosit pentru introducerea numerelor reale n format tiinific, cu exponent: [-]d.zzzzzz[e/E][+/-]rr, unde d este partea ntreag format dintr-o cifr, zzzzzz sunt cifre dup punctul zecimal i rr este exponentul; valoarea citit este convertit la tipul float; %g sau %G este folosit pentru introducerea numerelor reale i conversia lui la tipul float; %ld, %li, %lu, %lo, %lx, %lX introduce valori ntregi i le convertete la tipul long respectiv;

%lf, %le, %lE, %lg, %lG introduce valori reale i le convertete la tipul double; %Lf, %Le, %LE, %Lg, %LG introduce valori reale i le convertete la tipul long double. La tastare, datele de introdus pot fi separate prin spaii, tab (apsarea tastei Tab) sau apsarea tastei Enter. Citirea unei date ncepe cu primul caracter care nu este spaiu i se termin cu citirea caracterului dup care urmeaz un spaiu sau la citirea unui caracter ce nu corespunde specificatorului de format respectiv sau la citirea numrului de caractere indicat n specificator. La citirea de caractere, cu %c, cmpul citit conine un singur caracter, adic se introduce un singur caracter. Funcia scanf() nu poate fi folosit direct pentru citirea datelor din fiiere. Pentru aceasta este funcia fscanf(). Funcia sscanf() Citete date i le formateaz, ca i funcia scanf(), dar le citete nu de la intrarea standard, ci dintr-un ir de caractere. Are prototipul int sscanf(const char *buffer, const char *f, p1, p2, ...); n stdio.h. Apelul funciei se face printr-o construcie de forma sscanf( s, control, &p1,&p2,...,&pn ), unde p1,p2,...,pn sunt nume de variabile simple, iar &p1,&p2,...,&pn semnific adresele lor n memorie, unde vor fi stocate datele citite din irul s, dup convertirea lor din formatul extern n formatul intern, conform specificatorilor de format din parametrul control. n rest, funcia se comport ca i scanf().

2.6. Expresii i operanzi Expresia este o construcie format din operanzi i operatori. Operanzii reprezint datele care trebuie prelucrate, iar operatorii sunt operaiile de prelucrare a acestor date. Un operand este o constant, un identificator, un apel de funcie, o expresie. Operanzii au valoare i tip. Prin urmare, operatorii ce pot fi aplicai asupra operanzilor, depind de tipul acestora. Valoarea i tipul unui operand sunt determinate la compilare sau la execuie. O expresie are valoare i tip, ambele depind de valorile i tipurile operanzilor i sunt determinate la compilare sau le execuie. Deosebim expresii constante i expresii variabile. O expresie constant include doar constante, valoarea ei poate fi evaluat la compilare. Expresia variabil include i date variabile. Valoarea ei nu poate fi evaluat la compilare, ci n timpul execuiei programului.

2.7. Operatori Operatorii sunt operaiile de prelucrare a datelor. Sunt mai multe criterii de clasificare a operatorilor. Dup numrul de operanzi la care se aplic, deosebim operatori unari (se aplic la un singur operand), operatori binari (se aplic la doi operanzi) i operatori ternari. n C exist un sigur operator ternar, el se aplic la trei operanzi. Dup caracterul operaiei efectuate, sunt operatorii aritmetici, logici, de relaie .a. De obicei, ntr-o expresie sunt operatori de aceeai clas, dar pot fi i expresii destul de complicate, n care pot intra operatori de orice tip. La evaluarea valorii i tipului unei expresii se ine cont de prioritatea operaiilor, de asociativitatea lor i de regula conversiilor implicite. Operatori aritmetici. Operatorii unari + i -; + nu are efect, - schimb semnul valorii operandului. Operatori binari multiplicativi *, /, % i aditivi +, -. Operaia % (se mai numete operaia modulo) se aplic numai la valori ntregi i are ca rezultat restul mpririi ntregi a valorilor operanzilor si. Rezultatul mpririi, operatorul /, pentru doi operanzi ntregi, va fi un ntreg, partea ntreag a ctului, iar partea fracionar se pierde.

Operatori de relaie. Se folosesc pentru a compara dou valori numerice. Sunt 4 operaii: < (mai mic), <= (mai mare sau egal), > (mai mare), >= (mai mare sau egal). Operatori de egalitate. Se folosesc pentru a compara la egalitate dou valori numerice. Sunt 2 operatori: == (egal) i != (diferit). n C nu exist valori logice speciale. De aceea, rezultatul unei operaii de comparare (de relaie sau egalitate) este valoarea 1 sau 0 (de tipul int). De exemplu, valoarea expresiei 2<3 este 1, deoarece relaia este adevrat, iar valoarea expresiei 5!=5 este 0, deoarece relaia respectiv este fals. n C valoarea logic false (fals) se reprezint prin valoarea 0, iar valoarea logic true (adevr) se reprezint printr-o valoare diferit de 0. Operatori logici. Sunt trei: ! (negaia logic), && (i logic), || (sau logic). Expresia !x are valoarea 0 (false), dac x are o valoare diferit de 0 i are valoarea 1 (true), dac x are valoarea 0. Expresia x&&y are valoarea 1, dac i x i y au valori diferite de 0. n restul cazurilor, ea are valoarea 0. Expresia x||y are valoarea 0, dac i x i y au valoarea 0. n restul cazurilor, ea are valoarea 1. Atenie! Expresiile de tipul x&&y i x||y se evalueaz de la stnga la dreapta. Dac, dup evaluarea lui x se cunoate valoarea final a ntregii expresii, atunci nu se mai evalueaz y. Operatori logici pe bii. Se aplic la operanzi de tip ntreg. Dac e nevoie, operanzii se extind la 16 bii. Operaiile se execut bit cu bit. Operatorul ~ (complement fa de 1, se mai numete negare), este unar, schimb fiecare bit 1 al operandului n 0 i invers. Exemplu: ~12 . 12 n binar se reprezint ca 1100, extins la 16 bii va fi 0000 0000 0000 1100. Se aplic operaia complement fa de 1 i vom obine 1111 1111 1111 0011 sau n hexazecimal FFF3. Operatorul << (deplasarea biilor n stnga), deplaseaz biii primului operand n stnga cu un numr de poziii indicat de operandul al doilea. Exemplu: 12<<2. Va deplasa biii 0000 0000 0000 1100 (reprezentarea valorii 12 n binar pe 16 octei) n stnga cu 2 poziii i rezultatul va fi 0000 0000 0011 0000 sau 30 n hexazecimal sau 48 n zecimal. Pe poziiile biilor eliberai din dreapta se scrie 0. Valorile biilor cei mai din stnga dispar, se pierd. Operaia este echivalent cu nmulirea cu puteri ale lui 2. Operatorul >> (deplasarea biilor n dreapta), deplaseaz biii primului operand n dreapta cu un numr de poziii indicat de operandul al doilea. Exemplu: 12>>2. Va deplasa biii 0000 0000 0000 1100 (reprezentarea valorii 12 n binar pe 16 octei) n dreapta cu 2 poziii i rezultatul va fi 0000 0000 0000 0011 sau 3 n zecimal. Pe poziiile biilor eliberai din stnga se scrie 0, dac numrul deplasat e pozitiv sau zero i se scrie 1, dac numrul deplasat este negativ. Valorile biilor cei mai din dreapta dispar, se pierd. Operaia este echivalent cu mprirea cu puteri ale lui 2. Operatorul & (i logic pe bii). Se execut operaia logic i bit cu bit (1&1=1, 1&0=0, 0&1=0, 0&0=0). Se folosete la anularea biilor. Exemplu: Fie a un ntreg pe 16 bii, atunci a&0377 va avea ca valoare valoarea octetului mai puin semnificativ din valoarea a. ntradevr, valoarea octal 0377 se reprezint pe 16 bii ca 0000 0000 1111 1111. Dup efectuarea operaiei & ntre a i aceast constant, 8 bii ai lui a, cei din stnga, se vor anula, iar primii 8 bii, cei din dreapta, se vor pstra. Operatorul | (sau logic pe bii). Se execut operaia logic sau bit cu bit (1&1=1, 1&0=1, 0&1=1, 0&0=0). Se folosete la setarea biilor. Exemplu: fie a un ntreg, atunci valoarea expresiei a|1 are bitul cel mai nesemnificativ, adic cel mai din dreapta, egal cu 1, indiferent de valoarea lui a. Ceilali bii coincid cu biii lui a. Operatorul ^ (sau exclusiv logic pe bii). Se execut operaia logic sau exclusiv bit cu bit (1&1=0, 1&0=1, 0&1=1, 0&0=0). Se folosete pentru a anula sau a seta diferii bii. Exemplu: fie a un ntreg, atunci valoarea expresiei a^a are valoarea 0. Operatori de atribuire. n C atribuirea se face printr-o expresie de forma v=(expresie), unde = este operator de atribuire, v este numele unei variabile simple, numele unei variabile indexate, numele complet al unui cmp de structur sau chiar o expresie ce definete o adres de memorie. Operatorul de atribuire atribuie valoarea expresiei din dreapta sa variabilei din stnga sa. Dac e nevoie, se face, mai nti, conversia valorii din stnga la tipul variabilei din dreapta. Operatorul de atribuire are cea mai mic prioritate, de aceea

parantezele, din formatul expresiei de atribuire, pot fi omise: v=expresie. Expresia de atribuire are valoare i tip. Valoarea ei este valoarea atribuit, iar tipul este tipul variabile din stnga. Deci, construcia x=(v=expresie) este corect i reprezint o expresie de atribuire. Operatorii de atribuire se asociaz de la dreapta la stnga. Deci, putem omite parantezele: x=v=expresie. Operatorul de atribuire = poate fi combinat cu ali operatori n forma op=, unde op este un operator binar aritmetic sau un operator logic pe bii, adic unul din: *, /, %, +, -, <<, >>, &, |, ~. Expresia v op = expresie este echivalent cu expresia v = v op (expresie). Exemplu: x+=5 este echivalent cu x=x+5, iar z<<=2 este echivalent cu z=z<<2. Expresia de atribuire poate fi folosit oriunde n program, unde este legal o expresie. Operatorii ++ i -- se folosesc pentru incrementarea i decrementarea variabilelor. Sunt unari, ++ mrete, iar -- micoreaz valoarea operandului cu 1. Se folosesc n forma prefixata: ++x, --x i forma postfixat: x++, x--. n forma prefixat, ++x, mai nti se incrementeaz valoarea lui x, apoi rezultatul obinut se folosete. n forma postfixat, x++, mai nti se folosete valoarea x, apoi se incrementeaz valoarea lui x. Astfel, y=++x este echivalent cu x=x+1, y=x. Dar y=x++ este echivalent cu y=x, x=x+1. Evident, rezultatele vor fi diferite. Operatorul (tip), (se numete operator de conversie explicit) se folosete pentru a converti (explicit, forat) tipul unei expresii la tipul dorit. Tipul dorit se scrie n paranteze rotunde n faa operandului a crui tip trebuie convertit. Exemplu: double pi=3.14; int x; x=(int)pi+7; Expresiile de forma (tip)operand se numesc expresii cast, iar conversia explicit respectiv, se numete typecast. Operatorul sizeof (dimensiune) se folosete pentru a afla ci octei ocup n memorie o variabil de un anumit tip. Se folosete n forma: sizeof x sau sizeof(x) sau sizeof(tip). n primele 2 cazuri obinem numrul de octei ocupai n memorie de variabila x, n al treilea caz, numrul de octei alocai n memorie unei valori de tipul indicat. Dac x este numele unui tablou, vom obine numrul de octei alocai pentru ntregul tablou. La fel, dac x este numele unei structuri, vom obine numrul de octei alocai structurii respective. Operatorul & este operatorul adres, este unar. Se aplic pentru a determina adresa de nceput a memoriei alocate unei date. Pentru o variabila simpl sau o structur cu numele x, &x este adresa de nceput a memoriei alocatei variabile sau structurii respective. Dac x este numele unui tablou, atunci nsui numele x este adresa de nceput a tabloului, de aceea nu se mai cere folosirea operatorului &. Operatorii ( i ) (paranteze rotunde), se folosesc pentru a include n ele expresii, schimbnd astfel ordinea efecturii operaiilor. Nu orice operaie poate fi aplicat la o expresie inclus n paranteze rotunde. De exemplu, expresiile ++(a+b) i (b-a)-- vor fi greite. La funcii parantezele includ lista parametrilor, ntr-un apel de funcie, ele se numesc operatori de apel de funcie. Operatorii [ i ] (paranteze ptrate), se folosesc pentru a include n ele expresii ce reprezint, la un tablou de date, numrul de elemente sau indecii elementelor pentru a le accesa. Operatorii condiionali (? i :, se folosesc numai mpreun n acest context) ne permit folosirea expresiilor condiionale. O expresie, valoarea i tipul creia depind de o condiie, se numete condiional. O expresie condiional are forma e1?e2:e3, unde e1, e2, e3 sunt expresii. Evaluarea unei expresii condiionale se face n felul urmtor: Se evalueaz expresia e1. Dac ea are o valoare diferit de 0, adic are valoarea adevr, atunci se evalueaz expresia e2, valoarea creia i va fi valoarea expresiei condiionale. n caz, contrar, adic atunci cnd valoarea lui e1 este 0, adic are valoarea fals, atunci se evalueaz expresia e2, valoarea creia i va fi valoarea expresiei condiionale. Aceast expresie ne amintete de instruciunea if. Exemple: int x, y, c; ... c=x<y?x:y; va atribui lui c min(x,y), iar c=x<0?-x:x; va atribui lui c valoarea absolut a valorii x. Tipul valorii expresiei condiionale se determin dup regula conversiei implicite. Dac valorile pentru e1 i e2 sunt de tipuri diferite, atunci tipul cel mai mare va fi i tipul valorii expresiei condiionale. Astfel, pentru int x=2, n=3; float c=2.5; valoarea expresiei n>0?x:c are valoarea 2 de tipul float. Operatorul , (virgul, se mai numete operator secvenial) se folosete n construcii de tipul e1,e2,...,en. Aici e1,e2,...en sunt expresii, valoarea i tipul lor sunt evaluate pe rnd, de la stnga la dreapta. n final, expresia e1,e2,...,en va avea valoarea i tipul expresiei en. Se folosete acolo, unde se permite s scriem o singur expresie, dar avem nevoie s scriem mai multe. Exemplu: int x=10, y=20, z, t; t=(z=y/x, x+=y, x/5+2); Dup evaluare, aceste variabile vor fi: z=2, x=30, t=8, y=20. Operatorul * (operatorul de derefereniere) se folosete pentru accesarea coninutului unei zone de memorie cunoscute prin adresa ei. Astfel, dac p este un pointer cu o valoare concret, atunci *p este coninutul de pe adresa spre care face referin p. n acest context, operatorul & se numete i operator de refereniere, doar el face referin la o locaie din memorie.

10

Operatorii . (punct) i -> (sgeat) se folosesc pentru a face acces la componentele unei structuri. Exemplu, dac avem o structur s i c este un cmp al structurii, atunci s.c ne d accesul la cmpul c al structurii s. Analogic, dac w este un pointer spre o structur, iar d este un cmp al acelei structuri, atunci w->d ne d accesul la cmpul d spre care face referin pointerul w.

2.8. Regula conversiilor implicite La evaluarea valorii i tipului unei expresii se aplic regula conversiilor implicite, care const n urmtoarele. Se parcurge expresia i toi operanzii de tip char, short, enum (tipuri mai mici ca int) se convertesc la tipul int. Dup aceea, se execut operaiile, de obicei de la stnga la dreapta, n ordinea prioritilor lor. Dac o operaie binar este aplicat la doi operanzi de acelai tip, atunci se execut operaia i rezultatul va avea acelai tip ca i operanzii. Dac valoarea rezultatului iese din diapazonul tipului respectiv, atunci rezultatul va fi eronat. Dac operanzii sunt de tip diferit, atunci, mai nti operandul de tip mai mic se convertete la tipul celuilalt operand i numai dup aceea se execut operaia. Rezultatul va fi de tipul mai mare. Mai explicit, regula este: Dac un operand este de tipul long double, atunci i celalalt operand este convertit la tipul long double, i rezultatul operaiei va fi de tipul long double, altfel, Dac un operand este de tipul double, atunci i celalalt operand este convertit la tipul double, i rezultatul operaiei va avea tipul double, altfel, Dac un operand este de tipul float, atunci i celalalt operand este convertit la tipul float, i rezultatul va avea tipul float, altfel, Dac un operand este de tipul long unsigned, atunci i celalalt operand este convertit la tipul long unsigned, i rezultatul operaiei va avea tipul long unsigned, altfel, Dac un operand este de tipul long, iar altul este de tipul unsigned, atunci conversia depinde de rspunsul la ntrebarea dac tipul long poate reprezenta toate valorile tipului unsigned; dac rspunsul este pozitiv, atunci operandul de tip unsigned este convertit la tipul long i rezultatul va avea tipul long; n caz contrar, ambii operanzi sunt convertii la tipul long unsigned, i rezultatul va avea tipul long unsigned, altfel, Dac un operand este de tipul unsigned, atunci i celalalt operand este convertit la tipul unsigned, i rezultatul va avea tipul unsigned. Aceast regul se aplic pe rnd fiecrui operator pn, n final, se obine valoarea i tipul expresiei.

Anexa 1. Specificatori de format pentru funcia printf() Un specificator de format are forma %[cadraj][*/lime[.*/precizie]]liter[liter] cadraj implicit valoarea extras este aliniat la dreapta cmpului de extragere; prezena unui semn minus determin alinierea la stnga, iar un semn plus determin alinierea la dreapta; lime este un ir de cifre; determin limea cmpului de extragere; este ignorat, dac valoarea de extras cere mai mult poziii; valoarea este aliniat conform cadrajului, dac rmn poziii libere ele sunt umplute cu spaii; dac limea are prima cifr 0, atunci poziiile libere din stnga sunt umplute cu 0; poate fi specificat cu un semn *, atunci valoarea pentru lime se calculeaz din argumentul respectiv urmtor al funciei printf(), care trebuie s fie de tip int;

11

precizie este un ir de cifre; indic precizia cu care se va scrie valoarea extras; dac se extrage un numr, arat numrul de cifre dup punctul zecimal, se face rotunjire dac e cazul; dac se extrage un ir de caractere, precizia arat numrul maxim de caractere care se va extrage din irul respectiv; poate fi specificat cu un semn *, atunci valoarea pentru precizie se calculeaz din argumentul respectiv urmtor al funciei printf(), care trebuie s fie de tip int; liter[liter] pot fi una sau dou litere cu semnificaia din tabelul ce urmeaz; dac valoarea pentru liter este diferit din cele indicate n tabel, atunci rezultatul este imprevizibil.

Specificator %c %s

Semnificaie Extrage un caracter Extrage un ir de caractere

Observaii Numrul ntreg din memorie este interpretat ca un cod ASCII Extrage caractere din ir pn la primul caracter nul (\0); dac n specificator e indicat precizia .p, atunci extrage cel mult p caractere din ir Pentru numere negative extrage semnul -, pentru pozitive nu extrage semnul + Numrul ntreg din memorie este interpretat ca unsigned Numrul ntreg din memorie este interpretat ca unsigned i este extras n octal, fr 0 n fa Numrul ntreg din memorie este interpretat ca unsigned i este extras n hexazecimal, fr 0x sau 0X n fa, folosete abcdef sau ABCDEF pentru 10,11,...,15 Pentru numere negative extrage semnul -, pentru pozitive nu extrage semnul + dar extrage un spaiu Numrul ntreg din memorie este interpretat ca long unsigned Numrul ntreg din memorie este interpretat ca long unsigned i este extras n octal, fr 0 n fa Numrul ntreg din memorie este interpretat ca long unsigned i este extras n hexazecimal, fr 0x sau 0X n fa, folosete abcdef sau ABCDEF pentru 10,11,...,15 Pentru numere negative extrage semnul -, pentru pozitive nu extrage semnul + dar extrage un spaiu Numrul ntreg din memorie este interpretat ca short unsigned Numrul ntreg din memorie este interpretat ca short unsigned i este extras n octal, fr 0 n fa Numrul ntreg din memorie este interpretat ca short unsigned i este extras n hexazecimal, fr 0x sau 0X n fa, folosete abcdef sau ABCDEF pentru 10,11,...,15

%d %i %u %o %x %X

Extrage n zecimal valori de tipul int sau char Extrage n zecimal valori de tipul unsigned sau unsigned char Extrage n octal valori de tipul unsigned sau unsigned char Extrage n hexazecimal valori de tipul unsigned sau unsigned char Extrage n zecimal valori de tipul long Extrage n zecimal valori de tipul long unsigned Extrage n octal valori de tipul long unsigned Extrage n hexazecimal valori de tipul long unsigned Extrage n zecimal valori de tipul short Extrage n zecimal valori de tipul unsigned short Extrage n octal valori de tipul unsigned short Extrage n hexazecimal valori de tipul unsigned short

%ld %li %lu %lo %lx %lX

%hd %hi %hu %ho %hx %hX

12

%f %e %E

Extrage numere reale zecimale de tipul float sau double n forma [-]m.nnnnnn Extrage numere reale zecimale de tipul float sau double n format tiinific [-]m.nnnnnn[e/E][+/-]rr Este ca f sau e,E; alege acel format, care ocup un numr minim de poziii Extrage numere reale zecimale de tipul double (long float) Extrage numere reale zecimale de tipul double (long float) n format tiinific Este ca lf sau le,lE; alege acel format, care ocup un numr minim de poziii Extrage numere reale zecimale de tipul long double Extrage numere reale zecimale de tipul long double n format tiinific Este ca Lf sau Le,LE; alege acel format, care ocup un numr minim de poziii Extrage valoarea unui pointer

6 cifre dup punctul zecimal; dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal O cifr n partea ntreag, 6 cifre dup punctul zecimal, 2 cifre n exponent. Dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal Extrage dup punctul zecimal numai cifre semnificative; dac nu sunt cifre semnificative, nu extrage nici punctul 6 cifre dup punctul zecimal; dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal O cifr n partea ntreag, 6 cifre dup punctul zecimal, 2 cifre n exponent. Dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal Extrage dup punctul zecimal numai cifre semnificative; dac nu sunt cifre semnificative, nu extrage nici punctul 6 cifre dup punctul zecimal; dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal O cifr n partea ntreag, 6 cifre dup punctul zecimal, 2 cifre n exponent. Dac n specificator este indicat precizia 0, atunci lipsete i punctul zecimal Extrage dup punctul zecimal numai cifre semnificative; dac nu sunt cifre semnificative, nu extrage nici punctul Extrage adresa de nceput a locaiei spre care arat pointerul p; de obicei extrage valoarea n hexazecimal, dar depinde de implementare Argumentul respectiv trebuie s fie un pointer spre int; nu este convertit nici un argument Nu este convertit nici un argument

%g %G %lf %le %lE

%lg %lG %Lf %Le %LE

%Lg %LG %p

%n

Extrage, n argumentul respectiv, numrul de caractere extrase pn n momentul de fa de apelul curent al funciei printf() Extrage caracterul %

%%

Anexa 2. Specificatori de format pentru funcia scanf()

Specificator %c

Semnificaie Introduce un caracter

Observaii Urmtorul caracter de la intrare este stocat pe adresa indicat; nu se face salt peste spaiile albe; pentru a citi urmtorul caracter diferit de spaiu alb, folosii %1s irul nu se afl n ghilimele; destinaia trebuie s fie un tablou de caractere destul de mare pentru a stoca irul citit i un caracter

%s

Introduce un ir de caractere

13

terminator \0 care va fi adugat automat %d %i Introduce un numr ntreg zecimal Introduce un numr ntreg Numrul citit este interpretat ca zecimal i este convertit la int Numrul citit este interpretat ca zecimal, dac nu are 0 n fa; ca octal, dac are 0 n fa; ca hexazecimal, dac are 0x sau 0X n fa; este convertit la int Numrul citit este convertit la unsigned Numrul citit este interpretat ca octal; poate fi cu 0 sau nu n fa; este convertit la int Numrul citit este interpretat ca hexazecimal; poate fi cu 0x sau 0X sau nu n fa; este convertit la int Numrul citit este interpretat ca zecimal i este convertit la long Numrul citit este interpretat ca zecimal, dac nu are 0 n fa; ca octal, dac are 0 n fa; ca hexazecimal, dac are 0x sau 0X n fa; este convertit la long Numrul citit este convertit la long unsigned Numrul citit este interpretat ca octal; poate fi cu 0 sau nu n fa; este convertit la long Numrul citit este interpretat ca hexazecimal; poate fi cu 0x sau 0X sau nu n fa; este convertit la long Numrul citit este interpretat ca zecimal i este convertit la short Numrul citit este interpretat ca zecimal, dac nu are 0 n fa; ca octal, dac are 0 n fa; ca hexazecimal, dac are 0x sau 0X n fa; este convertit la short Numrul citit este convertit la short unsigned Numrul citit este interpretat ca octal; poate fi cu 0 sau nu n fa; este convertit la short Numrul citit este interpretat ca hexazecimal; poate fi cu 0x sau 0X sau fr n fa; este convertit la short Numrul citit poate avea semn opional, punct zecimal opional i exponent opional; este convertit la float Numrul citit poate avea semn opional, punct zecimal opional i exponent opional; este convertit la double Numrul citit poate avea semn opional, punct zecimal opional i exponent opional; este convertit la long double Numrul citit este interpretat ca adres de memorie Nu citete nimic de la intrare; numrul de valori convertite nu este

%u %o %x %X %ld %li

Introduce un numr ntreg zecimal fr semn Introduce un numr ntreg octal Introduce un numr ntreg hexazecimal Introduce un numr ntreg zecimal Introduce un numr ntreg

%lu %lo %lx %lX %hd %hi

Introduce un numr ntreg zecimal fr semn Introduce un numr ntreg octal Introduce un numr ntreg hexazecimal Introduce un numr ntreg zecimal Introduce un numr ntreg

%hu %ho %hx %hX %f %e %E %g %G %lf %le %lE %lg %lG %Lf %Le %LE %Lg %LG %p %n

Introduce un numr ntreg zecimal fr semn Introduce un numr ntreg octal Introduce un numr ntreg hexazecimal Introduce un numr n virgula mobil Introduce un numr n virgula mobil Introduce un numr n virgula mobil

Introduce o valoare de tip pointer, aa cum o extrage printf() cu %p Nu introduce nimic; scrie pe adresa respectiv

14

numrul de caractere citite pn n momentul de fa %% %[...] Citete caracterul % care trebuie s fie la intrare Citete un ir de caractere format numai din caractere indicate n paranteze Citete un ir de caractere format numai din caractere diferite de cele indicate n paranteze

incrementat Nu are argument de atribuire, nu face nici-o conversie Destinaia trebuie s fie un tablou de caractere destul de mare pentru a stoca irul citit i un caracter terminator \0 care va fi adugat automat Destinaia trebuie s fie un tablou de caractere destul de mare pentru a stoca irul citit i un caracter terminator \0 care va fi adugat automat

%[^...]

Anexa 3. Precedena operatorilor n tabelul de ce urmeaz este artat prioritatea operatorilor C n ordinea descreterii i asociativitatea lor.

Operatori () [] . -> + - & * (unari) ++ -- (tip) sizeof ! ~ * (binar) / % * (binar) / % + - (binari) << >> < <= > >= == != & (binar ^ |&& || ?: = <<= >>= += -= *= /= %= &= ^= |= ,

Asociativitate de la stnga la dreapta de la dreapta la stnga

Prioritate maxim

de la stnga la dreapta

de la dreapta la stnga de la stnga la dreapta minim

15

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