You are on page 1of 106

Sergiu G.

Istrati

PROGRAMARE
Iniializare n limbajele C i C++

Ciclu de prelegeri la disciplina Programare

Chiinu 2003

Adnotare
Lucrarea de fa este destinat studenilor anilor I i II seciile de nvmnt de zi i fr frecven a Universitii Tehnice a Moldovei ce studiaz disciplina Programare i n special studenilor Facultii de Radioelectronc i Telecomunicaii catedra Sisteme Otpoelectronice cu specializrile 1871 Inginerie i Management n Telecomunicaii i 2105 Sisteme Optoelectronice.

Autor: lector superior Sergiu G.Istrati

Redactor responsabil: conf. univ. dr. Pavel Nistiriuc

Recenzent: academician, dr. hab. Victor I. Borevici

U.T.M. 2003

Cuprins Limbajul de programare C/C++ ntroducere 1. Alfabetul limbajului 2. Structura unui program 3. Tipuri de date 3.1. Tipuri de date simple predefinite. Constante 3.1.1. Constante ntregi 3.1.2. Constante reale 3.1.2. Constante character 3.1.3. iruri de caractere 4. Variabile 4.1. Nume de variabile (identificatori) 4.2. Descrierea variabilelor 4.3. Iniializarea variabilelor 5. Operaii i expresii 5.1. Operaii aritmetice 5.2. Operaia de atribuire 5.3. Operaii de incrementare(decrementare) 5.4. Relaii i operaii logice 5.5. Operaiile logice poziionale 5.6. Operaia dimensiune 5.7. Operaia virgul 5.8. Expresii condiionate 5.9. Conversii de tip 5.10. Prioritile operaiilor 6. Instruciuni 6.1. Tipurile instruciunilor 6.2. Instruciuni expresie 6.3. Instruciuni de ramificare (condiionale) 6.3.1. Instruciunea de ramificare IF i IF-ELSE 6.3.2. Instruciunea de salt necondiionat GOTO 6.3.3. Instruciunea de selectare SWITCH 6.3.4. Instruciunea de ntrerupere BREAK 6.4. Instruciuni iterative(ciclice) 6.4.1. Instruciunea ciclic FOR 5 6 8 12 12 12 14 15 16 16 16 16 17 18 18 18 18 19 20 22 22 23 23 25 26 26 27 28 28 29 30 32 33 33

6.4.2. Instruciunea ciclic WHILE 6.4.3. Instruciunea de ciclare DO_WHILE 6.4.4. Instruciunea de continuare CONTINUE 7. Masive 7.1. Descrierea masivelor 7.2. Accesul la elementele masivului 7.3. Iniializarea masivelor 7.4. Exemple de prelucrare a masivelor 8. iruri de caractere 8.1. Masive de iruri 9. Structuri n C/C++ 9.1. Declararea variabilelor de tip structur 9.2. Iniierea variabilelor tip nregistrare 9.3. Folosirea structurilor 9.4. Structuri imbricate 9.5. Masive de structuri 10. Funcii n C/C++ 10.1. Transmiterea parametrilor n funcie 10.2. ntoarcerea valorilor din funcie 10.3. Prototipul funciei 10.4. Variabile locale i domeniul de vizibilitate 10.5.Variabile globale 10.6. Conflicte dintre variabile locale i globale 11. Indicatori (pointeri) 11.1. Indicatori i funcii 12. Fiiere n C/C++ 12.1. Deschiderea fiierelor 12.2. Funcii de nscriere/citire din fiier 12.2.1. nscriere/citire de caractere 12.2.2. nscriere/citire de iruri 12.2.3. ntrare/ieire cu format 12.2.4. Fiiere i structuri Anexa1. Funcii de intrare-ieire n C/C++ Anexa 2. Funcii matematice Anexa 3. Funcii folosite la prelucrarea irurilor de caractere

34 35 36 36 36 37 38 40 41 43 44 45 45 46 47 47 49 52 54 56 57 59 60 61 64 68 70 73 74 75 77 78 81 89 97

ntroducere Scopul prezentei lucrri este familiarizarea studenilor cu principalele instrumente i metode de programare n limbajele C i C++. Limbajul de programare C a fost elaborat de ctre Denis M.Ritchi n 1972 i descris detaliat n cartea Limbajul de programare C de Ritchi i Brian B.Kernigan. Realizarea limbajului n conformitate cu regulile descrise n carte poart denumirea de Standard C K&R i este realizarea standard minimal. n 1983 a fost creat un nou standard C de ctre American National Standards Institute numit Standard ANSI-C. Mai apoi a fost elaborat limbajul C++ ca o derivat a limbajului C. n aa fel limbajul C++ posed marea majoritate a posibilitilor limbajului ANSI-C i n plus la acestea alte instrumente de programare cu posibiliti mai avansate. Lucrarea de fa conine descrierea att a instrumentelor din limbajul ANSI-C ce snt susinute i de copmpilatoarele C++, ct i descrierea instrumentelor de programare ale limbajului C++. Deasemenea n lucrare este atras o deosebit atenie exemplelor practice de rezolvare a diferitor tipuri de probleme cu lmurire detaliat. Prezenta lucrare este o parte din suita de lucrri didactico- metodice elaborate de ctre lectorul superior Sergiu G. Istrati ndreptate spre optimizarea procesului de instruire a studenilor la disciplina Programare. Au fost elaborate urmtoarele lucrri: Ciclu de prelegeri la disciplina Programare. Limbajul Pascal. Ciclu de prelegeri la disciplina Programare. Limbajul C. (prezenta lucrare) ndrumar metodic privind ndeplinirea lucrrilor de laborator. ndrumar metodic privind ndeplinirea lucrrilor individuale. ndrumar metodic privind ndeplinirea lucrrii de curs. Toate aceste lucrri pot fi accesate n Internet pe adresa www.istrati.com

Limbajul de programare C. 1. Alfabetul limbajului. Numim limbaj de programare un limbaj prin care putem comunica unui calculator metoda de rezolvare a unei probleme. Iar metoda de rezolvare a problemei, dup cum tim deja o numim algoritm. ntreaga teorie informatic se ocup de fapt cu elaborarea unor noi calculatoare, limbaje de programare i algoritmi. Datoria oricrui limbaj de nivel nalt este s ne pun la dispoziie o sintax ct mai comod prin care s putem descrie datele cu care lucreaz programul nostru i instruciunile care trebuiesc executate pentru a rezolva o anumit problem. Limbajul de programare C ca i orice alt limbaj de programare i are alfabetul su i specificul de utilizare a simbolurilor. Alfabet al unui limbaj de programare se numete un set de simboluri permis pentru utilizare i recunoscut de compilator, cu ajutorul cruia pot fi formate mrimi, expresii i operatori ai acestui limbaj de programare. Alfabetul oricrui limbaj de programare conine cele mai simple elemente cu semnificaie lingvistic, iar sintaxa limbajului definete modul n care se combin elementele vocabularului pentru a obine fraze corecte (instruciuni, secvene de instruciuni, declarri de tipuri, variabile, constante, etichete, funcii, proceduri etc.). Elementele vocabularului sunt alctuite din caractere. Orice caracter este reprezentat n calculator, n mod unic, printr-un numr natural cuprins ntre 0 i 127, numit cod ASCII. Mulimea elementelor alfabetului limbajului de programare C se poate mpri n 5 grupe: 1) Simboluri folosite la formarea identificatorilor i cuvintelor cheie. n componena aceastei grupe intr literele minuscule i majuscule ale alfabetului latin (englez) i simbolul subliniere _. Este de menionat faptul c literele minuscule i majuscule de acelai fel (Exemplu: a i A) sunt interpretate ca simboluri diferite din cauza c au diferite coduri ASCII. ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz _ 2) Literele minuscule i majuscule ale alfabetului rus (sau altui alfabet naional) i cifrele arabe. 0123456789 3) Simboluri speciale ce se folosesc le organizarea proceselor de calcul i la transmiterea compilatorului unui set de instrunciuni.

Simbolul , . ; : ? ' ! | / \ ~ * + -

Denumirea Virgul Punct Punct-virgul Dou puncte Semnul ntrebrii Apostrof Semnul exclamrii Linie vertical Slash Slash inversat Tilda Stelua Plus Minus

Simbolul ) ( } { < > [ ] # % & ^ = "

Denumirea Parantez rotund nchis Parantez rotund deschis Parantez figurat nchis Parantez figurat deschis Mai mic Mai mare Parantez patrat deschis Parantez patrat nchis Numr (diez) Procent Ampersand Negare logic Egal Ghilimele

4) Simboluri de conducere i de desprire. n componena acestei grupe intr spaiul (blank-ul), simbolul tabulare, simbolul de trecere n rnd nou, ntoarcerea cruciorului, linie nou i pagin nou. Aceste simboluri au destinaia de a despri obiectele determinate de utilizator aa ca constante i identificatori. O consecutivitate de simboluri de desprire este precautat de ctre compilator ca un singur simbol. (Exemplu: mai multe blank-uri consecutive). 5) Pe lng grupele de simboluri precutate limbajul C pe larg folosete consecutiviti de conducere, adic combinaii de simboluri speciale folosite n funciile de intrare-ieire a informaiei. Consecutivitatea de conducere este alctuit dintr-un slash inversat (\), care se afl neaprat pe primul loc, dup care urmeaz o combinaie din litere latine i cifre. Consecutivitatea de conducere \a \b \t \n \v Echivalentul hexazecimal 007 008 009 00A 00B

Denumirea Sunet (beep) ntoarcere cu o poziie Tabulare orizontal Trecere n rnd nou Tabulare vertical
7

\r \f \" \' \0 \\ \ddd (d-cifr) \xddd (d-cifr)

ntoarcerea cruciorului Trecerea n alt format Ghilimele Apostrofa Simbolul zero Slash inversat Simbolul grupului de coduri PC n sistemul octal Simbolul grupului de coduri PC n sistemul hexazecimal

00C 00D 022 027 000 05C

Consecutivitatea de tipul \ddd i \xddd (aici prin d este notat o cifr orecare) permite a scrie un cod al calculatorului ca o consecutivitate de cifre octale sau hexazecimale respectiv. De exemplu simbolul de ntoarcere a cruciorului poate fi interpretat n diferite moduri: \r consecutivitatea general de conducere, \015 consecutivitatea octal de conducere, \x00D - consecutivitatea hexazecimal de conducere. n afar de aceasta n limbaj sunt rezervate cuvinte de serviciu, numite cuvinte cheie care pot fi folosite ntr-un sens strict definit: int, float, double, char, long, signed, unsigned, const, volatile, sizeof, if, else, goto, case, default, for, while, do, break, continue, near, far, void, return, pascal, cdecl, intrrupt, auto, extern, static, register, union, enum, typedef, asm, _cs. _ds, _es, _ss, _AH, _AX, _BX, _BL, _CH, _CL, _CX, _DX, _DL, _BP, _DI, _SI, _SP. Cuvintele cheie definesc sensul semantic al instruciunilor din C. Cuvintele cheie ce ncep cu semnul _ (subliniere) se folosesc pentru acces la segmentele de date i la registrele calculatorului. Prin sintaxa unui limbaj de programare se nelege, n general, un ansamblu de reguli de agregare a unitilor lexicale pentru a forma structuri mai complexe (instruciuni, declaraii, programe etc.) Structura unui program n limbajul de programare C deasemenea i are regulile ei de sintax dup cum urmeaz: un antet, urmat de funciile secundare dup care urmeaz corpul funciei principale (care conine n componena sa i o parte declarativ). i pentru descrierea n detaliu a acestor componente sunt necesare, desigur i alte reguli. 2. Structura unui program. Pentru a primi o reprezentare general a programului n C s urmrim un exemplu concret. Presupunem, c exist un masiv unidimensional x cu n elemente de

tip ntreg i e necesar s alctuim un program, care calculeaz i afiaz suma elementelor ntregului masiv. Aceasta este o problem tipic pentru prelucrarea masivelor unidimensionale. n concepiile limbajului C fiecare algoritm evideniat se realizeaz de o unitate de program numit funcie. Stilul de programare n C se caracterizeaz prin tendina de a evidenia un numr mare de funcii nu prea voluminoase, astfel, ca prelucrarea datelor n aceste funcii s nu depind de celelalte pri a programului. Acest lucru face programul destul de neles i d posibilitatea de a introduce uor corecii n unele funcii fr a tangenta celelalte. Prin funciile evideniate unica cu care ncepe ndeplinirea programului se numete principal i are denumirea fixat: main. Toate celelalte funcii au denumire arbitrare, pe care programatorul singur le numete. Ele pot fi nscrise n fiierul iniial pn la funcia main (n ordine arbitrar) sau se pot afla n fiiere diferite pe un suport magnetic. n programul de mai jos, ce realizeaz rezolvarea problemei intr funcia main() i funcia numit suma(). S analizm acest program: # include<stdio.h> # include<conio.h> int suma (int y[10], int m) { int i, suma=0; for (i=0;i<m;i++) { suma +=y[i]; } return (suma); } void main (void) { int w,n,i,x[10]; clrscr( ); printf("Culege marimea masivului n<10\n"); scanf("%d", &n); printf("Culege masivul x[%d]\n",n); for (i=0;i<n;i++) { printf("Culege elementul x[%d]\n",i); scanf("%d",&x[i]); } w=suma(x,n); printf("suma=%d\n",w); getch( ); } Primele dou rnduri: #include <stdio.h> i #include <conio.h> nu snt instruciuni ale limbajului C. Simbolul # indic c acestea snt directive ale procesorului. Procesorul execut prelucrarea prealabil a textului programului nainte de compilare. n cazul dat, aceste directive ne dau de neles c n fiierul ce se compileaz trebuie introdus informaia din fiierele sistemului Turbo C stdio.h

(Standard Input/Output Header titlu de introducere-extragere) i conio.h (Console Input / Output Header- titlu de introducere-extragere de la consol). Existena acestor directive este condiionat de faptul c n textul programului snt folosite funciile ncorporate printf() i clrscr(), informaia despre care se conine n fiierele indicate. Urmatorul rnd int suma (int y[10], int m) conine declararea functiei suma() cu 2 parametri: un masiv y[10] i o variabila simpla m de tip ntreg. Aici e necesar de menionat faptul, c n limbajul C orice program ncepe de la funcia principal main(), independent de faptul cte funcii auxiliare se conin n program. Lund n consideraie acest fapt, funcia suma() va fi analizat la momentul cnd apelul ei va fi efectuat din corpul funciei principale main(). Rndul din program: void main (void) definete titlul funciei principale cu numele main(). Cuvntul void din faa funciei semnific faptul, c aceast funcie nu va ntoarce valori n procesul execuiei sale. Parantezele rotunde ce urmeaza dup main() indic compilatorului c aceasta este o funcie, iar cuvntul void din paranteze faptul c funcia nu folosete parametri. Perechea acoladelor: prima ce se deschide dup main() i corespunztor acolada ce se nchide dup funcia getch(); mrginete instruciunile care formeaz corpul funciei principale main(). n limbajul C perechea de accolade {} mrginete o secven de instruciuni care se precaut ca un tot ntreg. Urmtoarul rnd conine descrierea variabilelor folosite n funcia principal main(): int w,n,i,x[10]; care transmite compilatorului c n program vor fi folosite variabilele w,n i i de tip ntreg i un masiv x cu mrimea de 10 elemente de tip ntreg. Dup descrierea datelor urmeaz instruciunea de adresare la funcia clrscr() ncorporat n biblioteca conio.h din Turbo C. Aceast funcie are destinaia de curire a ecranului. Dup ea urmeaz funcia printf(), care afiaz pe ecran un comentariu. n acest caz funcia printf("Culege marimea masivului n<10\n"); afiaz pe ecran propunerea de a culege mrimea masivului i simbolul \n de trecere n alt rind. Funcia urmtoare scanf("%d", &n); este o funcie de intrare i face posibil introducerea de la tastatur a valorii mrimii masivului n. Simbolul %d indic funciei c valoarea citit este de tip ntreg, iar simbolul & indic adresa de memorie unde va fi nscris valoarea lui n. Funcia printf("Culege masivul x[%d]\n",n); deasemenea afiaz un comentariu pe ecran i propune culegerea valorilor elementelor masivului x cu marimea n deja cunoscut. Urmtoarea instruciune este instruciunea ciclic for. Aceast instruciune este compus i are ca sarcin repetarea unui set de instruciuni de cteva ori cu diferite valori ale parametrilor. for (i=0;i<n;i++) {printf("Culege elementul x[%d]\n",i); scanf("%d",&x[i]);}

10

aici cuvntul for este cuvnt rezervat, i-parametrul ciclului, care-i schimb valoarea de la 0 la n cu pasul 1 datorit instruciunii de incrementare i++. Corpul ciclului, care va fi repetat de n ori este mrginit de perechea de accolade deschis i nchis, i este compus din 2 funcii: prima printf(), care afiaz un comentariu pentru culegerea valorii elementului current al masivului i a doua scanf(), care face posibil nscrierea valorii elementului current al masivului de la tastatur n memorie. n aa fel, la sfritul ndeplinirii ciclului toate elementele masivului x[n] vor avea valori, fapt ce face posibil calcularea sumei totale a elementelor din masiv. Dup executarea instruciunii ciclice for urmeaz instruciunea de atribuire w=suma(x,n);. n partea dreapt a acestei atribuiri este amplasat funcia suma(). Anume valoarea acestei funcii, dup executarea cu folosirea parametrilor locali x i n, va fi atribuit variabilei w. S analizm funcia suma(): int suma (int y[10], int m) { int i, suma=0; for (i=0;i<m;i++) { suma +=y[i]; } return (suma); } Ca i la declararea oricrei funcii n limbajul C nti de toate urmeaz antetul funciei: int suma (int y[10], int m) , unde cuvntul int din faa numelui funciei suma este tipul valorii ntors de funcie n programul principal main(). Parantezele rotunde dup numele funciei mrginesc lista de parametri formali folosii de funcie. Aceti parametri snt un masiv de tip ntreg y cu lungimea 10 elemente i o variabil de tip ntreg m. Este de menionat faptul c la momentul chemrii funciei suma() din cadrul programului principal main(), valorile parametrilor actuali (n cazul nostru x-masivul prelucrat i n-mrimea lui) snt atribuite parametrilor formali din funcie (n cazul nostru masivul y i marimea lui m) i este necesar ndeplinirea urmtoarei condiii: parametrii actuali trebuie s corespund ca cantitate, poziie i tip cu parametrii formali. Acoladele deschis dup antetul funciei i corespunztor nchis dup operatorul return(); delimiteaz corpul funciei suma(), care i are i ea seciunea de declarare a datelor. Aici int i, suma=0; declar variabila local i de tip ntreg i iniializeaz funcia suma() cu valoarea 0. Urmtoarea este instruciunea ciclic for care conine n corpul su delimitat de accolade o singur instruciune: instruciunea compus de atribuire suma+=y[i]; echivalent cu instruciunea suma=suma+y[i]; care calculeaz suma elementelor din masiv. Ciclul va fi repetat de m ori cu diferite valori a parametrului i, unde m este mrimea masivului, adic cantitatea elementelor din masiv, iar i-numrul de ordine a elementului current din masiv. Dup executarea ciclului variabila suma va conine valoarea final a sumei tuturor elementelor din masiv. Transmiterea acestei valori funciei principale main() este efectuat de ctre operatorul retun(suma); . Dup executarea acestui operator valoarea sumei va fi

11

inclus n locul de unde a fost chemat funcia suma(), n cazul nostru aceasta este instruciunea de atribuire w=suma(x,n); Deci, valoarea sumei elementelor masivului va fi atribuit variabile w. Dup aceasta urmeaz afiarea pe ecran a rezultatului final: printf("suma=%d\n",w); . Ultima instruciune din program este apelul la funcia getch(), care oprete executarea programului cu scopul vizualizrii rezultatului pn cnd nu va fi culeas tasta Enter. n aa fel poate fi descris structura general a unui program n C dup cum urmeaz: orice program ncepe cu includerea bibliotecilor de funcii care vor fi folosite n program, dup aceasta urmeaz declararea tuturor funciilor auxiliare folosite n program, care au urmtoarea componen: antetul funciei, secia de declarare a variabilelor, constantelor locale, dup care urmeaz corpul funcei; dup declararea tuturor funciilor auxiliare urmeaz corpul funciei principale main() delimitat de o pereche de accolade, care conine descrierea variabilelor, constantelor i nsi instruciunile programului principal. 3. Tipuri de date. Un program n limbajul C conine o descriere a aciunilor ce trebuie s fie executate de calculator i o descriere a datelor ce sunt prelucrate de aceste aciuni. Aciunile snt descrise prin instruciuni, iar datele prin declaraii (sau definiii).Prin tip de date se nelege o mulime de valori care pot fi atribuite unei variabile sau constante. Tipurile de date n C pot fi mprite n dou categorii: simple (elementare) i compuse (structurate). n general, tipurile de date sunt definite explicit de ctre programator i sunt specifice programului n care apar. Exist ns tipuri de date elementare de interes mai general, numite tipuri predefinite a cror definiie se consider cunoscut i nu cade n sarcina programatorului. 3.1. Tipuri de date simple predefinite. Constante. Un program n C conine n mod explicit diferite valori textuale i numerice. Aa valori, ce apar n program, snt numite constante. Constanta este o valoare numeric sau textual, care ntotdeauna este definit i n mersul ndeplinirii programului rmne neschimbat. Tipul constantei se definete de forma ei de nscriere, iar valoarea ei este ncheiat n ea nsei. 3.1.1. Constante ntregi. Constanta ntreag este un numr nscris n program fr punct zecimal i fr indicatorul de putere. Constantele ntregi n C pot fi: Zecimale, Octale, Hexazecimale.

12

Sistemul de enumerare a constantelor este recunoscut de compilator dup forma lor de nscriere.Dac constanta este nscris prin intermediul cifrelor 0..9 i prima cifr nu e zero, atunci constanta se consider zecimal. De exemplu: 123, 45, 37. Dac constanta este nscris folosind cifrele 0..7 i prima cifr este zero, atunci constanta se consider octal. De exemplu: 045, 037. Dac constanta este nscris cu ajutorul cifrelor 0..9 i literelor a..f sau A..F i se ncepe cu 0x sau 0X, atunci constanta este hexazecimal. De exemplu: 0x45, 0x37. n aceste exemple constantele nscrise cu unele i aceleai cifre au valori diferite, ce se definesc de baza sistemului de enumerare. Pentru determinarea constantelor de tip ntreg sunt folosite diferite cuvinte rezervate, care determin diapazonul valorilor i volumul de memorie rezervat pentru constant. Tipul int Short (short int) Long (long imt) unsigned int unsigned long Volumul de memorie (octei) 2 2 4 2 4 Diapazonul de valori -32768 32767 0 255 -2 147 483 648 2 147 483 647 0 65 535 0 4 294 967 295

n dependen de valoarea constantei, compilatorul aloc pentru reprezentarea ei n calculator doi sau patru octei de memorie. Pentru valorile -32768...32767 se aloc doi octei, unde primul bit se interpreteaz ca semnul constantei, iar 15 bii rmai definesc valoarea ei. n aa caz constanta este de tipul int (ntreg). Pentru valorile de la 0 65535 se aloc doi octei de memorie, ns toi 16 bii definesc valoarea constantei. Aa fel de constant are tipul unsigned int (ntreg fr semn). Constantele acestui diapazon, nscrise cu semnul minus se cerceteaz ca fr semn, la care se aplic operaia minus unar. Pentru valorile de la -2 147 483 648 pna la 2 147 483 647 se aloc 4 octei, la care primul bit se interpreteaz ca semn, iar 31 de bii rmai ca valoare a numrului. Aa constante au tipul long (lung). Pentru valorile de la 0 pna la 4 294 967 295 se aloc 4 octei, la care toi 32 de bii se interpreteaz ca valoare. Aa constant are tipul unsigned long (lung fr semn). Pentru acest tip la constantele negative se aplic operaia minus unar. Analogic se aloc memorie pentru constantele octale i hexazecimale, aflate n diapazonul zecimal respectiv.
13

Constantele, ce snt nscrise n program sub forma unui numr mai mare ca 4 294 967 295 aduc la suprancrcare, ns compilatorul nu face prentmpinare, iar n memorie se nscriu biii inferiori ai constantei trunchiate. Programatorul are posibilitate de a indica explicit compilatorului, c pentru o oarecare constant este necesar de alocat 4 octei i de a indica interpretarea lor ca fr semn (unsigned). Pentru aceasta se folosesc modificatori speciali, nscrii dup cifra mai mic a constantei. Pentru a indica, c constanta are tipul long, trebuie de nscris modificatorul L sau I ( se permite de asemenea i l sau i). n standardul K&R C iniializarea constantelor de tipul ntreg are urmtoarea sintax: #define name value care este plasat pn la funcia main(). Unde #define este directiva compilatorului, name numele constantei, value valoarea constantei. De exemplu: #define K 35 sau #define salariu 700. ntre directiv, nume i valoarea constantei este necesar prezena la minim un spaiu. n exemplele de mai sus compilatorul implicit va atribui variabilelor K i salariu valori de tipul ntreg, ntruct numerele 35 i 700 au sintaxa i formatul constantelor de tip ntreg. Unele compilatoare C, ce susin standardul ANSI-C permit iniializarea constantelor n 2 moduri. Primul mod cu folosirea directivei #define a fost descris mai sus. Al doilea mod folosete cuvntul rezervat const pentru iniializarea constantei, descrierea tipului ei i atribuirea valorii i are urmtoarea sintax: const int name = value; care este plasat dup funcia main(), unde const este cuvnt rezervat pentru iniializarea constantelor, int cuvntul rezervat pentru desemnarea constantelor de tip ntreg i value valoarea constantei. De exemplu: main() { const int K = 35; ; const int salariu = 700; ;} 3.1.2. Constante reale. Constantele reale (flotante) reprezint numere zecimale fracionare ce pot fi scrise sub dou forme: form cu punct i form cu ordin. Constanta real n form cu punct se scrie ca fracie zecimal cu semn sau fr semn, la care partea ntreag i partea fracionar se despart prin punct. Dac semnul constantei este omis ea se socoate pozitiv. Constanta real n form cu ordin este comod pentru scrierea numerelor foarte mari sau foarte mici. n C, ca i n majoritatea limbajelor de programare, pentru aa nscrieri se folosesc constante reale n form cu ordin, ce au

14

aspectul: mantisa_e_ordinul sau mantisa_E_ordinul. n aceste notaii n calitate de mantis poate fi scris sau o constant zecimal fr modificator sau o constant real n form cu punct. n calitate de ordin se scrie o constant ntreag zecimal, posibil cu semn, ce determin puterea numrului zece. Dac semnul ordinului lipsete se subnelege semnul +. De exemplu 7.32E+14 = 7.32*10 14 ; 55.000000E-3 = 0.055; Pentru determinarea constantelor de tip real sunt folosite diferite cuvinte rezervate, care determin diapazonul valorilor i volumul de memorie rezervat pentru constant. Tipul Float Double Long double Volumul de memorie (octei) 4 8 10 Diapazonul de valori 3.4E-38 3.4E+38 1.7E-308 1.7E+308 3.4E-4932 3.4E+4932

Constantele reale au un nivel orecare de aproximaie, care depinde de compilator. n aa fel cifra 6.12345678912345 n diapazonul de aproximaie pentru tipul float va fi interpretat de compilator ca 6.123456, acest tip se mai numete tip cu aproximaie unitar i are aproximaia 6 poziii dup punct. Tipul double se mai numete tip cu aproximaie dubl i are aproximaia de pn la 15 16 poziii dup punct. Sintaxa de iniializare a constantelor de tip flotant (real) este urmtoarea: Dup standardul K&R-C : #define PI 3.14. Dup standardul ANSI-C const float PI = 3.14; inclusiv cel din K&R C.

3.1.3. Constante caracter.


O constant caracter este un oarecare caracter al alfabetului luat n apostrofe. Exemplu: caracter . Valoarea unei constrante de tip caracter (char) poate fi o liter, o cifr sau un alt simbol al tastaturii. Pentru fiecare constant de tip caracter n memorie se aloc cte un octet. Mulimea valorilor unei constante de tip carecter este urmtoarea: literele minuscule i majuscule ale alfabetului latin, zece cifre arabe 0..9 i simboluri speciale ! @ # $ % ^ & * ( ) _ + = | \ / }{ : ; ? > . < , ~ ` Exist doua metode de scriere a caracterelor. Prima metod: Orice caracter al tabelului codurilor ASCII poate fi reprezentat n form de constanta caracter astfel: \ddd sau \xHHH , unde dddcodul octal, HHHcodul hexazecimal al caracterului. Zerourile ce stau n faa codului caracterului pot fi omise.

15

Metoda a doua: Caracterele des folosite ce nu se reflect pe ecran nu trebuie scrise sub form de cod. n acest caz se folosesc notaiile lor rezervate. Aceste caractere n C sunt repartizate n clasa caracterelor de control. Dac caractere de control se ntlnesc, spre exemplu, n rndul de extragere, atunci ele provoac o aciune corespunztoare. Sintaxa de iniializare a constantelor de tip caracter (char) este urmtoarea: Dup standardul K&R-C : #define Lit C. Dup standardul ANSI-C const char Lit = C; inclusiv cel din K&R C. 3.1.4. iruri de caractere. Un ir este o succesiune de caractere ale alfabetului cuprinse ntre ghilimele. Spre deosebire de alte limbaje de programare, limbajul C nu conine un tip de date special ce desemneaz irurile de caractere. Limbajul C opereaz cu irurile cum ar lucra cu o succesiune de date de tip caracter amplasate ntr-o structur numit masiv. Aici fiecare simbol din ir este o component aparte a masivului de tip char. Tipul masiv este un tip structurat n C i va fi studiat n capitolul Tipuri structurate Not: Unele compilatoare C i C++ susin tipuri de date speciale pentru operare cu iruri de caractere i conin biblioteci de funcii pentru prelucrarea irurilor. 4. Variabile. Variabila este o mrime care n procesul ndeplinirii programului poate primi valori diferite. Pentru variabile programatorul trebuie s determine notaii caracteristice proprii care se numesc identificatori. Deseori identificatorii sunt numii nume simbolice sau pur i simplu nume. 4.1. Nume de variabile (identificatori). Numele variabilei (identificatorul variabilei) este o succesiune de caractere i cifre ale alfabetului ce se ncepe cu o liter sau cu caracterul de subliniere. n Turbo C se permit urmtoarele caractere la formarea identificatorilor : Literele mari A..Z, literele mici a..z, cifrele arabe 0..9 precum i caracterul de subliniere_. n privina lungimii numelui nu-s nici un fel de limite, dar pentru compilatorul Turbo C au valoare doar primele 32 de caractere. Ex: A, b, x, y, Suma, Gama, Text_no, beta, a1, b_1. 4.2. Descrierea variabilelor. Toate variabilele din program trebuie s fie descrise. Descrierea variabilelor de obicei se efectueaz la nceputul programului cu ajutorul instruciunilor de descriere.

16

Instruciunea de descriere a variabilelor are urmtoarea form general de nscriere: tip v1,v2,,vn; unde : tip - determin tipul valorilor pe care le pot primi variabilele v1,v2,..,vn. n calitate de tip se folosete unul din cuvintele cheie deja cunoscute int, float, double sau char. Punctul i virgula este semnul sfritului instruciunii. ntre cuvntul cheie ce determin tipul variabilelor i lista numelor variabilelor, trebuie s fie cel puin un blanc. De exemplu: main() { float salary, suma, total; int timc, count; char znak, litera; } 4.3. Iniializarea variabilelor. Atribuirea valorii iniiale unei variabile n timpul compilrii se numete iniializare. La descrierea variabilelor compilatorului i se poate comunica despre necesitatea iniializrii. Exemple de instruciuni de descriere cu iniializarea variabilelor: main() { char bara=\, litera=T; int anul=2000, luna=9; float alfa,beta,gama=1,7e-12; } n ultima instruciune de descriere e iniializat doar variabila gama, cu toate c la prima vedere pare c toate trei sun egale cu 1,7e-12. Din aceats cauz e mai bine de evitat amestecarea variabilelor iniializate i neiniializate n una i aceiai instruciune de descriere. Exist cazuri, cnd folosirea unei variabile neiniializate poate duce la erori grave din punct de vedere logic la calcularea unor valori. n timpul includerii calculatorului, celulele de memorie nefolosite de sistemul operaional conin date aleatoare. Cnd variabila este declarat i ei i se rezerveaz loc n memorie, coninutul acestor celule de memorie nu se schimb pn cnd variabila nu este iniializat sau pn cnd ei nu i se atribuie vre-o valoare. Din aceast cauz, dac variabila ce n-a fost iniializat i nu i s-a atribuit nici o valoare pe parcursul programului este folosit n calculul unei valori, rezultatul va fi incorect. Acest fapt impune necesitatea iniializrii oricrei variabile n timpul declarrii acesteia. Aceste iniializri presupun atribuirea valorii 0 (zero) pentru variabile numerice i (spaiu) pentru cele caracteriale sau de tip ir de caractere.

17

5. Operaii i expresii. 5.1. Operaii aritmetice. n calitate de operaii aritmetice limbajul C folosete urmtoarele: 1) Adunare (+). 2) Scderea (-). 3) nmulirea (*). 4) mprirea (/). 5) Luarea modulului (%). 6) Plusul unar (+). 7) Minusul unar (-). 5.2. Operaia de atribuire. Operaia de atribuire poate fi simpl sau compus, n dependen de semnul operaiei de atribuire. Operaia de atribuire simpl se noteaz cu semnul = i e folosit pentru a atribui variabilei valoarea vreunei expresii. Ex: x=7; n limbajul de programare C n expresii se permite folosirea unui numr arbitrar de operaii de atribuire. Operaiile de atribuire au o prioritate mai joas dect cele descrise anterior i se ndeplinesc de la dreapta spre stnga. Operaia de atribuire leag variabila cu expresia, atribuind variabilei valoarea expresiei, ce st n dreptul semnului de atribuire. Operaiilor binare: + - * / % >> << & | le corespunde operaia de atribuire compus, care se noteaz ca op=, unde op este una din operaiile enumerate mai sus, de exemplu, += i *= etc. Operaia de atribuire compus sub forma: _variabila_op=_expresie_ se definete prin operaia de atribuire simpl astfel: _variabila_=_variabila_op_expresie_ De exemplu, d+=2 este echivalent cu d=d+2. De regul pentru operaiile de atribuire compuse calculatorul construiete un program mai efectiv. 5.3. Operaii de incrementare(decrementare). Operaia de incrementare notat prin dou semne plus consecutive, se aplic asupra unei singure variabile i mrete valoarea cu o unitate. Operaia de decrementare se noteaz prin dou semne minus micornd valoarea ei cu o unitate. Operaia de incrementare poate fi folosit att ca prefix ct i ca sufix. Diferena dintre acestea const n momentul schimbrii valorii variabilei. Forma prefix asigur schimbarea variabilei pn la folosirea ei. Iar forma sufix - dup folosirea ei. Operaiile de incremenatare decrementare se aplic asupra unor variabile de tip ordonat(aa ca int). Exemple: Operaia x++; asigur incrementarea variabilei x cu o unitate.

18

n expresia s=y*x++; incrementarea lui x se va face numai dup calcularea valorii lui s; Iar n expresia s=y*++x; nti se va incrementa x i numai dup aceia va fi calculat valoarea pentru s. i dac pentru m=5 vom scrie expresia m+++2, compilatorul trateaz primele dou plusuri ca forma sufix de incrementare a variabilei m. Valoarea expresiei va fi 7, i doar apoi variabila m se va mri cu unu. Expresia (i+j)++ este greit cci operaia de incrementare se aplic doar ctre numele variabilei. Operaia de incrementare are o prioritate mai nalt dect cea aritmetic. 5.4. Relaii i operaii logice. Operaiile de relaie snt: 1) Mai mare (>). 2) Mai mare sau egal (>=). 3) Mai mic (<). 4) Mai mic sau egal (<=). 5) Egal (==). 6) Diferit (!=). Operaiile de relaie formeaz o valoare adevrat sau fals n dependena de faptul n ce raport se afl mrimile ce se compar. Dac expresia de relaie e adevrat atunci valoarea ei este unu, n alt caz - 0. Operaiile de relaie au o prioritate mai mic dect cele aritmetice i de incrementare. ntre operaiile de relaie primele patru au aceiai prioritate i se ndeplinesc de la stnga la dreapta. Ultimele dou operaii au o prioritate nc mai mic i expresia a va primi valoarea unu doar atunci cnd i prima expresia i a doua expresie este adevrat. Operaiile de relaie se pot folosi pentru toate tipurile de date de baz, cu excepia irurilor de caractere (Pentru compararea irurilor se folosesc funcii incorporate). Exemple de expresii de relaii: a>b; (a + b )<2.5; 7.8<=(c+d); a>b==2; Expresia de relaie a>b==2 ntotdeauna va avea valoarea zero (fals). Cci independent de valoarea variabilelor, subexpresia a>b va avea valoarea zero sau unu i compararea oricrei din aceste valori cu 2 ne d 0.

19

Astfel observm c n limbajul de programare Turbo C putem scrie expresii ce par fr sens din punct de vedere al limbajelor de programare tradiionale. S cercetm operaiile logice. Ele , de obicei, se folosesc n calitate de legturi pentru reuniune a dou sau mai multe expresii . Tabelul ce urmeaz determin operaiile logice n Turbo C. Operaiile logice: Numele operaii logice 1.Conjuncie (SI logic) 2.Disjuncie (SAU logic) 3.Negare (NU logic) Semnul operaii n Turbo C && || |

Dac expr1 i expr2 sunt careva expresii , atunci expr1 && expr2 e adevrat n cazul cnd ambele sunt adevrate expr1||expr2 e adevrat n cazul cnd mcar una din expresii e adevrat. !expr1 e adevrat dac expr1 e fals i invers. Noi am stabilit pentru expr1 i pentru expr2 cazul cel mai general fr a mai indica ce fel de expresii ele sunt. Deci avem dreptul s scriem: 5&&2 . Valoarea acestei expresii va fi 1, din cauza c n Turbo C valoarea nenul se trateaaz ca adevr iar cea nul ca fals. Prioritile operaiilor logice se aranjeaaz n ordine descresctoare astfel: Negare (!). Conjuncie (&&). Disjuncie (||). Operaiile logice au o prioritate mai mic dect operaiile de relaie. Calcularea expresiilor logice, n care sunt numai operaii &&, se termin dac se descoper falsitatea aplicrii urmtoarei operaii &&. Reeind din definiia semanticii operaia &&, cum numai apare valoarea fals prelungirea calculelor nu are rost. Analog pentru expresiile logice ce conin numai operaii ||, calculele se termin odat ce apare valoarea adevr. Exemple de expresii logice: (5>2)&&47 adevarata; !(4>7) - adevarata; 4<7 adevarata; 5.5. Operaiile logice poziionale. Operaiile logice poziionale se folosesc pentru lucrul cu bii separai sau cu grupuri de bii de date. Operaiile poziionale nu se aplic ctre datele float i double. Operaiile logice poziionale: Numele operaiei logice poziionale I poziional Sau poziional
20

Semnul operaiei n Turbo C & |

Sau exclusiv poziional Deplasare la stnga Deplasare la dreapta Inversare

^ << >> ~

Operaia poziional I se realizeaz asupra fiecrii perechi de bii a datelor, de exemplu dac n program avem descrierea variabilelor : int n,d; i variabila n are valoarea 5, iar variabila d are valoarea 6, atunci expresia n&d ne d valoarea 4, deoarece reprezentarea interioar a valorii variabilei n este 0000000000000101 iar a variabilei d este 0000000000000110. Rezultatul aplicrii operaiei poziionale I va fi : n 0000000000000101 d 0000000000000110 4 0000000000000100 Operaia poziional I deseori se folosete pentru evidenierea vreunui grup de bii. Operaia poziional SAU se aplic asupra fiecrei perechi de bii a datelor i deseori se folosete pentru instalarea unor bii, de exemplu, expresia: X=X | mask instaleaz n unu acei bii ai lui x, crora le corespunde unu n mask. Nu trebuie s confundm operaile logice poziionale cu operaiile logice && i || . De exemplu, expresia 1&2 are valoarea 0, iar expresia 1&&2 are valoarea 1. SAU exclusiv poziional realizeaz asupra fiecrei perechi de bii operaia de adunare dup modulul 2. Rezultatele ndeplinirii operaiei SAU exclusiv poziional se determin n tabelul urmtor : Bitul primului operand 0 0 1 1 Bitul operandului al doilea 0 1 0 1 Bitul rezultatului 0 1 1 0

Operaiile de deplasare la snga(>>) i la dreapta (<<) ndeplinesc deplasarea primului operand la stnga sau la dreapta cu un numr de poziii binare determinat de operandul al doilea. n timpul deplasrii la stnga biii, ce se elibereaz, se completeaz cu zerouri. De exemplu, x<<2 deplaseaz x la snga cu dou poziii, completnd poziiile eliberate cu zerouri,ceea ce-i echivalent cu nmulirea la 4. n caz general, a deplasa x cu n poziii la stnga e echivalent nmulirii valorii lui x cu 2 la puterea n.

21

Deplasarea la dreapta a unei mrimi fr semn (unsigned) aduce la completarea cu zerouri a biilor eliberai. Deplasarea la dreapta a unei mrimi cu semn la unele mini aduce la multiplicarea bitului semnului, iar la altele biii se completeaz cu zerouri. Turbo C multiplic bitul semnului i de aceea pentru nemerele pozitive, deplasarea la dreapta cu n poziii e echivalent mpririi la 2 la puterea n. Operaia unar inversare (~) [tilda] transform fiecare poziie unar n nul i invers fiecare poziie nul n unar. 5.6. Operaia dimensiune. Operaia unar dimensiune, notat prin cuvntul-cheie sizeof, d mrimea operandului su n octei. Operaia dimensiune se folosete sub forma: sizeof_expresie sau sizeof_tip Valoarea operaiei sizeof este o constant ntreag, care determin lungimea tipului rezultatului expresiei. Dac n calitate de operand al operaiei sizeof folosim _tip, atunci primim mrimea obiectului de tipul indicat. n calitate de _tip pot fi folosite aceleai tipuri de obiecte, ce se folosesc la descrierea variabilelor. Operaia sizeof poate fi folosit peste tot, unde se admite folosirea unei constante ntregi. Construciile sizeof_expresie i sizeof_tip se cerceteaz ca ceva unitar i, astfel, expresia sizeof_tip -2 nseamn (sizeof(_tip)-2). Sau, de exemplu, expresia sizeof(a+b+c)+d e echivalent expresiei constana_+d, unde constanta_ are valoarea lungimii tipului rezultatului a+b+c. Expresia a+b+c e luat n paranteze pentru a indica c avem nevoie de lungimea tipului rezultatului a+b+c, i nu a+b+c+d. 5.7. Operaia virgul. Operaia virgul (,) permite de a uni cteva expresii n una singur i, astfel, n Turbo C se introduce noiunea de expresie cu virgul, ce are urmtoarea form general : expresie_,expresie_,expresie_, Perechea de expresii, desprite prin virgul, se calculeaz de la stnga spre dreapta. Tipul i valoarea rezultatului expresiei cu virgul este tipul i valoarea a celei mai din dreapta expresii. De exemplu: k=a+b,d=m+n,5.2+7 este o expresie cu virgul i se calculeaz de la stnga spre dreapta. Valoarea ei este 12.2 de tip float. n procesul calculrii acestei expresii variabilelor k i d li se atribuie valorile respective. Pentru expresia: d=(k=5+2,5+3) valoarea variabilei d va fi 8, deoarece ei i se atribuie valoarea expresiei cu virgul, care, la rndul su, este egal cu valoarea celei mai din dreapta expresii-operand.

22

Virgula n Turbo C se folosete n dou contexte: ca separator a datelor i ca operaie, ce determin calculul consecutiv al expresiilor. De aceea e admis, de exemplu, aa o expresie: int a,b,c=(1,2,5),d; unde variabila c se iniializeaz cu o expresie constant cu virgul 1,2,5 i primete valoarea 5. Contextul operaiei virgul (separator sau operaie) compilatorul l simte dup paranteze. n interiorul parantezelor avem operaia virgul, n exteriorul lor separatorul. n continuare vom vedea, c o situaie analogic poate aprea n lista argumentelor reale n timpul adresrii ctre funcie. Adresarea la funcie, ce conine trei argumente, unde al doilea are valoarea 5, poate arta, de exemplu, astfel: F(a,(t=3,t+2),c); 5.8. Expresii condiionate. Expresiile condiionate au urmtoarea form general: expr1_?:expr2_:expr3_; Valoarea expresiei condiionale se calculeaz astfel: prima se calculeaz expr1_. Dac ea este diferit de zero (e adevrat), atunci se calculeaz expr2_ i valoarea ei va fi valoarea ntregii expresii, n caz contrar se calculeaz expr3_. Astfel, semnele de operaie ? i : determin operaia ternar, adic operaie cu trei operanzi. De exemplu, pentru a calcula z maximum din a i b e suficient de a scri expresia: z=(a>b)?a:b; unde (a>b)?a:b expresie condiional. Parantezele din jurul primei expresii nu sunt obligatorii, deoarece prioritatea operaiei ternare ?: este foarte joas, nc mai joas este prioritatea operaiei de atribuire. Totui, se recomand de a pune parantezele, cci n aa fel condiia se evideniaz vizual. Expresia de mai sus o putem scrie mai puin efectiv astfel: a>b?(z=a):(z=b); 5.9. Conversii de tip. La scrierea expresiilor ar fi binevoit folosirea datelor omogene, adic a variabilelor i constantelor de acelai tip. ns, dac n expresie se amestec diferite tipuri de date, atunci compilatorul produce conversia automat a tipurilor n corespundere cu regulile care, n fond, se reduc la urmtoarele: dac operaia se ndeplinete asupra datelor de diferite tipuri, atunci ambele date se reduc la cel mai superior din aceste dou tipuri. O astfel de conversie se numete ridicarea tipului. O consecutivitate de tipuri ordonate de la superior la inferior e determinat n corespundere cu prezena interioar a datelor i arat astfel : double, float, long, int, short, char. Modificatorul unsigned mrete rangul tipului corespunztor cu un semn.

23

Pentru operaia de atribuire (simpl sau compus) rezultatul calculrii expresiei din partea dreapt se aduce la tipul variabilei creia i se atribuie aceast valoare. n acest timp poate avea loc ridicarea tipului sau coborrea tipului. Ridicarea tipului de atribuire, de obicei, se produce fr pierderi, pe cnd coborrea lui poate denatura esenial rezultatul din cauza c acel element de tip superior poate s nu ncap n zona de memorie a elementului de tip inferior. Pentru pstrarea preciziei calculului la efectuarea operaiilor aritmetice, toate datele de tip float se transform n double, ceea ce micoreaz greeala de rotungire. Rezultatul final se transform n tip float, dac acesta e condiionat de instruciunea de descriere respectiv. De exemplu, datele snt descrise astfel: float a,b,c; i avem expresia: a*b+c La calcularea valorii expresiei variabilele a, b i c vor fi convertate n double, iar rezultatul va avea tip float. ns dac datele sunt descrise astfel : float a,b; double c; atunci rezultatul a*b+c va fi de tip double din cauza ridicrii tipului. n afar de conversia automat a tipurilor, ndeplinit de compilator, Turbo C pune la dispoziia programatorului posibilitatea indicrii explicite a tipului, la care e necesar de adus o careva mrime sau expresie. Obinem acest lucru folosind operaia de conversie a tipului, ce are urmtoarea form general de scriere: (_tip_)_expresie Folosirea unei astfel de construcii garanteaz, c valoarea expresiei va fi convertat la tipul indicat n paranezele din faa expresiei. n aceast operaie n calitate de _tip_ pot fi folosite aceleai cuvinte cheie, ca i n instruciunile de descriere a tipului, mpreun cu modificatorii admisibili. S cercetm dou expresii n Turbo C. d=1.6+1.7 i d=(int)1.6+(int)1.7 cu condiia c variabila d este de tip ntreg. n rezultatul ndeplinirii primei expresii valoarea variabilei d va fi 3, deoarece 1.6+1.7 nu necesit conversia tipurilor i d rezultatul 3.3 de tip float, iar coborrea tipului pn la int, realizat n timpul ndeplinirii operaiei de atribuire, d variabilei d valoarea 3 din cauza truchierii prii fracionare. n rezultaul ndeplinirii expresiei a doua valoarea variabilei d va fi 2, deoarece indic conversia explicit a constantelor float n tip int pn la adunarea lor. n timpul ndeplinirii operaiei de atribuire nu va avea loc conversia tipului, deoarece tipul variabilei coincide cu tipul expresiei. Operaia de reducere a tipului cel mai des se folosete n cazurile, cnd dup context nu se presupune conversia automat a tipurilor. De exemplu, pentru asigurarea lucrului corect a funciei sqrt ea are nevoie de un argument de tip double. De aceea, dac avem descrierea: int n; atunci pentru calcularea rdcinii patrate din n trebuie s scriem sqrt((double)n);

24

Menionm, c n timpul aducerii la tipul necesar se converteaz valoarea lui n, dar nu se schimb coninutul ei, cci ea rmne de tip int. 5.10. Prioritile operaiilor. Prioritiile operaiilor se cercetau n procesul expunerii lor. n paragraful de fa sunt reprezentate operaiile descrise mai sus i e indicat ordinea ndeplinirii lor. Pentru compararea prioritilor operaiilor le prezentm n tabel n ordinea descreterii prioritii. Coloana tabelului Ordinea execuiei determin consecutivitatea ndeplinirii pentru operaiile cu aceiai prioritate. De exemplu n expresia k=d+=b-=4; consecutivitatea ndeplinirii operaiilor se va determina n ordinea de la dreapta la snga i n rezultat b se va micora cu 4, d se va mri cu b-4, k=d+b-4. Ordinea de evaluare, descris de o simpl operaie de atribuire, va fi urmtoarea: b=b-4; d=d+(b-4); k=d; Prioritatea 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Semnul operaiei () ! ~ ++ -- - + (unar) sizeof (tip) * / % +<< >> < > <= >= == != & ^ | && || ?: = *= /= %= += -= &= |= >>= <<= ^= , Tipul operaiei Expresie Unare Multiplicative Aditive Deplasare Relaii Relaii (egalitate) I poziional SAU exclusiv poziional SAU poziional I logic SAU logic Condiie Atribuire simpl compus Virgul De la dreapta la stnga De la stnga la dreapta De la stnga la dreapta Ordinea execuiei De la stnga la dreapta De la dreapta la stnga

25

6. Instruciuni. Prin instruciune n C se subnelege o oarecare nscriere, ce se termin cu caracterul; (punct i virgul), sensul creiea determin aciunile compilatorului n timpul prelucrarii textului iniial al programului sau actiunile procesorului n timpul ndeplinirii programului. Instruciunile pot fi mprite n dou grupe: 1) Instruciunile perioadei de compilare 2) Instruciunile perioadei de ndeplinire a programului. La instruciuni de compilare se refer instruciuni, ce caracterizeaz datele din program, iar la instruciuni de ndeplinire se refer instruciuni, ce determin aciuni de prelucrare a datelor n conformitate cu algorilmul dat. Instruciunile de compilare au fost precautate n compartimentele de descriere i declarare a datelor. n continuare vor fi studiate instruciunile de ndeplinire. Fiecare instruciune are sintaxa i semantica sa. Sintaxa reflect metoda nscrierii corecte a construciilor instruciunii, iar semantica este descrierea aciunilor efectuate de instruciune. 6.1. Tipurile instruciunilor. Instruciunea reprezint o unitate de ndeplinire a programului. Instruciuni pot fi simple, compuse i blocuri. Simpl se numete instruciunea, care nu conine n componena sa o alt instruciune. La instruciunile simple se refer instruciunea expresie, instruciunea continurii continue, instruciunea de terminare break, instruciunea de ntoarcere return, instruciunea de salt necondiionat goto, pe care le vom cerceta mai departe. Compus se numete instruciunea, ce conine n componena sa alte instruciuni. La instruciunile compuse se refer instruciunea condiional if else instruciunile ciclului for, while, do while i instruciunea de selecie switch. Bloc se numete un ir de instruciuni luate n acolade({}). Instruciunile blocului se ndeplinesc consecutiv n ordinea nscrierii lor n interiorul blocului. La nceputul blocului pot fi descrise variabilele interioare. n aa caz se spune, c aceste variabile sunt localizate n interiorul blocului, exist i lucreaz numai n interiorul blocului i se pierd n afara lui. n Turbo C instruciunea compus i blocul pot fi folosite oriunde, unde este admis folosirea instruciunii simple. Prin urmare, instruciunea compus poate conine alte instruciuni compuse, iar blocul poate conine instruciuni compuse i alte blocuri.

26

Orice instruciune poate fi marcat de un identificator, nunit etichet. Eticheta este separat de instruciune prin dou puncte i, astfel, n caz general instruciunea are forma: etichet_:corpul_instruciunii; Eticheta se folosete doar n cazul cnd se folosete saltul necondiionat la aceaast instruciune cu ajutorul instruciunii goto. n exemplul de mai sus pot lipsi ori eticheta_, ori corpul_instruciunii, ori ambele. n cazul lipsei corpul instruciunii, avem o instruciune vid, adic aa o instruciune ce nu ndeplinete nici o aciune. n cazul cnd avem lipsa instruciunii i prezena etichetei avem o instruciune vid etichetat. Exemplu: Empty : ; Dac n calitate de corpul instruciunii e folosit un bloc, atunci (;) nu se pune. n acest caz, rolul sfritului l va juc acolada dreapt, de nchidere (}). De exemplu: label:{k=a=b;k+=8;} 6.2. Instruciuni expresie. Orice expresie va deveni instruciune dac se va termina cu (;). n aa fel, instruciunea-expresie va avea urmtoara form: expresie_; Dup cum sa menionat, orice instruciune poate fi etichetat. Instruciuneaexpresie ader la clasa instruciunilor simple ai limbjului Turbo C. n rezultatul ndeplinirii n program a instruciunii-expresie se calculeaz valoarea expresiei n conformitate cu operaiile, care sunt definite n ea. De obicei, pot fi una sau mai multe operaii de atribuire i atunci instruciunea-expresie n limbajul Turbo C are acelai sens i n alte limbaje. S studiem secvene din program unde e folosit instruciunea-expresie: Exemplu 1: int x,y,z; x =-3+4*5-6; y =3+4%5-6; z =-3*4%-6/5; n rezultat vom avea x=11, y=1, iar z=0. Vom scrie ordinea ndeplinirii a acestei secvene n conformitate cu prioritatea operaiilor, folosind parantezele rotunde: Pentru x=-3+4*5-6 : x=(((-3)+(4*5))-6); Pentru y=3+4%5-6 : y=((3+(4%5))-6) Pentru z=-3*4%5-6/5 : z=((((-3)*4)%(-6))/5); Exemplu 2: int x=2,y,z; x*=3+2,x*=y=z=4; Aici instruciunea-expresie conine o expresie cu virgul compus din dou subexpresii. n primul rnd se calculeaz prima subexpresie, apoi- subexpresia a doua. n rezultat vom obine z=4, y=4, x=40. Menionm faptul, c la declarare x are valoarea 2: x=(x*(3+2))*(y=(z=4));

27

6.3. Instruciuni de ramificare (condiionale). 6.3.1. Instruciunea de ramificare IF i IF-ELSE. n structurile ramificate de calcul, unele etape nu ntotdeauna se ndeplinesc n una i aceiai ordine. n dependen de careva condiii, care sunt controlate(verificate) pe parcursul calculelor, se aleg pentru executare diferite consecutiviti de instruciuni. Pentru descrierea astfel de procese n limbajul C se folosesc instruciunile ramificate (condiionale). O instruciune condiional selecteaz o singur instruciune dintre alternativele sale, pe care apoi o execut. Astfel de instruciuni sunt if i if else. Instruciunea if e compus i sintaxa ei admite unul din urmtoarele formate: if_(expresie)_instruciune sau if_(expresie)_instruciune1_else_instruciune2; n instruciunile de ramificare lipsete (;), deoarece construcia instruciune_ care a fost descris deja include n sine acest semn (;). Dac instruciunea_ este simpl, atunci ea se va sfri cu (;), iar dac instruciunea_ reprezint un bloc, atunci acest bloc va fi definit de acolade, unde acolada dreapta va juca rolul sfritului. Instruciunea if lucreaz n felul urmtor: 1. Formatul if(expresie)_instruciune. Mai nti se calculeaz valoarea expresiei. Dac rezultatul ei este ADEVR ( adic expresia != 0), atunci se ndeplinete _instruciunea, iar n caz contrar se sare peste instruciune i nu avem nici o aciune. Schema algoritmic a formatului if(expresie)_instruciune este prezentat pe desen. Fie c d este egal cu c. Atunci vom mri d cu o unitate, iar c cu trei uniti. n celelalte cazuri d i c rmn neschimbate. Instruciunea de ramificare a acestui caz: if(d==c) ++d,c+=3; n calitate de instruciune_ aici se folosete instruciunea expresie cu virgul. Vom descrie aceast instruciune astfel: if(d= =c)++d;c+=3; Diferena const n aceea c n exemplu al doilea avem 2 instruciuni: if i instruciunea-expresie c+=3; n acest caz dac (d==c) va avea valoare ADEVR, atunci totul va rmne ca mai nainte: d se va mri cu o unitate, iar c se va mri cu trei uniti. n caz contrar, d nu se schimb, i numai c se mrete cu 3. Vom considera acest exemplu din nou: if(d= =c){++d;c+=3;}

28

n cazul c (d == c) va avea valoarea FALS, d i c vor rmne neschimbate, deoarece aceste instruciuni snt incluse n acolade, adic formeaz un bloc, i din punct de vedere logic sunt privite ca o singur instruciune bloc. 2. Formatul if(expresie)_instuciune1_else_instruciune2. Ca i n cazul precedent, n primul rnd se calculeaz valoarea expresiei. Dac ea difer de zero, adic este ADEVR, atunci se ndeplinete instruciunea1, n caz contrar se ndeplinete instruciunea2. Schematic aceast instruciune e preszentat pe desen. De exemplu : fie c e necesar de a calcula z, care este egal cu maximum dintre dou numere a i b. Atunci putem scrie : if(a>b)z=a;else z=b; Prezena (;) dup z=a este necesar, deoarece aceasta este o instruciune ce intr n coponena instruciunii if. Prima form prescurtat a instruciunii if ne d posibilitatea ndeplinirii sau nendeplinirii oricrei operaii, pe cnd a doua form ofer posibilitatea alegerii i ndeplinirii unei operaii din dou posibile. Totui, cte odat apare necesitatea alegerii unei operaii din mai multe.Vom examina un lan de instruciuni: if(expresie1)_instruciune1_else_if(expresie2)_instruciune2_else_if(expresie3) _instruciune3_else _instruciunea4 Aa un lan de instruciuni e admis, deoarece n locul instruciunii n instruciunea if poate fi orice instruciune, inclusiv i if. ns o aa nscriere e complicat. Pentru aa procese n C exist o instruciune special care va fi studiat ceva mai trziu. S precutm 2 exemple: a) if(n>0) if(a>b) z=a; else z=b; b) if(n>0){if(a>b) z=a;}else z=b; Deosebirea const n faptul c n cazul a) avem instruciunea if de form scurt, care are ca instruciune forma if_else; . n cazul b) avem instruciunea if_else n form plin, avnd n calitate de instruciune1 forma if prescurtat. Secvena b difer de a numai prin prezena acoladelor, ce definesc un bloc, ns, evident, joac un rol important la interpretarea acestor intruciuni. 6.3.2. Instruciunea de salt necondiionat GOTO. Instruciunea goto ne d posibilitatea transmiterii controlului execuiei programului la o instruciune marcat cu o etichet. Instruciunea goto are formatul: goto_etichet;

29

Dup instruciunea goto, evident, se ndeplinete instruciunea, eticheta creia coincide cu eticheta din goto. Folosirea cestei instruciuni n Turbo C nicidecum nu se deosebete de folosirea ei n alte limbaje algoritmice. ns e dorita folosirea ct mai redus, a acestei instruciuni, deoarece limbajul Turbo C face parte din clasa limbajelor structurate. Totodat, avnd la dispoziie instruciunile goto i if, programatorul poate programa diferite operaii complicate. Exemplu :Folosirea instruciunilor if i goto la organizarea ciclurilor. Acest program calculeaz valoarea lui y care este egal cu n/(n+5),unde n=1,..,50 #define lim 50 main() { int n=0; float y=0; m1:++n; if(n<=lim) { y+=n/(n+50); goto m1;} } Prima linie a programului e menit preprocesorului, cruia i se indic valoarea constantei lim=50. Astfel se procedeaz n cazul cnd vom necesita schimbarea limitei de sumare. Pentru aceasta trebuie schimbat doar directiva #define, iar substituirile corespunztoare n textul programului preprocesorul le va face fr participarea noastr. Programul const dintr-o singur funcie main(), corpul creia e definit cu ajutorul acoladelor exterioare. Instruciunea if are aici forma prescurtat, avnd ca instruciune un bloc, care conine instruciunea goto, ce ne d posibilitatea calculrii ciclice a sumei. n ncheiere menionm c utilizarea if i goto la organizarea ciclurilor e un semn de cultura insuficient de programare. Exemplu dat arat numai cum se poate organiza un ciclu cu ajutorul instruciunilor if i goto, dar n nici un caz nu servete drept exemplu pentru copiere. La organizarea ciclurilor n limbajul de programare Turbo C se folosesc alte posibiliti, cu mult mai fine. 6.3.3. Instruciunea de selectare SWITCH. Instruciunea de selectare e destinat pentru selectareaa unei singure variante dintr-o mulime posibil de ramificri n program. Orice ramificare poate fi organizat cu ajutorul lanului de instruciuni if_else_if__else_, ns n cazurile cnd sunt prezente mai mult de 3 condiii e mai raional folosirea lui switch. Instruciunea de selectare este compus i are formatul prezentat mai jos: switch (expresie) { case expr_const1:instruciune1; case expr_const2:instruciune2;
30

case expr_const_n:instruciune_n; default:instruciune; } Dup cuvntul cheie switch n paranteze este scris o expresie, valoarea creia trebuie s fie de tip int sau char. Mai departe n acolade se nscriu instruciunile varantele marcate cu prefixele: case expresia_constant: unde expresia constant deasemenea trebuie s fie de tip ntreg, iar toate prefixele trebuie s fie diferite. O variant poate avea prefixul default, prezena careia nu este obligatorie, dar n majoritatea cazurilor acest prefix este prezent n construcia switch. Instruciunea de selectare lucreaz n felul urmtor. La nceput se afl valoarea expresiei din paranteze, apoi aceast valoare se compar cu expresiile constante ale case prefixelor i se ndeplinete variantaa i, pentru care aceste valori coincid. Dup ce sau ndeplinit instruciunile ce se conin n caseul respectiv, se ndeplinesc instruciunile variantei urmtoare i aa pn ce se termin toate instruciunile variantei. Dac valoarea expresiei n switch nu coincide cu nici o valoare a case prefixelor, atunci ori se ndeplinete instruciunea variantei cu prefixul default (dac default este prezent), ori nu se ndeplinete nici o variant (dac default este absent). Schema algoritmic de ndeplinire a instruciunii switch este prezent pe desen. S examinm exemplul de ntrebuinare a instruciunei switch : se scrie un fragment de program, ce tiprete patru rnduri din poezie, ncepnd de la rndul k: switch(k) { case 1: printf(A fost o dat ca-n poveti,\n); case 2: printf(A fost ca niciodat,\n); case 3: printf(Din rude mari mprteti,\n); case 4: printf(O preafrumoas fat.\n); default printf(Poezia nu conine rnd cu aa numr); } n acest exemplu e folosit funcia printf(), ce asigur tiparul rndului cu format. Dac k ar fi egal cu 3, atunci vom avea ca rezultat : Din rude mari mprteti O preafrumoas fat. Poezia nu conine rnd cu aa numr

31

6.3.4. Instruciunea de ntrerupere BREAK. n practica programrii cteodat apare necesitatea ndeplinirii numai a unei variante case fr indeplinirea celor ce urmeaz dup ea, adic trbuie ntrerupt logica stabilit de lucrul a instruciunii switch. Evident c pentru aa ceva e necesar inroducerea unei instruciuni ntre instruciunile variantei, care ar servi ca sfrit al ndeplinirii lui switch. Aa o instruciune este BREAK, executarea creia rovoac terminarea instruciunii switch. n acest caz instruciunea switch va avea urmtorul format: switch (expresie) { case expr_const1:instruciune1; break; case expr_const2:instruciune2; break ; ................. case expr_const_n:instruciune_n; break; default:instruciune; break; } Instruciunea BREAK se nscrie n variante atunci cnd este nevoie de ea. ndeplinirea ei aduce la trecerea controlului la instruciunea urmtoare dup switch. La prima vedere pare c nu este necesar de a scri instruciunea BREAK dup varianta default. Default poate fi situat n orice loc al instruciunii switch, chiar i pe primul loc ntre variante, i atunci BREAK este necesar pentru a evita ndeplinirea celorlalte variante. Exemplu: Schimbm formularea problemei precedente n felul urmtor : fie c e necesar de tiprit rndul k dinte cele patru rnduri ale poeziei date: switch(k){ case 1 : printf(A fost o dat ca-n poveti,\n);break; case 2 : printf(A fost ca niciodat,\n); break; case 3 : printf(Din rude mari mprteti,\n); break; case 4 : printf(O preafrumoas fat.\n); break; default:printf(Poezia nu conine rnd cu aa numr\n); } Trebuie de menionat, c instruciunile din variantele case sau default pot lipsi. Aceasta este necesar cnd avem nevoie de a obine acelai rezultat la trecerea la diferite prefixe. Exemplu: switch (L) { case `C`: case `c`: printf(Calculator\n);break; } n acest caz, dac L=c va fi tiprit cuvntul calculator. n caszul cnd L=`C`, atunci va fi ndeplinit instruciunea ce urmeaz dup primul case, dar deoarece aici lipsete instruciunea, se vor ndeplini instruciunile situate mai jos, pn ce nu se ntlnete instruciunea break.

32

6.4. Instruciuni iterative(ciclice). Instruciunile precutate mai sus redau operaii care trebuie efectuate conform algoritmului i fiecare din ele se ndeplinesc numai odat. n cazul, cnd una i aceiai instruciune trebuie s fie executat de n ori cu diferite valori ale parametrilor se folosesc instruciunile ciclice. Distingem 3 instruciuni ciclice n C : 1) Instruciunea ciclic cu parametru (FOR) 2) Instruciunea ciclic precedat de condiie (WHILE) 3) Instruciunea ciclic cu postcondiie (DO-WHILE) 6.4.1. Instruciunea ciclic FOR. Ciclul FOR posed urmtoarele caracteristici: numrul de repetri ale ciclului este cunoscut de la nceputul executrii lui; conducerea ciclului este efectuat cu ajutorul unei variabile de tip int, numit parametrul ciclului, care, n acest proces ciclic primete valori consecutive de la valoarea iniial dat pn la valoarea final dat. Sintaxa instruciunii este urmtoarea: for(expresie1;expresie2;expresie3) instruciune; unde expresie1 expresie de iniializare a parametrului ciclului, expresie2- expresie de control, expresie3- expresie de incrementare/decrementare(corecie) a parametrului ciclului. Instruciunea ciclic for lucreaz n felul urmtor: la nceput se calculeaz expresia de iniializare. Apoi, dac expresia de control este adevrat, atunci se ndeplinete instruciunea. Dup ndeplinirea instruciunei se execut expresia de corecie i din nou se controleaz expresia de control, justeea creia duce la ndepliniea repetat a instruciunii. Dac expresia de control are valoarea fals atunci ndeplinirea ciclului for se termin, adic controlul se transmite instruciunii programului ce urmeaz dup instruciunea for. De exemplu: de calculat y=i/(i+1); unde i=1..50; y=0; for(i=1;i<=50;i++) {y+=i/(i+1) }; aici i=1 este expresie de iniializare, i<=50 expresie de control, i++ - expresie de corecie. Acoladele mrginesc corpul ciclului (instruciunea). n caz cnd corpul ciclului e compus numai dintr-o instruciune, acoladele nu sunt necesare. Schema algoritmic ndeplinrii instruciuni for este prezentat pe desen. Din schema algoritmic se vede, c instruciunea for este un ciclu cu precondiie : decizia de a ndeplini din nou ciclul sau nu se ia naintea nceperii ndeplinirii lui i evident, se poate ntmpla ca corpul ciclului s nu fie ndeplinit nici o dat.

33

Cteodat apare necesitatea ieirii din ciclu nainte de termen. Pentru aceasta n corpul ciclului, n locul unde se dorete ieirea din ciclu se folosete instruciunea BREAK, dup ndeplinirea reia are loc transmiterea controlului la instruciunea urmtoare dup ciclu. Limbajul C nu pune restrucii la tipul instruciunilor din cadrul corpului ciclului. n aa mod, corpul ciclului poate fi alctuit din instruciuni i simple i compuse, n particular- corpul unui ciclu poate fi alt ciclu. n unele algoritme apar situaii, cnd e necesar imbricarea unui ciclu n altul. De exemplu la prelucrarea unei matrice un ciclu exterior rspunde de prelucrarea rndurilor, iar altul interior a coloanelor. n acest caz sintaxa va fi urmtoarea: For(i=1;i<=n;i++){ For(j=1;j<=m;j++){ corpul ciclului } }; unde n-numrul de rnduri n matrice, m- numrul de coloane, acoladele interioare mrginesc corpul ciclului cu parametrul j, iar acoladele exterioare mrginesc corpul ciclului exterior cu parametru i. 6.4.2. Instruciunea ciclic WHILE. Ciclul while este folosit n cazul, cnd nu este cunoscut numrul de repetri ale ciclului i nu exist necesitatea ca ciclul s fie executat mcar o singur dat. Instruciunea de ciclare while are urmtoarul format: while (expresie) instruciune; Instruciunea de ciclu while lucreaz n felul urmtor: dac expresia este adevrat (sau diferit de zero, ce din punct de vedere al limbajului Turbo C este una i aceiai), atunci instruciunea se ndeplinete o dat i apoi expresia din nou se testeaz. Aceast succesiune de aciuni, ce const n testarea expresiei i ndeplinirea instruciunei, se repet periodic pn ce expresia nu devine fals(din punct de vedere al limbajului Turbo C devine egal cu zero). Instruciunea se numete corpul ciclului i n majoritatea cazurilor reprezint un bloc, n componena cruia intr cteva instrciuni. Schema algoritmic a executrii instruciuniii while e prezentat pe desen. Se observ, c instruciunea while este un ciclu cu precondiie. Testul de control este executat naintea intrrii n corpul instruciunii. De aceea este posibil ca corpul ciclului nu va fi ndeplinit niciodat. n afar de aceasta, pentru a nu admite ndeplinirea la infinit a ciclului, ci numai de anumite

34

ori, este necesar la fiecare ndeplinire nou a ciclului de a modifica variabila parametru , ce intr n componena expresiei. Spre deosebire de ciclul for, unde variabila parametru putea fi numai de tip ntreg, parametrul ciclului while poate fi i de tip float, adic pasul ciclului poate fi diferit de 1 i chiar un numr fracoinar. Exemplu: i=1; while(i<=50) {y+=i(i+1); i++; } ; Ca i n cazul ciclului for, corpul unui ciclu while poate fi deasemenea un ciclu. Exemplu: i=1; while(i<=n) { j=1; while(j<=m) { corpul ciclului; j++;} i++ }; 6.4.3. Instruciunea ciclic DO_WHILE. Instruciunea ciclic DO_WHILE se folosete n cazul cnd numrul de repetri ale ciclului nu-i cunoscut, dar n acelai timp e necesar ca ciclul s fie ndeplinit mcar o singur dat. Instruciunea de ciclare do_while are urmtoarea form: do instruciune while(expresie); Instruciunea do_while lucreaz n felul urmtor: la nceput se ndeplinete instruciunea, apoi se calculeaz valoarea expresiei. Dac valoarea expresiei este adevrat, atunci instruciunea se ndeplinete din nou, dac expresia este fals, atunci ndeplinirea ciclului se termin. Schema algorimtic de ndeplinire a instruciunii do_while este reprezentat pe desen. Instruciunea do while determin un ciclu cu postcondiie, deoarece controlul necesitii ndeplinirii repetate a instruciunei are loc dup ndeplinirea corpului ciclului i, astfel, corpul ciclului ntotdeauna se ndepliete cel puin o dat. Analogic, ca i pentru ciclul while, programatorul trebuie s aib grij de terminarea ciclului, schimbnd parametrul ciclului n corpul ciclului. Parametrul ciclului do while, ca i parametrul ciclului while poate fi de tip float, fapt ce permite de a opera cu pa zecimali la organizarea ciclului. Exemplu: i=1;do {y+=i(i+1); i++;} while(i<=50); Ciclul do_while deasemenea poate fi imbricat: i=1; do { j=1; do {corpul ciclului;j++;} while(j<=m) i++; } while(i<=n); Deci, fiind cunoscute cele 3 instruciuni ciclice FOR,WHILE i DO_WHILE le putem folosi n diferite scopuri aparte sau mpreun pentru cazuri concrete. n cazul cnd cunoatem numrul de repetri al ciclului, pasul indexului fiind =1 folosim instruciunea ciclic FOR. n cazul cnd numrul de repetri al ciclului e necunoscut,

35

dar corpul ciclului trebuie s fie executat mcar o singur dat folosim instruciunea ciclic DO_WHILE. i n cazul cnd nu este cunoscut numrul de repetri al ciclului, iar corpul ciclului e necesar s fie executat de 0 sau mai multe ori, n dependen de o condiie folosim instruciunea ciclic WHILE.Mai mult ca att, n cazul ciclurilor imbricate sunt posibile combinaii de instruciuni ciclice: for-while; do_while-while; s.a. 6.4.4. Instruciunea de continuare CONTINUE. Instruciunea CONTINUE este folosit n corpul ciclului cu scopul de a preda controlul la nceputul ciclului. Exist cazuri, cnd la ndeplinirea a careva condiii trebuie de ntrerupt executarea iteraii curente i de trecut la ndeplinirea iteraiei urmtoare a ciclului. n aa cazuri este folosit instruciunea CONTINUE. Instruciunea de continuare are urmtoarea form: continue; Instruciunea continue poate fi realizat n toate cele trei tipuri de cicluri, dar nu i n instruciunea switch. Ea servete la depirea prii rmase a iteraiei curente a ciclului, ce o conine nemijlocit. Dac condiiile ciclului admit o nou iteraie, ea se ndeplinete, n caz contrar el se termin. S precutm urmtorul exemplu: int a,b; b=0; for(a=1;a<100;a++) {b+=a; if (b%2) continue; ... prelucrarea sumelor pare ... } n cazul, cnd suma b va fi impar, operatorul continue transmite controlul iteraiei urmtoare a ciclului for fr a executa partea urmtoare a corpului ciclului, unde are loc prelucrarea sumelor pare. 7. Masive. 7.1. Descrierea masivelor. Masivul reprezint un ir ordonat de elemente de acelai tip. Faptul, ca masivul este un tot intreg, compus din cteva elemente ne permite s numim variabila de tip masiv variabila de tip compus. Masivul se poate caracteriza prin nume, tip, dimensiune. Formatul comun de descriere a masivelor este: tip nume[d1][d1][dn]; unde : tip este tipul comun pentru toate elementele masivului, adica tipul masivului. Tip al unui masiv poate fi orice tip de date deja definit: ntreg, real, caracterial .a. nume este numele masivului. In calitate de nume al masivului este folosit orice identificator. Mai mult ca att, deoarece numele masivului este identificator, asupra lui se rspndete totul ce-i indicat n compartimentul Nume de variabile

36

(identificatori), d1,d2,dn- dimensiunile masivului. Dimensiunea masivului indica numarul de elemente prezente in masiv. Dimensiunea masivului poate fi o expresie constanta cu rezultat intreg. In dependenta de cantitatea de dimensiuni, masivele se clasifica in: 1. masive unidimensionale(cu 1 dimensiune); masivul unidimensional reprezint un ir de elemente aranjate uniform ntr-un rnd. Fiecare element al unui masiv unidimensional are 1 coordonat: numrul de ordine a elementului n ir. 2. masive bidimensionale (cu 2 dimensiuni); masivul bidimensional reprezint o structur format din rnduri i coloane. Fiecare element al unui masiv bidimensional are 2 coordonate: numarul rndului i numrul coloanei. 3. masive tridimensionale (cu 3 dimensiuni); masivul tridimensional reprezint o structur echivalent cu un cub n volum cu 3 dimensiuni: lungimea, limea, nlimea. Fiecare element al unui masiv tridimensional are 3 coordonate: numarul rndului(n lungime), numrul coloanei(n lime) i numrul nlimei(n adncime). 4. masive multidimensionale. Exemple de descriere a masivelor: int vector[20]; vector - masiv unidimensional din 20 de numere ntregi; float x[10]; x masiv cu 10 elemente de tip ntreg; float matrix[7][9]; matrix - masiv bidimensional din 63 (7*9) de numere flotante; char fraza[25]; fraza - masiv(propoziie) din 25 de caractere ; int spase[15][30][18]; space - masiv tridimensional de numere ntregi (masiv unidimensional de masive bidimensionale); 7.2. Accesul la elementele masivului. Cu toate c masivul este un tot ntreg, nu se poate vorbi despre valoarea masivului ntreg. Masivele conin elemente cu valorile crora se opereaz n program. Fiecare element n masiv i are indicele i valoarea sa. n calitate de indice a unui element se folosete un numr ntreg ce indic numrul de ordine al elementului n masiv. Enumerarea elementelor n masiv conform numrului de ordine se ncepe de la zero. Deci, indicele unui element poate avea valori de la 0 pna la d-1, unde d este dimensiunea masivului. n calitate de valoare a unui element din masiv poate servi orice numr de tipul indicat la descrierea masivului, adica tipul valori atribuit oricrui element din masiv trebuie s fie compatibil cu tipul masivului. Sintaxa de acces la orice element a unui

37

masiv este urmtoarea: nume[i1][i2]..[in]. Unde nume este numele masivului, i1 indicele elementului n dimensiunea 1, i2-indicele elementului n dimensiunea 2, in indicele elementului n dimensiunea n. n cele mai dese cazuri se opereaz cu masive unidimensionale i bidimensionale. Accesul la un element al unui masiv unidimensional se face n felul urmtor: nume[i]; unde nume - numele masivului, inumarul de ordine a elementului n masiv. Exemplu: vector[5]; se acceseaz elementul cu numrul de ordine 5 din masivul vector. fraza[20]; se acceseaz elementul cu indicele 20 din masivul fraza. Accesul la un element al unui masiv bidimensional se face prin nume[i][j]; unde i este numarul rndului pe care se afl elementul; j este numrul coloanei pe care se afl elementul. Exemplu: matrix[4][7]; se acceseaz elementul de pe rndul 4 i coloana 7 a masivului matrix. y[0][0]; se acceseaz primul element al masivului, adic rndul 0, coloana 0; n cazul cnd masivul este de tip simplu, atribuirea valorii unui element al masivului se face ca i n cazul atribuirii valorii unei variabile simple. Exemple: x[0]=7.125; vector[19]+=1; matrix[1][1]=5.5; fraza[3]=b; space [3][5][2]=8; n cazurile cnd masivul este de tip structurat, atribuirea valorii i accesul la un element al masivului se face conform regulilor de atribuire i accesare pentru variabile structurate. Un element al masivului poate aprea n orice expresie, unde e admisibil prezena unei variabile de tip compatibil cu tipul valorii elementului. 7.3. Iniializarea masivelor. Deseori e necesar ca elementele masivului s posede valori chiar la momentul descrierii masivului. Procesul de atribuire a valorilor elementelor masivului n timpul descrierii lui se numete iniializarea masivului. Sintaxa de iniializare a unui masiv unidimensional este: tip nume[d]={v0,v1,v2,,vn-1}; unde tip este tipul masivului, nume este numele masivului, v0,v1,v2,vn-1 valorile respective ale elementelor nume[0],nume[1] etc. Exemplu: int x[8]={1,3,15,7,19,11,13,5};

38

n acest caz elementele masivului vor avea urmtoarele valori: x[0]=1; x[1]=3; x[2]=15; x[3]=7; x[4]=19; x[5]=11; x[6]=13; x[7]=5; E de menionat faptul, c indicii masivului se schimb ncepnd dela zero.Adic la descrierea masivului valoarea maxim a indicelui masivului coincide cu numrul de elemente n masiv minus unu. La iniializarea masivului nu e numaidect de indicat dimensiunile masivului.Compilatorul va determina numrul elementelor dup descrierea masivului i va forma un masiv cu mrimea respectiv. De exemplu: int x[]={1,3,15,7,19,11,13,5}; Elementele masivului vor primi valori ca i n cazul precedent. Vom examena nc cteva exemple de iniializare a masivelor: float vector[4]={1.2,34.57,81.9,100.77}; // vector masiv din 4 elemente de tip float; int digit[5]={1,2,3}; // digit masiv de tip ntreg din 5 numere,ultimelor dou elemente li se atribuie valoarea zero. char m[5]={A,B,C,D}; // m masiv din 5 caractere, ultimul element are valoarea nul-caracter; float const y[4]={25,26,17,18}; // iniializarea masivului y[4], elementele cruia sunt constante de tip float i nu pot fi schimbate n decursul ndeplinirii programului. S examenm iniializarea masivului bidimensional: Int a[3][3]={ {1,4,2}, {7,5,3}, {8,6,9} }; Iniializarea masivului bidimensional se efectueaz pe rnduri. Elementele acestui masiv au urmtoarele valori: a[0][0]=1; a[0][1]=4; a[0][2]=2; a[1][0]=7; a[1][1]=5; a[1][2]=3; a[2][0]=8; a[2][1]=6; a[2][2]=9; La iniializarea masivului dat fiecare rnd se include n acolade . Dac n rndurile indicate de noi nu vor ajunge elemente pentru completarea rndurilor, n acest caz n locul elementelor pentru care n-au ajuns valori vor aprea zerouri. Dac n acest exemplu vom omite acoladele interioare, rezultatul va fi acelai. Dac lipsesc acoladele interioare ,elementelor masivului se vor atribui valorile n mod succesiv extrase din list .Completarea masivului se efectuiaz pe rnduri. Elementele masivului pentru care n list n-au ajuns valori, primesc valorile zero.Dac n list snt mai multe valori dect elemente, atunci o astfel de list se socoate greit. Cele menionate mai sus se refer la toate tipurile de masive.Exemple: Iniializarea masivului bidimensional:

39

int a[3][3]={ 1,4,2,7,5,3,8,6,9}; Trei metode echivalente de iniializare a masivului tridimensional: int p[3][2][2]={ { {1,2},{3,4} }, { {5,6},{7,8} }, { {9,10},{11,12} } }; int p[3][2][2]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; int p[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12}; 7.4. Exemple de prelucrare a masivelor. Prezentm 2 exemple de prelucrare a masivelor unidimensional i bidimensional: Exemplu 1. Prelucrarea unui masiv unidimensional: Este dat un masiv unidimensional x cu n elemente. Comparai suma primei jumti a masivului cu media aritmetic jumatii a doua a masivului. #include<stdio.h> #include<conio.h> #include<math.h> #include<stdlib.h> void main(void) { int x[20],n,k,i,s=0; float m,s1=0,r=0; printf("\nCulege mrimea masivului n<=20\n"); scanf("%d",&n); for(i=0;i<n;i++){ printf("Culege elementul %d\n",i); scanf("%d",&x[i]);} printf("Masivul iniial este:\n"); for(i=0;i<n;i++){ printf("%d ",x[i]);} if (fmod(n,2)==0) k=floor(n/2); else k=floor(n/2)+1; for(i=0;i<n;i++){ if (i<k) s+=x[i]; else {s1+=x[i]; r++;} } m=s1/r; printf("\nSuma primei jumti este %d\n",s); printf("Media la a doua jumtate este %f",m); getch();} Exemplu 2. Prelucrarea unui masiv bidimensional: Este dat un masiv bidimensional. X[n,n]. Calculai produsul elementelor pozitive pare din aria haurat. #include<stdio.h> #include<conio.h> #include<math.h> #include<stdlib.h> void main(void) { int x[20][20],n,i,j,p,k;
40

printf("\nCulege mrimea masivului n<=20\n"); scanf("%d",&n); printf("\nCulege elementele masivului\n"); for(i=0;i<n;i++){ for(j=0;j<n;j++){ printf("\nCulege elementul x[%d][%d]\n",i,j); scanf("%d",&x[i][j]);}} printf("\nMasivul iniial este:\n"); for(i=0;i<n;i++){ for(j=0;j<n;j++){ printf("%d ",x[i][j]);} printf("\n");} p=1; k=floor((float)n/float(2)); for(i=0;i<n;i++){ for(j=k;j<n;j++){ if ( (x[i][j]>0)&&(fmod(x[i][j],2)==0) ) p=p*x[i][j]; }} printf("\nProdusul elementelor din aria haurata este=%d k=%d\n",p,k); getch(); } 8. iruri de caractere. Numim ir o succesiune de caractere ale alfabetului, adic o propoziie. Spre deosebire de alte limbaje de programare, limbajul C nu contine un tip de date special ce desemneaz iruri de caractere. Limbajul C opereaza cu irurile cum ar lucra cu o succesiune de date de tip caracter amplasate ntr-un masiv. Aici fiecare simbol din ir este o component aparte a masivului. Deci, pentru a defini o variabil, valoarea careia va fi un ir de caractere, n limbajul C trebuie de declarat un masiv de tip char cu o lungime egal cu cantitatea maximal posibil de caractere n ir. Urmtorul exemplu arat cum s-ar putea declara un asemenea masiv cu scopul de a culege un nume de la tastatur i apoi de-l afiat la monitor: void main(void) { char a[20]; int i; printf ("Culege numele"); for(i=0; i<20; i++) scanf ("%c",a[i]); printf("Numele dumneavoastra este:"); for(i=0; i<20; i++) printf("%c",a[i]); } n acest program se observ multe neajunsuri i incomoditi. Pentru a culege numele aici este folosit un ciclu cu 20 repetri care citete cte un caracter de la tastatur i-l nscrie n celula corespunztoare a masivului a[20]. Rezult c cu ajutorul acestui program se poate culege numai nume alctuite din 20 de caractere,
41

sau nume din k caractere cu 20-k spaii dup ele. Iar afiarea numelui este fcut cu ajutorul funciei printf( ) inclus n ciclu, care afiaz la monitor cte un caracter din numele cules. Not: La declararea masivului de tip char pentru descrierea unui ir se indic mrimea masivului cu o celul mai mult de ct lungimea maxim presupus a irului din cauz c ultima celul din masiv este rezervat pentru simbolul nul "/0". Evident c imposibil de programat ntr-un limbaj de nivel nalt folosind astfel de mecanisme. Din cauza c programele pentru prelucrarea informaiei textuale au o popularitate foarte mare, limbajul C conine mecanisme care uureaz lucru cu irurile de caractere. Aici irurile snt precutate ca un tip special de masive, fapt ce permite ntroducerea si afiarea irurilor ca un tot ntreg. Pentru ntroducerea irului n memoria calculatorului este folosit funcia gets( ). Aceast funcie are urmtoarea sintax: gets (nume); unde nume este parametrul funciei i reprezint numele variabilei tip ir, adic a masivului de tip char. Exemplu: void main(void) { int i; char name [15]; printf ("Culege numele:"); gets(name); printf ("Numele dumnevoastra este:"); for (i=0; i<15; i++) printf ("%C", name[i]); } Aici funcia gets( ) va precuta primele 14 caractere culese de la tastatur ca valoare a irului cu nume name, iar ultima celul din masiv va conine simbolul nul \0. n timpul lucrului functiei gets( ) executarea programului se stopeaz. Funcia gets( ) ateapt pn utilizatorul va culege un ir de la tastatur. Pentru ca textul cules s fie atribuit ca valoare unei variabile de tip ir, utilizatorul trebuie s culeag tasta ENTER. Dup aceasta propoziia culeas va deveni valoare a variabilei de tip ir, iar cursorul va trece n rnd nou pe monitor. Anume in timpul culegerii tastei ENTER compilatorul C adaog la sfritul irului simbolul nul. n exemplu de mai sus culegerea irului se precaut ca culegerea unei variabile de tip ir aparte i nu ca culegerea a mai multor variabile de tip caracter. ns afiarea numelui rmne incomod. Aici, dac vor fi culese mai puin de 15 simboluri de la tastatur, atunci elementele masivului name[15] ce urmeaz dup simbolul nul vor conine mrimi aleatoare. n afar de funcia gets() limbajul C mai conine o modalitate de a ntroduce o propoziie n memorie ca valoare a unei variabile de tip ir. Folosind funcia de

42

ntroducere cu format scanf(), se poate aplica urmtoarea sintax: scanf("%s",name); care atept culegerea de la tastatur a unui ir de caractere, pe care apoi (dupa culegerea tastei ENTER l atribuie ca valoare variabilei name. Aici %s este formatul tipului ir de caractere. Pentru afiarea la monitor a unui ir de caractere este folosit funcia puts(). Funcia puts( ) poate avea n calitate de parametru numai un ir de caractere. Sintaxa funciei este urmatoarea: puts(parametru); unde n calitate de valoare poate fi folosit un ir de caractere sau numele unei variabile de tip ir de caractere. Exemplu: puts("Elena"); puts(name); Majoritatea compilatoarelor C trec cursorul din rnd nou dup executarea funciei puts(). ns exist i aa versiuni de compilatoare, care nu ndeplinesc aceast trecere din rnd nou. n acest caz e binevoit folosirea simbolului de trecere n rnd nou \n. Exemplu: puts("Elena|n"); Folosind funciile gets( ) i puts( ) exemplul de mai sus se poate scrie n felul urmtor: void main (void) { char name[15]; puts (" Culege numele"); gets (name); puts ("Numele dvs este:"); puts (name); } 8.1. Masive de iruri. Declarnd un masiv char S[20] putem pstra n el valoarea unui ir de caractere. n cazul, cnd este nevoie de prelucrat o totalitate din cteva iruri, e comod de folosit masive de iruri. Un masiv de iruri este un masiv bidimensional tip char compus din linii i coloane. Pe fiecare linie din aa masiv va fi nscris cte un ir de caractere. Numrul maximal de iruri astfel nscrise n masiv va fi egal cu cantitatea liniilor din masiv. De exemplu: char propoziie[10][35]este un masiv, n care pot fi scrise 10 variabile de tip ir de caractere, fiecare avnd lungimea maximal de 34 de caractere. Pentru a accesa un ir din aa masiv se va folosi sintaxa: propoziie[i], unde i este numrul rndului din masiv unde se va afla irul. Pentru a accesa un caracter al irului i din masiv se va folosi sintaxa: propoziie[i][j] unde j este poziia caracterului n irul i.

43

9. Structuri n C/C++. Pn n momentul de fa au fost studiate tipurile de date compuse, elementele crora aparin aceluiai tip de date(simplu sau compus). n cazul unui masiv, elementele acestuia erau de acelai tip: ntreg, real, caracterial etc; fr a fi posibil atribuirea diferitor elemente ale masivului valori de tipuri diferite. ns deseori apar situaii cnd este necesar prelucrarea i pstrarea unei informaii mai complexe, aa c orarul leciilor, reuita unui student etc. Dac precutm cazul cu reuita studentului, atunci este simplu de presupus c va fi necesar urmtoarea informaie: numele studentului, grupa, notele la examen, balul mediu calculat. Aceste date snt legate ntre ele prin faptul c aparin aceleiai persoane. Ca urmare ar fi justificat tratarea lor ca o singur valoare compus. ns tipurile datelor defer ntre ele: numele i grupa vor fi de tip ir, notele la examen - de tip ntreg, iar balul mediu calculat - de tip real(float). Gruprea acestor componente ntro variabil compus este posibil folosind un tip nou de date numit n limbajul C structur. Primul pas n gruparea componentelor de diferite tipuri ntr-o variabil compus este declararea i descrierea structurii. Declarnd o structur, se creeaz un tip nou de date a utilizatorului, care pn n momentul dat n-a fost cunoscut de compilator. Declararea structurilor se face n partea declarrii tipurilor, nainte de nceputul funciei principale main(). Declararea unei structuri ncepe cu cuvntul chee struct, dup care urmeaz numele structurii, care se mai numete tip nregistrare. Elementele unei variabile de tip nregistrare snt nscrise dup numele structurii ntre acolade. Sintaxa de descriere a elementelor structurii e analogic cu sintaxa declarrii variabilelor: se indic numele i tipul elementelor din structur desprite prin simbolul ;. Descrierea structurii de asemenea se termin cu simbolul ;. Sintaxa descrierii unei structuri n caz general este urmtoarea: struct nume {tip_1 nume_1; tip_2 nume_2;; tip_n nume_n;}; Lista elementelor din structur poart numele de ablon. O structur, ca atare nu declar nici o variabil. Elementele unei structuri nu snt variabile aparte, ele snt componente ale unei sau a mai multor variabile. Astfel de variabile se numesc structurale i trebuie declarate ca fiind de tipul structurii respective. ablonul respectiv va descrie aceste componente, astfel va fi determinat volumul de memorie necesar de rezervat pentru fiecare variabil structurat de tip nregistrare. Dac precutm exemplu cu reuita unui student, declararea unei structuri va fi urmtoarea : struct stud {char name [20] ; int ex1, ex2; float med; char grup [10];};

44

9.1. Declararea variabilelor de tip structur. Declararea structurii nu rezerveaz spaiu de memorii pentru ea. nainte de a folosi orice tip de date, e necesar de declarat o variabil corespunztoare. Este imposibil de a folosi o structur n program fr a declara o variabil de tip nregistrare, fix aa cum e imposibil folosirea unei valori de tip float naintea declarrii variabilei de tip float. Sintaxa de declararea a unei variabile-structuri e urmtoarea: struct nume_structura nume_variabil; Aici cuvntul cheie struct indic compilatorului faptul c merge vorba despre o structur, iar tipul nregistrrii stud determin ablonul dup care va fi compus variabila. Dup tipul nregistrrii urmeaz numele variabilei, care va fi folosit n program. De exemplu, pentru a primi acces la datele despre reuita unui student trebuie declarat o variabil: struct stud a; Acum avem variabila a compus din 5 cmpuri, pentru care a fost rezervat memorie. Dac n program trebuie folosite cteva variabile de unul i acelai tip nregistrare, e posibil de folosit urmtoarea sintax: struct stud a, b, c; Aici snt declarate 3 variabile de tip nregistrare stud: a, b, c. n cazul cnd e necesar folosirea variabililor de tip nregistrare diferit, ele se vor declara aparte. Exist posibilitatea declarrii variabilei de tip nregistrare odat cu descrierea structurii. Pentru aceasta numele variabilei va fi amplasat ntre acolada de nchidere i simbol ; la sfritul declarrii structurii. Exemplu: struct stud { char name [20]; char grup [10] ; int ex1, ex2; float med;}a; Aici stud este tipul nregistrrii i numele unui nou tip de date numit structur. Elementele, din care se compune structura se mai numesc cmpuri structurate, a este numele variabilei , care va fi folosit n program i e compus conform ablonului din 5 componente. 9.2. Iniierea variabilelor tip nregistrare. n cazul, cnd valorile iniiale ale componentelor unei variabile-structu snt cunoscute, este posibil atribuirea lor n timpul declarrii variabilei. n cazul cnd se declar o simpl variabil tip nregistrare iniierea va fi o parte a declarrii structurii: struct stud { char name [20]; char grup [10]; int ex1, ex2; float med;}

45

a={Ivanov, SOE-991, 8,7,7.5}; Aici a fost descris structura stud i concomitent declarat variabila a cu iniializarea valorilor pentru componentele sale. O alt variant de iniializare a componentelor structurii este iniializarea lor n tipul declarrii unei variabile tip nregistrare. Exemplu: struct stud { char name [20]; char grup [10]; int ex1, ex2; float med;} main () { struct stud a={Ivanov, SOE-991, 8,7,7.5}; } O structur este global, dac e declarat nainte de funcia principal main(), i este local dac e declarat nuntru funciei main(), sau nuntru altei funcii. ns dac e necesar iniializarea unei structuri ce conine iruri, ea trebuie declarat nainte de funcia main() sau ca variabil static: static struct stud; 9.3. Folosirea structurilor. O structur poate fi prelucrat n program, numai dac exist declarat o variabil de tip nregistrare. Aceast variabil e compus din cteva elemente fiecare avnd valoare de tip diferit. ns adresarea ctre valorile ce se conin n cmpurile structurii este imposibil folosind nemijlocit numele cmpului respectiv. De asemenea e imposibil accesarea valorilor din variabila tip nregistrare folosind numai numele ei. Conform regulilor de sintax a limbajului C++, pentru a accesa un element al structurii, este necesar de indicat numele variabilei tip nregistrare i numele cmpului respectiv folosind urmtoarea sintax: nume_var.nume_cmp , unde nume_var este numele variabilei tip nregistrare, iar nume_cmp numele cmpului respectiv din variabil. Not: La prelucrarea valorilor din cmpurile structurii se vor folosi toate funciile, instruciunile i operaiile aplicabile tipului crui i aparin cmpurile structurii. Exemplu: De alctuit o structur care ar conine informaii despre un student (nume, grupa) i ar calcula nota medie dup rezultatele la dou examene: struct stud {char name [20], group[10]; int ex1, ex2; float med;}; void main (void) { struct stud a; puts(Culege numele i grupa); gets(a.name); gets(a.group); puts(Culege notele la dou examene); scanf(%d%d,&a.ex1,&a.ex2); a.med=(a.ex1+a.ex2)/2; printf(media=%f,a.med);}

46

9.4. Structuri imbricate. Tipul structur este un tip compus, aceasta nseamn c o variabil de acest tip poate fi alctuit din cteva elemente simple sau compuse, care la rndul su pot deasemenea s conin alte elemente. Acest fapt ne d posibilitate s folosim unele structuri n calitate de cmpuri pentru altele structuri. Astfel de structuri se vor numi imbricate. Cantitatea de niveluri de structuri imbricate teoretic poate fi infinit, ns nu se recomand de a folosi foarte multe nivele de imbricare din cauza sintaxei incomode. n cazul cnd structura A contine n componena sa un cmp, care la rndul su este deasemenea o structur B, atunci structura A trebuie declarat numai dup ce va fi declarat structura B. Urmtorul exemplu folosete variabila a de tip structur stud imbricat, care conine informaia despre un student i rezultatele unei sesiuni. Informaia despre rezultatele sesiunii este grupat ntr-o structur aparte cu numele sesia i e folosit n calitate de cmp nota n structura stud: struct sesia {int ex1,ex2,ex3; float med;}; struct stud {char name [20], group[10]; struct sesia nota;}; void main (void) { struct stud a; puts(Culege numele i grupa); gets(a.name); gets(a.group); puts(Culege notele la 3 examene); scanf(%d%d%d,&a.nota.ex1, &a.nota.ex2, &a.nota.ex3); a.nota.med=( a.nota.ex1+a.nota.ex2+a.nota.ex3)/3; printf(\nmedia=%f,a.nota.med);} Aici a fost calculat nota medie reieind din rezultatele la 3 examene. Din acest exemplu este simplu de observat sintaxa de adresare la o valoare dintr-un cmp a unei structuri imbricate: se folosesc numele fiecrui cmp imbricat, separat prin punct i scrise n ordine descresctoare pn la cmpul destinaie. Sintaxa a.nota.med nseamn ca se face o adresare la cmpul med ce aparine unei structuri (sesia), care la rndul su este cmp (nota) n componena altei structuri (stud) apelat prin intermediul variabilei a. 9.5. Masive de structuri. n timpul declarrii unei variabile tip nregistrare, n memorie se nregistreaz spaiu pentru pstrarea i prelucrarea datelor ce se vor conine n cmpurile structurii

47

conform ablonului numai pentru o nscriere: un student, o persoan .a.m.d. n cele mai dese cazuri este necesar prelucrarea informaiei despre un grup de persoane, n cazul nostru despre un grup de studeni. n acest caz este necesar declararea a mai multor variabile de tip nregistrare, fiecare reprezentnd nscrierea concret, pentru un student aparte. Pentru a sistematiza informaia pstrat ntr-o mulime de nscrieri este binevenit declararea unui masiv de structuri. n acest caz fiecare element al masivului unidimensional tip structur va pstra informaia despre o persoan i numrul maximal persoane nregistrate in aa fel va fi egal cu cantitatea de elemente ce se conin din masiv. Un masiv unidimensional de structuri se poate declara n modul urmtor: struct nume_structur nume_ masiv [N]; unde N - numrul de elemente din masiv. Exemplu: struct stud x[10]; n aa fel au fost rezervate 10 regiuni de memorie, fiecare avnd volumul necesar pentru a pstra o structur ntreag pentru prelucrarea informaiei despre reuita unui student. Adresarea in program la un element al masivului de structuri va fi fcut ca i n cazul unui masiv simplu: se va indica numele masivului cu numrul de ordine al elementului in paranteze ptrate. Exemplu: x[3]. ns aa o adresare ctre structur va fi ncorect. Prelucrarea structurii are loc prin intermediul prelucrrii cmpurilor aparte din ea. Accesarea unui cmp din variabila de tip nregistrare care este n acela timp cmp al masivului va fi posibil folosind sintaxa: nume_msiv[k].Nume_cmp, unde k este numrul de ordine a nregistrii necesare. Exemplu: Pentru a nscrie n cmpul name din structura stud numele studentului cu numrul de ordine 2 vom folosi urmtoarea sintax: struct stud x[10]; gets(x[2].name). Not: De nu uitat c numrarea elementelor n masiv se face ncepnd cu indexul zero. n cazul nostru find alctuit un masiv din 10 structuri , numrul de ordine va varia de la 0 la 9. Exemplu: Este dat o baz de date cu n nscrieri ce conin informaia despre reuita unui grup de studeni. Dup notele date la examenele unei sesiuni de calculat nota medie pentru fiecare student. Cmpuri necesare: Numele, Grupa, Notele la examene, Balul mediu calculat: #include<conio.h> #include<stdio.h> #include<math.h> #include<stdlib.h> struct stud {char name[20], grupa[10];

48

int ex1,ex2; float med;}; void main (void){ clrscr(); struct stud x[50]; int i,N; printf("Culege numarul studentilor\n"); scanf("%d",&N); printf("Culege informatia despre %d studenti:\n",N); for (i=0; i<N; i++){ printf("Culege numele studentului %d\n",i);scanf("%s",x[i].name); printf("Culege grupa studentului %d\n",i); scanf("%s",x[i].grupa); printf("Culege 2 note pentru studentul %d\n",i); scanf ("%d%d",&x[i].ex1,&x[i].ex2); x[i].med=(x[i].ex1+x[i].ex2)/2;} printf("\nMasivul final este:\n"); printf("******************************************************\n"); printf("** Numele ** Grupa ** nota1 ** nota2 ** media **\n"); printf("******************************************************\n"); for (i=0;i<N;i++) { printf("**%10s**%9s**%7d**%7d**%9.2f**\n", x[i].name,x[i].grupa,x[i].ex1,x[i].ex2,x[i].med); printf("******************************************************\n"); } getch(); } 10. Funcii n C/C++. Rezolvarea eficient a problemelor cu ajutorul tehnicii de calcul presupune folosirea tuturor tuturor posibilitilor i instrumentelor limbajului n care are loc programarea. n timpul studierii instruciunilor i tipurilor noi n C/C++ apar posibiliti de rezolvare eficient a unor probleme complicate. ns odat cu creterea complicitii problemei de rezolvat, se mrete volumul programului i complicitatea lui. n acest caz exist necesitatea de a evidenia careva sarcini concrete din program mprindu-l n module separate numite funcii. Fiecare funcie din program trebuie s ndeplineasc o singur sarcin. De exemplu, dac se afl notele medii la un grup de studeni, atunci se poate de creat 3 funcii: prima pentru culegerea valorilor iniiale despre studeni; a doua - pentru calcularea notei medii i a treia - pentru afiarea rezultatelor. Folosind aceste funcii, dac n program trebuie de ndeplinit o sarcin oarecare, atunci se apeleaz la funcia

49

respectiv asigurnd-o cu informaia necesar pentru prelucrare. Folosirea funciilor n C++ presupune respectarea urmtoarelor concepii de baz: a) Funciile grupeaz setul de operatori pentru ndeplinirea unei sarcini concrete. b) Programul principal apeleaz la funcie, adresndu-se la numele ei, dup care urmeaz paranteze rotunde. Exemplu: afiare(). c) Dup terminarea prelucrrii informaiei, majoritatea funciilor ntorc programului principal valori de tipuri concrete. De exemplu: int sau float, care pot fi folosite n calcule. d) Programul principal transmite funciilor parametrii (informaia iniial), inclus n paranteze rotunde, care urmeaz dup numele funciei. e) Limbajul C++ folosete prototipi de funcie pentru determinarea tipului valorii returnate de ctre funcie, deasemenea a cantitii si tipurilor parametrilor transmii funciei. Odat cu mrirea volumului i complicitii programului, folosirea funciilor va deveni condiia principala pentru rezolvarea eficient i corect. n acelai moment crearea i folosirea funciilor snt proceduri simple. n timpul crerii programului e necesar de rezervat fiecare funcie pentru rezolvarea unei sarcini. Dac apar situaii, cnd funcia rezolv cteva sarcini, ea trebuie divizat n cteva funcii mai mici. Fiecare funcie creat trebuie s primeasc un nume unical. Ca i n cazul cu variabilele, numele unei funcii este un identificator i e de dorit s corespund cu sensul logic al sarcinei pe care o ndeplinete. Funciile n C++ se aseamn la structur cu funcia principal main(). n faa numelui funciei se indic tipul ei, iar dup numele funciei urmeaz lista de parametri descrii nuntrul parantezelor rotunde. Corpul funciei compus din operatori este amplasat dup descrierea parametrilor i-i nconjurat cu acolade deschis i nchis. Sintaxa descrierii unei funcii este urmtoarea: tip_f nume_f (lista parametri) {declarare de variabile; operatori;} unde tip_f este tipul funciei sau tipul valorii returnate de funcie, nume_f este numele funciei. Dac facem analogie dintre funcie i programul principal main( ), atunci putem scrie: void main (void) {corpul programului}, unde funcia nu ntoarce rezultate (cuvntul void naintea funciei main() ) i nu primete parametri din exterior (cuvntul void ntre paranteze rotunde dup funcia main() ). Urmtorii operatori determin funcia cu numele afiare(), care afiaz la monitor un mesaj: void afiare (void) {printf(Hello World\n);} Dup cum a fost spus, cuvntul void ce precedeaz numele afiare indic funciei c nu trebuie de ntors vre-o valoare n program, iar cuvntul void dup

50

numele afiare indic (compilatorului C++ i programatorului ce citete acest cod) c funcia nu folosete parametri (informaie iniial pentru ndeplinirea sarcinei). Urmtorul program folosete funcia afiare() pentru afiarea mesajului pe ecran: # include<stdio.h> # include<conio.h> void afisare (void) { printf(\ Hello World\n); void main (void) { puts (inaintea folosirii funciei); afisare( ); puts (dupa folosirea funciei); getch(); } Ca i orice program n C++ acest exemplu va fi ndeplinit ncepnd de la funcia principal main( ). nuntru programului operatorul de apel la funcie apeleaz la funcia de afiare astfel: afiare(); unde parantezele rotunde dup identificator indic compilatorului c n program se folosete funcia afiare(). Cnd programul va ntlni apelul la funcie, se va ncepe ndeplinirea tuturor operatorilor din corpul funciei, i dup aceasta executarea programului principal va fi continuat cu operatorul amplasat nemijlocit dup operatorul de apel la funcie. Urmtorul program-exemplu conine dou funcii, prima afiaz pe ecran o salutare, iar a doua tema leciei: # include<stdio.h> # include<conio.h> void hello (void){ printf(\n Hello\n);} void tema (void){ printf(Funcii in C++\n);} void main (void){ hello(); tema(); } n rezultatul ndeplinirii acestui exemplu vor fi afiate pe ecran dou mesaje: Hello i Funcii n C++ , n ordinea cum apar n program. Funciile prezentate mai sus ndeplinesc sarcini foarte simple. n aceste cazuri programul putea fi alctuit fr folosirea funciilor, cu includerea acelorai operatori n corpul funciei main(). ns funciile au fost folosite pentru a analiza descrierea i folosirea ulterioar a funciilor. n timpul rezolvrii problemelor complicate va fi posibil, n aa fel, de simplificat rezolvarea, mprind sarcina n module aparte realizate de funcii. n acest caz va fi simplu de observat c analiza i modificarea

51

funciilor este cu mult mai simpl dect prelucrarea unui program voluminos i complicat. Mai mult ca att, funcia creat pentru un program poate fi folosit i n alt program fr schimbri. n aa mod pot fi alctuite biblioteci de funcii, folosirea crora cu mult va micora timpul folosit pentru alctuirea programelor. 10.1. Transmiterea parametrilor n funcie. Pentru a mri posibilitile funciilor din program, limbajul C++ permite de a transmite informaie n ele. Informaia iniial transmis din program n funcie la momentul apelului acesteia se numete parametru. Dac funcia folosete parametri, ei trebuie descrii n timpul descrierii funciei. n timpul descrierii parametrelor funciei se indic numele i tipul fiecrui parametru n urmtorul mod: tip_parametru nume_parametru; Dac funcia conine civa parametri, ei vor fi descrii mpreun ntre parantezele rotunde dup numele funciei desprii prin virgul dup cum urmeaz: tip_funcie nume_funcie (tip_parametru1 nume_parametru1, tip_parametru2 nume_parametru2 ......................................................... tip_parametruN nume_parametruN ); Funcia din exemplu urmtor folosete un parametru de tip ntreg, care n rezultatul ndeplinirii sale, l afieaz la monitor. # include<stdio.h> void numr (int a) { printf(Parametru=%d\n,a);} void main (void) { numr (1); numr (17); numr (-145); } n rezultatul ndeplinirii acestui exemplu vor fi primite 3 fraze ca rspuns: Parametru=1 Parametru=17 Parametru=-145 n timpul executrii acestui program, funcia numr() este apelat de 3 ori cu diferite valori a parametrului. De fiecare dat cnd n program este ntlnit funcia numr() valoarea parametrului este nlocuit n funcie i rezultatul est diferit. Parametrii funciei pot fi de tipuri diferite. n cazul exemplului precedent parametrul a este de tip ntreg. Dac n program va fi fcut ncercarea de a

52

transmite funciei un parametrul de alt tip, de exemplu float, compilatorul va ntoarce o eroare. Majoritatea funciilor folosesc mai muli parametri, n acest caz trebuie s fie indicat tipul fiecrui parametru. Urmtorul exemplu folosete funcia muncitor(); care afieaz numele i valoarea salariului unui muncitor: # include<stdio.h> void muncitor (char nume[15], float salariu) {printf(Muncitorul %s are salariu= %f lei\n,nume,salariu);} void main (void) { muncitor(Ivanov, 355.35); muncitor(Petrov, 560.00); } n rezultatul ndeplinirii acestui program funcia muncitor() este apelat de dou ori i snt afiate mesajele: Muncitorul Ivanov are salariul= 355.35 lei. Muncitorul Petrov are salariul= 560.00 lei. Not: n unele surse de descriere a limbajului de programare C/C++ parametrii ce se transmit din program n funcie se numesc actuali, iar parametrii ce snt declarai n antetul funciei i crora le se atribuie valorile parametrilor actuali se numesc parametri formali. Aadar n exemplul precedent valorile Ivanov i 355.35 snt parametri actuali, iar char num[15] i float salariu snt parametri formali. Urmatorul exemplu folosete funcia max(), care compar 2 numere ntregi: # include<stdio.h> void max (int a, int b) { if (a>b) printf (%d este mai mare ca %d\na,b); else if (b>a) printf(%d este mai mare ca %d \n,b,a); } else printf(%d este egal cu %d \n,a,b); } void main (void) { max(17,21); max(5,3); max(10,10); } Deci n timpul folosirii parametrilor n funcie este necesar respectarea urmtoarelor reguli: Dac funcia folosete parametri, ea trebuie s indice numele unical i tipul fiecrui parametru. Cnd programul apeleaz la funcie, compilatorul atribuie valoarea parametrlor de la stnga la dreapta.

53

Valorile transmise din program n funcie, trebuie s coincid ca numr, loc i tip cu parametrii din funcie. 10.2. ntoarcerea valorilor din funcie. Destinaia oricrei funcii este ndeplinirea unei sarcini concrete. n majoritatea cazurilor funciile vor efectua careva calcule. Dup aceasta funcia va ntoarce rezultatul funciei din care a fost apelat fie aceasta funcia principal main(), fie alt funcie. La momentul cnd funcia ntoarce o valoare, trebuie s fie cunoscut tipul ei. Tipul valorii returnate de funcie se indic n timpul descrierii funciei nainte de numele ei. Tipul valorii returnate se mai numete i tipul funciei. Funcia din urmtorul exemplu adun 2 numere ntregi i ntoarce rezultatul programului principal: # include<stdio.h> # include<conio.h> int suma (int a, int b) { int R; R=a+b; Return (R);} void main (viod) { int K; K=suma(15,8); printf(suma=,K);} n acest caz, cuvntul int, ce se afl naintea numelui funciei suma() n timpul descrierii acestuia, este tipul valorii returnate de funcie n programul principal. Funciile folosesc operatorul return pentru a ntoarce valori funciilor din care au fost apelate. Cnd compilatorul ntlnete operatorul return, el ntoarce valoarea dat i ncheie executarea funciei curente, controlul executrii programului fiind transmis funciei din care a fost chemat funcia curent. Dac dup operatorul return, n funcie mai exist operatori, ei vor fi ignorai, funcia terminndu-se odat cu ndeplinirea operatorului return. Funcia suma() din exemplu precedent este alctuit din 3 instruciuni. Exist posibilitatea de a micora corpul acestei funcii dup cum urmeaz n exemplu urmtor: int suma (int a, int b) {return(a+b);} n acest caz, n calitate de parametru pentru operatorul return a fost folosit o expresie ce calcul suma a dou numere. n general, parametrul return folosete n calitate de parametrul o expresie ce are rezultate tip identic cu tipul funciei, adic tipul valorii returnate de funcie.

54

Nu toate funciile returneaz valori de tip ntreg. Urmtorul exemplu folosete funcia media() , care returneaz media aritmetic a 3 numere ntregi. Evident rezultatul funciei poate fi i un numr real: # include<stdio.h> # include<conio.h> float media (int a, int b, int c,){ return (float(a+b+c)/3.0); } float R; R=media(5,7,10); printf(media este =%f,R); } n rezultatul ndeplinirii acestui exemplu, va fi primit rezultatul R=7,333. n funcie a fost folosit conversia (float(a+b+c)) a uni numr ntreg n echivalentul su real pentru a primi ca rezultat media aritmetic a 3 numere de tip real. n acest exemplu cuvntul float ce se afl naintea numelui funciei media() n momentul descrierii acestea, indic tipul valorii returnate. Exist situaii cnd operatorul return este folosit n funcii ce nu ntorc valori. Urmtorul exemplu demonstreaz aceast posibilitate: # include<stdio.h> # include<conio.h> max (int a, int b) { if (a>b) printf(%d>%d\n,a,b); else if (a<b) printf(%d<%d\n,a,b); else printf (%d=%d\n,a,b); return 0;} void main (void) { max (17,21); max (3,-7); max (5,5); } Valoarea ntoars de funcie poate fi folosit n orice loc al programului, unde e posibil folosirea unei valori de tip identic cu valoarea returnat. Cnd funcia ntoarce o valoare, aceast valoare poate fi atribuit unei variabile de acelai tip folosind operatorul de atribuire. Exemplu: R=media (5,7,10); n continuare la acele spuse, nsi numele funciei poate fi folosit, n cazul cnd exist necesitatea folosirii valorii returnate de funcie, de exemplu valoarea returnat poate fi folosit n interiorul funciei de afiare: printf(Media este =%f,media (5,7,10));

55

Mai mult ca att funcia poate folosi valoarea returnat n condiii, dup cum urmeaz: if (media(5,7,-14)<0) printf(media este negativa\n); 10.3. Prototipul funciei. nainte de a face apelul unei funcii compilatorul C++ trebuie s cunoasc tipul valorii returnate, cantitatea i tipul parametrilor folosii de funcie. n fiecare exemplu precutat pn n prezent descrieria funciei era fcut naintea apelului ei din programul principal. ns snt situaii, cnd unele funcii n program snt apelate reciproc. n aa cazuri este posibil situaia cnd o funcie va fi apelat nainte descrierii sale. Pentru a garanta faptul, c compilatorul C++ cunoate particularitile fiecrei funcii folosite n program, se folosesc prototipi ai funciilor. Prototipul unei funcii este amplasat la nceputul programului i conine informaia despre tipul valorii returnate, cantitatea i tipul parametrilor folosii de funcie. Exemplul urmtor demonstreaz cum s-ar putea alctui prototipi pentru funciile folosite anterior. void afiare (void); void hello (void); void tema (void); void numr (int); void muncitor (char, float); void max (int, int); int suma (int, int); float media (int, int, int); Dup cum se vede din exemplu fiecare funcie i are prototipul su care descrie tipul valorii returnate, cantitatea i tipul parametrilor. Este important de nu uitat de simbolul ; la sfritul fiecrui prototip. Lispa lui duce la eroare n compilare, la fel cum duce la eroare lipsa prototipului unei funcii dac aceasta apare n program naintea descrierii sale. Fiind declarat prototipul unei funcii nainte de a fi nceput corpul programului, descrierea ei poate fi fcut dup acolada de nchidere a programului principal. Exemplu: # include<stdio.h> # include<conio.h> float media (int,int,int); void main (void) {float r; clrscr(); r=media (5,17,10);

56

printf (media=%f/n,r); getch ( ); } float media (int a, int b, int c) { return (float(a+b+c)/3.0);} 10.4. Variabile locale i domeniul de vizibilitate. Funciile folosite n exemplele precedente ndeplinesc nite sarcini relativ simple. La momentul, cnd funciile vor trebui s ndeplineasc nite sarcini mai complicate, va aprea necesitatea folosirii n funcii a variabilelor proprii. Variabilele declarate n cadrul funciei se numesc locale. Numele i valoarea unei variabile locale snt cunoscute numai funciei n care ea a fost declarat. Chiar faptul c variabila local exist este cunoscut numai funciei n care ea a fost declarat. Declararea variabilelor are loc la nceputul funciei, ndat dup acolada ce deschide corpul acesteia. Numele variabilei locale trebuie s fie unical numai n funcia n care a fost declarat. O variabil se numete local, din cauz c este vzut numai din funcia n care a fost descris. Sintaxa de declarare a unei variabile locale este: tip_f numele_f (lista parametrilor) {tip_vl numele_vl;} unde: tip_f - tipul funciei; nume_f - numele funciei; tip_vl - tipul variabilei; numele_vl - numele variabilei; Principiile de declarare i folosire a unei variabile locale oricrei funcii snt identice cu principiile de declarare i utilizare a unei variabile declarate n corpul funciei principale main(); O variabil declarat n corpul funciei main()este local acestei funcii. n general, tot ceia ce a fost spus despre variabilele declarabile n funcia main(): tipurile, numele, principiile de utilizare .a. este aplicabil pentru o variabil local din orice alt funcie. Urmtorul exemplu folosete funcia fact() pentru calcularea factorialului unui numr. #include<stdio.h> #include<conio.h> int fact (int R) { int i, k=1; for (i=1;i<=R;i++){k*=i;} return (k);} void main (void) { int n; clrscr();

57

printf (Culege o cifra\n); scanf(%d,&n); printf (%d!=%d\n,n,fact(n)); getch( );} n exemplu precedent funcia fact() folosete 2 variabile locale i i k de tip ntreg. Variabila k se iniializeaz cu valoarea 1 chiar n momentul declarrii sale. Anume n aceast variabil va fi pstrat valoarea factorialului pe parcursul execuiei funciei fact(). S analizm acest exemplu. La nceputul executrii programului, utilizatorul culege o cifr de tip ntreg din care mai apoi va fi calculat factorialul. Cifra culeas de utilizator se pstreaz iniial n variabila n, apoi odat cu apelul funciei fact() se transmite ca parametru fiind atribuit parametrului formal R din funcie. La nceputul executrii funciei, variabilei locale k, n care va fi pstrat valoarea factorialului i se atribuie valoarea iniial 1 pentru a evita orice valori ntmpltoare. Anume prin intermediul variabilei locale k funcia ntoarce valoarea final a factorialului n programul principal. n continuare ciclul for e repetat de n ori pentru a calcula valoarea factorialului n!, nmulind de fiecare dat valoarea nou a parametrului ciclului i la valoarea veche a lui k. La sfrit valoarea final a lui k va fi ntoars n program cu ajutorul operatorului return (). n timpul declarri variabilei locale pentru funcii exist probabilitatea, c numele variabilei locale declarate ntr-o funcie s fie identic cu numele variabilei locale din alt funcie. Dup cum a fost spus, o variabil local este cunoscut numai n funcia, n care a fost declarat. Aadar, dac dou funcii folosesc acelai nume pentru variabilele sale locale, aceasta nu aduce la situaie de conflict. Compilatorul C++ precaut numele fiecrei variabile ca local pentru funcia corespunztoare. Urmtorul exemplu folosete funcia suma() pentru adunarea a dou numere ntregi. Aceast funcie atribuie rezultatul ndeplinirii sale variabilei locale x. ns funcia main() folosete n calitate de parametru transmis funciei suma() deasemenea o variabil cu numele x. Din cele spuse mai sus rezult c ambele variabile vor fi precutate ca locale i nu va aprea situaie de conflict. #include <stdio.h> #include<conio.h> int suma(int a, int b) { int x; x=a+b; return(x); } void main (void) {

58

int x,y; printf(Culege 2 cifre\n); scanf(%d%d,&x,&y); printf(%d+%d=%d,x,y,suma(x,y)); getch(); } Exemplul urmtor folosete funcia suma() pentru a calcula suma elementelor unui masiv unidimensional de tip ntreg. n calitate de parametri se folosesc masivul i mrimea sa. # include<stdio.h> # include<conio.h> int suma (int y[10], int m) { int i, sum=0; for (i=0;i<m;i++){ sum+=y[i];} return(sum); } void main (void) { int w,n,i,x[10]; clrscr(); printf(Culege marimea masivului n<10\n); scanf(%d, &n); for (i=0;i<n;i++){ printf(Culege elementul x[%d]\n,i); scanf(%d,&x[i]); } w=suma(x,n); printf(suma masivului = %d\n,w); getch( ); } 10.5. Variabile globale. Numim variabil global o variabil, numele i valoarea creia snt cunoscute pe parcursul ntregului program. Despre existena unei variabile globale ntr-un program C++ tie orice funcie din acest program. Pentru a crea o variabil global se folosete declararea ei la nceputul programului n afara oricrei funcii. Orice funcie, care va urma dup aa o declarare poate folosi aceast variabil global. Declararea unei variabile globale are urmtoarea sintax: # include<stdio.h> tip_vg nume_vg; void main (void) {}

59

unde tip_vg este tipul variabilei globale, iar nume_vg numele variabilei globale. Fiind declarat o variabil global, valoarea ei nu numai e cunoscut oricrei funcii din program, dar i poate fi schimbat din oricare din funciile prezente n program. Exemplu urmtor folosete variabila cu numele cifra. Fiind accesibil din oricare din 2 funcii prezente n program, valoarea variabilei globale cifra este schimbat pe rnd din ambele funcii: # include<stdio.h> int cifra=100; void f1 (void) { printf(cifra=%d\n, cifra); cifra*=2; } void f2 (void) { printf(cifra=%d\n,cifra); cifra+=2;} void main (void) { printf(cifra= %d\n, cifra); //100 cifra ++; f1(); //101, 202 f2 ( ); //202, 204 printf(cifra=%d\n,cifra); //204 getch( ); } Cu toate c prezena variabilelor globale n program adaog noi posibiliti, e de dorit de a evita folosirea lor frecvent. Din cauza, c orice funcie din program poate schimba valoarea variabilei globale este foarte greu de urmrit toate funciile, care ar putea schimba aceast valoare, ceia ce duce la control dificil asupra execuiei programului. Pentru a rezolva aceast problem se poate declara variabila n corpul funciei main() i apoi de a o transmite altor funcii, n calitate de parametru. n acest caz n stiv va fi amplasat copia temporar a acestei variabile, iar valoarea iniial (originalul) va rmne neschimbat. 10.6. Conflicte dintre variabile locale i globale. n cazul cnd un program trebuie s foloseasc o variabil global, poate aprea situaie de conflict, dintre numele variabilei globale i numele variabilei locale. n aa cazuri limbajul C++ ofer prioritate variabilei locale. Adic, dac exist variabil global cu acelai nume ca i variabila local, compilatorul consider, c orice apel a variabilei cu aa nume este un apel al variabilei locale. ns apar situaii, cnd exist

60

necesitatea de a se adresa la o variabil global ce se afl n conflict cu o variabil local. n acest caz se poate folosi operatorul global de acces (::). Urmtorul exemplu folosete variabila global num. Pe lng aceast funcia afiare() folosete variabila local num. Folosind operatorul global de acces (::) funcia apeleaz la variabila global num fr conflict cu variabila local num: # include<stdio.h> int num=505; void afisare (void) { int num=37; printf(variabila locala num=%d\n,num); printf(variabila globala num=%d\n,::num);} void main (void) { afisare(); } 11. Indicatori (pointeri). Un program n limbajul de programe C/C++ conine n cele mai frecvente cazuri o mulime de variabile mpreun cu descrierea lor. Fie variabila x descris n program prin declararea de forma int x; n acest caz compilatorul rezerveaz un spaiu de 2 octei n memoria calculatorului. La rndul su, celula de memorie unde va fi alocat valoare variabilei x, i are adresa sa. De exemplu: 21650. Cnd variabila x primete o valoare, aceast valoare neaprat se nscrie n celula de memorie rezervat variabilei x. Deoarece, n cazul nostru variabila x i pstreaz valorile pe adresa 21650, celula cu aceast adres va conine valoarea atribuit variabilei x. n aa caz, ctre orice variabil din program se poate de se adresat n 2 moduri: folosind numele variabilei sau folosind adresa din memorie unde este pstrat valoarea variabilei x. Folosind numele variabilei, noi ne adresm la valoarea variabilei care se pstreaz n memorie. Folosind adresa, noi ne adresm la celula de memorie cu adresa respectiv, unde se pstreaz valoarea variabilei. Limbajul de programare C/C++ conine tehnici mai avansate de lucru cu valoarea unei variabile i adresa de memorie unde se pstreaz aceast valoare. n aceste scopuri se folosesc indicatori. Indicatorul reprezint o variabil, ce conine adresa altei variabile. Sintaxa de declarare a unui indicator este urmtoarea: tip *nume; unde tip este tipul de date a variabilei la care se poate referi indicatorul (adic tipul de date a variabilei, adresa de memorie a creia va conine indicatorul); astericsul * indic c identificatorul ce urmeaz dup el este un indicator. nume este un identificator ce desemneaz numele variabilei indicator. Exemple de declarare a indicatorilor:

61

int *x; // indicator la date de tip ntreg. float *p; // indicator la date de tip flotant. char *z; // indicator la date de tip caracterial. int *y[3]; // masiv de indicatiori la date de tip ntreg. void *k; //indicator la obiectul datelor tipul crora nu-i necesar de definit char *S[5]; // masiv de indicatori la date de tip caracter. char (*S)[5]; // indicator la date de tip caracter din 5 elemente. Odat ce indicatorul a fost declarat ca referin la date de tip ntreg, el nu se va putea referi la o variabil tip float, cauza fiind volumul diferit rezervat n memorie pentru variabile ntregi i flotante. Exist indicatori i ctre elemente fr tip - void. Putem atribui unui pointer void valoarea altui pointer non-void, fr a fi necesar operaia de conversie de tip. Exemplu: int *a; void *b; b=a; //corect a=b; //incorect, lipsete conversia de tip. Fie c a avut loc o atribuire de forma: int x=5;. n acest caz pentru variabila x a fost rezervat o zon de memorie cu volumul de 2 octei, care i are adresa sa. Adresa zonei de memorie, unde se pstreaz valoarea variabilei x se poate obine cu operatorul obinerii adresei &. Rezultatul operaiei obinerii adresei este adresa locaiei de memorie ce a fost alocat pentru variabila respectiv. De exemplu: presupunnd c x e nscris n memorie pe adresa 21650, atunci &x va fi egal cu 21650. Este important, c &x este constant de tip indicator i valoarea sa nu se schimb n timpul execuiei procramului. Exemplu: # include <stdio.h> void main (void) int x=5; float r=1.7; int *q; float *w; q=&x; w=&r; printf (%f se afl pe adresa % d \n,r,w); printf (% d se afl pe adresa %d \n,x,q);} Din exemplu uor se observ c adresa celulei de memorie se reprezint printro valoare de tip ntreg. n acelai timp aceast valoare nu poate fi schimbat n program i expresia &x=55; este incorect. Analiznd toate aceste noiuni, apare ntrebarea: Cu ce scop se folosesc indicatori, dac valoarea variabilei i valoarea adresei sale se poate pstra n variabile simple?.

62

Prioritatea folosirii indicatorului const n faptul, c la el se poate adresa n 2 moduri: q i *q. Astericsul * n acest caz indic c se apeleaz la coninutul celulei de memorie, adresa creia este valoarea indicatorului. Adic valoarea variabilei x de tip ntreg este 5; valoarea indicatorului q este 21650; iar valoarea lui *q este egal cu cifra de tip ntreg 5 nscris pe adresa de memorie 21650. n aa mod: 1) Variabila q poate primi valori numai n form de adres q=&x i atribuirea de forma q=21650; este incorect din cauza c aici se ncearc atribuirea unei valori ntregi unui indicator i nu a adresei. 2) Variabila *q poate primi valori de tip ntreg. De exemplu: *q=6; Aceast atribuire se descifreaz astfel: de amplasat valoarea ntreag 6 n celula de memorie ce are adresa indicat n variabila q. Din cauza, c variabila q indic la celula cu adresa 21650, valoarea variabilei ce-i pstreaz valoarea n celula de memorie cu aceast adres va fi egal cu 6. Exemplu: #include <stdio.h> main void (main){ int x=5; int *q; q=&x; printf (x=%d\n,x); // x=5; *q=6; printf (x=%d\n,x) } // x= 6; n rezultatul ndeplinirii exemplului vor fi afiate 2 expresii: x=5 i x=6. Prima valoare primit de variabila x este valoarea 5 atribuit la momentul iniializrii acesteia. A doua valoare primit de variabila x este valoarea 6 atribuit celulei de memorie la care indic indicatorul q. Desigur variabila x ar putea primi valoare nou prin simpla atribuire, x=6; dar efectul deplin de la folosirea indicatorilor se poate observa la transmiterea lor n calitate de parametri unei funcii, la crearea unui fiier, etc. Este de remarcat faptul, c n anumite cazuri indicatorul neiniializat reprezint un pericol n program. De exemplu, dac exist necesitatea de a transmite datele pe adresa, ce conine indicatorul, n condiiile cnd acesta nu e corect iniializat, se poate de ters informaia important pentru funcionarea sistemului operaional, sau altor programe, fiindc indicatorul neiniializat poate indica la orice adres de memorie inclusiv la adresa unde snt pstrate date importante ale sistemului de operare. Un exemplu de iniializare a indicatorului este: int *q=&x.

63

Cu scopul folosirii eficiente a memoriei limbajul C/C++ ofer programatorilor posibilitatea eliberrii memoriei alocate, dac e necesar. Pentru aceasta se folosete funcia free(), prototipul creia se afl n biblioteca alloc.h. Exemplu: # include <stdio.h> # include <alloc.h> main void (main){ int x=5, *q=&x; *q=6; printf(x=%d \n, x); // x=6; free (q); printf (x=%d \n, x); // x=-16; printf (adresa x = %d/n, &x) // -12. n rezultatul executrii acestui program vor fi primite mesajele: x=6; x=-16, adresa x=-12. Primul mesaj va fi acelai, dac programul va fi executat pe orice calculator. Ultimele 2 mesaje vor fi diferite de la un calculator la altul n dependen de alocarea memoriei. Aici dup folosirea funciei free(q) valoarea pstrat n celula de memorie la care indic indicatorul q va fi pierdut, adic valoarea variabilei x va fi pierdut. 11.1. Indicatori i funcii. Din temele precedente se tie c n timpul lucrului cu o funcie, la apelul ei se poate transmite ati parametri, de ci este nevoie n program. n acelai timp cu ajutorul operatorului return, se poate ntoarce numai o singur valoare din funcie. i situaiile, cnd funcia trebuie s calculeze i s ntoarc cteva valori n program par a fi nesoluionate. n calitate de alternativ se pot folosi variabile globale, ns n acest caz deseori se pierde controlul asupra ndeplinirii programului i se complic cutarea greelilor. n cazul, cnd exist necesitatea de a ntoarce din funcie mai multe valori, este util de folosit indicatori. Fr folosirea indicatorilor, noi trebuie s transmitem parametri funciei dup valoare. Aceasta nseamn, c valoarea parametrului actual se atribuie parametrului formal. Aceti parametri ocup zone de memorie diferite, i deci schimbarea valorii parametrului formal din funcie nu duce la schimbarea valorii parametrului actual. n cazul transmiterii parametrilor dup adres cu ajutorul indicatorilor, nu se creaz copii de valori ce dubleaz parametrii. n acest caz se creaz o a doua variabil ce indic la aceiai celul de memorie. n aa fel, dac este schimbat valoarea

64

parametrului formal din funcie prin indicator, deasemenea este schimbat i valoarea parametrului actual. Exemplu: # include <stdio.h> int schimb (int w, int *z) (*z)*=2; w=w*2; return(w);} void main (void) int x=5, y=8,a; printf (x=%d, y=%d,x,y); a=schimb(x, &y); printf (x=%d,y=%d\na,y);} n acest exemplu snt date 2 variabile x=5 i y=8. Funcia schimb() schimb valorile lor nmulindu-le la 2. ns, dac valoarea lui x este schimbat n funcie i ntoars n program prin intermediul operatorului return, atunci valoarea lui y este schimbat prin intermediul indicatorului. Apelnd funcia schimb(), noi transmitem n calitate de parametru nu valoarea variabilei y, ci adresa celulei de memorie, unde ea i pstreaz valoarea. n aa fel, orice schimbare a valorii indicatorului *z din funcie va duce la schimbarea valorii variabilei y din program. Un caz aparte n lucrul cu indicatorii este folosirea indicatorului la un ir de caractere. irul de caractere prezint un masiv tip caracterial. Cnd programul transmite un masiv n funcie, compilatorul transmite adresa primului element al masivului. n rezultat este admisibil ca funcia s foloseasc indicator la ir de caractere. Exemplul urmtor calculeaz de cte ori ntr-o fraz dat se ntlnete caracterul a: # include <stdio.h> int litera (char *s){ int k=0; wutile (*s!=\0) { prinf (caracterul % c pe adresa %d,*s,s); if (*s ==a) k++; s++;} return (k);} void main (void) int p; char x [25]; puts (culege o fraz); gets (x); p=litera(x);

65

printf (fraza conine %d caractere a,p); } Aici, la apelul funciei litera() n calitate de parametru se transmite nu adresa irului de caractere x, ci nsi irul. Aceasta e condiionat de faptul, c la transmiterea masivelor n calitate de parametru actual, se transmite nu masivul ntreg, ci adresa primului element al masivului. Deci indicatorul s va conine adresa elementelor masivului, iar *s valorile lor. n aa mod, la prima iteraie a ciclului while variabila *s va avea valoarea egal cu primul caracter din irul x transmis funciei. Dup ndeplinirea primei iteraii funcia mrete valoarea variabilei s cu 1 unitate. Aceasta nseamn c valoarea adresei primului caracter din ir va fi ncrementat, n rezultat primindu-se adresa caracterului al doilea din ir. Ciclul se va termina cnd va fi depistat caracterul nul n ir. Acelai lucru se poate de fcut i cu un masiv tip ntreg: # include <stdio.h> # include <conio.h> int masiv (int *s, int z) {int k=0, i; for (i=0; i<z; i++){ printf (elementul %d=%d si se afla pe adresa %d,i,*s,s); if (*s==0) k++; s++;} return (k);} void main (void){ int p,n,i, x[25]; clrscr (); printf (culege mrimea masivului x\n); scanf ( %d,&n); printf (culege masivul x[%d]\n,n); for(i=0; i<n; i++) scanf (%d,&x[i]); p=masiv (x, n); printf (masivul conine %d zerouri,p); getch(); } n acest exemplu se calculeaz cantitatea de zerouri din masiv. Mrimea masivului se transmite n funcie de la parametrul actual n la parametrul formal z. Iar pentru transmiterea masivului x n funcie se folosete atribuirea valorii primului element x[0] variabilei *s; Folosind indicatori se pot alctui funcii, sarcina crora ar fi culegerea valorilor elementelor unui masiv unidimernsional. Aceste funcii ar fi util de folosit n

66

programele unde se prelucreaz cteva masive. Urmtorul exemplu ilustreaz acest fapt i face posibil prelucrarea a 2 masive: x i y. # include <stdio.h> # include <conio.h> int masiv(int *k){ int i,z; printf (Culege mrimea masivului <50 \n); scanf (%d,&z); for (i=0;i<n; i++) { printf (culege elementul %d \n,i); scanf (%d,k); k++;} return (z);} void main (void){ int n1, n2, i, x[50], y[50]; clrscr (); printf (ntroducem masivul x \n); n1=masiv(x); printf (ntroducem masivul y \n); n2=masiv(y); printf (Afiare masiv x:\n); for (i=0; i<n; i++) printf (x[%d]=%d\n,i,x[i]); printf (Afiare masiv y:\n); for (i=0;i <n; i++) printf (y[%d]= %d\n,i, y[i]); getch();} n exemplu precedent elementele masivul i mrimea lui snt ntroduse n funcie, iar programul principal afiaz rezultatul executrii funciei. n calitate de parametri funcia masiv() folosete un indicator de tip ntreg *k, crui i se transmite din program adresa primului element al masivului prelucrat. n interiorul ciclului valoarea adresei din indicator se incrementeaz, n aa fel primindu-se adresa urmtorului element al masivului ce se prelucreaz. Funcia ntoarce n program valoarea mrimii masivului curent ce se atribuie variabilelor n1 pentru masivul x i n2 pentru masivul y. Avnd la dispoziie un aa algoritm este uor de compus programe ce prelucreaz mai multe masive i chiar masive bidimensionale. ns n cazul masivelor bidimensionale trebuie de menionat, c valorile elementelor masivului snt pstrate n celule de memorie adresele crora se schimb liniar pentru elementele masivului pe rnduri apoi pe coloane, adic de la stnga la dreapta i de sus n jos. Exemplu: # include <stdio.h> # include <conio.h> int masiv (int(*k)[50]) { int i,j,z;

67

printf ("Culege marimea masivului\n"); scanf ("%d",&z); for (i=0; i<z; i++) { for (j=0; j<z ; j++){ printf ("Culege elementul [%d][%d]\n",i,j); scanf ("%d",(k[i]+j)); }} return (z); } void main (void){ clrscr(); int n,n1,n2,i,j,x[50][50],y[50][50]; printf ("Introducem masivul x\n"); n1=masiv(x); printf ("Introducem masivul y/n"); n2=masiv(y); printf ("Masivul x este:\n"); for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { printf ("%d ", x[i][j]);} printf ("\n"); } printf ("Masivul y este:\n"); for (i=0; i<n2; i++) { for (j=0; j<n2; j++) { printf ("%d ", y[i][j]);} printf ("\n"); } getch(); } Aici n calitate de parametru funcia folosete un indicator (*k)[50] la masiv unidimensional din 50 elemente. Deci, fiecare schimbare a adresei prin k++, va duce la poziionarea pe primul element al urmtorului rnd din masivul bidimensional. Iar fiecare indicator (k[i]+j) n ciclu va duce la poziionare pe elementul coloanei j din rndul i al masivului bidimensional. 12. Fiiere n C/C++. n timpul executrii programelor, n majoritatea cazurilor, exist necesitatea afirii rezultatelor. ns posibilitile simplei afiri a datelor la monitor snt destul de mici. Chiar i folosirea opririi temporare a execuiei programului, cu scopul de a da posibilitate utilizatorului s citeasc toat informaia afiat, nu rezolv pn la sfrit problema. Dac mesajul afiat dispare din limitele monitorului, afiarea lui repetat va fi posibil numai dup lansarea din nou a programului ntreg. Mai mult ca

68

att, valorile atribuite variabilelor din program snt pstrate numai pe parcursul ndeplinirii programului. Odat cu terminarea execuiei programului, toat informaia ntrodus se pierde. Pentru a pstra informaia odat ntrodus, cu scopul folosirii ulterioare este necesar nscrierea ei pe disc n structuri de date speciale, ce poart denumirea de fiiere. Folosirea fiierelor permite pstrarea informaiei de orice natur pentru un timp ndelungat, transferarea datelor de pe un purttor informaional pe altul, citirea i afiarea datelor n caz de necesitate. Tat informaia, n ceea ce privete lucrul cu fiierele n limbajul C/C++ este pstrat n biblioteca stdio.h. Deaceea nainte de a ncepe prelucrarea unui fiier n C/C++, este necesar de inclus aceast bibliotec n program cu ajutorul directivei #include<stdio.h>, care va face posibil nscrierea informaiei n fiier i citirea ei. n timpul intrrii datelor n program dintr-un fiier de pe disc, are loc copierea lor n memoria operativ a calculatorului, iar informaia din fiier ce se afl pe discul rigid rmne neschimbat pe parcursul executrii programului. La ieirea datelor din program pe disc, n fiier snt nscrise datele ce se pstrau pn n acel moment n memoria operativ. nscrierea sau citirea informaiei din fiier este efectuat cu ajutorul indicatorului la fiier. n timpul nscrierii sau citirii informaiei din fiier compilatorul folosete un nivel intermediar de legtur ntre program i discul rigid, unde este pstrat fiierul. Acest nivel reprezint o zon de memorie numit zona tampon care are destinaia de pstrare temporar a informaiei cu scopul de a o nscrie sau citi apoi din fiier. Pentru a trimite sau a citi informaia din zona tampon compilatorul folosete o structur special numit structur-fiier. n aceast structur este pstrat informaia necesar calculatorului pentru a efectua nscrierea/citirea datelor din fiier, inclusiv adresa zonei de memorie, unde este amplasat fiierul. Sintaxa de declarare a unui indicator de fiier este urmtoarea: FILE *file_pointer; unde cuvntul cheie FILE indic compilatorului c variabila declarat este un indicator la fiier, iar file_pointer este numele indicatorului. n caz cnd programul presupune lucrul cu cteva fiiere, este necesar declararea a mai multor indicatori la fiiere dup cum urmeaz: FILE *f1, *f2, *f3; unde f1, f2, f3 snt numele indicatorilor la fiiere diferite. Prelucrarea fiierelor n limbajul C/C++ presupune ndeplinirea urmtorilor pai:

69

1) Deschiderea fiierului. (Pentru a putea fi posibil nscrierea sau citirea informaiei din fiier, el trebuie deschis.) 2) Prelucrarea fiierului (operaiunile de citire/nscriere). 3) nchiderea fiierului. Pentru ca informaia nscris n fiier s fie pstrat, acesta trebuie nchis. 12.1. Deschiderea fiierelor. Deschiderea unui fiier se realizeaz cu ajutorul funciei fopen() care are urmtoarea sintax: pointer=fopen(nume_f, mod); unde pointer este numele indicatorului la fiier, nume_f este numele fiierului real de pe discul rigid, mod este modul de acces la fiier. Rezultatul ndeplinirii acestei funcii este atribuirea adresei structurei tip fiier indicatorului la fiier. Primul parametru este numele fiierului, care de obicei are urmtoarea structur: nume.ext, unde ext este extensia fiierului compus din 3 caractere. n calitate de parametru doi funcia primete modalitatea de acces la fiier, adic informaia despre operaiile ce pot fi efectuate cu fiierul. Exist 3 modaliti generale de deschidere a fiierului: 1) Modul w permite deschiderea fiierului cu scopul nscrierii n el a informaiei sau scoaterea informaiei la mprimant. Dac fiierul indicat nu exist, el va fi creat. Dac fiierul deja exist, toat informaia existent n el va fi nimicit. 2) Modul rindic compilatorului, c fiierul va fi deschis cu scopul citirii din el a informaiei. Dac fiierul nu existla momentul deschiderii va fi generat o eroare de execuie. 3) Modul a permite deschiderea fiierului cu scopul completrii, adic a nscrierii informaiei la sfritul lui. n caz c fiierul nu exist, el va fi creat din nou. Dac fiierul indicat exist, atunci informaia nscris va fi amplasat la sfritul fiierului fr a fi nimicit informaia deja existent n fiier. De exemplu, pentru a crea un fiier nou cu nume info.txt va fi folosit urmtoarea sintax: FILE *fiier; fiier=fopen(info.txt, w); n cazul cnd exist necesitatea de a citi careva date din fiier trebuie folosit modul de acces r: FILE*fiier; fiier=fopen(info.txt,r);

70

Pentru a imprima informaia din fiier pe hrtie cu ajutorul imprimantei, numele fiierului va fi PRN, iar modul de acces w: FILE *fiier; fiier=fopen(PRN,w); E de menionat faptul, c i numele fiierului i caracterul ce determin modul de acces la fiier snt delimitate de ghilimele duble. Aceasta este condiionat de faptul, c parametrii n funcia fopen() se transmit n calitate de iruri de caractere. Folosind aceste posibiliti, se poate culege de la tastatur numele fiierului dorit de utilizator: char name [12]; FILE *f; printf (Culege numele fiierului\n); gets (name); f=fopen (name,w); n timpul lucrului cu fiierela n C/C++ este folosit un indicator special, n care se pstreaz informaia despre poziia curent de citire din fiier. n timpul citirii a datelor din fiier indicatorul determin poria urmtoare de date care trebuie citit de pe disc. Dac fiierul e deschis pentru prima dat cu regimul de acces r, indicatorul se amplaseaz pe primul simbol din fiier. n timpul ndeplinirii operaiei urmtoare de citire, indicatorul se amplaseaz la nceputul urmtoarei porii de date. Mrimea pasului de citire din fiier depinde de cantitatea de informaie citit din fiier. Dac dintr-un pas se citete numai un caracter, atunci indicatorul se va amplasa pe caracterul urmtor, dac se citete o structur, indicatorul va fi amplasat pe urmtoarea structur. La momentul, cnd toat informaia a fost citit din fiier, indicatorul nimerete pe un cod special numit sfrit de fiier: (eof). ncercarea de citire din fiier dup sfritul fiierului duce le eroare. Dac fiierul este deschis cu regimul de acces w, indicatorul deasemenea se amplaseaz la nceputul fiierului n aa fel primele date nscrise n fiier vor fi amplasate la nceputul lui. n timpul nchiderii fiierului, la sfritul lui va fi nscris simbolul de sfrit de fiier (eof). Dac la momentul deschiderii n regimul de acces w fiierul exist, toat informaia deja existent n el va fi nimicit i deasupra ei va fi nscris informaia nou. Orice date precedente ce pot rmne neterse n fiier vor fi amplasate dup codul sfrit de fiier (eof), deci accesul la ele va fi nchis. n aa fel toat informaia din fiierul deschis n regim de acces w va fi nimicit, chiar i n cazul cnd fiierul va fi deschis fr nscrierea n el a careva date.

71

Dac fiierul se deschide n regim de acces a, indicatorul se amplaseaz pe simbolul sfrit de fiier (eof). Orice informaie n aa fel nscris n fiier va fi amplasat dup datele deja existente, iar dup nscriere la sfritul fiierului se adaog codul sfrit de fiier (eof). n unele cazuri apare situaia cnd sistemul operaional nu poate deschide fiierul indicat n funcia fopen(). Aceasta poate condiionat de lipsa de loc pe discul rigid, sau de faptul c fiierul indicat pur i simplu nu exist. Este posibil deasemenea situaia cnd e necesar imprimarea datelor la imprimant, iar aceasta nui inclus sau lipsete hrtie. n cazul ncercrii folosirii fiierului ce nu poate fi deschis, programul va fi stopat n rezultatul unei greeli de execuie. Pentru a evita stoparea avariat a programului poate fi controlat starea de deschidere a fiierului cu ajutorul instruciunii condiionate if, care va opri programul n caz de eec. Aici va fi folosit particularitatea sistemului operaional, care ntoarce valoarea NULL n caz cnd apare greal i fiierul nu poate fi deschis. n acest caz codul NULL este ntors n loc de adresa structurei-fiier i programul se stopeaz. Condiia pentru evitarea ieirii avariate din program va avea urmtoarea sintax: if ( (fiier=fopen(info.txt,w))==NULL ) puts (Fiierul nu poate fi deschis); exit(); Dup ce toat informaia este nscris n fiier sau citit din el e necesar de nchis fiierul, adic de a ntrerupe legtura dintre fiier i program. nchiderea fiierului se realizeaz cu ajutorul funciei fclose() care are urmtoarea sintax: fclose(f_pointer); unde f_pointer este numele indicatorului la fiier. Odat cu nchiderea fiierului, noi primim garania c toat informaia din zona tampon ntr-adevr a fost nscris n fiier. Dac programul se termin pn la nchiderea fiierului, e posibil situaia cnd o parte din informaie ce nu a fost nscris pe disc rmne n zona tampon i n rezultat este pierdut. n afar de aceasta dac fiierul nu se nchide corect, la sfritul lui nu va fi nscris n modul necesar codul sfrit de fiier (eof) i urmtoarea deschidere a fiierului va fi eronat. Deci sistemul operaional va pierde accesul la fiier. Mai mult ca att, nchiderea fiierului elibereaz indicatorul i dup aceasta el poate fi folosit pentru accesul la alt fiier sau pentru ndeplinirea altor operaii cu fiierul. Spre exemplu fie c trebuie de creat un fiier, de nscris informaia n el, apoi de o citit din fiier. Menionm faptul, c dup nscrierea datelor, fiierul trebuie nchis i numai dup aceasta de-l deschis pentru citire, astfel avnd acces respectiv la datele din fiier: #include<stdio.h>

72

void main (void) { FILE *fiier; if ((fiier=fopen(info.txt,w))==NULL) { puts (Fiierul nu poate fi deschis\n); exit(); } //Aici vor fi amplasate instruciunile de nscriere a infirmaiei n fiier. fclose (fiier); if ((fiier=fopen(info.txt,r))==NULL) { puts (Fiierul nu poate fi deschis\n); exit(); } //Aici vor fi amplasate instruciunile de citire a informaiei din fiier. fclose (fiier); } Aici fiierul se deschide n interiorul condiiei if, adic n timpul deschiderii este controlat valoarea ntoars de sistemul operaional la deschiderea fiierului i dac este ntoars valoarea NULL se genereaz mesajul corespunztor i programul este stopat. Menionm faptul, c unele compilatoare permit nscrierea datelor n fiier prin curirea zonei tampon cu ajutorul funciei flush(). Aceast funcie permite, fr a nchide fiierul, s nscrie toat informaia din zona tampon n fiier, apoi aceast zon este eliberat de careva date. 12.2. Funcii de nscriere/citire din fiier. Limbajul C/C++ conine mai multe posibiliti de transmitere a datelor n fiier i citire din fiier n dependen de funcia folosit: - Funciile fputc() i putc() se folosesc n cazul nscrierii unui caracter n fiier sau scoaterii la imprimant. - Funciile fgetc() i getc() se folosesc pentru citirea unui caracter din fiier. - Pentru a nscrie un ir de caractere n fiier sau a-l imprima la imprimant este folosit funcia fputs(). - Pentru a citi un ir de caractere din fiier se folosete funcia fgets(). - Funcia fprintf() este folosit n cazul ieirii cu format a caracterelor, irurilor de caractere i cifrelor pe disc sau la imprimant. - Funcia fscanf() se folosete pentru citirea cu format a caracterelor, irurilor de caractere sau cifrelor din fiier. - nscrierea unei structuri n fiier e posibil folosind funcia fwrite(). - Citirea unei structuri din fiier se efectueaz cu ajutorul funciei fread().

73

12.2.1. nscriere/citire de caractere. nscrierea/citirea caracterelor din fiier este forma de baz pentru lucru cu fiiere. Cu toate c nu se bucur de o popularitate mare, aceste operaii bine ilustreaz principiile de baz n lucrul cu fiierele. Un caracter poate fi nscris n fiier dup, cum a fost spus, cu ajutorul funciei fputc() folosind urmtoarea sintax: fputc(v,fp); unde v este o variabil tip caracterial (char), i fp numele indicatorului la fiier. Urmtorul exemplu face posibil nscrierea n fiier a unui set de caractere pn cnd nu va fi apsat tasta Enter: # include <stdio.h> # include <conio.h> void main (void) { FILE *f; char lit; clrscr(); f=fopen(info txt,w); printf (culege cteva caractere \n); do { lit=getch(); putch (lit); fputc(lit,f);} while(lit!=/ r); fclose (f); } Aici, fiierul este deschis n regimul de acces w. i dac la momentul deschiderii fiierul cu numele info.txt nu exist, el va fi creat. n ciclul do are loc citirea consecutiv a caracterelor de la tastatura cu ajutorul funciei getch() i nscrierea lor n fiier cu ajutorul funciei fputc() Este de menionat faptul, c cu acelai succes aici ar putea fi folosit funcia putc() cu aceiai parametri. Ciclul do va continua pn cnd va fi detectat culegerea tastei ENTER i dup aceasta fiierul este nchis. Cu scopul citirii din fiier a caracterelor snt folosite funciile getc() i fgetc() care au urmtoarea sintax: ch_var=getc(fp); unde ch_var este variabil tip catacterial, iar fpindicator la fiier. Exemplul urmtor demonstreaz cum ar putea fi citit informaia din fiierul creat n exemplul precedent: # include <stdio.h> # include <conio.h>

74

void main (void) { FILE *f1; char lit; clrscr(); f1=fopen(info.txt,r); printf(informaia citit:\n); while( (lit=fgetc(f1))!=EOF) printf (%c,lit); fclose(f1); getch(); } Fiind deschis fiierul n regimul r, este posibil citirea informaiei din el. Ciclul while, n care are loc citirea consecutiv a caracterelor din fiier este ndeplinit pn cnd nu este detectat simbolul sfrit de fiier EOF, care este nscris la sfritul oricrui fiier n momentul nchiderii acestuia. Funcia de citire fgetc(f1) folosete alt indicator la acelai fiier f1. Acest fapt este condiionat de faptul, c chiar dac la operaiile de nscriere i citire din fiier este folosit acelai nume de fiier, nscrierea sau citirea este recomandat de efectuat cu ajutorul diferitor indicatori. 12.2.2. nscriere/citire de iruri. n cazul, cnd e necesar de nscris n fiier seturi de caractere, adic iruri este binevenit funcia fputs(); care are urmtoarea sintax: fputs (s_var, fp); unde s_var este o variabil tip ir de caractere, iar fp indicator la fiier. Funcia fputs() efectueaz nscrierea irurilor n fiier sau imprimarea lor pe hrtie fr nserarea caracterului sfrit de linie. Pentru ca fiecare ir nscris n aa mod n fiier s nceap din rnd nou, este necesar nserarea manual a simbolului sfrit de linie. Urmtorul exemplu face posibil nscrierea n fiier a unui set de familii: # include <stdio.h> # include <conio.h> # include <string.h> void main (void) { FILE *k; char fam[15]; clrscr(); printf (culegei familia\n); gets (fam); k=fopen(familia.txt,w); while(strlen(fam)>0){

75

fputs(fam,k); fputs(\n,k); printf(culegei urmtoarea familie\n); gets (fam);} fclose (k);} Aici ciclul while va fi repetat pn cnd va fi ntrodus un ir de lungime 0. Funcia fputs() va nscrie n fiier irurile fiecare din rnd nou datorit inserrii fputs(\n,k); La sfritul prelucrrii sale, fiierul familia.txt este neaprat nchis fclose(k); Este de menionat faptul, c pentru a imprima pe hrtie familiile culese folosind imprimanta, este necesar de indicat numele fiierului prn n felul urmtor: k=fopen (prn,w);. Pentru imprimarea corect la imprimant este necesar folosirea irurilor cu lungime de 81 caractere, cu scopul ca irul s ncap n ntregime n limea monitorului, nainte de a fi culeas tasta ENTER. Ciritea irurilor de caractere din fiier este realizat de funcia fgets() ce are urmtoarea sintax: fgets(s_var, l, fp); unde s_var este o variabil tip ir de caractere, l este o variabil sau constant de tip ntreg, ce indic cantitatea maxim posibil de caractere n ir, fp este un indicator la fiier. Urmtorul exemplu face posibil citirea familiilor din fiierul familia.txt creat n exemplul precedent: # include <stdio.h> # include <conio.h> void main (void) { FILE *r; char name[15]; clrscr(); r=fopen(familia.txt,r); printf(Informaia cititdin fiier:/n); while ( fgets(name, 15, r)!=NULL ) printf (%sname); fclose(r); getch(); } Aici ciclul while va fi repetat pn cnd nu va fi defectat codul sfrit de fiier. n cazul citirii informaiei din fiier la nivel de iruri de caractere, pentru a indica sfritul fiierului se folosete codul NULL, iar codul EOF este folosit la citire caracterial. Funcia fgets() va citi irul n ntregime pn la codul linie nou, dac lungimea lui nu depete valoarea l-1 indicat n parametrii funciei. Atragei atenia la faptul, c funcia printf(%s,name); nu folosete codul /n pentru deplasarea n rnd nou, fiindc fiecare ir citit din fiier deacum conine

76

codul \n - linie nou nscris n fiier n exemplul precedent cu ajutorul funciei fputs(\n,k). 12.2.3. ntrare/ieire cu format. Funciile pentru prelucrarea caracterelor i irurilor au destinaia de nscrierecitire din fiier numai a informaiei textuale. n caz, cnd e necesar de nscris n fiier date ce conin valori numerice este folosit funcia fprintf() cu urmtoarea sintax: fprintf (fp, format, data); unde fp este indicatorul la fiierul n care se realizeaz nscrierea, format este irul de control a formatului datelor nscrise i data este lista variabilelor sau valorilor ce trebuie nscrise n fiier. Exemplu: fprinf (f, %d, cost); Urmtorul exemplu demonstreaz modul de nscriere n fiier a informaiei despre un set de produse. n fiier vor fi nscrise denumirile, preurile i cantitile produselor pstrate ntr-un depozit: # include<stdio.h> # include<conio.h> # include<string.h> void main (void) { FILE *f; clrscr(); char name[20], rspuns= y ; float pret; int unit; f=fopen(produs.txt,w); while (rspuns==y ){ printf (Culege denumirea produsului\n); scanf (%s, name); printf (Culege preul produsului %s\n,name); scanf (%f, &pret); prinf (Culege cantitatea produsului %s\n, name); scanf (%d, &unit); fprintf (f, %s %f %d\n, name, pret, unit); printf (Dorii s continuati? y/n\n); rspuns=getch();} fclose(f);} n rezultatul ndeplinirii acestui program n fiier va fi nscris informaia despre cteva produse spre exemplu n felul urmtor: discheta 4.500000 100 mouse 140.000000 3

77

monitor 2000 1 Atragei atenia la simbolul \n- sfrit la linie la sfritul irului de control a formatului din funcia fprintf(), anume datorit lui, informaia despre fiecare produs este nscris din rnd nou n fiier. Citirea informaiei cu format din fiier se realizeaz cu funcia fscanf(), care are aceleai restricii ca i funcia scanf(), i folosete urmtoarea sintax: fscanf (fp, format, data); care este identic cu sintaxa funciei fprintf() n ciea ce privete descrieria parametrilor. n exemplu urmtor se realizeaz citirea informaiei din fiierul produs.txt despre produsele din depozit nscrise n fiier n exemplu precedent: # include<stdio.h> # include<conio.h> void main (void) { clrscr(); FILE *a; char name[20]; float pret; int unit; a=fopen(produs.txt,r); while( fscanf( a, %s%f%d, name, &pret, &unit)!=EOF) { printf(Denumire: %s\n,name); printf(pret: %f\n,pret); printf(cantitatea:%d\n,unit); } fclose(a); getch(); } Aici citirea datelor din fiier are loc chiar odat cu controlul condiiei de continuare a ciclului while. Ciclu while va fi ndeplinit pn cnd nu va fi detectat codul de sfrit de fiier care n acest caz este EOF. Datele din fiier snt citite n variabilele name, pre i unit i apoi afiate la monitor. 12.2.4. Fiiere i structuri. Pentru a nscrie o variabil tip structur (nscriere) n fiier este folosit funcia fwrite(), care are urmtoarea sintax: fwrite (&struct_var, struct_size, n, fp); unde: - &struct_var este numele variabilei tip structur cu operatorul de adres, care comunic compilatorului adresa celulei de start din memoria unde este amplasat structura. - struct_size este mrimea structurii. Pentru determinarea mrimii structurii se folosete funcia sizeof(s); unde s este numele variabilei de tip structur.

78

- n este un numr ntreg, care determin cantitatea de structuri ce vor fi nscrise n fiier dintr-o ncercare. Aici este recomandat de folosit valoarea 1. Valori mai mari ca 1 se folosesc n cazul nscrierii n fiier a unui masiv de structuri dintr-o singur ncercare. - fp este numele indicatorului la fiier. Exemplu: fwrite(&a,size(a),1,f); n urmtorul exemplu este creat un masiv de structuri cu informia despre un grup de studeni ce conine numele studentului, anul naterii, i balul mediu. nti de toate masivul de structuri se completeaz cu informaie, apoi structurile, cte una cu ajutorul ciclului for i funciei fwrite() snt nscrise n fiier. Numele fiierului este numit de utilizator i pstrat n variabila filename de tip ir de caractere: #include<stdio.h> #include<conio.h> sctruct stud { char nume [15]; int an; float med;}; void main (void) { clrscr(); struct stud x[10]; int i,n; FILE *f; char filename[12]; float m; printf(culege numrul de studen \n); scanf(%d&n); for (i=0; i<n; i++) { printf (culege numele studentului\n); scanf (%s, x[i] nume); prinf (culege anul nateri \n); scanf (%d, x[i]. an); printf (culege nota medie\n); scanf(%f, &m); x[i].med=m; } printf (culege numele fiierului \n); scanf (%s,filename); f=fopen(filename,w); for(i=0; i<n; i++) fwrite (&x[i], sizeof (x[i]), 1, f); fclose(f); getch(); } n rezultatul ndeplinirii acestui program, va fi creat un fiier cu numele, care a fost atribuit variabilei filename i n el nscrise structurile cu informaia despre studeni. Dac vom deschide fiierul cu ajutorul unui redactor de texte obinuit vom

79

observa n el un coninut neneles. n realitate informaia (sau mai bine zis structurile) ce se afl n acest fiier este neleas de compilator i poate fi citit cu ajutorul funciei fread() ce are aceiai sintax ca i funcia fwrite(), n ceea ce privete descrierea parimetrilor: fread (&struct_var, struct_size, n, fp); n urmtorul exemplu se realizeaz citirea tuturor nscrierilor (structurilor) din fiierul creat n exemplul precedent i afiarea lor la monitor. Este de menionat momentul c funcia fread(), n rezultatul executrii sale ntoarce o valoare ce corespunde cantitii structurilor citite cu succes din fiier. n cazul nostru are loc citirea structurilor cte una din fiier, deci funcia n caz de succes va ntoarce valoarea 1. n caz de creare sau de detectare a sfritului de fiier funcia va ntoarce valoarea 0. #include<stdio.h> #include<conio.h> sctruct stud { char nume[15]; int an; float med;}; void main (void) {clrscr(); struct stud y [10]; FILE *k; char fn[12]; int i=0; printf (culege numele fiierului \n); scanf (%s, fn); k=fopen (fn,r); printf (Informaia citit din fiier:\n); while ( fread (&y[i], sizeof(y[i]), 1, k)==1) { printf (Numele studentului: %s\n,y[i].nume); printf (Anul naterii: %d\n,y[i].an); printf (Media: %f \n,y[i].med); i++;} fclose(k); getch(); } Urmtorul tabel conine descrierea tuturor posibilitilor de intrare a datelor referitor la fiiere, inclusiv valorile ntoarse de funcii n caz de citire eronat: Tipul de date caractere iruri de caractere date cu format structuri Funcii de ieire putc(); fputc(); fputs(); fprintf(); fwrite(); Funcii de intrare getc(); fgetc(); fgets(); fscanf(); fread();
80

Valoarea ntoars la citire EOF NULL EOF 0

Anexa1. Funcii de intrare-ieire n C/C++ Funcii de ieire n C Funciile de ieire n orice limbaj de programare au destinaia de a transfera datele din memoria calculatorului la alte dispozitive periferice de ieire cum ar fi monitorul, imprimanta, un fiier pe disc etc. n timpul procedurii de ieire se face o copie a datelor care vor fi trimise la dispozitivul de ieire, pstrndu-se originalul lor n memoria calculatorului. n limbajul de programare C exist mai multe funcii de ieire. i folosirea unei sau altei funcii depinde de tipul datelor ce vor fi extrase i metoda de prezentare a lor. Cea mai simpl sintax o au funciile de extragere a caracterelor i irurilor de caractere. Not: Toate funciile de ieire din limbajul C sn susinute i n limbajul C++. Funcia puts() Funcia puts() are destinaia de a afia un ir de caractere la monitor. Sintaxa acestei funcii este urmtoarea: puts(P); unde P este parametrul funciei i poate fi: 1) un literal; 2) o constant de tip ir; 3) o variabil de tip ir. Definiie: Literal se numete un set concret de caractere care este inclus nemijlocit n instruciunile limbajului C/C++ n locul numelui constantei sau a variabilei.n cazul folosirii unui literal n calitate de parametru pentru funcia puts() fraza ce trebuie afiat pe ecran este inclus n parantezele rotunde i delinitat de ghilimele. De exemplu: puts(Hello world!); Folosirea unei constante de tip ir n calitate de parametru al funciei puts() folosete regulile dup cum urmeaz n exemplu: #define MESAJ Hello world void main(void) {puts(MESAJ);} Aici fraza Hello world a fost atribuit constantei MESAJ, care apoi este folosit ca parametru al funciei puts() far delimitarea cu ghilimele. A treia metod de folosire a funciei puts() cu variabil de tip ir n calitate de parametru este ilustrat n exemplul urmtor: void main (void) { char MESAJ[]=Hello world; puts(MESAJ);}. Folosirea constantelor i variabilelor de alt tip n calitate de parametru al funciei puts() va duce la eroare de compilare. Unica diferena la folosirea literalelor i constantelor sau variabilelor este faptul c literalul trebuie delimitat de ghilimele iar variabila i constanta se folosesc fara ghilimele. Majoritatea compilatoarelor efectuiaz trecerea n alt rind dup ndeplinirea funciei puts(). Aceasta nseamn, c dup afiarea datelor pe ecran, cursorul n mod automat se deplaseaz la nceputul urmtorului rind. ns aceast regul este respectat nu de toate compilatoarele. n

81

acest caz, pentru trecerea cursorului n alt rind trebuie folosit consecutivitatea de simboluri \n destinat afirii pe ecran a simbolului de conducere trecere n alt rind, n acest caz funcia puts() va avea urmtoarea sintax: puts(Hello world!\n); Prototipul funciei puts() este descris n biblioteca stdio.h din aceast cauz este necesar includerea acestei biblioteci n cadrul programului cu ajutorul directivei #include<stdio.h>. Funcia putchar() Are destinaia afirii unui singur simbol la ecran . Ca i n cazul funciei puts() n calitate de parametru al funciei poate fi folosit un literal, o constant sau o variabil de tip caracter. De exemplu: literal n calitate de parametru: putchar(C); constant tip caracter n calitate de parametru: #define lit C void main(void) {putchar(lit);} variabil tip caracter n calitate de parametru: void main(void) {char lit; lit=C; putchar(lit);} Menionm faptul, c cu ajutorul funciei putchar() este posibil afiarea numai a unui singur caracter i instrucia de tipul putchar(Da); va duce la eroare de compilare. Diferena principal la folosirea caracterelor i irurilor de caractere const n faptul, c irurile de caractere snt delimitate de ghilimele, pe cnd caracterele se delimitate de apostrofe. Majoritatea compilatoarelor nu efectuiaz deplasarea cursorului n rind nou dup executarea funciei putchar() i el rmne nemijlocit dup simbolul afiat. Pentru trecerea n alt rind dup afiare se recomand folosirea simbolului \n. Unele compilatoare folosesc pentru afiarea caracterelor i funcia putch(), care are sintaxa de folosire identic cu cea a funciei putchar(). Prototipul funciei putchar() este descris n biblioteca standard stdio.h, ceea ce face necesar includerea acestei biblioteci n textul programului cu ajutorul directivei #include<stdio.h>. Iar prototipul funciei putchar() este descries n biblioteca standard stdio.h, ceea ce face necesar includerea acestei biblioteci n textul programului cu ajutorul directivei #include<stdio.h>. Iar prototipul funciei putc() este descries n biblioteca conio.h i folosirea ei va fi nsoit de directiva #include<conio.h>.

82

Funcia printf() Funciile putch() i puts() snt folosite destul de des, n s posibilitile lor , cu prere de ru snt limitate. Aceste funcii nu asigur afiarea unei valori numerice la ecran i pot prelucra numai un singur argument (parametru). n limbajul C exist o funcie mult mai universal numit printf(). Ea permite afiarea pe ecran a datelor de orice tip i poate prelucra o list din civa parametri. n afar de aceasta cu ajutorul funciei printf() se poate determina formatarea datelor afiate pe display. n cel mai simplu caz funcia printf() poate fi folosit n locul funciei puts() pentru afiarea unui ir de caractere: #define MESAJ Hello world!; void main(void) { printf(MESAJ); printf(Bine ati venit); } Ca i n cazul funciei puts(), funcia printf() poate avea n calitate de parametru un literal, o constant, o variabil de tip ir de caractere. Pentru a afia pe display mrimi numerice i a avea posibilitate de a formata datele de diferite tipuri, lista de parametri a funciei printf() se mparte n dou pri: printf(irul cu format, lista datelor); Primul parametru se numete ir de conducere sau ir cu format. Acest parametru se delimiteaz cu ghilimele indic compilatorului n ce poziie din ir trebuie s apar datele. irul cu format poate conine orice text mpreun cu nite etichete numite indicatori de format care determin tipul datelor i amplasarea lor. Orice indicator de format ncepe cu simbolul procent (%), dup care urmeaz un caracter ce indic tipul datelor. Aa indicatori snt: %d numr ntreg; %u numr ntreg fr semn; %f numr real de tipul float sau double;%e numr real n form exponenial; %g numr real afiat n format %f sau %e n dependen de faptul care form de scriere este cea mai scurt; %c caracter; %s ir de caractere. n aa fel prima parte a funciei printf se poate scrie n felul urmtor printf(%d,); simbolul procent (%) spune compilatorului c dup el va urma un indicator de format, iar pantru a afia pe ecran nsi simbolul procent (%) este necesar de-l scris de 2 ori n felul urmtor: printf(%%); Litera d indic compilatorului faptul c va trebui afiat o valoare de tip ntreg, adic un numr scris n sistemul zecimal. Partea a doua din lista parametrilor este lista datelor, care poate conine literale, nume de variabile sau constante, valorile crora este necesar de afiat pe ecran. Lista datelor se desparte de irul cu forma prin virgul. Toate elementele din lista datelor deasemenea se despart ntre ele prin virgul. Cnd compilatorul prelucreaz aceast funcie, el nlocuiete indicatorii de format cu valorile din lista datelor. De exemplu: printf(%d,5); n timpul ndeplinirii acestei funcii valoarea 5 va fi amplasat n

83

locul indicatorului de format (%d). irul cu format poate conine nu numai indicatori de format, ci i text obinuit care conine i indicatori de format. De exemplu: printf(Este ora %d,5); n rezultatul executrii acestui exempplu pe ecran va fi afiat mesajul Este ora 5. Acelai effect poate fi primit i la folosirea funciei puts(Este ora 5); ns pentru combinarea textului cu valori, constante i variabile numerice e necesar folosirea funciei printf(). Exemplu: void main(void) { int ora; ora=5; printf(Este ora %d,ora); } Acest exemplu folosete n calitate de parametru o variabil de tip ntreg ora, care este amplasat n lista datelor. Bineneles lista datelor poate conine civa parametri. De exemplu: void main(void) { int ora,min; ora=5; min=25; printf(Este ora %d i %d minute,ora,min);} n rezultat vom avea afiat la ecran mesajul: Este ora 5 i 25 minute. n cazul folosirii ctorva parametri n lista datelor i respectiv n irul cu format,parametri din lista datelor trebuie s corespund ca cantitate, poziie i tip cu indicatorii din irul cu format. n cazul nostru primul simbol %d corespunde variabilei ora, iar al doilea variabilei min. n cadrul unei funcii printf() pot fi folosii nu numai civa parametri de acelai tip, ci i parametri de tipuri diferite. De exemplu: void main(void) { int cant; float pret; pret=5.21; cant=3; printf(Preul este de %f lei pentru %d kg.,pret,cant); n rezultat va fi afiat mesajul: Preul este de 5.210000 lei pentru 3 kg. Aici ntradevr parametrii din lista datelor corespund ca cantitate, poziie i tip cu indicatorii de format din irul cu format. Funcia printf() nu trece automat cursorul n alt rind dup afiarea datelor. Adic dip afiare cursorul rmne n acelai rind nemijlocit dup ultimul caracter afiat. Pentru trecerea cursorului alt rind aici va fi folosit consecutivitatea de conducere \n, care trece cursorul pe prima poziie a rndului urmtor ca i n cazul funciei puts(). De exemplu: printf(Preul este de %f lei \npentru %d kg.,5.21,3); Aici dup afiare mesajul va vi amplasat n 2 rnduri: Preul este de 5.210000 lei pentru 3 kg. La fel ca i simbolul \n aici pot fi folosite i simbolurile: \a , \b , \t , \v , \r .a.

84

Funcia printf() poate fi folosit pentru dirijarea cu formatul datelor. Aici, determinarea cantitii de poziii pe care va fi afiat numrul se determin cu indicatorul de lime a cmpului. Fr folosirea indicatorului de lime a cmpului cifrele vor fi afiate n formatul standard pentru tipul de date corespunztor. De exemplu cifrele reale vor fi afiate cu 6 poziii dup virgul. n exemplul precedint preul 5.210000 este afiat ntradevr cu 6 poziii dup virgul, acest format se poate de schimbat dup dorina utilizatorului. Folosind indicatorul de lime a cmpului se poate determina cantitatea de poziii pe care va fi afiat o valoare de orice tip de date. De exemplu: printf(Preul este de %.2f lei \npentru %d kg.,5.21,3); Aici numrul real va fi afiat cu 2 poziii dup virgul: 5.21. Iar n versiunea printf(Preul este de %6.2f lei \npentru %d kg.,5.21,3); vom avea _ _5.21 unde _ este spaiu. n general indicatorul de lime a cmpului pentru numerele reale are urmtoarea form %k.rf, unde k este numrul total de poziii (inclusive virgula) pe care va fi afiat cifra real, r este numrul de poziii dup virgul. Dac k va fi mai mare dect r+2 atunci vor fi inserate spaii naintea numrului n cantitate de k-r+2. Sub cifra 2 aici se are n vedere 2 poziii din numrul real: o poziie de la cifra ntreag pn la virgul i o poziie este nsi virgula. Dac k va fi mai mic ca r+2, indicatorul de lime a cmpului pur i simplu va fi ignorat. Indicatorul de lime a cmpului de forma %6.4f va prezenta cifra 5.21 n form de 5.2100. Pentru numerele ntregi, caractere i iruri de caractere indicatorul de lime a cmpului are forma %kd, %kc, %ks, unde k este numrul total de poziii pe care va fi afiat valoarea. n acelai timp dac k va fi mai mare ca lungimea real a valorii afiate, naintea acestei valori vor fi inserate spaii n cantitate de k-p, unde p este numrul de poziii pe care real este amplasat valoarea afiat. Iar dac k va fi mai mic ca lungimea real a valorii, indicatorul de lime a cmpului pur i simplu va fi ignorat.De exemplu: printf(Este ora %3d,5); //n rezultat Este ora _ _5; printf(M numesc %2s,Anatol); //n rezultat M numesc Anatol; printf(Litera %2c,A); //n rezultat Litera _A; unde simbolul _ reprezint spaiu. Afiarea informaiei n C++ Toate funciile de ieire analizate mai sus snt valabile att pentru limbajul C, ct i pentru C++. ns limbajul C++ are o posibilitate adugtoare de afiare a datelor de orice tip. Limbajul C++ conine fluxul standard de ieire cout, care permite mpreun cu operatorul inserrii, compus din dou simboluri (<<) mai mic, afiarea literalelor, valorilor constantelor i variabilelor fr folosirea indicatorilor de format.

85

Pentru folosirea fluxului cout este necesar de inclus n textul programului C++ fiierul <iostream.h> cu ajutorul directivei #include<iostresm.h>, din cauza c el conine descrierea fluxurilor de intrare i ieire n C++. Structura instruciunei ce folosete fluxul cout este urmtoarea: cout<<lista_de _date; unde simbolul << este operatorul inserrii i indic compilatorului necesitatea afirii listei de date ce urmeaz dup el. n calitate de informaia afiat cu ajutorul fluxului cout pot servi literali, nume de constante i variabile de orice tip. Mai mult ca att, folosind unul i acelai flux de ieire se poate afia pe ecran civa argumeni, cu condiia c ei vor fi delimitai ntre ei prin operatorul inserrii. De exemplu: #include<conio.h> #include<iostream.h> void main(void) { clrscr(); const cant=3; int ora, min; float suma; suma=5.21; ora=9; min=20; cout<<"Hello world\n"; cout<<"Este ora "<<9; cout<<"\nEste ora "<<ora<<" si "<<min<<" minute\n"; cout<<"Pretul este de "<<suma<<" lei pentru "<<cant<<" kg"; getch();} Deasemenea ca i funcia printf() fluxul cout nu trece cursorul n rind nou automat dup afiarea datelor. Pentru prezentarea comod a datelor aici este necesar folosirea consecutivitii de conducere \n dup cum este artat n exemplul precedent. Funcii de intrare n C. Procesul de intrare a datelor presupune ntroducerea informaiei necesare pentru lucrul normal al programului. Informaia ntrodus se amplaseaz n variabile, aceasta nseamn c valorile venite de la utilizator n urma afirii comentariului corespunztor pentru ntroducere snt atribuite ca valori variabilelor ce se pstreaz n memorie. n general intrarea datelor poate fi efectuat de la diferite surse aa ca tastatura, memoria, unitatea de disc rigid sau flexibil, scanner, CD-ROM .a. Intrarea datelor este un process ce determin lucrul de mai departe al programului. Corectitudinea datelor de intrare influieneaz direct asupra corectitudinii rezultatelor obinute cu folosirea acestor date de intrare. Datele de intrare pot fi atribuite ca valori numai variabilelor i nici ntr-un caz constantelor, valorile crora nu se schimb pe ntreg parcursul de ndeplinire a programului. Dac variabila n care va fi amplasat o

86

valoare de la un dispozitiv de intrare deja are o valoare oarecare, atunci valoarea nou venit va nlocui valoarea veche. n continuare vor fi studiate i analizate numai posibilitile de intrare de la tastatur, lsnd pentru temele viitoare studierea mecanismelor intrrii datelor din alte surse. Funcia getchar() Funcia getchar() face posibil introducerea de la tastatur a unui singur simbol. Majoritatea compilatoarelor nu fac diferen ntre valori de tipul int i char la folosirea funciei getchar(), fapt condiionat de standardul K&R C. Daca variabila va fi declarat de tip int, funcia getchar() va primi-o n calitate de valoare de intrare i compilatorul nu va semnala eroare, ns valoarea caracterului culeas de la tastatur va fi conversat ntr-un numr ntreg egal cu codul corespunztor acestui caracter din tabelul cu caractere ASCII. Sintaxa de folosire a acestei funcii este urmtoarea: var=getchar(); , unde var este numale variabilei crei i va fi atribuit caracterul cules de la tastatur. Aici funcia getchar() este chemat folosind alt sintax n comparaie cu funciile puts(), putch(), printf(). Inscripia folosit nseamn: de a atribui variabilei cu numele var valoarea primit n rezultatul executrii funciei getchar(). Funcia getchar() nu folosete argument, din aceast cauz parantezele rotunde de dup numele funciei rmn goale. Dup ce utilizatorul culege o tast de la tastatur, getchar() afiaz simbolul ntrodus pe ecran. n acest caz nu e necesar culegerea tastei Enter dup ndeplinirea funciei, din cauza c getchar() face posibil ntroducerea numai unui singur simbol, dup ce programul trece la ndeplinirea de mai departe. Valoarea ntrodus este atribuit variabilei ndat dup ce a fost cules un caracter. n timpul folosirii funciei getchar(), n textul programului trebuie inclus fiierul <stdio.h>, care conine descrierea prototipului acestei funcii. Unele compilatoare C i C++ folosesc funcia getch() analogic cu funcia getchar(). ns descrierea prototipului funciei getch() se afl n fisierul <conio.h>, care trebuie inclus n textul programului: #include<conio.h>. Exemplu: #include<stdio.h> #include<conio.h> void main(void) {char lit, lit1; lit=getchar(); lit1=getch(); putchar(lit); putchar(\n); putchar(lit1);} n timpul ndeplinirii programului compilatorul nu are indicaii implicite de a opri ndeplinirea acestuia dup executarea ntregului program. Acest fapt este necesar pentru a fi posibil vizualizarea i analiza rezultatelor nemijlocit dup sfritul

87

executrii programului. Funciile getch() i getchar() ne dau posibilitatea de a obine acest efect folosind urmtoarea sintax: getch() sau getchar(). Exemplu: #include<stdio.h> #include<conio.h> void main(void) {char lit, lit1; lit=getchar(); lit1=getch(); putchar(lit); putchar(\n); putchar(lit1); getch();} n acest caz, ajungnd la sfritul programului i ntlnind funcia getch(), compilatorul va opri executarea programului pn cnd va fi culeas tasta Enter. Not: Limbajul C/C++ conine funcia gets() destinat ntroducerii de la tastatur a irurilor de caractere. Sintaxa i principiul de lucru al acestei funcii vor fi studiate la tema iruri de caractere. Funcia scanf() Funcia de intrare scanf() face posibil ntroducerea n calculator a datelor de orice tip. Funcia scaneaz tastatura, determin tastele care au fost culese i apoi interpreteaz informaia culeas cu ajutorul indicatorilor de format, ce se afl n componena funciei. Ca i n cazul funciei printf() funcia scanf() poate avea mai muli argumeni fcnd posibil ntroducerea valorilor de tip ntreg, caracterial i ir de caractere n acelai timp, adic n cadrul unei funcii. Lista de parametri ai funciei scanf() este compus din dou pri ca i la funcia printf(). Prima parte este irul cu format, iar a doua lista cu date. irul cu format conine indicatori de format numii convertori de simboluri, care determin modul n care trebuie s fie interpretate datele de intrare. Lista datelor conine lista variabilelor n care vor fi pstrate valorile ntroduse. Sintaxa funciei scanf() este urmtoarea: scanf(irul cu format, lista datelor); De exemplu: #include<stdio.h> void main(void) { int a; float b; printf(Culege valorile a ntreg i b real\n); scanf(%d%f,&a,&b); printf(a=%d b=%f\n,a,b); getchar(); } S analizm funcia scanf(%d%f,&a,&b); Folosind funcia scanf() n timpul cnd se ntroduc datele, este necesar n lista de date de indicat adresa variabilei creia i va fi atribuit valoarea curent. Adresa de memorie rezervat variabilei n timpul declarrii sale se poate afla folosind operatorul de adres &. n timpul cnd funcia scanf() ntlnete formatul variabile a, ea l

88

determin ca format al unui numr ntreg i scaneaz tastatur ateptnd culegerea unui numr ntreg pe care apoi l nscrie pe adresa de memorie rezervat variabilei a ocupnd doi octei. Odat fiind nscris n celula de memorie rezervat variabilei a, numrul corespunztor devine valoare a acestei variabile. La fel se ntimpl i n cazul cu variabila de tip real b. Dup prelucrarea tuturor variabilelor din lista parametrilor, funcia scanf() i termin lucrul n cazul dac a fost culeas tasta Enter. Procedura de intrare n C++ Compilatoarele limbajului C++ susin funciile de intrare gets(), getchar() i scanf() despre care s-a vorbit mai sus. n afar de aceste funcii C++ mai conine o posibilitate de intrare a datelor. Fluxul standard de intrare cin n ansamblu cu dou simboluri (>>) mai mare ce se numesc operatori de extragere, face posibil intrarea datelor de orice tip de la tastatur i are urmtoarea sintax: cin>>var; unde var este numele variabilei crei i va fi atribuit valoarea citit de la tastatur. De exemplu: #include<stdio.h> #include<iostream.h> void main(void) { int a; float b; printf(Culege valorile a ntreg i b real\n); cin>>a>>b; cout<<a=<<a<< b=<<b; getchar(); } n acest exemplu cu ajutorul fluxului standard de intrare cin au fost scanate de la tastatur i atribuite valori variabilelor a i b. n acest caz nu e necesar de indicat adresa de memorie unde va fi amplasat valoarea scanat ca n cazul funciei scanf(), ci se indic numai numele variabilei. n afar de aceasta fluxul standard de intrare are posibilitatea de a determina automat tipul valorii introduse i nu e necesar folosirea indicatorilor de format. Iar n caz de lucru cu mai multe variabile, ele trebuie desprite cu ajutorul operatorului de extragere. Anexa 2. Funcii matematice. Dup cum a mai fost spus stilul de programare n C se caracterizeaz prin tendina de a evidenia un numr mare de funcii nu prea voluminoase, astfel, ca prelucrarea datelor n aceste funcii s nu depind de celelalte pri ale programului. Acest lucru face programul destul de neles i d posibilitatea de a introduce uor corecii n unele funcii fr a tangenta celelalte. n marea majoritate acest fapt este cert n cazul funciilor create de utilizator pentru a mpri problema n cteva sarcini mai mici dar mai simple. ns limbajul C conine i o mulime de funcii standarde care uureaz cu mult programarea. Aceste funcii ofer o varietate de faciliti. n

89

plus, fiecare programator i poate construi propria sa bibliotec de funcii care s nlocuiasc sau s extind colecia de funcii standard ale limbajului. Ca atare limbajul de programare C conine n arsenalul su de instruciuni foarte puine instrumente pentru a putea fi numit limbaj ce se afl pe primele locuri n top-ul limbajelor de programare de nivel nalt. Renumita capacitate de a prelucra expresii matematice complicate n limbajul C este datorat bibliotecilor de funcii standarde, care uureaz cu mult rezolvarea unor situaii destul de complicate. Unele din aa funcii matematice ale limbajului C ntlnite mai des n practica de programare vor fi studiate n prezentul paragraf. Menionm faptul, c aceste funcii snt valabile i n limbajul C++ i folosirea lor ntr-un program n C sau C++ necesit includerea fiierului mat.h cu ajutorul directivei #include<math.h>. 1. Funcia abs(x). Prototip: int abs(int x); double fabs(double x); long int labs(long int x); Efect: ntoarce valoarea absolut a numrului x. Exemplu: #include<math.h> #include<iostream.h> #include<conio.h> void main(void) {clrscr(); int x,y; cout<<"Culegeti valoarea x\n"; cin>>x; y=abs(x); cout<<"modulul lui "<<x<<" este = "<<y; getch(); } 2. Funcia cos(x). Prototip: double cos(double x); long double cosl(long double x); Efect: ntoarce valoarea cosinus a numrului x [cos(x)]; Exemplu: #include<math.h> #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double x,y; cout<<"Culegeti valoarea x\n"; cin>>x; y=cos(x); cout<<"cosinusul lui "<<x<<" este = "<<y; getch(); }

90

3. Funcia sin(x). Prototip: double sin(double x); long double sinl(long double x); Efect: ntoarce valoarea sinus a numrului x [sin(x)]; Exemplu: vezi funcia cos(x). 4. Funcia tan(x). Prototip: double tan(double x); long double tanl(long double x); Efect: ntoarce valoarea tangentei a numrului x [tg(x)]; Exemplu: vezi funcia cos(x). 5. Funcia acos(x). Prototip: double acos(double x); long double acosl(long double x); Efect: ntoarce valoarea arccosinus a numrului x [arccos(x)]; Exemplu: #include<math.h> #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double x,y; cout<<"Culegeti valoarea x\n"; cin>>x; y=acos(x); cout<<"arccosinusul lui "<<x<<" este = "<<y; getch(); } 6. Funcia asin(x). Prototip: double asin(double x); long double asinl(long double x); Efect: ntoarce valoarea arcsinus a numrului x [arcsin(x)]; Exemplu: vezi funcia acos(x). 7. Funcia atan(x). Prototip: double atan(double x); long double atanl(long double x); Efect: ntoarce valoarea arctangentei a numrului x [arctg(x)]; Exemplu: vezi funcia acos(x). 8. Funcia log(x). Prototip: double log(double x); long double logl(long double x); Efect: ntoarce logaritmul natural al numrului x; Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double x,y;

91

cout<<"Culegeti valoarea x\n"; cin>>x; y=log(x); cout<<"logaritmul natural a lui "<<x<<" este = "<<y; getch(); } 9. Funcia log10(x). Prototip: double log10(double x); long double log10l(long double x); Efect: ntoarce logaritmul zecimal al numrului x; Exemplu: Vezi funcia log(x); 10.Funcia exp(x). Prototip: double exp(double x); long double expl(long double x); Efect: ntoarce valoarea e x , unde e=2.7 este constant. Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double x,y; cout<<"Culegeti valoarea x\n"; cin>>x; y=exp(x); cout<<"exponenta lui "<<x<<" este = "<<y; getch(); } 11.Funcia ldexp(a,b); Prototip: double ldexp(double a, int b); long double ldexpl(long double a, int b); Efect: ntoarce valoarea 2 b *a; Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double a,y; cout<<"Culegeti valoarea a\n"; cin>>a; y=ldexp(a,3); cout<<"2 la puterea 3 nmulit cu "<<a<<" este = "<<y; getch(); } 12.Funcia frexp(x,y). Prototip: double frexp(double x, int *y); long double frexpl(long double x, int *y); Efect: ntoarce valoarea x*2 y calculnd deasemenea i valoarea lui y.

92

Exemplu: n calitate de necunoscut aici este folosit numai variabila x. Avnd un x=8, operaia k=frexp(x,y) calculeaz cifra real (k), care trebuie nmulit la 2 y pentru a primi rezultatul egal cu x=8, determinndu-l n acelai timp i pe y (valoarea puterii la care va trebui ridicat cifra 2). n cazul nostru x=8 i 8 k=frexp(x,y); va avea urmtoarele rezultate: y=4; k=0.5; adic 0.5= 4 2 #include<conio.h> #include <math.h> #include <stdio.h> int main(void){clrscr(); double k,x; int y; x = 8.0; k = frexp(x,&y); printf("numarul %f va fi primit in rezultatul\n" ,x); printf("inmultirii lui 2 la puterea %d si %f ",y,k); getch(); } 13.Funcia pow(x,y). Prototip: double pow(double x, double y); long double powl(long double x, long double y); Efect: ntoarce valoarea x y ; Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double x,y,k; cout<<"Culegeti valoarea x\n"; cin>>x; cout<<"Culegeti valoarea y\n"; cin>>y; k=pow(x,y); cout<<x<<" la puterea "<<y<<" este = "<<k; getch(); } 14.Funcia pow10(x). Prototip: double pow10(int x); long double pow10l(int x); Efect: ntoarce valoarea 10 x ; Exemplu: #include<iostream.h> #include<conio.h>

93

void main(void) {clrscr(); double y; int x cout<<"Culegeti valoarea x\n"; cin>>x; y=pow10(x); cout<<"10 la puterea <<x<<" este = "<<y; getch(); } 15.Funcia sqrt(x). Prototip: double sqrt(double x); Efect: ntoarce valoarea x ; Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double y,x; cout<<"Culegeti valoarea x\n"; cin>>x; y=sqrt(x); cout<<"rdcina patrat din <<x<<" este = "<<y; getch(); } 16.Funcia ceil(x). Prototip: double ceil(double x); long double ceill(long double x); Efect: ntoarce valoarea ROUND UP a numrului x. Adic l rotungete pe x n partea de sus. Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double y,x; cout<<"Culegeti valoarea x\n"; cin>>x; y=ceil(x); cout<<"valoarea rotungit a lui <<x<<" este = "<<y; getch(); } 17.Funcia floor(x). Prototip: double floor(double x); long double floorl(long double x); Efect: ntoarce valoarea ROUND DOWN a numrului x. Adic l rotungete pe x n partea de jos. Exemplu: vezi funcia ceil(x).

94

18.Funcia fmod(x,y). Prototip: double fmod(double x, double y); long double fmodl(long doublex, long double y); Efect: ntoarce valoarea restului de la mprirea lui x la y. Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double y,x,k; cout<<"Culegeti valoarea x\n"; cin>>x; cout<<"Culegeti valoarea y\n"; cin>>y; k=fmod(x,y); cout<<"restul de la mprirea <<x<<" la "<<y<< etse = <<k; getch(); } 19.Funcia modf(x,y). Prototip: double modf(double x, double *y); long double modfl(long double x, long double *y); Efect: ntoarce partea fracionar a numrului real x, pstrndu-se n y i valoarea prii ntregi a numrului real x. Exemplu: #include<iostream.h> #include<conio.h> void main(void) {clrscr(); double y,x,k; cout<<"Culegeti valoarea x\n"; cin>>x; k=modf(x,&y); cout<<"Cifra <<x<<" are partea ntreag = "<<y<< i partea fracionar = <<k; getch(); } 20.Funcia div(x,y). Prototip: div_t div(int x, int y); ldiv_t ldiv(long int x, long int y); unde tipul div_t este declarat n felul urmtor: typedef struct { long int quot; /* partea ntreag long int rem; /* restul }div_t;

95

Not: Este necesar includerea bibliotecii <stdlib.h>; Efect: ntoarce o valoare compus de tip structur div_t, care conine 2 valori: partea ntreag i restul de la mprirea lui x la y. Exemplu: #include<stdlib.h> #include<conio.h> #include<stdio.h> div_t a; void main (void) { clrscr(); a=div(16,3); printf("16 div 3 =%d, restul=%d\n",a.quot,a.rem); getch();} 21.Funcia randomize(). Iniializator de generator al numerelor aleatoare. Prototip: void randomize(void); Efect: iniializeaz generatorul de numere aleatoare. Not: Este necesar includerea bibliotecii <stdlib.h>; Exemplu: Se folosete mpreun cu funcia random(x). Vezi funcia random(x); 22.Funcia random(x). Generator de numere aleatoare. Prototip: int random(int x); Efect: ntoarce o valoare ntreag aleatoare n intervalul de la 0 la (x-1); Not: Este necesar includerea bibliotecii <stdlib.h>; Exemplu: #include <stdlib.h> #include <stdio.h> #include<conio.h> void main(void) {int i; clrscr(); randomize(); for(i=50;i<60;i++) printf("cifra aleatoare: %d\n",random(i)); getch();} 23.Funcia rand(). Generator de numere aleatoare. Prototip: int rand(void) Efect: ntoarce o valoare ntreag aleatoare n intervalul de la 0 la RAND_MAX, unde RAND_MAX depinde de realizarea limbajului. Not: Este necesar includerea bibliotecii <stdlib.h>. Nu necesit iniializare. Exemplu:

96

#include <stdlib.h> #include <stdio.h> #include<conio.h> void main(void) {int i; clrscr(); for(i=0;i<15;i++) printf("cifra aleatoare: %d\n",rand()); getch(); } Anexa 3. Funcii folosite la prelucrarea irurilor de caractere. Majoritatea compilatoarelor C/C++ au incorporate funcii speciale pentru lucrul cu irurile. Evident, c pentru aa scopuri se poate crea funcii proprii, dar este mai efectiv de folosit funciile din bibliotecile standarde. Prototipurile acestor funcii snt descrise n biblioteca string.h i deci pentru folosirea lor, n program trebuie inclus aceast bibliotec folosind sintaxa: #include<string.h>. Unele din aceste funcii snt: 1. Funcia strcat(); Prototip: char *strcat (char *dest, const char *sursa); Efect: Adaog irul surs la sfritul irului destinaie Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void) { char dest [50]; char sursa [5]; dess=Turbo ; sursa =C++; strcat (dest,sursa); puts(dest); getch(); } Aici rezultatul va fi: dest=Turbo C++. 2. Funcia strcmp(); Prototip: int strcmp (const char * S1, const char* S2); Efect: Compar dou iruri. Limbajul C nu permite compararea a dou iruri n forma: if (S1==S2) ; Aici compararea este fcut cu ajutorul funciei strcmp() care ntoarce valoare nul, n caz c irurile snt identice, sau o valoare diferit de zero, n caz c irurile nu coincid. Dup executarea funciei strcmp(), va fi ntoars o valoare ntreag care va fi: mai mic ca 0 dac S1<S2; mai mare ca 0 dac S1>S2;

97

egal cu 0 daca S1==S2; Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void) { char S1 [30]; char S2 [30]; int k; gets (S1); gets (S2); k=strcmp(S1,S2); If (k==0) puts (sirurile coincid); else puts (sirurile nu coincid); getch();} 3. Funcia strcmpi(); Prototip: int strcmpi (const char *S1, const char *S2); Efect: compar 2 iruri fr a lua n consideraie registrele simbolurilor. Exemplu: E identic cu funcia strcmp(). 4. Funcia strncmp(); Prototip: int strncmp( const char *S1, const char *S2, size_t k); Efect: funcia strncmp() compar un numr dat de cartere n 2 variabile de tip ir de caractere. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a [40]=Turbo, b[40]=Pascal ; int k; k=strncmp(a,b,1); printf(%d,k); } aici va fi comparat primul caracter din irul a cu primul caracter din irul b. Dup executarea funciei strncmp(), va fi ntoars o valoare ntreag care va fi: mai mic ca 0 dac a<b; mai mare ca 0 dac a>b; egal cu 0 daca a=b; Aici va fi primit raspuns k>0; 5. Funcia strncmpi(); Prototip: int strncmpi( const char *S1, const char *S2, size_t k); Efect: Compar un numr dat de caractere, ncepnd cu primul, din 2 iruri de caractere fr a face diferen ntre caractere minuscule i cele majuscule. Exemplu: Echivalent cu funcia strncmp().

98

6. Funcia strlen(); Prototip: size_t strlen(const char *S); Efect: Determin lungimea irului de caractere S. n majoritatea cazurilor lungimea irului nu coincide cu lungimea masivului n care se afl irul. Adic lungimea masivului este mai mare. Funcia strlen() determin lungimea real a irului i ntoarce o valoare de tip ntreg egal cu cantitatea de caractere ce se afl n ir. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void) { char name[20]; int k; puts (culege numele); gets (name); k=strlen(name); printf (Numele dvs are % d caractere,K); getch(); } 7. Funcia strcpy(); Prototip: char *strcpy(char *S1, const char *S2); Efect: Copie irul S2 n irul S1. Dup ndeplinirea funciei strcpy (S1,S2); irul S1 i va pierde valoarea iniial i va avea valoarea nou din S2. Iar S2 va rmne neschimbat. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void) { char name [30]; char fam [30]; puts (Culege numele); gets (nume); puts (culege familia); gets (fam); strcpy (nume, fam); puts(nume); puts(fam); getch(); } n rezultatul ndeplinirii acestui exemplu numele va fi identic cu familia. 8. Funcia strcspn(); Prototip: size_t strcspn (const char *S1, const char *S2); Efect: Determin poziia caracterului din irul S1, care primul a fost ntlnit n irul S2. ntoarce o valoare de tip ntreg egal cu numrul de ordine a acestui caracter.

99

Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char name[20],fam[20]; int k; puts ("culege numele"); gets (name); puts ("culege familia"); gets (fam); k=strcspn(name,fam); printf ("Simbolul %c din %s primul a fost gasit in %s", name[k],name,fam); getch(); } Dac n cazul nostru name=Stepan i fam=Ivanov, atunci rezultatul funciei k=strcspn(name,fam); va fi k=4, din cauz c pe locul patru n numele Stepan se afl caracterul a care primul a fost depistat n Ivanov . 9. Funcia strspn(); Prototip: size_t strspn(const char *S1, const char *S2); Efect: Determin poziia caracterului din irul S1 ncepnd cu care S1 difer de S2. ntoarce o valoare tip ntreg egal cu poziia acestui caracter. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char name[20],fam[20]; int k; puts ("culege numele"); gets (name); puts ("culege familia"); gets (fam); k=strspn(name,fam); printf ("ncepnd cu simbolul %c irul %s difer de %s", name[k],name,fam); getch(); } n caz c name=Stepan, iar fam=Stoianov lui k va fi atribuit valoarea 2 din cauz c anume ncepnd cu caracterul cu numrul de ordine 2 variabila nume difer de variabila fam. 10.Funcia strdup(); Prototip: char *strdup (const char *S);

100

Efect: Dubleaz irul de caractere S. n caz de succes funcia strdup() ntoarce ca valoare indicatorul adresei de memorie, ce conine irul dublat. i ntoarce valoare nul n caz de eroare. Funcia strdup(S) face o copie a irului S, obinnd spaiu prin apelul funciei malloc(). Dup folosirea irului dublat programatorul trebuie s elibereze memoria alocat pentru el. Exemplu : #include < alloc.h> #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a []=UTM; char *b; b=strdup(a); puts (b); free (b);} Aici a este un ir de caractere, iar b un indicator la adresa de mmorie unde se va nscrie irul dublat. La executarea funciei strdup() valoarea irului din a este copiat ntr-o locaie de memorie, adresa creia se afl n b. Funcia puts() afiaz coninutul irului dublat la monitor. Funcia free() eliberez memoria ocupat pn acum de irul dublat. 11.Funcia strlwr(); Prototip: char *strlwr (char *S); Efect: Trece toate caracterele din irul S n echivalentul lor minuscul. n calitate de parametru funcia folosete o variabil de tip ir de caractere. n rezultatul executrii acestei funcii, dac n ir se vor conine caractere majuscule, ele vor fi transformate n echivalentul lor minuscul, iar dac n ir caractere majuscule nu se vor conine - irul va rmne neschimbat. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a[10]= Pascal; strlwr(a); puts (a); getch(); } 12.Funcia strupr(); Prototip: char *strupr(char *S); Efect: transform toate caracterele din ir n echivalentul lui majuscul. Exemplu: Echivalent cu funcia strlwr();

101

13.Funcia strncat() Prototip: char *strncat (char *dest, const char *sursa, size_t k); Efect: funcia strncat() adaog un numr egal cu k caratere de la nceputul irului sursa la sfritul irului dest. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a[20]=Turbo; b[10]=Pascal; strncat (a, b, 3); puts (a); } n rezultatul executrii acestui exemplu primele 3 caractere din irul b[10], (adica subirul Pas) vor fi adaogate la sfritul irului a[20]. Rezultatul executrii funciei strncat() va fi de tip ir de caractere i se va conine n vaiabila a. Dup executarea exemplului variabila a va conine valoarea TurboPas. 14.Funcia strncpy(); Prototip: char *strncpy (char *dest, const char *sursa, size_t n); Efect: Copie un numar dat de caractere dintr-un ir n altul; Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a[40]=turbo; b [40]=basic ; strncpy (a,b,2); puts (a); } Funcia strncpy() nscrie un numr N dat de caractere din irul surs la nceputul irului destinaie. Dac irul destinaie va avea lungime mai mare ca N, atunci rezultatul va avea nceputul egal cu caracterele copiate, iar sfritul iniial. Valoarea rezultatului se va conine n irul destinaie. n exemplu de mai sus variabila a va avea valoare egal cu barbo. 15.Funcia strnset(); Prototip: char *strnset (char* s, int ch, size_t n) ; Efect: Funcia strnset() copie caracterul ch pe primele n locuri din irul *S. n caz c n>strlen (s), atunci n va deveni egal cu strlen(s)

102

Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char a[15] = student , b=W ; strnset (a,b,3); puts (a) ;} n urma executrii funciei strnset() va fi ntoars o valoare de tip ir care va fi nscris n irul destinaie . Din exemplu de mai sus a =WWWdent. 16.Funcia strrev(); Prototip char *strrev( char *s); Efect: Funcia strrev() inverseaz irul de caractere S. Dup execuia funciei strrev() primul caracter din ir va fi schimbat cu locul cu ultimul caracter, caracterul 2 cu penultimul, etc. fr a lua n consideraie caracterul nul. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char s1[10]=student; printf(irul iniial - %s\n,s1); strrev(s1); printf(irul final - %s\n,s1);} Dup executarea programului va fi primit mesajul: irul final tneduts. 17.Funcia strstr (); Prototip: char *strstr(const char *s1, const char *s2); Efect: Funcia strstr() determin dac irul S2 se conine n irul S1. Funcia ntoarce un indicator la caracterul din S1 ncepnd cu care a fost depistat irul S2. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char S1[20], S2[20], rez; S1 = international; S2 = nation; rez = strstr (S1,S2); printf (subsirul este : %s,rez); }

103

Rezultatul: subirul este: national ;. Dac irul S2 n-a fost depistat n S1, funcia strstr() ntoarce valoarea null. 18.Funcia strchr(); Prototip: char *strchr(const char *S, int c); Efect: Scaneaz irul S n cutarea caracterului c. n caz de succes funcia ntoarce un indicator la caracterul din S care primul a fost gsit identic cu caracterul c. n caz de eroare (dac aa caracter nu exist n irul S) funcia ntoarce valoare nul. Exemplu: #include <string.h> #include <conio.h> #include <stdio.h> void main(void) { clrscr(); char S[15]; char *ptr, c = 'r'; strcpy(S, "TurboC++"); ptr = strchr(S, c); if (ptr) {printf("Caracterul %c are pozitia %d in sirul %s\n", c, ptr-S, S); puts(ptr);} elseprintf("Caracterul n-a fost gasit\n"); getch(); } n rezultatul ndeplinirii acestui exemplu la monitor va fi afiat mesajul: Caracterul r are poziia 2 n irul TurboC++ i apoi datorit funciei puts(ptr); va fi afiat irul S trunchiat de la caracterul r la care indic ptr: rboC++. 19.Funcia strerror(); Prototip: char *strerror(int errnum); Efect: Determin eroarea dup numrul erorii i returneaz un indicator la irul de caractere ce conine descrierea erorii. Exemplu: #include <stdio.h> #include <conio.h> #include <errno.h> void main(void) { clrscr(); char *numerr;

104

numerr = strerror(11); printf("Eroarea este: %s\n", numerr); getch(); } n rezultaul executrii acestui exemplu funcia strerror(11); va determina eroarea dup numrul ei, iar funcia printf va afia: Eroarea este: Invalid format. 20.Funcia strpbrk(); Prototip: char *strpbrk(const char *s1, const char *s2); Efect: Funcia caut n irul S1 primul caracter ce exist i n irul S2; n caz de succes funcia ntoarce un indicator la primul caracter din S1 aprut n S2. Exemplu: #include <stdio.h> #include <conio.h> #include <string.h> void main(void) { clrscr(); char *S1="Universitate"; char *S2="Moldova"; char *ptr; ptr=strpbrk(S1,S2); if (ptr) printf("Primul caracter din S1 gasit n S2 este: %c\n", *ptr); else printf("Caracter nu a fost gasit\n"); getch(); } n rezultat va fi gsit caracterul v . 21.Funcia strrchr(); Prototip: char *strrchr(const char *s, int c); Efect: Funcia caut ultima apariie a caracterului c n irul S. n caz de succes funcia ntoarce un indicator la ultimul caracterdin S identic cu caracterul c. Exemplu: #include <stdio.h> #include <conio.h> #include <string.h> void main(void) { clrscr(); char S[15]; char *ptr, c = 'r';

105

strcpy(S,"Programare"); ptr = strrchr(S, c); if (ptr) {printf("Caracterul %c este pe pozitia: %d\n", c, ptr-S); puts(ptr);} else printf("The character was not found\n"); getch();} n rezultatul ndeplinirii acestui exemplu la monitor va fi afiat mesajul: Caracterul r este pe poziia 8 i apoi datorit funciei puts(ptr); va fi afiat irul S trunchiat de la ultimul caracter r la care indic ptr: re. 22.Funcia strset(); Prototip: char *strset(char *s, int ch); Efect: Schimb toate caracterele din irul S n valoarea caracterului c. Rezultatul final se va pstra n acelai ir S. Exemplu: #include<string.h> #include<stdio.h> #include<conio.h> void main(void){ char s[10]=student; printf(irul iniial - %s\n,s); strset(s,a); printf(irul final - %s\n,s); getch();} n rezultat va fi primit: irul iniial student, irul final aaaaaaa.

106

You might also like