Sunteți pe pagina 1din 42

Fundamentele procedural

programrii

programare

Curs 1 Introducere n limbaje de programare


Obiective:
Acest curs are scopul de a forma o privire de ansamblu asupra programrii n general i a programrii C n particular.

C este numit un limbaj de programare de nivel mediu. Aceast etichet nu este datorat unei lipse de putere a limbajului de programare (din potriv C este considerat de mul i ca un limbaj prea puternic) ci mai degrab a posibilitatea de a accesa func ii de sistem de nivel cobort. Majoritate limbajelor de nivel nalt Pasal, Java etc. presupune faptul c orice ar avea nevoie programul exist deja n limbaj. Un limbaj de nivel cobort (de exemplu un limbaj de asamblare) furnizeaz doar un acces la instruc iunile de baz ale unit ii centrale. Un limbaj de nivel intermediar ca de exemplu C nu are toate construc iile gsite n limbajele de nivel nalt dar furnizeaz un mod de programare suficient de elegant asemntor unui limbaj de nivel nalt oferind pe de alt parte i unelte opera ii i facilit i ntlnite la limbajele de nivel cobort.

Folosirea limbajului C
C a fost folosit la nceput pentru a dezvolta sisteme de operare. Practic peste 80% din Linux este scris n C. De ce? Pentru c programul C generat ruleaz aproape la fel de rapid ca cel scris n limbaj de asamblare, dar modul de scriere al programelor este asemntor cu cel al limbajelor de nivel nalt. Ce fel de programe sunt scrise n C: Sisteme de operare Compilatoare de limbaj (compilatoarele de C dar nu numai sunt de obicei scrise in C) Asambloare Editoare de text Drivere de re ea Baze de date sau programe care gestioneaz baze de date Interpretoare de comenzi Programe utilitare etc. Popularitate limbajului C a fcut ca alte limbaje de programare moderne sa fie inspirate din C ca func ionalitate sau sintax; dintre acestea a aminti Java i php dar sunt multe altele.

Limbaje de programare
Limbajul de programare poate fi definit astfel: O unealt software ce permite unui programator s scrie comenzi ntr-un format care poate fi uor de n eles i re inut de o persoan i poate fi tradus ntr-un cod pe care un calculator l poate n elege i executa. Exist foarte multe limbaje de programare El este apropiat de limbajul natural i de aceea este un excelent mod de a explica un algoritm. Din exemplul de mai sus reiese cu claritate finitudinea algoritmului i eficacitatea acestuia. Este un algoritm generalizat deoarece este conceput pentru a rezolva orice ecua ie de gradul I. Pentru a putea fi generalizat, orice solu ie algoritmic are nevoie de a verifica datele din toata plaja posibil de valori. Algoritmului trebuie s poat accepta date de intrare, de a le prelucra i de a le afia ca rezultate. Aceste lucruri nu sunt posibile dect dac datele pot fi "memorate". Cea mai folosit cale de a memora i identifica date este aceea de a folosi variabile.

De ce s folosim limbajul C?
Limbajul de programare C n ciuda vrstei sale destul de naintate este i rmne un limbaj de succes n rezolvarea oricrei probleme de programare imaginate de cineva, de la programe parte integrant a sistemelor de operare pn la programe de inteligen artificial, oferind compilri eficiente pe toate calculatoarele existente de la controlerele robo ilor industriali pn la supercalculatoare. Acest succes se datoreaz folosirii unitare si bine structurate a urmtoarelor concepte practice: O varietate mare si puternic de operatori; O sintax elegant; Conceptul de biblioteci standard; O accesibilitate sporit la nivel hardware; Posibilitatea facil de a optimiza codul pentru fiecare buc ic de program n parte Portabilitate ntre calculatoare;

Istoric
C este un limbaj de uz general, care este asociat de sistemul de operare UNIX (din care a derivat apoi i Linux), sistem care folosete intensiv acest limbaj fiind n foarte mare msur scris n C. Ideile din limbajul C au fost preluate din limbajul BCPL, dezvoltat de Martin Richards. Fiind precedat de limbajul B scris de Ken Thompson n 1970 la Bell Labs, pentru primul sistem UNIX pe calculatore DEC PDP-7. n 1972 Dennis Ritchie de la Bell Labs scrie limbajul C i n 1978 public The C Programming Language de Kernighan & Ritchie avnd ca rezultat revolu ie n lumea calculatoarelor. n 1983, American National Standards Institute (ANSI Institutul Na ional de Standarde American) stabilete o definire clar a termenelor pentru limbajul C, rezultatul fiind definirea standardului ANSI pentru C supranumit "ANSI C", care apoi a fost completat n 1988. 1

Curs 2 No iunea de algoritm


Def.1. Un algoritm este o succesiune de pai finit, cu punct unic de intrare i de ieire, care conduce ntr-un timp finit la rezolvarea unei clase de probleme. Def2. Algoritmul este un mod prin care o transformare este descrisa sistematic i condi ional n desfurarea sa. Transformarea impune de obicei folosirea unor valori numite date de intrare sau parametrii de intrare pe care algoritmul le transform n rezultate sau date de ieire. Algoritmii au urmtoarele caracteristici:

Date de intrare

Algoritm

Date de ieire

generalizare: adic sunt concepu i pentru a rezolva cu succes mai multe probleme care au o cale de rezolvare asemntoare determinism: adic ob inerea de rezultate identice pentru valori de intrare identice finitudine: procesul de prelucrare se termin dup un numr finit de pai; (exist cazuri n care programele scrise nu respect aceast condi ie ceea ce conduce la bucl infinit) claritate: toate ac iunile sau condi ionrile din algoritm sunt clar specificate Exemplu1: Rezolvarea unei ecua ii de gradul I. Analiza problemei: Forma generala a unei ecua ii de gradul I este ax+b=0. Date de intrare: a i b. Date de ieire: rdcina calculata x a ecua iei sau un mesaj ("nu exista solu ie" sau "Exist o infinitate de solu ii") Procesul prelucrrii datelor de intrare poate fi descris astfel: PAS 1. Se citesc valorile coeficien ilor a, b; PAS 2. Dac a=0 i b=0 atunci se afieaz "Exist o infinitate de solu ii"; PAS 3. Dac a=0 i b<>0 atunci se afieaz "nu exista solu ie"; PAS 4. Dac a<>0 atunci solu ia este x=-b/a; PAS 5. Afieaz valoarea lui x; Pentru a reprezenta un algoritm putem alege orice model care repezit dezideratele artate mai sus. Algoritmul din exemplul anterior a fost reprezentat prin pseudocod. Pseudocodul este un mod de a descrie liber (fr ngrdiri) a unui algoritm.

El este apropiat de limbajul natural i de aceea este un excelent mod de a explica un algoritm. Din exemplul de mai sus reiese cu claritate finitudinea algoritmului i eficacitatea acestuia. Este un algoritm generalizat deoarece este conceput pentru a rezolva orice ecua ie de gradul I. Pentru a putea fi generalizat, orice solu ie algoritmic are nevoie de a verifica datele din toata plaja posibil de valori. Algoritmului trebuie s poat accepta date de intrare, de a le prelucra i de a le afia ca rezultate. Aceste lucruri nu sunt posibile dect dac datele pot fi "memorate". Cea mai folosit cale de a memora i identifica date este aceea de a folosi variabile. O variabil este o zon identificabil de memorie a crei valoare poate fi modificat prin ac iunile algoritmului. Caracteristicile variabilelor sunt identificarea de obicei realizat printr-un nume (format dintr-o niruire de litere i cifre). Numele unei variabile dac exist se numete identificator; tip de date. Este indicat ca s se cunoasc ce fel de date vor fi memorate de ctre variabil. Unele limbaje de programare (n special interpretoarele) admit existen a unui tip de date variabil adic variabila poate n perioada sa de defini ie s-i modifice tipul. zon de memorie care va con ine valoarea la un moment dat a variabilei. Dimensiunea rezervat pentru o variabil este de obicei n func ie de tipul de dat pe care l con ine. Localizarea exact a zonei de memorie este de obicei cunoscut doar n momentul execu iei programului. Variabila i poate schimba valoarea pe parcursul parcurgerii algoritmului, dar la un moment dat o variabil nu poate avea dect o singur valoare. Valoarea variabilei poate fi utilizata de ctre algoritm prin intermediul numelui: oriunde apare numele unei variabile se n elege de fapt valoarea pe care aceasta o are la momentul respectiv. Prin tip de date se n elege gruparea datelor asemntoare ca domeniu de defini ie sub un nume numit identificator de tip de date. n general, tipurile de date utilizate n informatica sunt submul imi ale mul imilor cunoscute din matematica. Limitarea plajei de valori este datorat caracterului finit al zonei de memorie folosite memorare. De exemplu, n limbajul C++ sunt utilizate, printre altele, urmtoarele tipuri: int: valori ntregi intre -32767 i 32768 (memorare pe 2octe i); long int: valori ntregi intre -2147483648 i 2147483647 (memorare pe 4octe i) Obs. Compilatoarele C moderne memoreaz tipul int pe 4 octe i, iar un ntreg cu semn reprezentat pe 2 octe i se numete short int. Unii autori considera inclus n defini ia tipului de date i mul imea operatorilor i func iilor care se pot aplica elementelor tipului respectiv. De exemplu, pentru un tip ntreg, exista opera ii specifice: mpr irea ntreag i modul aritmetic (restul mpr irii ntregi). Prin constant n elegem o valoare fix, care nu se modific de-a lungul aplicrii unui algoritm. Constantele se reprezint uzual printr-o valoare efectiva: 3, -2, -123, 9452 sunt constante ntregi 3.456, 2.000, 3.4000E+10 sunt constante reale 'a', 'B', '&' sunt constante de tip caracter 2

'ecua ia are o infinitate de solu ii !' este o constanta ir de caractere

Modalit i de reprezentare a algoritmilor


Nu Da C

6. Blocul de decizie Nu C Da

Schema logic
Cea mai utilizata metoda de scriere a algoritmilor, cel pu in pentru nceptorii n programare, este aceea a utilizrii schemelor logice, care descriu opera iile ce pot fi aplicate datelor prin simboluri grafice numite blocuri. Sunt utilizate urmtoarele blocuri: START 1.Blocul START: Este blocul care indica nceputul oricrei scheme logice i este folosit o singura dat (orice schema logica are un nceput unic). 2.Blocul STOP Este blocul care ncheie schema logica i este, de asemenea, unic.

Blocul de decizie evalueaz valoarea de adevr a condi iei C i, dac aceasta este adevrata se trece pe ramura DA, iar dac este fals pe ramura NU. 6. Conectori Conectarea blocurilor ce formeaz o schema logica se realizeaz cu ajutorul unor sge i, acestea indicnd i sensul de efectuare a opera iilor ce compun schema logic. De asemenea, pentru a putea reuni mai multe sge i se folosesc cercule e. Cercule ele mici fr text ncorporat au rolul de a uni estetic mai multe linii (conectori). Cercule ele mai mari avnd ncorporate de obicei o liter din alfabetul grecesc pot avea rolul de a indica o continuare a schemei logice pe o alt pagin sau se folosesc pentru a elimina sge ile lungi inestetice.

STOP

3.Blocul de citire Blocul de citire corespunde opera iei de introducere a datelor, n timpul creia se ateapt ca utilizatorul s introduc valori concrete, ce vor fi stocate n zona de memorie alocata variabilelor prezente dup comanda CITETE. Cu alte cuvinte, pentru fiecare variabila al crui CITETE nume este precizat n blocul de citire se cere introducerea unei valori. 4. Blocul de scriere Blocul de scriere corespunde operatei de afiare a valorii unei variabile sau a unui mesaj. Dup comanda SCRIE se precizeaz o lista cu numele variabilelor a cror valoare va fi afiat i a mesajelor.

Scheme logice structurate


Schema logic poate fi definit ca o succesiune de blocuri de tipurile prezentate mai sus, cu urmtoarele caracteristici: a. con ine un singur bloc Start i un singur bloc Stop; b. n fiecare bloc intra o singura sgeata i, cu excep ia blocului de decizie, iese o singura sgeata (blocurile au o singura intrare i o singura ieire) c. exista cel pu in un traseu ce pleac din blocul Start i mergnd n sensul sge ilor se ajunge n blocul Stop; secven a A1 Nu A2 C Da A Nu A2 C Da A1
Execu ie condi ionat simpl Execu ie condi ionat complet

SCRIE

5.Blocul de calcul variabila expresie Blocul de calcul corespunde opera iei numite atribuire, care are ca efect calcularea valorii expresiei i memorarea valorii ob inute n zona de memorie alocata variabilei var. Schimbarea valorii unei variabile se poate realiza fie prin utilizarea unei atribuiri, fie prin citirea valorii prin intermediul unei opera ii de citire. Exist i un bloc de calcul de forma care indic o ac iune complex (grafic indicat prin dublarea marginilor laterale), de obicei o procedur. Uzual informa iile din blocul de calcul sunt sub forma unor atribuiri variabila expresie care se traduc prin modificarea valorii variabilei cu valoarea dat de calculul expresiei.

d. blocul de decizie poate con ine, pe cele doua ramuri, orice combina ie de blocuri dintre cele prezentate; O schema logica ce are aceste propriet i reprezint un algoritm structurat.

Sunt posibile urmtoarele combina ii de opera ii ce descriu tipuri de scheme logice structurate: 1. Secven a nseamn de fapt dou sau mai multe ac iuni care se vor desfura una n continuarea celeilalte (adic ac iunea A2 se va realiza doar dup ncheierea ac iunii A1) 3

2. Execu ii condi ionate. Ele sunt de dou feluri. Simpl, n cazul n care ac iunea apare doar pe ramura Da, respectiv complet, n cazul n care apar ac iuni pe ambele ramuri ale condi iei C. Condi ia simpla se exprim prin: Dac C atunci A sau n englez If C then A iar cea complet se exprim prin Dac C atunci A1 altfel A2 sau n englez If C then A1 else A2 Bucl cu Bucl cu 3. Bucle, care se folosesc pentru execu ia repetat test ini ial test final a unei ac iuni pn n momentul n care condi ia devine fals. Exist dou tipuri de bucle, cu test ini ial n care secven a este test-ac iune, si bucle cu test final n care secven a este de tip ac iune-test A Da C Bucla cu test ini ial se exprim prin: att timp ct C execut A Da A sau n englez Nu C while C do A iar cea cu test final se Nu exprim prin execut A att timp ct C sau n englez do A while C S revenim pu in asupra opera iei de atribuire, opera ie care se efectueaz ntr-un bloc de calcul i care implic definirea mai multor termeni:

Prezentarea general a no iunii de limbaj de programare


Am vzut n sec iunea precedenta cum pot fi reprezenta i algoritmii prin utilizarea pseudocodului sau a schemelor logice, ins prelucrarea automata a datelor presupune scrierea algoritmului intr-o forma ce poate fi n eleas de calculatorul electronic. Algoritmii vor fi scrii intr-un limbaj de programare, care va con ine opera ii asemntoare celor despre care am amintit, numite acum instruc iuni. Limbajul de programare con ine: ALFABETUL: o mul ime de simboluri pentru scrierea cuvintelor din limbaj. Majoritatea limbajelor de programare folosesc alfabetul latin specific limbii engleze, cifre arabe, simboluri matematice etc. organizate sub forma unei codificri ASCII. Codificarea ASCII este de fapt o echivalarea a fiecrui simbol uzual folosit cu o valoare numeric (ini ial n intervalul [0, 127]). n elegerea acestei codificri de altfel intens folosit nu numai n programare este fundamental n a n elege modul n care se memoreaz datele n calculator.

VOCABULARUL (LEXICUL): mul ime de cuvinte acceptate ca fcnd parte din limbaj Se numete UNITATE LEXICALA cea mai mica "mbinare" de caractere din vocabular, care are un n eles. Exista un set de reguli privind combinarea unit ilor lexicale n cuvinte i a cuvintelor n "fraze" (reguli de SINTAXA), respectarea regulilor ducnd la ob inerea unor construc ii corecte. SEMANTICA unui limbaj se refera la n elesul structurilor ob inute prin combinarea cuvintelor acceptate de limbaj. n vocabular avem: cuvinte cheie = cuvinte sau prescurtri ale unor cuvinte din limba engleza, ce reprezint elemente de limbaj participnd la crearea unor construc ii sintactic corecte (de exemplu comenzi sau instruc iuni). Cuvintele cheie sunt tratate diferit de restul textului din program de aceea ele trebuie cunoscute i folosite doar n modul i locul n care ele au fost definite. identificatori = nume folosite pentru variabile, tipuri de date i func ii definite de utilizator. Un identificator este format dintr-un ir de caractere care ncepe cu o litera i poate con ine litere, cifre i caracterul "_" (underscore). Identificatorul, n func ie de limbajul n care este folosit nu poate con ine n general spatii sau apostrof, virgula, ghilimele ... Identificatorii nu pot coincide cu cuvintele cheie. Prin PROGRAM se n elege o succesiune de comenzi(instruc iuni) de prelucrare a datelor, scrise intr-un limbaj de programare. Programul este memorat intr-o entitate numita fiier sursa (este un fiier text). Prelucrrile dintr-un program C++ sunt grupate n FUNC II. Rezolvarea unei probleme se face prin utilizarea unor func ii definite n limbaj i / sau a unor func ii scrise de programator, atunci cnd func iile deja existente nu sunt suficiente. Func iile pe care limbajul le pune la dispozi ia utilizatorului sunt grupate, dup tipul de prelucrare oferit, n mai multe fiiere numite "biblioteci" (fiiere HEADER). Pentru a putea utiliza o func ie trebuie s se specifice la nceputul programului numele bibliotecii care con ine func ia respectiva. Orice program C++ trebuie s con in o func ie numita "main" (un fel de program principal), instruc iunile con inute de aceasta fiind cele prelucrate atunci cnd programul este lansat n execu ie. Pentru a se putea ob ine rezultatele prelucrrii datelor cu ajutorul programelor, trebuiesc parcurse urmtoarele faze: scrierea programului (editarea textului sursa); compilarea programului (=verificarea corectitudinii sintactice i semantice a textului sursa i prelucrarea sa fiier obiect) editarea legturilor (fiierul / fiierele obiect ob inute n urma compilrii sunt transformate intr-un fiier executabil, adic ntr-un fiier care poate fi lansat n execu ie prin simpla scriere a numelui sau la prompt-ul sistemului de operare; Numim mediu de programare un program care permite asistarea programatorului n toate fazele de elaborare a unui program, scris intr-un limbaj de programare (editare, depanare, compilare, execu ie). n paragraful urmtor vor fi prezentate elementele de baza ale limbajului C. 4

Prezentarea generala a limbajului C++


Alfabetul
Alfabetul limbajului este format din acele simboluri utilizate la reprezentarea entit ilor unui program, adic a unitarilor lexicale. Reamintim ca, prin unit i lexicale n elegem cele mai mici entit i cu valoare semantica (adic au o semnifica ie), prin combinarea crora rezulta construc iile sintactice ("propozi ii i fraze"). Alfabetul limbajului C se compune din urmtoarele categorii de simboluri: Literele mari i mici ale alfabetului englez i caracterul de subliniere "_" (eng. underscore) Cifrele arabe: 0-9 Semne de punctua ie: ; , " Alte caractere: +, -, *, / (, ), {, }, [, ], \, ~, ^, <, >, =, ?, !, #, &, Literele i cifrele, precum i caracterul underscore, de multe ori asimilat n mul imea literelor, sunt utilizate pentru construirea identificatorilor i cuvintelor cheie, dup reguli ce vor fi descrise n paragrafele corespunztoare. n limbajul C se face diferen a dintre literele mici i majusculele corespunztoare, deci identificatorul "a" va fi diferit de identificatorul "A".

Lista cuvintelor cheie ale limbajului C depinde de tipul de compilator folosit pentru mediul Borland C++ este: auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while Identificatorii defini i de utilizator nu trebuie s coincid cu cuvintele rezervate. n limbajul C++ se mai adaug cteva cuvinte cheie, care vor fi descrise la momentul oportun (n capitolul rezervat programrii orientate obiect).

Comentarii
Comentariile sunt acele iruri de caractere utilizate la explicarea programelor sursa, delimitate prin caractere speciale care determina ignorarea lor de ctre compilator. Un comentariu este o construc ie de forma /* */ ca de exemplu: /* ir de caractere */ sau de forma // ca de exemplu: // ir de caractere comentariu pn la sfrit de linie unde prin ir de caractere se n elege o secven a de caractere din setul caracterelor reprezentabile, mai pu in combina ia */. Nu se admit comentariile imbricate (adic un comentariu n alt comentariu). Comentariul poate fi scris pe mai multe linii dac este scris n prima form. A doua form este specific pentru C++ i permite scrierea unor comentarii ce nu depesc o linie.

Identificatori
Identificatorul reprezint nume pe care le atribuim variabilelor, constantelor, func iilor, tipurilor de date definite de utilizator. Un identificator este o secven a de litere, cifre i caracterul underscore, primul caracter trebuind s fie litera sau underscore. Folosi i cu multa precau ie identificatori care ncep cu underscore, pentru a nu intra n conflict cu numele rutinelor sistem, a cror ortografiere nu se cunoate (numele rutinelor sistem ncep ntotdeauna cu "_"). Regulile de formare a identificatorilor sunt aceleai cu regulile din Pascal. Un identificator poate avea, teoretic, o lungime arbitrara, dar n general doar primele 31 de caractere sunt luate n considerare de compilator (iari depinde de compilator). Compilatorul de C face distinc ie ntre literele mici i cele mari din numele identificatorilor (eng case sensitive) astfel c identificatorii urmtori sunt to i diferi i ntre ei: nume, Nume, NuME, NUMe Exemple (virgula are rol de separare): i, j, abc, tablouDeCaractere, tablou_de_caractere, _, _1,

Tipuri de date
Defini ia no iunii de tip de dat cuprinde, pe lng mul imea de valori a tipului, i alte aspecte: dimensiunea memoriei alocate mul imea opera iilor ce ac ioneaz asupra elementelor tipului timpul de viata asociat datei, dat de clasa de memorie Aceste tipuri de date le vom folosi n continuare deoarece acesta definete o foarte important proprietate a constantelor ct i a variabilelor folosite n programare. Tipurile de date sunt: tipuri de baza: tipuri predefinite n limbaj; o caracter (char) - memoreaz un singur caracter scris n codificare ASCII (memorare pe 1octet) pentru C tipul char poate fi de asemenea asimilat unui tip ntreg de dimensiunea unui octet. o diferite variante de tipuri ntregi ntreg (int), care vor memora date ntregi avnd de la valori n intervalul [32767, 32768] (memorare pe 2octe i) pn la valori memorate pe 4 octe i.

Cuvinte rezervate (eng. keywords)


Numele rezervate instruc iunilor, tipurilor predefinite i sintaxei de definire a func iilor i tipurilor de date se numesc cuvinte cheie.

o o o o o o

real (float, double, long double) folosite pentru a memora valori ra ionale n limite foate largi de reprezentare, unde precizia (numrul de cifre posibil de reprezentat( devine de asemenea important. tipuri derivate: tipuri definite de utilizator; enumerare referin a structurate: tablou structura uniune

unsigned int
long long int signed long signed long int unsigned long unsigned long int

depinde implementare 2 sau 4 octe i 4 Octe i

de

ntreg fr semn complement de 2 fa

[0, 65535] sau [0, 4294967295]


[UINT_MIN, UINT_MAX]

[-2147483648,2147483647]
[LONG_MIN , LONG_MAX]

4 Octe i

ntreg fr semn

[0,4294967295]
[ULONG_MIN, ULONG_MAX]

Tipuri de date predefinite


Tipurile de baza definite n limbajul C sunt: ntreg, real i caracter. Exista insa mai multe tipuri ntregi i reale, n func ie de numrul de bi i pe care se pot memora valorile i dac valorile sunt cu sau fr semn. n plus, unele dintre aceste tipuri difer de la o implementare la alta a limbajului (n func ie de calculatorul pe care se lucreaz). n tabelul urmtor sunt prezentate tipurile fundamentale, memoria necesara stocrii valorilor de acel tip i limita valorilor ce pot fi memorate intr-o variabil de acel tip.

Primul tip este tipul caracter. O variabila de acest tip va avea ca valoare codul ASCII asociat caracterului respectiv. De exemplu, dac unei variabile i se atribuie caracterul a, variabila va con ine valoarea 97 (numrul de ordine al caracterului a n codul ASCII). Tipul ntreg cel mai des utilizat n programe este int, dar numrul de Byte (octe i) pe care se memoreaz valorile de acest tip difer de la o implementare la alta a limbajului C (n func ie de tipul calculatorului). Astfel, tipul int este echivalent cu short int sau long int, n func ie de implementare. Celelalte tipuri ntregi sunt ob inute prin folosirea prefixului signed sau unsigned, indicnd dac valorile respective sunt cu semn (con in i valori negative), respectiv fr semn ( valori naturale). Exemplu: Un program C pentru a identifica tipurile de date folosite de compilatorul curent
#include <stdio.h> #include <limits.h> volatile int char_min = CHAR_MIN; int main(void){ printf("\n\n\n\n\n Tipuri Caracter\n"); printf("Numrul de biti pt un caracter: %d\n", CHAR_BIT); printf("Dimensiunea caracterului este: %d byte\n", int)sizeof(char)); printf("Signed char: [%d,%d]\n", SCHAR_MIN, SCHAR_MAX); printf("Unsigned char: [0,%u]\n", (unsigned int)UCHAR_MAX); printf("Implicit char este: "); if (char_min < 0) printf("signed\n"); else if (char_min == 0) printf("unsigned\n"); else printf("non-standard\n"); printf("\n Tipuri short\n"); printf("Dimensiune short int: %d bytes\n", (int)sizeof(short)); printf("Signed short min: [%d,%d]\n",SHRT_MIN, SHRT_MAX); printf("Unsigned short min: [0,%d]\n", (unsigned int)USHRT_MAX); printf("\n Tipuri Int \n"); printf("Dimensiunea pentru int: %d bytes\n", (int)sizeof(int));

Tipuri de date ntregi


Tipul
char

Tipuri ntregi de date Dimensiune Tip Limita valorilor definit mai memorie reprezentare clar de <limits.h> 1 Octet (Byte) Complement fa [-128,127] sau [0, 255]
de 2 sau ntreg fr semn. Identific un caracter ASCII [CHAR_MIN,CHAR_MAX]

signed char unsigned char int

1 Octet (Byte) 1 Octet depinde de implementare (pentru compilatoarele vechi 2octe i pentru cele moderne 4octe i) 2 Octe i 2 Octe i 2 Octe i ntreg fr semn complement de 2 fa

[-128,127] sau
[SCHAR_MIN,SCHAR_MAX]

[0, 255] sau


[UCHAR_MIN,UCHAR_MAX]

[-32768,32767] sau [-2147483648,2147483647]


[INT_MIN , INT_MAX]

short int signed short int unsigned int short

complement fa de 2 complement fa de 2 ntreg fr semn

[-32768,32767] sau
[SHRT_MIN, SHRT_MAX]

[-32768,32767] sau
[SHRT_MIN, SHRT_MAX]

[0, 65535] sau


[USHRT_MIN, USHRT_MAX]

printf("Signed int: [%d,%d]\n",INT_MIN, INT_MAX); printf("Unsigned int [0,%u]\n",(unsigned int)UINT_MAX); printf("\n Tipuri Long Int\n"); printf("Dimensiunea pentru long int: %d bytes\n", (int)sizeof(long)); printf("Signed long: [%ld,%ld]\n",LONG_MIN, LONG_MAX); printf("Unsigned long: [0,%lu]\n",ULONG_MAX); return 0; }

Exemple: pentru simplitate voi considera o reprezentare a datelor pe un octet (altfel spus pe 8 bi i) cu semn. O reprezentare a datelor pe 16bi i, 32 de bi i etc. se realizeaz simulat cu cea descris de exemplele mele numai c numrul de bi i difer.

Valoare de reprezentat

Echivalent Hexazecimal Octal de la 00 la ff de la 000 la 377

Reprezentare 00 0 0 0 0 0 0 00 0 0 0 0 0 1 00 0 0 1 0 1 0 01 1 1 1 1 1 1 11 1 1 1 1 1 1

Observa ii 0 este un numr pozitiv deoarece are bitul semn 0 Valorile se cadreaz la dreapta cea mai mare valoare pozitiv Se ob ine scznd 1 din reprezentarea lui 0 0 0 0 0 0 0 0 0000 0 0 0 0 1 111 1 1 1 1 1

Din tabel se observa ca nu exista un tip logic, aa cum este el definit n alte limbaje de programare. n limbajul Pascal, tipul logic (BOOLEAN) e definit ca mul imea cu valorile {False, True} mpreuna cu operatorii logici cunoscu i (i, sau , nega ia logica). n limbajul C nu s-a definit acest tip dar se folosete urmtoarea conven ie: o expresie este considerat adevrat dac valoarea ob inuta la evaluarea ei este nenul (are o valoare diferit de 0 exprimat prin valoarea 1) i fals (are valoarea 0) n caz contrar. Variabilele care se vor folosi ca variabile logice vor fi declarate de tip ntreg. Tipul char se folosete n C pentru a identifica fie o valoare de reprezentare a unui caracter ASCII fie pentru a reprezenta o valoare ntreag cu un domeniu de valori foarte mic (256 valori diferite reprezentate pe 1Byte sau Octet).Tipul char difer de tipul caracter din Pascal (unde caracterele nu se amestec cu valorile ntregi), n C caracterele fiind de fapt ntregi, care desemneaz codul ASCII corespunztor.

0 1 10 127 -1

00 01 0a 7f Ff

000 001 012 177 377

Complement fa de 2
Complementul fa de 2 reprezint o modalitate foarte folosit pentru a reprezenta valori cu semn n memorie. Pentru a face o reprezentare a unor numere cu semn n memoria calculatorului trebuie s pornim de la urmtoarele premize: n calculator se poate reprezenta un numr finit de valori ntr-o zon de memorie de dimensiune prestabilit. Regula este c ntr-un spa iu de memorie avnd x bu i vom putea reprezenta 2x (2 la puterea x) valori distincte. Astfel pe 8 bi i reprezentm 28=256 valori, pe 16bi i 216=65536 valori etc. dac vom dori reprezentarea unor date cu semn atunci trebuie s alocm jumtate din spa iul de reprezentat pentru valorile pozitive i jumtate pentru cele negative semnul de reprezentare (pozitiv sau negativ) trebuie s fie cunoscut calculele realizate cu valorile memorate trebuie sa fie ct mai simple. Modalitatea de reprezentare a datelor cu semn la care s-a ajuns i este foarte cunoscut se numete complement fa de 2. Aceast modalitate de memorare folosete urmtoarele reguli: primul bit din reprezentare se numete bitul de semn i prin conven ie bitul de semn are valoarea 0 pentru numere pozitive i 1 pentru cele negative valorile pozitive sunt memorate ca i valori direct ob inute ca transformri n baza 2 a valorilor date cadrate la dreapta i completate cu zerouri nesemnificative n partea stng valorile negative sunt ob inute din cele pozitive fiind rezultatul scderii valorii pozitive din reprezentarea valorii zero (vezi exemplele de mai jos).

-128 80 200 1 0 0 0 0 0 0 0 Avantajul reprezentrii n complement fa de doi a valorilor ntregi cu semn este acela c opera iile aritmetice pentru valorile cu semn fa de cele fr semn sunt identice (abstrac ie fcnd de faptul c apar depiri de reprezentare prin transporturi dincolo de prima cifr a reprezentrii).

Reprezentarea celei mai mici valori negative

Tipuri de date reale


Tipuri reale de date conform standardului IEEE 754 (mantis i exponent) Tipul Dimensiune Limite de reprezentare Precizie n cifre memorie semnificative float 4 Octe i [1.175494*10-38 , 3.402823*10+38] 7 double 8 Octe i [2.225073*10-308, 1.7976931*10+308] 15 long double 10 Octe i [3.37*10-4932, 1.18*10+4932] 19 Ultimele trei tipuri din tabel sunt tipuri reale, diferen a dintre ele constnd n cantitatea de memorie utilizata, intervalul de valori i precizia memorrii valorilor (numrul de zecimale re inute). Valorile reale se reprezint conform nota iei din standardul IEEE 754 (folosind semnul, mantisa i exponentul). De exemplu, pentru tipul float se utilizeaz reprezentarea n simpla precizie, folosind un bit de semn, 7 bi i pentru exponent i 24 de bi i pentru mantisa. Aceasta reprezentare are un exponent n limita a 10-37 i 1038 cu 6 - 7 zecimale precizie. Pentru mai multe detalii referitoare la modul de memorare a datelor reale consulta i subcapitolul constante reale.

Tipul de date void


O alta caracteristica aparte o constituie introducerea tipului void, pentru a desemna nimic sau orice tip, n func ie de contextul n care este utilizat. n exemplele de pn acum tipul void a fost folosit pentru a indica faptul ca func ia main nu ntoarce nici o valoare.

Constanta ntreag
12 12u 12ul

Tip constant zecimal cu semn zecimal fr semn Zecimal fr semn zecimal cu semn

Tip dat
short int unsigned short int unsigned long int long int (deoarece depete reprezentar ea de 16bi i) unsigned long int unsigned short int eronat

Reprezentare binar
00 0 0 0 0 0 0 0 0 0 0 1 1 0 0 00 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 00 0 0 00 0 0 00 0 0 00 0 0 00 0 0 00 0 0 01 1 0 00 0 0 00 0 0 00 0 0 00 0 0 00 1 1 00 0 0 11 0 1 01 0 0 00

Constante
O constant este (de fapt ca i o variabil) o zon de memorie care are un tip i o valoare. Spre deosebire de variabil valoarea unei constante nu se poate modifica n timpul execu iei programului. Tipul constantei ca i valoarea sunt determinate de modul n care aceast constant a fost scris. Exist mai multe tipuri de constante dintre care amintim: Constante ntregi Constante flotante Constante caracter Constante ir de caractere

50000

50000u -13 -13u

zecimal fr semn zecimal cu semn eronat deoarece nu se pot reprezenta numere negative eronat deoarece 9 nu este o cifr octal Octal fr semn eronat deoarece nu se pot reprezenta numere negative hexazecimal fr semn hexazecimal fr semn hexazecimal fr semn eronat deoarece nu se pot reprezenta hexazecimal numere negative

0 0 00 0 0 00 0 0 00 0 0 00 1 1 00 0 0 11 0 1 01 0 0 00 11 1 1 1 1 1 1 1 1 1 1 0 0 1 1

Constante ntregi
Noi suntem obinui i cu sistemul de numera ie zecimal, adic folosim zece simboluri prin care exprimm valorile numerice (cifrele de la 0 la 9). Calculatorul, din motive tehnice lucreaz n binar (folosete doar valorile 0 i 1) pentru a reprezenta valorile. Valorile binare sunt destul de greu de memorat i folosit, de aceea programatorii folosesc frecvent reprezentarea n octal (baza 8) sau hexazecimal (baza 16) a datelor. Limbajul C fiind mai apropiat ca alte limbaje de codul main i fiind folosit pentru a descrie sisteme de operare permite utilizarea nu numai a valorilor scrise zecimal dar i octal sau hexazecimal. O constant ntreag zecimal cu semn se scrie n C fr nici un prefix sau sufix. Constantele sunt reprezentate fie pe 16 bi i (dac valoarea variabilei este n intervalul de reprezentare a unei valori de tip short int adic [-32768,32767], sau reprezentare pe 32 de bi i dac fie depete intervalul de definire pentru short int (dar valoarea ei este in intervalul unui long int [-2147483648, 2147483647]) sau valoarea este postfixat cu caracterul L sau l (de exemplu 12345678, 23l sau 123L). O constant ntreag zecimal fr semn se scrie n C folosind sufixul u sau U. Constantele sunt reprezentate fie pe 16 bi i (dac valoarea variabilei este n intervalul de reprezentare a unei valori de tip unsigned short int adic [0,65535], sau reprezentare pe 32 de bi i dac fie depete intervalul de definire pentru unsigned short int (dar valoarea ei este in intervalul unui long int [0, 4294967295]) sau valoarea este postfixat de caracterele ul, lu, UL, sau LU (de exemplu 12345678u, 23ul sau 123LU). O constant ntreag octal este o valoare fr semn scris n baza 8 (o succesiune de cifre de la 0 la 7) ncepnd obligatoriu cu valoarea 0 (zero). De exemplu 0123 este o constant octal iar 123 este o constant zecimal. Ca i constanta zecimal, constanta octal poate fi reprezentat pe 16bi i sau (dac are o valoare mare sau este postfixat cu litera l sau L) pe 32de bi i. Exemple:

-192 012 -012

eronat unsigned short int eronat 00 0 0 0 0 0 0 0 0 0 0 1 0 1 0

0x12 0xaa2b 0XAbCdE -0x12

unsigned short int unsigned short int unsigned long int eronat

00 0 0 0 0 0 0 0 0 0 1 0 0 1 0 11 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 00 0 0 00 0 0 01 0 1 01 0 1 11 1 0 01 1 0 11 1 1 00

Constante flotante
O constant flotant se folosete pentru a reprezenta un numr ra ional i este compus din maxim trei componente plus eventual un indicator de tip: parte ntreag o constant zecimal parte frac ionar un indicator separator de parte zecimal (reprezentat printr-un punct zecimal) urmat eventual de mai multe cifre zecimale exponent un indicator de exponent (litera e sau E), urmat de o valoare zecimal cu semn care reprezint o putere a lui 10 la care este nmul it valoarea. Oricare dintre cele trei pr i poate lipsi dar, la scrierea unei astfel de contante trebuie inut cont de faptul c obligatoriu trebuie s fie prezent fie partea frac ionar, fie partea de exponent fie indicatorul lor. 8

n C exista trei tipuri de date reale (float, double i long double), n consecin exist posibilitatea de a folosi trei tipuri de constante reale: constanta double se reprezint pe 64bi i, nu are sufix deci este implicit n C constanta float se reprezint pe 32bi i i are sufixul f sau F constanta long double se reprezint pe 80 de bi i i are sufixul l sau L

Reprezentarea datelor flotante conform IEEE 754-2008.


Tipul float Con ine 1. 1 bit de semn (0 reprezint un numr pozitiv, 1 un numr negativ) 2. 8 bi i exponent (pentru a reprezenta exponen i negativi exist o valoare (eng. bias) pentru simpl precizie 127 care trebuie sczut din exponent pentru a indica valoarea exact a exponentului. 3. 23 bi i pentru a memora partea zecimal normalizat a valorii de reprezentat (24 bi i precizie real) aceast parte se mai numete i mantis. Precizia real este dat de faptul c n mod implicit primul bit al unei reprezentri este totdeauna 1 (i nu este direct reprezentat) Exemplu: 25 se reprezint astfel: Valoarea sa normalizat este 25(10)=11001(2) = 1,1001*24 Deducem c: Semnul 0 deoarece numrul este pozitiv Exponentul este 127(bias) + 4 = 131 reprezentat ca 10000011 n baza 2 Mantisa este 1,1001 din care cifra supraunitar nu se scrie deci 1001 deci n final numrul este: 0 10 0 000 1 110 0 100 0 000 0 000 0 000 0 000 0 Adic n hexazecimal 41c8 0000 Exemple: Valoare Constanta Zecimal flotant 1 1.f -2
1/3 0 -0 + -

11 bi i exponent (pentru a reprezenta exponen i negativi exist o valoare pentru dubl precizie 1023 (210-1) care trebuie sczut din exponent pentru a indica valoarea exact a exponentului. 3. 52 bi i pentru a memora partea zecimal normalizat a valorii de reprezentat (53 bi i precizie real) adic cca. 15 cifre zecimale. Tipul long double are o reprezentare pe 80 bi i. Modul de reprezentare con ine: 1. 1 bit de semn (0 reprezint un numr pozitiv, 1 un numr negativ) 2. 15 bi i exponent (pentru a reprezenta exponen i negativi exist o valoare pentru precizie 214-1 care trebuie sczut din exponent pentru a indica valoarea exact a exponentului. 3. 64 bi i pentru a memora partea zecimal normalizat a valorii de reprezentat (65 bi i precizie real) adic cca. 19 cifre zecimale. Observa ii: 1. Cele trei reprezentri reale sunt destul de complicate dar de multe ori dorim sa folosim n calcul numere ra ionale deci utilizarea lor este pe deplin justificat. 2. Calculatoarele personale moderne folosesc procesoare ce realizeaz calcule n virgul flotant folosind o reprezentare a datelor pe 80 de bi i (deci precizie de long double).

2.

Constant caracter
Exist multe programe sau subprograme care sunt scrise cu scopul de a prelucra text. Unitatea fundamental a textului este caracterul. Caracterul este o modalitate simpl i elegant de a reprezenta literele, cifrele sau alte simboluri care apar ntr-un text ntr-o form codificat numeric prin aceasta simplificndu-se mult prelucrarea i memorarea acestuia. Cel mai intens folosi mod de a codifica literele i celelalte simboluri din text este standardizat pentru limba englez (american) i se numete ASCII. Din pcate aceast standardizare nu ine cont de simbolurile specifice altor ri (care nu folosesc literele engleze), exist preocuparea la nivel interna ional de a realiza standarde interna ionale cere s includ i caracterele acestor ri dar din pcate acest lucru este departe de a fi realizat la un nivel acceptabil de ctre toat lumea. Setul ASCII cuprinde 128 de caractere realiznd o codificare ini ial pe 7 bi i. Pentru c marea majoritate a calculatoarelor reprezint datele n multipli de 8 bi i (sau octe i sau Byte) putem spune c reprezentarea unui caracter (folosit de fapt i de C este pe 8 bi i). Observa ii Pentru informa ii suplimentare studia i anexa Exist unele versiuni foarte noi de C (n special folosite n mediul grafic) care recunosc i folosesc o reprezentare pe 16 bi i a unui caracter dar aceste versiuni nu sunt dezbtute pe cuprinsul acestui curs. Caracterele ASCII sunt mpr ite n: caractere grafice (adic acele caractere care pot fi reprezentate printr-un simbol grafic) intervalul [33,126] precum i caractere negrafice care cuprind valorile {[0,32], 127} O constant caracter n C va avea valoarea corespunztoare codului ASCII al caracterului ASCII pe care l reprezint. 9

Reprezentare hexazecimal 3f80 0000 c000 0000 7f7f ffff 3eaa aaab 0000 0000 8000 0000 7f80 0000 ff80 0000

Reprezentare binar
0 01 1 1 11 1 1 00 0 00 00 00 00 00 00 0 00 0 0 00 0 1 10 0 0 00 0 0 00 0 00 00 00 00 00 00 0 00 0 0 00 0 0 11 1 1 11 1 0 11 1 11 11 11 11 11 11 1 11 1 1 11 1 0 01 1 1 11 0 1 01 0 10 10 10 10 10 10 1 01 0 1 01 1 0 00 0 0 00 0 0 00 0 00 00 00 00 00 00 0 00 0 0 00 0 1 00 0 0 00 0 0 00 0 00 00 00 00 00 00 0 00 0 0 00 0 0 11 1 1 11 1 1 00 0 00 00 00 00 00 00 0 00 0 0 00 0 1 11 1 1 11 1 1 00 0 00 00 00 00 00 00 0 00 0 0 00 0

Observa ii
Mantisa are valoarea 0 Cea mai mare valoare Valoare rotunjit Caz special Ciudat dar posibil Plus infinit Minus infinit

-2.f
0.3333333f 0.f -0.f

3.4028234*1038 3.4028234e38f

Tipul double are o reprezentare pe 64 bi i. Modul de reprezentare con ine: 1. 1 bit de semn (0 reprezint un numr pozitiv, 1 un numr negativ)

O constant caracter va fi memorat ca un ntreg (va avea tipul int). O constant de tip caracter n C poate fi definit ca o construc ie lexical incluse ntre dou caractere (apostrof). Construc ia lexical dintre apostroafe poate fi: un caracter dac acesta este un simbol grafic cu excep ia caracterului \ (backslash) sau care sunt tratate special de ctre compilator un caracter \ urmat de un alt caracter sau liter caz n care caracterul are o semnifica ie special (vezi tabelul de mai jos). una sau mai multe (maxim 3) cifre octale (numit secven escape) care sunt interpretate ca o valoare octal pentru a descrie un caracter din tabelul ASCII. O secven escape poate depi intervalul normal de definire a unei reprezentri ASCII ([0,127]) ajungnd i n intervalul [128,255] (o extindere pe 8 bi i a codului ASCII) astfel valoare poate fi n octal ntre 0 i 377. Exemple Constant Cod Cod Denumire Utilizare Caracter ASCII ASCII caracter zecimal octal \\ 49 57 Backslash Pentru a putea scrie caracterul backslash \ 39 47 Apostrof Pentru a putea crea o constant caracter cu valoarea apostrof \ 34 42 Ghilimele Pentru a putea crea o constant caracter cu valoarea ghilimele a 97 141 a Litera a minuscul A 65 101 A Litera A majuscul 0 48 60 0 Cifra 0 (zero) 1 41 61 1 Cifra 1 (unu) \a 7 7 Bell Calculatorul genereaz un sunet \b 8 10 Backspace Un spa iu napoi \t 9 11 HT Tabulator orizontal \n 10 12 LF Trecere la linie nou (n C echivalent cu trecere la rnd nou) \v 11 13 VT Tabulator vertical foarte rar folosit \f 12 14 FF Salt la pagin nou (la imprimant) \r 13 15 CR Retur de car revenire la nceputul rndului curent \7 7 7 Bell Ca mai sus la Bell \101 65 101 A Litera A majuscul \377 255 377 ??? Cea mai mare valoare ASCII posibil de reprezentat nu se tie caracterul reprezentat deoarece depinde de la un SO la altul \401 Eroare valoare imposibil de reprezentat (nu exist n tabela ASCII \182 Eroare e nevoie de cifre octale iar 8 nu e una dintre ele

Constant ir de caractere
O succesiune de zero au mai multe caractere care sunt incluse ntre ghilimele formeaz o constant ir de caractere sau mai pe scurt un ir de caractere. Fiecare dintre caracterele ce compun irul poate fi un caracter ca i cele descrise la constant caracter. Practic limbajul C va descrie irul de caractere ca un tablou de caractere care con ine toate caracterele scrise n ir precum i caracterul \0 (supranumit caracterul null) care in C indic terminarea irului de caractere. Exemple:
ir de caractere

a 123 \123 \1234

ASCII NUL a NUL 1 2 3 NUL S NUL S 4 NUL

Reprezentare Hexazecimal 00 61 00 41 42 43 00 53 00 53 44 00

Octal 000 141 000 061 062 063 000 123 000 123 063 000

Byte 1 2 4 2 3

Observa ii ir nul de caractere

ab\0cd

N N a bUc dU L L

61 62 00 63 64 00

141 142 000 143 144 000

Cele 3 cifre sunt interpretate ca o valoare ASCII octal Cele 3 cifre sunt interpretate ca o valoare ASCII octal a 4-a ramne 4 Dei se aloc 6 octe i pentru ir doar primele 2 caractere vor fi vizibile, practic echivalent cu ab

Constante predefinite
n C exist anumi i identificatori care de fapt sunt asimila i unor constante. Un exemplu tipic este PI cunoscut din matematic dar sunt multe astfel de cazuri ca de exemplu CHAR_MIN i CHAR_MAX .a. care au fost deja definite. Aceti identificatori sunt asimila i unor constante dar de fapt modul de descriere i implementare este total diferit astfel nct amnunte despre ele voi da n capitolul directive precompilator.

Variabile
O variabil este o zon identificabil de memorie, modificabil prin opera ii de atribuire care are un tip i o valoare. Spre deosebire de variabil valoarea unei constante nu se poate modifica n timpul execu iei programului. n C orice variabil vom folosi trebuie declarat. Pentru nceput vom spune c toate variabilele vor avea un nume i anume un identificator folosit att la declarare ct i la utilizarea lor. Acest fapt nu este ntotdeauna adevrat dar deocamdat ideea c variabilele au un nume ne este de foarte mare ajutor n folosirea lor. Limbajul C este unul complicat astfel nct este bine de tiut faptul c numele unei variabile nu se pstreaz n mod normal n faza de execu ie a programului. Variabilele se pot clasifica dup modul n care se memoreaz datele n: 10

variabile simple care pot memora o singur valoare. Variabilele care folosesc tipuri de date predefinite sunt n general simple. variabile compuse care memoreaz mai multe valori de o dat. De multe ori se dorete gruparea mai multor date care au att separat ct i mpreun semnifica ie. Limbajul C ofer mai multe metode prin care se pot grupa datele, cele mai importante tipuri de date complexe fiind tablourile i structurile.

Exemple de tablouri unidimensionale cu sau fr ini ializri: int x[10]; double tablou[25]; char sir[20]=Primul program C; int prime[10]={1, 2, 3, 5, 7, 11, 13, 17, 19, 23} int primePeste100[]={101, 103, 107, 109}

Variabile simple
Pentru a putea utiliza o variabila intr-un program C, este obligatorie declararea acesteia, astfel: [clasa_de_memorie]TIP_DE_DATE lista_variabile; unde: clasa_de_memorie specifica locul unde se va aloca memorie pentru variabila i durata sa de viata, no iuni la care vom reveni mai trziu). Specificarea clasei de memorie este op ionala; TIP_DE_DATE este orice tip predefinit sau derivat; practic tipul variabilei va indica i dimensiunea de memorie alocat pentru variabila respectiv. lista_variabile con ine lista variabilelor de acel tip, despr ite prin virgula; Efectul unei declara ii este crearea unei zone de memorie ca loca ie a variabilei, identificarea zonei de memorie cu numele dat variabilei i eventual ini ializarea variabilei (adic atribuirea unei valori ini iale implicite sau explicite variabilei). Exemple: int a,b,c; char ch; float x,y; long int z; int g=7; Observa ie: La declararea variabilei ntregi g s-a realizat i ini ializarea acesteia (adic stabilirea unei valori ini iale). Variabilele care sunt declarate n interiorul corpului unei func ii se numesc variabile locale, iar cele declarate n afara oricrei func ii din program se numesc variabile globale. Variabilele globale vor putea fi utilizate n toate func iile ce compun programul, iar variabilele locale doar n cadrul func iei n care au fost definite, dar aceste amnunte vor fi discutate mai trziu.

Indicii tablourilor
Pentru a ne referi la un element al unui tablou n C se folosesc indicii. Dac la definirea unui tablou valoarea dintre parantezele dreptunghiulare reprezint numrul de elemente pe care le va avea un tablou, apoi n timpul execu iei programului elementele unui tablou se identific prin tablou[indice], unde tablou nseamn numele tabloului iar indice al ctelea element din tablou (ncepnd cu elementul 0 n limbajul C). Indicele unui tablou este expresia care apare ntre paranteze drepte dup numele tabloului. Exemple pentru defini ia: int prime[10]={1, 2, 3, 5, 7, 11, 13, 17, 19, 23} prime[0] are valoarea 1 prime[1] are valoarea 2 prime[2] are valoarea 3 prime[3] are valoarea 5 .a. pentru defini ia char sir[20]=Primul program C; sir[0] are valoarea P sir[15] are valoarea C sir[16] are valoarea \0 sau null n C se pot folosi i construc ii mai ciudate ca de exemplu se poate folosi indicele pentru o constant ir de caractere ca n exemplele de mai jos: Construc ia 123456789[0] este echivalent cu 1 iar 123456789[9] este echivalent cu \n.

Tablouri multidimensionale
Este posibil declararea i folosirea unor tablouri care au dou sau mai multe dimensiuni numite tablouri multidimensionale, un exemplu cunoscut este acela al matricelor care sunt tablouri ce au dou dimensiuni. Aceste tablouri pentru a fi controlate au nevoie de mai mul i indici, de exemplu pentru matrici primul indice se folosete pentru a arta liniile unei matrici iar coloanele sunt indicate de al doilea indice. Exemple: double matrice [4] [5]; definete o matrice cu 4 linii i 5 coloane iar matrice [2] [4] ne indic elementul de pe linia 3 i coloana 5 a matricei cu numele matrice.

Variabile compuse. Tablouri.


Un tablou este o mul ime ordonat de elemente de acelai tip la care ne putem referi folosind indici. Un tablou unidimensional este echivalentul n programare a unui ir din matematic. Spre deosebire de irurile din matematic n programare irurile sunt obligatoriu de dimensiune limitat iar pentru programele scrise n C sau alte limbaje compilate dimensiunea acestor tablouri trebuie s fie cunoscut n momentul declarrii lor i ea rmne fix pe toat durata execu iei programului.

11

Operatori, operanzi, expresii


O expresie const din unul sau mai mul i operanzi lega i prin operatori.

Operand
n C mai multe construc ii lexicale pot avea rol de operand. Printre altele un operand poate fi: constant variabil simpl nume de tablou nume de structur numele unui tip de dat numele unei func ii un element al unei structuri fiecrui operand al unei expresii are dou propriet i interesante pentru a calcula o expresie i anume o valoare prin care particip la calculul expresiei i un tip prin care compilatorul determin tipul rezultat n urma calculului.

Operatori
Operatorii constituie unul din conceptele cele mai importante i mai interesante care stau la baza unui limbaj de programare. Limbajul C este vestit pentru marea varietate de operatori pe care-i pune la dispozi ia programatorului rezultnd i o diversitate de expresii ce se pot forma pe baza acestora. Dup cum se tie, o expresie este formata din variabile, constante, func ii i operatori. n acest paragraf voi aminti cteva din categoriile de operatori ai limbajului C:

Operatorii aritmetici:
+ adunare, - scdere, * produs, / mpr ire, % - restul mpr irii ntregi ++, -- incrementare i decrementare

Operatori
Operatorul reprezint o opera ie care se aplica datelor. Limbajul C este vestit pentru marea varietate de operatori pe care-i pune la dispozi ia programatorului rezultnd i o diversitate de expresii ce se pot forma pe baza acestora. Dup cum se tie, o expresie este formata din variabile, constante, func ii i operatori. n acest paragraf voi aminti cteva din categoriile de operatori ai limbajului C: Exist foarte mul i operatori n C. motivul pentru care avem o varietate mare de operatori este acela c C a fost conceput ca un limbaj care sa permit folosirea ct mai bun a codului main (generat de program) i a ob ine un program executabil ct mai rapid cu putin (cerin e foarte importante pentru componentele unui sistem de operare). Unii operatori sunt foarte rar gsi i n alte limbaje de programare, al ii sunt trata i diferit de alte limbaje de programare. Exist mai multe moduri prin care putem organiza aceti operatori. Dintre aceste moduri amintim: dup numrul de operanzi operatori unari au un singur operand Operatorul unar poate fi plasat n dreapta sau stnga operandului iar pentru diferite paranteze (care sunt considerate de c tot ca operatori) att n stnga ct i n dreapta operandului operatori binari au doi operanzi, primul fiind plasat n stnga operatorului iar cellalt operand n dreapta operator ternar are trei operanzi. C are un astfel de operator i anume ?: unde operanzii sunt organiza i sub forma: operand ? operand : operand ordinea de execu ie a opera iile de la stnga la dreapta o ordine normal i obinuit din matematic care se aplic la majoritatea de la dreapta la stnga o ordine care pare anormal i neobinuit dar destul de logic la o analiz mai atent 12

Expresia
poate fi definita astfel: Variabilele i constantele sunt expresii Dac E1 este expresie atunci op_unar E1 este expresie; (operator prefixat) Dac E1 este expresie atunci E1 op_unar este expresie; (operator postfixat) Dac E1, E2 sunt expresii, atunci E1 op_binar E2 este expresie; Dac E1, E2 , E3 sunt expresii, atunci E1 op_ternar1 E2 op_ternar2 E3 este expresie; (f) Orice expresie corecta se ob ine prin aplicarea pailor (a)...(e) de un numr finit de ori; Exemple de expresii: 23.4+12/4-a*b+1, c && d || e && f, 1234, -765.34 Evaluarea unei expresii = ob inerea unei valori n func ie de valorile operanzilor ce apar n expresie. Dac expresia este numerica, atunci se ob ine o valoare numerica, dac expresia con ine operatori logici i rela ionali atunci se ob ine o valoare logica (adevrat sau fals). n C (sau C++) nu exist de fapt tipul de date logice ci este valabil urmtoarea constatare: - Orice valoare numeric egal cu 0(zero) se consider fals. - Orice valoare numeric diferit de 0(zero) se consider adevrat. (dac n urma unei evaluri de expresie este nevoie de calcularea unei expresii care returneaz adevrat atunci de fapt valoarea calculat este 1(unu)). Exemple: 1 < 3 este adevrat iar acest adevr este reprezentat prin valoarea 1. 2 > 7 este fals deci este reprezentat prin valoarea 0. (a) (b) (c) (d) (e)

prioritatea operatorilor dac doi operatori (sau mai mul i) operatori sunt folosi i natural este ca ordinea n care acetia vor fi aplica i s fi semnificativ de exemplu pentru cazul 2+3*4 pot fi dou ordini de efectuare a opera iilor astfel (2+3)*4=20 sau 2+(3*4)=14. n matematic (dar i in limbajul C) dac nu exist paranteze atunci nmul irea va avea prioritate mai mare dect adunarea. n continuare v voi prezenta un tabel n care vor aprea pentru fiecare dintre operatorii C toate aceste informa ii de care am vorbit mai sus. Nu to i operatorii vor fi descrii n acest capitol. Motivul este c unii dintre operatori sunt nc prea complica i pentru acest capitol dar vor fi descrii n capitolele urmtoare sau se reper la programarea obiectual care nu face obiectul acestei cr i. Tabel cu operatorii specifici C++ Nivel Operator Tip Descriere ordine 1 :: Unar Operatorul scop folosit Stnga Dreapta pentru a identifica elemente ale unei clase 2 () [] . -> ++ -- const ++ Unar Pentru ++ respectiv Stnga Dreapta -- ~ ! sizeof new delete operatorul poate fi att postfixat ct i prefixat 3 *& Unar Indirectare i referin Dreapta Stnga pentru (pointeri) +Unar Operator de semn unar Dreapta Stnga 4 (tip) Unar Operatorul de for are a Dreapta Stnga tipului (eng. casting) 5 .* ->* Binar Pointer la membru Stnga Dreapta 6 */% Binar Operatori aritmetici Stnga Dreapta multiplicativi 7 +Binar Operatori aritmetici de Stnga Dreapta adunare 8 << >> Binar Operatori de deplasare Stnga Dreapta (eng. shift) 9 < > <= >= Binar Operatori rela ionali Stnga Dreapta 10 == != Binar Test de egalitate sau Stnga Dreapta inegalitate 11 & Binar Operatorul i (eng. AND) Stnga Dreapta pe bi i 12 ^ Binar Operatorul Sau exclusiv Stnga Dreapta (eng. XOR) pe bi i 13 | Binar Operatorul Sau (eng. OR) Stnga Dreapta pe bi i 14 && Binar Operatorul logic i (eng. Stnga Dreapta AND) 15 || Binar Operatorul logic Sau Stnga Dreapta (eng. OR)

16 17

?: Ternar Operatorul condi ional Dreapta Stnga = *= /= %= += -= >>= Binar Operatorii de atribuire Dreapta Stnga <<= &= ^= != 18 , Binar Operatorul virgul Stnga Dreapta n continuare voi prezenta operatorii nu n ordinea din tabel ci grupa i dup felul opera iilor pe care le execut.

Operatori aritmetici
Operatorii aritmetici sunt cunoscu i din matematic i de aceea ei vor fi prezenta i primii acetia sunt: Nivel Operator Tip Descriere ordine 3 +Unar Operator de semn unar Dreapta Stnga 6 */% Binar Operatori aritmetici Stnga Dreapta multiplicativi 7 +Binar Operatori aritmetici de Stnga Dreapta adunare 18 , Binar Operatorul virgul Stnga Dreapta Obs. Operatorii enumera i mai sus pot fi utiliza i n limbajul C i C++; dac ve i folosi alte limbaje uni dintre aceti operatori pot diferi ca forma de cei prezenta i de aceea este indicat studierea documenta iilor pentru a vedea diferen ele de nota ie. Limbajul C++ definete o mul ime de al i operatori, care vor fi studia i la momentul oportun. Atribuirea se desfoar astfel: (a) Se evalueaz expresia din partea dreapta a atribuirii; (b) Valoarea ob inut n urma evalurii se memoreaz n zona de memorie a variabilei cu numele specificat n partea stng a atribuirii. Obs: Vechea valoare a variabilei se pierde n momentul efecturii unei opera ii de atribuire. Fie urmtoarele atribuiri: i=3; i=i+1; Ne punem ntrebarea dac a doua atribuie este corecta. Din punct de vedere matematic, a doua atribuire este o absurditate ns, din punct de vedere al programrii este corecta i se realizeaz astfel: (a) a. Se evalueaz expresia i+1, iar rezultatul ob inut este 4 (vechea valoare a lui I, 3, la care se adaug o unitate); (b) b. Se stocheaz n i valoarea 4; Exerci iul 1 : Ce valoare are variabila x dup urmtoarea secven a de atribuiri: x=3; y=5; x=x+y; y=2*y; x=x-y; Exerci iul 2: (Bacalaureat 1999) Se da urmtoarea secven a de atribuiri: 13

a=10; b=4; a=a-b; b=a+b; a=b-a; (a) Ce valori au variabilele a i b ? (b) Ce efect au ultimele trei atribuiri ? Teme: Construi i schema logica pentru rezolvarea ecua iei de gradul al II-lea.

Dac valoarea ob inuta prin evaluarea expresiei din dreapta atribuirii este de alt tip dect tipul variabilei din stnga atunci se ncearc conversia tipului valorii la tipul variabilei. Nu ntotdeauna conversia este posibila, caz n care se va afia un mesaj de eroare n urma compilrii. Exemplul 1 : Fie urmtoarea secven a de program: void main(void){ int a; float c; a=3./2.+9./4.; cout<<a=<<a<<\n; c=3./2.+9./4.; cout<<c=<<c<<\n /* aceeai expresie are valori diferite, n func ie de tipul variabilei din stnga atribuirii */ } Observa ie: Executnd programul de mai sus se vor ob ine valori diferite pentru variabilele a i c, dei expresia care apare n dreapta ambelor atribuiri este aceeai. Pentru a se ob ine valoarea 3, iar pentru c se ob ine 3,75. Explica ia sta n modul n care se realizeaz conversiile de tip n cadrul atribuirilor. Valoarea expresiei 3./2.+9./4. este 3.75 dar variabilei a i se va atribui partea ntreaga a acestei valori, adic 3. Variabila c este de tip float (numr real), deci nu va mai fi nevoie de conversia rezultatului evalurii expresiei la tipul variabilei. Exemplul 2: void main(void){ float a; a=5/2; cout<<a; } Observa ie: Executnd acest program se va afia valoarea 2 i nu valoarea 2.5 aa cum ar fi fost de ateptat. Explica ia este urmtoarea: operatorul / realizeaz, atunci cnd operanzii sunt ntregi, mpr irea ntreaga, deci vom ob ine catul mpr irii ntregi dintre 5 i 2. Exista doua modalit i de rezolvare a problemei: fie nlocuim expresia cu 5./2. (5.=5.0) fie utilizam operatorul de conversie explicita ( ). Acest nou operator ( numit cast), se utilizeaz astfel ( tip_de_date) expresie; Semnifica ia este urmtoarea: Se cere convertirea valorii rezultate din evaluarea expresiei la o valoare de tipul specificat intre paranteze. n exemplul de mai sus vom nlocui atribuirea cu: a=(float) 5/2; (rezultatul expresiei va fi de tip float, deci variabilei a i se va atribui valoarea 2.5). Exerci iu: Fie urmtorul program, care calculeaz media aritmetica a trei numere a,b,c , primele doua introduse de la tastatura.:

Operatori rela ionali:


<,> == egal <= mai mic sau egal >= mai mare sau egal != diferit

Operatori logici:
&& - i logic || - sau logic ! - nega ie logica Operatorii logici i rela ionali sunt implica i n formarea expresiilor cu valoare logica. Spre exemplu: a<2, 7/5+2<s-1, (x>-3) &&(x<3), !(a==b) sunt expresii cu valoare logica.

Operatori de atribuire.
n sec iunea precedenta am amintit, vorbind despre reprezentarea algoritmilor prin scheme logice, de opera ia de atribuire. n limbajul C se considera ca atribuirea este un operator. Atribuirea are urmtoarea sintaxa: variabila = expresie; Modul de func ionare este urmtorul: 1. se evalueaz expresia; 2. valoarea ob inuta este stocata n zona de memorie a variabilei, realizndu-se eventuale conversii de tip. 3. valoarea rezultata n urma atribuirii este valoarea atribuita variabilei. Observa ie: Atribuirea fiind un operator, se considera ca operanzii sunt variabila din partea stnga, respectiv expresia din partea dreapta. Orice expresie trebuie s aib, n urma evalurii sale, o valoare (un rezultat). Valoarea expresiei de atribuire este valoarea ob inuta prin evaluarea expresiei din partea dreapta a atribuirii.

14

void main(void){ int a,b,c; float s; cin>>a; cin>>b; c=a/2+b/3; s=(a+b+c)/3; cout<<Media aritmetica este=<<s; } Executa i acest program i identifica i greelile. Corecta i greelile gsite.

operatori de atribuire compusa:


+=, -=, *=, /=, %= Operatorii de atribuire compusa au fost introdui pentru a fi utiliza i n locul atribuirilor de tipul: v=v+expresie; v=v-expresie; v=v*expresie; etc. unde: v - variabila expresie-orice expresie corecta n limbajul C n locul acestor expresii se vor folosi: v+=expresie; v -= expresie; etc. Folosirea operatorilor de atribuire compus sporete lizibilitatea programului i viteza de execu ie. Dac atribuirea este de forma: v=v+1; sau v=v-1; se pot utiliza operatorii de incrementare i decrementare ++ i --. Expresiile de mai sus se vor putea scrie: v++; respectiv v--; Exemplul 3: Se da urmtorul program:

void main(void){ int a,b,i=3; a=++i; //preincrementare a lui i cout<<a; b=a--; //postdecrementare cout<<a=<<a<<\n; cout<<b=<<b<<\n; a+=++b; //atribuire compusa cout<<a=<<a<<\n; cout<<b=<<b<<\n; } Observa ie: Cnd apar expresii de tipul : ++variabila sau --variabila; spunem ca se realizeaz o preincrementare, respectiv predecrementare. n cazul preincrementrii, variabila va primi ca valoare 1+valoarea ini ial. Dac preincrementarea apare intr-o expresie se realizeaz nti aceasta opera ie i abia apoi celelalte opera ii care mai apar n expresie (preincrementarea are prioritate mai mare). n atribuirea a = ++i se realizeaz nti preincrementarea, n urma creia i va avea valoarea 4, i abia apoi se realizeaz atribuirea (a va avea valoarea 4). n expresia b=a se realizeaz o postdecrementare, adic se modifica valoarea variabilei a doar dup ce s-au efectuat celelalte opera ii din expresie. n cazul nostru, b va primi valoarea lui a (4, n momentul acela) i abia apoi se va micora valoarea lui a cu o unitate. Exerci iu: Executa i programul de mai sus i urmri i rezultatele care se ob in. Mai exista operatori de atribuire compusa, folosindu-se operatorii logici ce ac ioneaz la nivel de bit, dar despre acetia vom vorbi intr-o sec iune viitoare. Tot atunci vom discuta i despre atribuirea multipla.

Citirea i afiarea datelor. Primele programe n C++


Pentru introducerea datelor prin intermediul tastaturii avem nevoie de func ia cin, iar pentru afiarea valorilor sau mesajelor de func ia cout. Exemplul 1: Cel mai simplu program este programul care nu realizeaz nici o prelucrare: void main (void) { } Exemplul 2: S se afieze pe ecran un mesaj.

15

#include <iostream.h> void main (void) { cout<< "Acesta este primul program in C!"; } Observa ii: 1. Linia #include <iostream.h> declara ca se va utiliza biblioteca de func ii cu numele "iostream.h", din care face parte i func ia de afiare cout. 2. Func ia main() este func ia principala a unui program C, prelucrrile con inute de aceasta fiind primele efectuate la executarea unui program. 3. Prelucrrile ce apar intr-o func ie trebuiesc scrise intre { i } 4. Dup scrierea unei comenzi (func ie / instruc iune) se pune ; Exemplul 3: Relum exemplul precedent: #include <iostream.h> void main(void){ cout<< "Acesta este primul program n C "; cout<<"\n scris n prima ora de laborator "; } Observa ii: Caracterul "\n" are ca efect afiarea a ceea ce urmeaz pe linia urmtoare a ecranului (adic salt la rndul urmtor). Mesajul trebuie precedat de << (aceste semne trebuie n elese ca o direc ie a fluxului de date de la textul scris spre func ia care afieaz textul pe ecran) Exemplul 4: S se scrie un program pentru nsumarea a doua numere. #include <iostream.h> void main(void){ int a; //variabila care va memora primul numr int b; //variabila care va memora al doilea numr int s; // memoreaza suma celor doua numere cout <<"Introduce i primul numr:"; cin >> a; cout <<"Introduce i al doilea numr:"; cin >>b; s=a+b; cout<<"Suma "<<a<<"+"<<b<<"="<<c<<"\n"; } Observa ii: Se folosesc trei variabile pentru a memora numerele i suma acestora. Prin "int a" se declara folosirea unei variabile de tip ntreg, avnd numele "a". "cin >> a" determina citirea unei valori de la tastatura, valoare ce va fi memorata n zona de memorie a variabilei "a". Cel care introduce date trebuie s tasteze o valoare ntreag, altfel semnalndu-se eroare. Dac se afieaz un mesaj, con inutul acestuia trebuie pus intre ghilimele. Dac se dorete afiarea valorii unei variabile atunci se scrie, dup simbolurile <<, numele acesteia.

Executnd programul de mai sus ve i observa modul de afiare al rezultatului. n textul programului au fost introduse mici comentarii, precedate de //, pentru a facilita n elegerea textului sursa. Exemplul 5: Scrie i un program care s afieze urmtorul meniu: Buturi Bere ..12500 Vin 34764 Suc...5000 Cafea Nes.10000 Expreso6000 #include <iostream.h> void main(void){ cout <<Bauturi:\n; cout <<\t Bere12500\n; cout <<\t Vin..34764\n; cout <<\t Suc5000\n; cout <<Cafea:\n; cout <<\t Nes.10000\n; cout <<\t Expreso6000\n; } Observa ii: S-a folosit caracterul \t pentru a se ncepe un nou paragraf. Caracterele \t i \n fac parte dintre caracterele numite caractere escape, deoarece sunt caractere neafiabile pe ecran dect prin utilizarea unor simboluri (secven e de evitare).

Instruc iunea alternativa (if)


Pn acum am folosit ca exemple programe simple, care con ineau doar func iile de intrare / ieire i operatorul de atribuire. Atunci cnd elaboram programe ceva mai complexe este necesar ca, intr-un anumit punct al programului, s decidem continuarea acestuia n func ie de o condi ie. n primul laborator am dat ca exemplu de algoritm rezolvarea ecua iei de gradul 1 (pseudocod i schema logica). Intr-o schema logica ni se permitea utilizarea unui bloc de decizie de urmtorul tip: NU C A B DA

cu semnifica ia: dac este adevrata condi ia se executa prelucrarea B, altfel se executa prelucrarea A. n limbajul C este utilizata instruc iunea if, cu urmtoarea sintax: 16

if (expresie) instruc iune1; [else instruc iune2;} unde: expresie - orice expresie valida n limbajul C instruc iune1, instruc iune2 - orice instruc iune corecta din limbajul C ; Mod de func ionare: se evalueaz expresia dac expresia este ne nul (conven ia pentru adevrat) se executa instruc iune1 dac expresia este nula (fals) se executa instruc iune2 se trece la urmtoarea instruc iune a programului Observa ie: alternativa else instruc iune2 poate s lipseasc. Exemplul 4: S se scrie un program pentru calcularea maximului a doua numere. #include <iostream.h> void main(void){ int a,b; int max; cout<<a=; cin>>a; cout<<\nb=; cin>>b; if (a<=b) max=b; else max=a; cout<<Maximul celor doua numere este=<<max<<\n; } Exemplul 5: Scrie i un program care calculeaz maximul a 3 numere.

#include <iostream.h> void main (void){ int a,b,c; int max; cout<<a=; cin>>a; cout<<\nb=; cin>>b; cout<<\nc=; cin>>c; if (a<=b) if (c<=b) max=b; else max=c; else if (c<=a) max=a; else max=c; cout<<\nMaximul este=<<max; } Observa ie: Dup cum se vede din exemplu, instruc iune1 i instruc iune2 pot fi de asemenea instruc iuni if. Spunem ca sunt instruc iuni if imbricate. A se observa i modul cum a fost scris programul, astfel nct s se vad clar crei instruc iuni if ii apar ine fiecare else. Exemplul 6: Se dau trei numere ntregi a,b,c. S se testeze dac numerele date pot fi lungimile laturilor unui triunghi.

17

#include <iostream.h> void main (void){ int a,b,c; cout<<a=; cin>>a; cout<<\nb=; cin>>b; cout<<\nc=; cin>>c; if (a<b+c) if (b<a+c) if c<a+b) cout<< Numerele pot fi lungimile laturilor unui triunghi !; else cout<<Numerele nu pot fi lungimile laturilor unui triunghi !; else cout<<Numerele nu pot fi lungimile laturilor unui triunghi !; else cout<<Numerele nu pot fi lungimile laturilor unui triunghi !; } Observa ie: Nu am mai verificat dac a, b, c sunt pozitive. Exemplul 7. Relum exemplul precedent cu inten ia de a folosi mai pu ine instruc iuni if. #include <iostream.h> void main (void) { int a,b,c; cout<<a=; cin>>a; cout<<\nb=; cin>>b; cout<<\nc=; cin>>c; if ((a<b+c) && (b<a+c) && (c<a+b)) cout<<Numerele pot fi lungimile laturilor unui triunghi !; else cout<<Numerele nu pot fi lungimile laturilor unui triunghi !; } Observa ie: Am folosit o singura instruc iune if, cele trei condi ii anterioare fiind conectate prin operatorul I logic. Dup cum se tie, dac avem propozi iile p,q,r, atunci propozi ia p&&q&&r va fi adevrata dac toate propozi iile componente sunt adevrate i fals dac una dintre propozi iile componente este fals.

Este indicata aceasta scriere pentru ca sporete lizibilitatea programului. Exemplul 8: Rezolvarea ecua iei de gradul I. #include <iostream.h> void main(void) { int a,b; float x; cout<<\na=; cin>>a; cout<<\nb=; cin>>b; if (a!=0){ x=(float) -b/a; cout<<\nx=<<x; } else if (b==0) cout<<\n x apar ine lui R ; else cout <<\n Ecua ia nu are solu ii; } Observa ie: n cazul n care a este nenul avem de realizat doua opera ii: atribuirea valorii -b/a variabilei x i afiarea valorii rdcinii. Atunci cnd se realizeaz mai multe opera ii acestea trebuiesc incluse intre { i }.

Instruc iuni iterative


Toate problemele prezentate pn acum au putut fi rezolvate folosind numai func ii de citire / scriere, atribuiri i instruc iunea de decizie (if). Cele mai multe dintre probleme vor necesita structuri de date mai complexe precum i folosirea unor noi instruc iuni, care s permit repetarea de un numr oarecare de ori a unor par i din algoritm. S luam ca exemplu algoritmul de calcul al sumei a 2 numere introduse de la tastatura. El consta n citirea valorilor pentru cele doua numere i afiarea sumei acestora. Nu era nevoie dect de doua variabile, cate una pentru fiecare numr. Acest exemplu este doar unul didactic, n practica ne ntlnindu-se prea des cazuri n care s fie nevoie de a suma doua numere. Generalizarea problemei pentru n numere va modifica substan ial algoritmul nostru. Nu vom putea folosi cate o variabila pentru fiecare numr introdus deoarece nu cunoatem exact cate numere avem (n este introdus de utilizatorul programului, altfel algoritmul nu ar mai fi general). Chiar dac s-ar ti ca avem, s zicem, 2500 de numere ar fi cam dificil s utilizam 2500 de variabile distincte. Problema noastr se poate rezolva simplu dac utilizam o instruc iune iterativa (ciclica), care s ne permit repetarea de n ori a urmtoarei secven e de opera ii: 1. citim o valoare folosind variabila a; 2. adunam valoarea citita la rezultatul par ial, memorat n variabila s; Instruc iunile ce descriu aceste prelucrri ciclice sunt compuse din doua pr i: corpul ciclului, format din prelucrrile ce se doresc a fi realizate de mai multe ori; 18

condi ia, pe baza creia se stabilete dac se vor mai executa prelucrrile din ciclu (este obligatorie executarea prelucrrilor din corpul instruc iunii de un numr finit de ori); Corpul ciclului sau condi ia trebuie s con in acele opera ii care, dup efectuarea de un numr de ori a corpului instruc iunii, s determine schimbarea valorii de adevr a condi iei, permi nd ncheierea executrii instruc iunii ciclice i trecerea la urmtoarele instruc iuni ale algoritmului. n cazul n care este neglijat acest aspect, programul se va executa la infinit. Condi ia trebuie s fie o expresie cu valoare logica. Reamintesc faptul ca n limbajul C++ nu exista un tip de date logic, dar se utilizeaz conven ia ca orice valoare ne nula s fie considerata ca adevr iar valoarea zero ca valoarea fals. n consecin , orice expresie cu valoare de tip ntreg va putea fi utilizata drept condi ie intr-o instruc iune iterativa. n finalul paragrafului o chestiune de terminologie: o execu ie a corpului instruc iunii poarta numele se itera ie. Instruc iunile iterative pot fi clasificate, n func ie de momentul evalurii condi iei, astfel: cicluri cu test ini ial (While i For)- evaluarea condi iei se face naintea fiecrei itera ii; cicluri cu test final (Do .. While)- evaluarea condi iei se face la sfritul fiecrei itera ii;

#include <iostream.h> void main() { float a; int i,n; float suma=0; i=1; cout<<"\n Numrul de elemente="; cin>>n; while(i<=n){ cout<<"Elementul "<<i<<"este: "; cin>>a; suma=suma+a; //se mai poate scrie suma+=a i++; } cout<<"Suma este= "<<suma; } Exemplul 2: Suma primelor n numere naturale. #include <iostream.h> void main() { int n; int i; int suma=0; cout<<"n="; cin>>n; i=1; while(i<=n){ suma=suma+i; i++; } cout<<"Suma este: "<<suma; } Observa ie: Se poate utiliza o scriere mai compacta, care elimina i necesitatea utilizrii variabilei i: while (n--) suma+=n; Modul de execu ie este urmtorul: valoarea condi iei este valoarea variabilei n, valoare care scade cu o unitate dup fiecare itera ie (postdecrementare) condi ia devine fals atunci cnd valoarea lui n devine zero;

Instruc iunea While


Instruc iunea while (att timp cat) este o instruc iune iterativa cu test ini ial i are urmtoarea sintaxa: while ( <condi ie>) instruc iune; unde: <condi ie> - orice expresie cu valoare ntreaga; instruc iune - orice instruc iune valida a limbajului; Mod de func ionare: dac expresia este adevrat se executa prelucrrile din ciclu; altfel, se trece la urmtoarea instruc iune de dup while; Cu alte cuvinte, prelucrrile din ciclu se executa att timp cat condi ia este adevrata. Dac expresia este fals de la nceput corpul ciclului nu se va executa deloc. Problema propusa n paragraful precedent se poate rezolva astfel: Exemplul 1 Suma a n numere introduse de utilizator

19

Instruc iunea do .. while


Instruc iunea do .. while este o instruc iune iterativa cu test final i are urmtoarea sintaxa: do instruc iune; while (<condi ie>) Mod de func ionare: se executa corpul instruc iunii; se evalueaz condi ia: dac aceasta este adevrata se reia execu ia, altfel se trece la urmtoarea instruc iune din program; Deosebirea esen ial fa de instruc iunea while este aceea ca expresia se evalueaz dup itera ie. n cazul n care condi ia este fals de la nceput, corpul instruc iunii se executa o singura dat. Utilizarea instruc iunii do .. while este mai pu in frecventa (se folosete pentru acele prelucrri care trebuiesc executate cel pu in o dat). Dac rescriem exemplul 1 utiliznd do .. while, ob inem: . do{ cin>>a; suma+=a; i++; } while(i<=n); .

Exemplul 3: Relum exemplul 1 folosind instruc iunea for: #include <iostream.h> void main(){ int i, n; float a, suma=0; cin>>n; for(i=1;i<=n;i++){ cin>>a; suma+=a; } cout<<suma =<<suma; } Observa ii: Variabila i este utilizata pe post de contor al instruc iunii for, numrnd la a cta itera ie s-a ajuns. Execu ia instruc iunii for se ncheie atunci cnd numrul de itera ii devine egal cu n. Ini ializarea lui i cu 1 se realizeaz o singura dat, la nceput; i <= n este condi ia de continuare a execu iei; i++ se efectueaz dup fiecare execu ie a ciclului (postincrementare). Aceasta forma a instruc iunii for este cea mai utilizata. Un alt mod de a descrie execu ia acesteia este urmtorul: pentru i de la 1 la n se executa corpul instruc iunii. Nu este obligatoriu ca valoarea lui i s se mreasc de fiecare dat cu o unitate. Nu este obligatorie utilizarea tuturor celor trei expresii din for, dar este obligatorie scrierea separatorului ; . Exemplul de mai sus se poate rescrie astfel: for( ;n--; ){ cin>>a; suma+=a; }

Instruc iunea for


Una dintre cele mai puternice instruc iuni iterative ale limbajului C (i nu numai) este instruc iunea for, care are urmtoarea sintaxa: for (expresie1; expresie2; expresie3) [instruc iune]; unde: expresie1, expresie2, expresie3 - expresii valide n C++; instruc iune - orice instruc iune a limbajului C++; Parantezele ptrate semnifica faptul ca instruc iunea este op ionala; Mod de execu ie: expresiile au urmtoarea semnifica ie generala: expresie1 - expresie de ini ializare; expresie2 - condi ia de continuare a execu iei ciclului; expresie3 - expresie de actualizare; att timp cat expresie2 este adevrata se executa corpul ciclului; de fiecare dat se evalueaz expresia de actualizare, care are rolul esen ial de a determina ca, dup un numr de itera ii, expresie2 s devin fals; expresie1 se evalueaz o singura dat;

No iunea de tablou
n laboratorul precedent explicam de ce nu putem s utilizam 2500 de variabile distincte atunci cnd dorim s nsumam 2500 de numere. Rezolvarea propusa atunci se baza pe citirea repetata a cate unei valori, folosind o variabila a, urmata de adugarea acesteia la suma par iala. Dezavantajul metodei este acela ca nu se pot memora toate valorile citite ci doar ultima (citind o valoare intr-o variabila, vechea valoare a acesteia se pierde). Cele mai multe programe presupun prelucrri complexe asupra datelor de intrare, deci va fi nevoie s memoram irul nostru de numere astfel nct s poat fi utilizat i n alte prelucrri, nu numai pentru calcularea sumei. 20

Pentru a rezolva astfel de situa ii s-a introdus n limbajele de programare no iunea de tablou. Tablourile ne permit memorarea unui numr mare de valori utiliznd o singura variabila. Prin tablou se n elege un numr de elemente de acelai tip, numit tip de baza, stocate intro zona compacta de memorie. Un tablou poate fi definit astfel: tip_de_baza nume [dimensiune1] [dimensiune2] [dimensiune_n]; unde: tip_de_baza = tipul elementelor tabloului; n = numrul de dimensiuni al tabloului; [dimensiune_i] = numrul de elemente pe dimensiunea i tabloul are dimensiune1**dimensiune_n elemente No iunea de tablou multidimensional poate fi n eleas mai bine dup parcurgerea no iunilor referitoare la vectori i matrice.

#include <iostream.h> void main(){ int n; //numrul de elemente int a[50]; /* se definete o variabila de tip tablou cu maxim elemente, deci n va trebui sa fie mai mic dect 50 */ int min; //variabila ce va memora minimul int i; //contor n instruc iunea for

50

de

Tablouri unidimensionale
Declararea unui tablou unidimensional: tip_de_baza nume[dimensiune]; unde dimensiune specifica numrul de elemente al vectorului. De exemplu: int a[30]; declara un vector ce con ine 30 de elemente de tip int, float b[50]; declara un vector cu 50 elemente reale; Numerotarea elementelor se face de la 0 la dimensiune-1, adic cele 30 de elemente ale primului tablou sunt: a[0], a[1], a[2], , a[29]. Spunem ca tabloul este o variabila indexata, deoarece fiecare element al tabloului poate fi gsit / utilizat cunoscnd numrul sau de ordine. Vectorul este un ir de valori n care se cunoate precis care este primul, al doilea, .,ultimul element. Numrul de ordine al unui element se numete indice. Exemplul 1: S se calculeze minimul elementelor unui ir de n numere, utiliznd vectori.

cout<<n=; cin>>n; /* se citesc elementele irului */ for(i=0;i<n;i++){ cout<<a[<<i<<]=; cin>>a[i]; } // se calculeaz minimul min=a[0]; /*ini ializam minimul cu primul element din ir */ for(i=1;i<n;i++) if (a[i]<min) min=a[i]; cout<<Minimul este=<<min; //afiare minim } Dup cum se poate observa din programul de mai sus, fiecare element al irului se poate utiliza ca i cum ar fi o variabila de tip int independenta, deci valoarea unui element al vectorului poate fi modificata independent de celelalte elemente. S presupunem ca utilizatorul introduce pentru n valoarea 4. Ini ial, elementele vectorului nu au o valoare bine definita; putem reprezenta grafic vectorul astfel: S presupunem ca utilizatorul introduce valorile 3, 7, 2, 9 pentru cele patru elemente ale vectorului. Reprezentarea vectorului a va fi urmtoarea: a[0] a[1] a[2] a[3] 3 7 2 9 Valoarea oricrui element al vectorului poate fi modificata fie printr-o atribuire, fie prin introducerea unei valori (folosind func ia cin, de exemplu) de la tastatura. Dac vom introduce atribuirea a[2]=23; valoarea elementului al treilea din vectorul a nu va mai fi 2 (vechea valoare) ci 23. De asemenea, dac se scrie: cin>>a[2]; valoarea elementului va fi cea introdusa de utilizator de la tastatura. Exemplul 2: Se considera n numere ntregi introduse de la tastatura. S se afle cate numere sunt pare i cate impare.

21

#include <iostream.h> #include <conio.h> void main() { int n; //numrul de elemente int v[30]; //vector maxim 30 ntregi int pare, impare; // memoreaz nr. elementelor pare, impare int j; //variabila contor pentru for clrscr(); //citim numrul de elemente cout<<n=; cin>>n; /* se citesc elementele irului */ for(i=0;i<n;i++) { cout<<v[<<i<<]=; cin>>v[i]; } //ini ializam variabilele pare=0; impare=0; //luam fiecare element din v i testam dac acesta este sau nu par for(j=0;j<n;j++) if (v[j] % 2 = =0) pare++; else impare++; //afiam rezultatul cout<<Am gsit <<pare<< numere pare i <<impare; } n programul de mai sus verificam, pentru fiecare element, dac acesta se mparte exact la doi, caz n care am mai descoperit un element par. n caz contrar, numrul elementelor impare se mrete cu unu. Am utilizat operatorul % , numit i modul aritmetic, care are ca rezultat restul mpr irii lui v[j] la 2. Exemplul 3: S se introduc de la tastatura un cuvnt i s se afieze.

#include <iostream.h> #include <conio.h> void main(){ char cuvant[30]; clrscr(); cout<<Introduceti cuvantul:; cin>>cuvant; cout<<Cuvantul introdus este:<<cuvant; } Observa i cu aten ie cum am declarat variabila ce va memora cuvntul: folosim un vector cu elemente de tip caracter. Acest mod de declarare ne permite s lucrm cu oricare dintre caracterele ce formeaz cuvntul. De exemplu, dac utilizatorul introduce cuvntul salariu, vectorul nostru de caractere arata cam aa: Dac dorim s modificam pu in cuvntul putem scrie: cuvant[6]=i; i vom ob ine cuvntul salarii. Exemplul 4: S se citeasc un cuvnt i s se gseasc numrul de vocale pe care le con ine. #include <iostream.h> #include <conio.h> # include <string.h> void main(){ char c[30];// memoreaz cuvntului int vocale; // numrul vocalelor int j; clrscr(); cout<<Introduceti cuvantul:; cin>>c; vocale=0; //cutam vocalele for(j=0;j<strlen(c);j++) if ( c[j]==a || c[j]==e || c[j]==i || c[j]==o || c[j]==u) vocale++; cout<<Am gasit <<vocale<< vocale.; } Observa ii: Am utilizat func ia strlen, care are ca rezultat numrul de caractere al irului dat ca parametru. Func ia poate fi utilizata doar dac a fost inclus fiierul header string.h, fiier ce con ine func iile ce ac ioneaz asupra irurilor de caractere.

22

Mecanismul algoritmului este urmtorul: se ia cate un caracter din irul introdus i se verifica dac elementul respectiv con ine unul dintre caracterele a, e, i, o, u. De fiecare dat cnd condi ia este adevrata se incrementeaz numrul de vocale. Mai multe despre irurile de caractere vom spune dup capitolul dedicat pointerilor. Exemplul 5 (Cutare secven iala) Se considera un ir de n elemente ntregi i un numr ntreg x. S se verifice dac numrul x face parte din irul considerat.

#include <iostream.h> #include <conio.h> void main(){ int v[25]; int n; int x; int j; int gasit; //variabila logica ce indica dac x apar ine lui v clrscr(); //citim numrul de elemente cout<<n=; cin>>n; /* se citesc elementele irului */ for(j=0;j<n;j++){ cout<<v[<<j<<]=; cin>>v[j]; } //se citete elementul x cout<<x=; cin>>x; gasit=0; j=0; //cutam x n irul v while( (j<n)&&(!gasit)){ if (v[j]==x) gasit=1; j++; } if(gasit) cout<<Elementul apar ine irului dat !; else cout<<Elementul nu apar ine irului !; } Am utilizat instruc iunea while, condi ia de efectuare a ciclului fiind (j<n) && (!gasit). Corpul instruc iunii while se va executa att timp cat nu s-a ajuns la sfritul irului i elementul x nu a fost gsit n v. Condi ia de mai sus devine fals n doua cazuri: fie am epuizat elementele irului (j a ajuns egal cu n), fie am gsit un element egal cu x. Dup executarea ciclului while testam dac variabila gsit este ne nula (adevr), caz n care x apar ine lui v, altfel x nu apar ine irului.

Exemplul 6. (sortare) Se considera un ir cu n elemente reale. S se aranjeze elementele n ordine cresctoare utiliznd acelai vector. #include <iostream.h> #include <conio.h> void main(){ double v[40]; int n; int j, k; cout<<n=; cin>>n; for(j=0;j<n;j++){ cout<<v[<<j<<]=; cin>>v[j]; } //sortarea cresctoare a irului v for(j=0;j<n-1;j++) for(k=j+1; k<n;k++) if (v[j]>v[k]){ //interschimbm valorile v[j] i v[k] temp=v[j]; v[j]=v[k]; v[k]=temp; } //afiarea valorilor sortate cresctor for(k=0;k<n;k++) cout<<v[k]<<\t; }

Tablouri bidimensionale (matrice)


Pe lng vectori, cel mai utilizat tip de tablou de numere este tabloul bidimensional, numit de cele mai multe ori matrice. Declararea unei matrice se face astfel: tip_de_baza nume[dimensiune_1][dimensiune_2]; Exemplu: double a[10][5]; //tablou cu 10 linii i 5 coloane de elemente reale int a[3][2]; //tablou cu 3 linii i 2 coloane de elemente ntregi Pentru a putea avea acces la valoarea unui element al matricei, trebuie s precizam linia i coloana pe care se afla acesta. Un element poate fi specificat prin a[i][j], i - reprezentnd linia i j - coloana. n cazul vectorilor citeam o valoare reprezentnd numrul de elemente. Pentru matrice vom citi o valoare m - numrul maxim de linii i o valoare n - numrul maxim de coloane. O matrice cu m linii i n coloane va avea m * n elemente. Dac m = n atunci matricea se numete matrice ptrata de ordin n. Exemplul 7. S se citeasc elementele unei matrice i s se afieze. 23

#include <iostream.h> #include <conio.h> void main(){ int a[20][20]; //matrice cu elemente ntregi int m, n; // linii, respectiv coloane int i, j; //contoare pentru for //citim numrul de linii i coloane cout<<Numrul de linii:; cin>>m; cout<<Numrul de coloane:; cin>>n; //se citesc elementele matricei for(i=0;i<m;i++) for(j=0;j<n;j++){ cout<<a[<<i<<][<<j<<]=; cin>>a[i][j]; } //afiarea elementelor matricei for(i=0;i<m;i++){ for(j=0;j<n;j++) cout<<a[i]][j]<<\t; cout<<\n; } } Exemplul 8. Se dau doua matrice cu m linii i n coloane. S se calculeze matricea suma. . int a[20][20], b[20][20], c[20][20]; int m,n; int i, j; .. //se citesc dimensiunile m, n i cele doua matrici a i b . //calculam matricea suma for(i=0;i<m;i++) for(j=0;j<n;j++) c[i][j]=a[i][j]+b[i][j]; //se afieaz matricea c .. Atunci cnd lucrm cu matrice avem nevoie de doi indici: i pentru a parcurge liniile matricei i j pentru a parcurge coloanele acesteia. Pentru fiecare valoare a lui i, j ia toate valorile intre 0 i n-1, deci se parcurge linia i. n ultimul exemplu am utilizat trei matrice. Pentru mai multa claritate, putem declara un tip ale crui elemente s fie matrice:

typedef int matrice[20][20]; matrice a, b, c; Am definit un tip de date (tip de date definit de utilizator) ale crui elemente sunt matrice cu maxim 20 de linii i coloane cu elemente ntregi. Numele noului tip este matrice. Declararea variabilelor de acest tip se poate face oriunde n programul n care apare defini ia. Definirea unui tip de date se poate face numai prin utilizarea cuvntului cheie typedef naintea declara iei. Dac definim mai multe tipuri se va folosi typedef pentru fiecare defini ie.

No iunea de pointer
Pointerii au fost introdui n limbajele de programare pentru a putea rezolva mai eficient anumite probleme sau pentru a da mai multa claritate anumitor programe. O prima defini ie poate fi urmtoarea: Pointerul este o variabila ce con ine adresa unui obiect. Obiectul a crei adresa este re inuta de pointer poate fi: variabila func ie Fie urmtorul exemplu: int x; int *px; Am definit o variabila de tip ntreg x i o variabila pointer, care poate con ine adresa unei variabile de tip ntreg. Simbolul * ce apare n stnga variabilei px arata ca px este o variabila pointer. Prin atribuirea px=&x; Pointerul va avea ca valoare adresa de memorie alocata variabilei x (vezi laboratorul nr.1, defini ia variabilei). Operatorul unar & este utilizat pentru a se ob ine adresa variabilei x (operator unar = are un singur operand) Acum putem s lucrm cu con inutul variabilei x (adic cu valoarea acesteia) prin intermediul pointerului px, deci indirect, fr s mai folosim variabila x. La prima vedere, aceasta modalitate de lucru poate prea dificila i nu tocmai utila. Necesitatea utilizrii pointerilor va apare cu mai multa claritate n sec iunea dedicata irurilor de caractere i func iilor. Exemplul 1. Fie programul urmtor:

24

#include <iostream.h> void main(){ int x,y; int *px; cout<<"x="; cin>>x; cout<<"y="; cin>>y; px=&x; cout<<"x are valoarea "<<*px; *px=y; cout<<"\nx a devenit "<<x; } n programul de mai sus am introdus valorile variabilelor ntregi x i y, am definit un pointer la variabila x i am atribuit acestuia adresa de memorie alocat variabilei x. S analizam atent linia: cout<<"x are valoarea "<<*px; Prin *px se n elege valoarea aflata n zona de memorie a crei adresa este memorata n pointerul px. Valoarea afiat va fi chiar valoarea introdusa pentru x deoarece, nainte de afiare, pointerul px a primit ca valoare adresa variabilei x, adresa la care se afla valoarea acesteia (valoare dobndita prin utilizarea func iei cin). Atribuirea *px=y; va modifica valoarea care se afla la adresa memorata de px, valoare care va fi valoarea introdusa de utilizator pentru variabila y. Astfel va fi modificata chiar valoarea pe care o are variabila x. Firete ca era mai simplu s folosim atribuirea x=y; care are acelai efect i ne scutete de de-a mai folosi pointeri, insa exemplul este pur didactic. Operatorul unar * este folosit sub forma *variabila_pointer, valoarea acestei expresii fiind valoarea care se gsete n memorie la adresa memorata de pointerul ce apare ca operand. n concluzie, prin px avem acces la adresa variabilei x, iar prin *px la valoarea variabilei x. Vom spune ca un pointer refera indirect un obiect sau ca pointeaz(arata) la obiectul respectiv. Variabilele pointer pot fi ncadrate ca fiind de tip referin a. Exemplul 2. S se calculeze suma a doua numere reale folosind pointeri.

#include <iostream.h> void main(){ double x, y, z; double *px, *py, *pz; cin>>x; cin>>y; px=&x; py=&y; pz=&z; *pz=*px+*py; cout<<"Suma este: "<<*pz; }

Pointeri i tablouri
n limbajul C, exista o foarte strnsa legtura intre pointeri i tablouri, astfel ca pointerii i tablourile sunt tratate la fel. Orice program n care apar tablouri poate fi modificat astfel nct s foloseasc pointeri n locul tablourilor. n aceasta sec iune vom discuta despre legtura dintre pointeri i vectori (tablouri unidimensionale). Fie urmtoarele declara ii: int a[20]; int *pa; Am declarat o variabila a , care este un vector cu maxim 20 elemente ntregi i pa un pointer la o variabila de tip ntreg. Dup cum se tie, o valoare int are nevoie de 16 bi i pentru a fi memorata, adic 2 Byte (o variabila int poate retine numere ntregi intre -32768 i 32767, vezi curs Bazele Informaticii). Pentru tabloul a vor fi aloca i 2*20=40Byte consecutivi n memorie adic, pentru primul element a[0] sunt aloca i primii 2Byte, pentru a[1] urmtorii 2Byte,, pentru a[19] ultimii 2 Byte din cei 40 aloca i. Fie atribuirea: pa=&a[0]; Dup aceasta atribuire, pointerul pa con ine adresa primului element al vectorului, adic pa pointeaz la nceputul vectorului a. Dac scriem pa=&a[3]; atunci pa va referi elementul al 4-lea din vectorul a, iar *pa va con ine valoarea sa. Opera iile care se pot realiza cu pointeri sunt: compara ia adunarea unui pointer cu un ntreg scderea unui ntreg dintr-un pointer Doi pointeri pot fi compara i folosind operatori rela ionali. n compara ia:

25

if(p1==p2) cout<<Adrese identice; else cout<<Adrese diferite; se verifica dac adresa memorata de p1 este aceeai cu adresa re inuta de p2, unde p1 i p2 sunt pointeri de acelai tip. Se poate compara un pointer cu valoarea NULL (sau 0). Un pointer are valoarea NULL (valoare nedefinita) dac nu refera nici un obiect. Adunarea unui pointer cu un ntreg este definita numai atunci cnd pointerul refera un tablou (un element al tabloului). Scderea este definita n acelai caz. Exemplul 3. S se citeasc elementele unui vector i s se afieze acestea utiliznd pointeri. #include <iostream.h> void main(){ int a[20]; int *pa; int i,n; cout<<"Numrul de elemente= "; cin>>n; for(i=0;i<n;i++){ cout<<"Elementul"<<i<<"="; cin>>a[i]; } //afiarea vectorului folosind pointeri pa=&a[0]; for(i=0;i<n;i++){ cout<<*pa<<"\n"; pa++; } } Prima pate a programului nu con ine elemente noi, doar a doua parte meritnd aten ie. Mai nti ini ializam pointerul pa cu valoarea primului element al vectorului a. Ciclul for con ine urmtoarele prelucrri: afieaz valoarea aflata la adresa indicata de pointer; aduna pointerul pa cu 1 Incrementarea pointerului pa are ca efect modificarea adresei memorate n pa. Noua adresa este adresa zonei de memorie corespunztoare elementului urmtor, o adresa cu 2Byte mai mare dect precedenta. Observam ca mrirea pointerului cu o unitate nseamn de fapt trecerea la urmtorul element din vector. Dac vom introduce pentru n o valoare mai mare dect 20 (numrul maxim de elemente ale vectorului, aa cum reiese din declara ie) atunci pointerul pa va depi zona de memorie alocata vectorului i va referi o adresa la care se pot afla date importante pentru program. Urmrile pot fi imprevizibile, de la blocarea programului pn la blocarea sau nchiderea calculatorului !!!

No iunea de func ie. Structura i definirea func iilor


No iunea de func ie este o no iune de mare importanta n informatica, orice limbaj de programare furniznd facilit i de lucru cu func ii. n matematica, func ia era definita ca fiind tripletul (A, B, f), unde: A - domeniul de defini ie; B - codomeniul sau domeniul de valori; f - lege, conven ie, prin care fiecrui element din domeniul de defini ie i se asociaz un unic element din codomeniu; n informatica, no iunea de func ie difer pu in de modul matematic de abordare. n limbajul C, orice program trebuie s con in obligatoriu o func ie numita main. Dac prelucrrile ce compun programul sunt foarte complexe, utilizarea unei singure func ii duce la un program greu de n eles i depanat. n acest caz este bine ca problema de rezolvat s fie mpr ita n sub probleme prin a cror combinare s se ob in rezolvarea problemei ini iale. Pentru rezolvarea fiecrei sub probleme se poate utiliza cate o func ie separata. Func ia main (programul principal) nu va mai fi de mare ntindere, ea con innd doar apeluri ctre func iile deja definite. Decizia de a folosi o func ie poate fi luata i n cazul n care anumite prelucrri trebuiesc realizate de mai multe ori, cum se va vedea i n exemplul de mai jos. Exemplul 1. S se calculeze aria a n triunghiuri, dac se cunosc lungimile laturilor acestora.

26

#include <iostream.h> #include <conio.h> #include <math.h> float aria(int a, int b, int c){ float p,s; p=(float)(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); return s; } void main(){ int a,b,c; float S; int i,n; cout<<"Numrul de triunghiuri= "; cin>>n; i=1; for(i=1;i<=n;i++){ cout<<"a="; cin>>a; cout<<"b="; cin>>b; cout<<"c="; cin>>c; S=aria(a,b,c); cout<<"Aria triunghiului "<<i<< " este "<<S<<"\n"; } } Programul trebuie s calculeze aria a n triunghiuri, deci calculul ariei trebuie realizat de n ori. Am definit func ia aria, care calculeaz aria triunghiului cu lungimile laturilor a, b, c prin formula lui Heron. Structura func iei este urmtoarea: antet: float aria(int a, int b, int c) care con ine urmtoarele elemente: tipul rezultatului func iei (codomeniul) - rezultatul func iei va fi o valoare de tipul declarat; numele func iei: - numele nu poate fi identic cu un cuvnt cheie lista parametrilor formali - variabilele de care depinde calcularea rezultatului (argumentele func iei); pentru fiecare parametru formal se specifica tipul. corpul func iei:

{ float p,s; p=(float)(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); return s; } Corpul func iei con ine declara iile variabilelor utilizate n func ie i prelucrrile realizate de func ie. Variabilele utilizate n func ia aria, numite i variabile locale, sunt semi perimetrul p i aria s. Nu declaram variabilele a, b, c (parametrii formali nu se declara n corpul func iei) i nici nu citim valori pentru ele n cadrul func iei. Orice func ie care are drept codomeniu un tip diferit de tipul void trebuie s con in n corpul func iei o instruc iune return expresie; unde expresie este orice expresie corecta n C cu valoare de tipul declarat pentru codomeniu. Instruc iunea return este utilizata pentru a semnala faptul ca valoarea func iei este valoarea expresiei. n programul principal (func ia main) se citete numrul de triunghiuri n. Instruc iunea for va repeta de n ori (pentru fiecare triunghi) urmtoarele prelucrri: se citesc valori pentru variabilele a, b, c care reprezint lungimile laturilor triunghiului curent; se calculeaz aria triunghiului pentru valorile date; se afieaz valoarea ariei triunghiului curent; Modul de utilizare al func iei aria este interesant. Atribuirea: S=aria(a,b,c); are urmtorul efect; se evalueaz expresia din dreapta atribuirii, expresie ce consta din apelul func iei aria pentru valorile a, ,b, c evaluarea func iei nseamn executarea prelucrrilor din func ie pentru valorile parametrilor formali a, b, c valoarea ntoarsa de func ie este valoarea variabilei s, care apare n return; valoarea este memorata n zona de memorie a variabilei S. Func iile pot fi clasificate astfel: func ii predefinite = func ii deja definite de autorii mediului de programare C i grupate, n func ie de utilitatea lor, n biblioteci numite fiiere header. De exemplu, n biblioteca math.h sunt grupate func iile matematice, n string.h avem func iile de lucru cu iruri de caractere, n iostream.h func ii pentru introducerea i afiarea datelor, n malloc.h i alloc.h func ii pentru alocarea memoriei func ii definite de utilizator = func ii scrise de creatorul unui program pentru acele prelucrri pentru care nu exista func ii predefinite (caz destul de frecvent); O func ie poate s aib drept codomeniu orice tip predefinit scalar (ntreg, caracter sau real), tip compus (uniune sau structura), precum i pointeri la orice tip. Tipul void nseamn ca func ia nu returneaz nici o valoare. Programatorul poate s strng func iile definite de el intr-un fiier header propriu, care se poate include n program prin 27

#include nume_fisier.h.

Apelul func iilor i transferul parametrilor


Orice apari ie a numelui func iei nso it de un numr de valori egal cu numrul parametrilor formali se numete apel al func iei. Puteam apela func ia i n modul urmtor: cout<<aria(3,4,5); Aceasta instruc iune are ca efect afiarea ariei triunghiului cu laturile de lungimi 3, 4, 5. Observa i ca nu este obligatoriu ca parametrii din apel s fie variabile, ci pot fi expresii. Dac func ia noastr ar aprea intr-o expresie ca 23*aria(3,4,5)2*aria(2,6,6), evaluarea expresiei ar ncepe cu executarea func iei aria pentru valorile 3, 4, 5 i apoi pentru 2, 6, 6; dup ce se ob in rezultatele celor doua apeluri ale func iei se realizeaz evaluarea celorlalte operatori (nmul irile i apoi scderea). Func ia n care apare un apel al altei func ii se numete func ie apelanta. Parametrii sunt de doua tipuri: parametri formali: valoare referin a (pointer) parametri efectivi (actuali) Parametrii sunt utiliza i pentru a putea transmite din func ia apelanta valorile necesare prelucrrilor efectuate de func ia apelata. Atunci cnd parametrii formali sunt utiliza i doar pentru a transmite valori n func ia apelata, aceti parametrii se numesc parametri valoare. Dac se dorete transmiterea ca parametru a unei variabile, n scopul modificrii valorii acesteia astfel nct modificarea s fie disponibila n func ia apelanta, avem de-a face cu un parametru formal referin a (se realizeaz printr-o variabila de tip pointer). Pentru a putea apela o func ie, trebuie s precizam, pe lng numele acesteia, valorile parametrilor pentru care se realizeaz apelul (parametri actuali). Numrul parametrilor actuali dintr-un apel de func ie trebuie s fie acelai cu numrul parametrilor formali din defini ia func iei apelate i s corespunda ca tip. De exemplu, n programul de mai sus, nu puteam apela func ia aria ca s = aria(4.56, 5, 5); deoarece primul parametru formal din defini ia func iei este definit ca de tip int, iar parametrul actual (4.56) este de tip double (incompatibilitate de tip). Nu este obligatoriu s existe parametrii formali intr-o func ie dac nu este nevoie. De asemenea, nu toate func iile ntorc o valoare. Aceste aspecte sunt tratate n urmtoarele exemple. Exemplul 2. S se scrie o func ie care afieaz pe ecran un numr dat de asteriscuri. void asterisc(int nr){ int j; for(j=1;j<=nr;j++) cout<<* ; } Func ia are un singur parametru formal, un ntreg nr reprezentnd numrul de asteriscuri ce trebuie afiate. Func ia poate fi apelata prin asterisc(10); care are ca efect afiarea a 10 asteriscuri.

Func ia nu ntoarce nici o valoare, deoarece nu este necesar (n-are sens s ntoarcem vreo valoare), deci codomeniul va fi tipul void. Din moment ce func ia nu ntoarce vreo valoare, nu se va mai utiliza return. Exemplul 3. Scrie i o func ie care s afieze un mesaj. void mesaj( ){ cout<<Triasc Reforma !!!; } Func ia mesaj nu ntoarce nici o valoare i nici nu con ine parametrii formali (nu exista valori care s fie necesare execu iei func iei). Apelul func iei se va face prin: mesaj(); exact ca i pentru func ia pre definit clrscr( ). Dac am dori ca func ia s afieze un mesaj dat, ob inem: void mesaj(char s[80]){ cout<<s; } Apelul func iei poate fi: mesaj("Triasc pacea i bunstarea poporului chinez !!!); Exemplul 4. Scrie i o func ie care stabilete dac un numr este prim. #include <iostream.h> int este_prim(int n){ int j; int este; este=1; //presupunem ca numrul este prim for(j=3;j*j<=n;j++) if(n%j==0) este=0; return este; } void main(){ int numr; cout<<Introduceti numrul=; cin>>numr; if(este_prim(numr)!=0) cout<<Numrul este prim !; else cout<<Numrul nu este prim !; } Exerci iul 1: Folosi i func ia este_prim pentru a afia toate numerele prime mai mici dect un numr ntreg dat. Exemplul 5. Scrie i o func ie care s citeasc un vector de numere ntregi.

28

void citeste(int a[30], int n) { int k; for(k=0;k<n; k++) cin>>a[k]; } Func ia are doi parametri: variabila de tip vector care va retine numerele citite i variabila n, care ne spune cate elemente trebuiesc citite. Func ia main poate s arate astfel: void main (){ int b[30]; int n; cout<<n=; cin>>n; citeste(a,n); } Exerci iul 6: Scrie i o func ie pentru afiarea elementelor unui vector i aduga i-o exemplului precedent. Exemplul 7. Scrie i o func ie care calculeaz suma elementelor dintr-un vector. int suma(int a[40], int n) { int k; int s; s=0; for(k=0;k<n;k++) s=s+a[k]; return s; } Este necesar s introducem ca parametru i numrul de elemente din vector n. Exerci iul 8: Folosi i func ia de mai sus n programul de la exerci iul precedent. Exemplul 9. Scrie i o func ie care calculeaz ax, unde a real i x ntreg pozitiv. float putere(float a, int x) { int k; int p; //retine puterea p=1; for(k=1;k<=x;k++) p=p*a; return p; } Exerci iul 10. Modifica i func ia din exemplul 7 astfel nct s poat ridica pe a i la puteri negative. Exemplul 11. Scrie i o func ie pentru a calcula cel mai mare divizor comun a 2 numere ntregi folosind algoritmul lui Euclid.

#include <iostream.h> int cmmdc(int m, int n){ int r; do{ r=m%n; m=n; n=r; }while(r!=0); return m; } void main(){ int a,b; cout<<"Primul numr="; cin>>a; cout<<"Al doilea numr="; cin>>b; cout<<cmmdc(a,b); } Exemplul 12 S se scrie o func ie care verifica dac un ntreg x apar ine unui vector v. int cauta(int v[50], int n){ int k; int apartine; apartine=0; //se presupune ca x nu este element n v for(k=0;k<n;k++) if(v[k]==x) apartine=1; return apartine; } Exemplul 13. S se scrie o func ie care realizeaz suma a doua matrice cu m linii i n coloane. void suma_mat(int a[20][20], int b[20][20], int c[20][20], int m, int n){ int j, k; //variabile contor n for for(j=0;j<m;j++) for(k=0;k<n;k++) c[j][k]=a[j][k]+b[j][k]; } Parametrii de care depinde rezolvarea sarcinii sunt: a - prima matrice b - a doua matrice c - matricea suma (rezultatul sumei) 29

m - numrul de linii n - numrul de coloane Exerci iul 5. S se scrie func ia main corespunztoare func iei de mai sus, precum i func ii pentru citirea i afiarea unei matrice. O situa ie interesanta apare atunci cnd vrem ca variabilele ce apar ca parametri formali s poat fi modificate n cadrul func iei, modificrile fiind disponibile n func ia apelanta. S luam urmtorul exemplu: Exemplul 14. S se scrie o func ie care interschimb valorile a doua variabile ntregi. Varianta urmtoare este greita: void schimba(int x, int y){ int temp; temp=x; x=y; y=temp; } void main(){ int a, b; cin>>a; cin>>b; schimba(a,b); cout<<a; cout<<b; } La prima vedere func ia pare corecta, insa lucrurile stau tocmai pe dos. Dac introducem valorile 5 pentru a i 7 pentru b, programul ar trebui s schimbe intre ele valorile celor doua variabile (a trebuie s devin 7, iar b s devin 5). Programul de mai sus nu va realiza acest lucru. Explica ia este ca, atunci cnd parametri formali sunt parametri valoare, chiar dac se modifica valoarea lor n cadrul func iei aceste modificri nu vor avea efect n func ia apelanta (n cazul nostru, n func ia main nu va fi sesizabila schimbarea realizata n func ia schimba). Problema se poate rezolva dac parametrii din func ia schimba vor fi parametri referin a (pointeri). Varianta corecta este urmtoarea: void schimba(int *x, int *y){ int temp; temp=*x; *x=*y; *y=temp; } Singura schimbare din func ia main este apelul func iei, care devine schimba(&a, &b); Explica ia corectitudinii acestei variante este aceea ca se lucreaz cu adresele variabilelor, deci orice modificare a con inutului zonelor de memorie alocate variabilelor x i y va fi resim it i n func ia main.

Parcurge i din nou exemplul 10 i privi i cu aten ie antetul func iei suma_mat. Parametrul formal c este o matrice calculata ca suma matricelor a i b, deci valoarea elementelor lui c este modificata n cadrul func iei, dar parametrul formal este corect? Rspunsul este afirmativ deoarece, dup cum ti i, tablourile sunt tratate exact ca i pointerii, deci tablourile care apar ca parametrii formali se considera parametri referin a.

30

Anexe
Recomandri pentru scrierea programelor
Conven ii generale de nume
Numele compuse reprezentnd tipuri de date ar fi bine s con in litere mari la nceputul fiecrui cuvnt component. Vector, StudentBursier Numele compuse reprezentnd variabile ar fi bine s nceap cu liter mic i s con in litere mari la nceputul fiecrui cuvnt component. contor, nrStud Astfel, variabilele se vor distinge uor de tipuri i se vor evita eventualele conflicte de nume, ca n declara ia: Line line. Numele de constante (inclusiv al celor folosite n enumerri) ar fi bine de scris cu litere mari n ntregime, utilizndu-se liniu a de subliniere pentru separarea cuvintelor componente. NR_MAX, SEMAFOR_ROSU, PI Numele compuse reprezentnd metode, ca i cele ale func iilor trebuie s descrie efectul respectivei metode sau func ii, recomandabil n format Camel Case (la nceput cu liter mic, apoi cu liter mare la nceputul fiecrui cuvnt component) sumElem(), maxVect(), obtNume(), calcLungTotala() Numele compuse reprezentnd spa ii de nume ar fi bine s con in n ntregime doar litere mici. analizor, managerdialog, fereastraprinc Numele pentru tipuri ablon ar fi bine s fie alctuite dintr-o singur majuscul. template<class T> template<class C, class D> ... Abrevierile i acronimele nu trebuie scrise cu majuscule atunci cnd intr n componen a unui nume. exportHtmlSource();// NU: exportHTMLSource(); openDvdPlayer(); // NU: openDVDPlayer(); Ar fi bine ca variabilele globale s fie totdeauna referite utiliz nd operatorul "::". ::ferPrinc.open(), ::contextApl.obtNume() n general, e bine de evitat folosirea variabilelor globale, acestea putnd fi nlocuite cu obiecte avnd un singur membru. Ar fi bine ca toate numele s fie scrise n romn (n orice caz, ntr-o aceeai limb). numeFisier; // NU: filNavn Engleza este limba general adoptat de comunitatea interna ional, ns este mai firesc ca programele destinate utilizatorilor romni s con in nume ct mai sugestive, n limba nativ. Ar fi bine ca variabilele cu domeniu mare de vizibilitate s aib nume mai lungi, iar cele cu domeniu mic de vizibilitate s aib nume scurte.

Este recomandat ca diversele variabile cu rol temporar sau de indici s aib nume scurte, aceasta fiind o indiciu pentru programator c ele nu sunt folosite dincolo de limita a ctorva linii de cod. Numele cel mai des folosite pentru astfel de variabile ntregi sunt: i, j, k, m, n, respectiv c sau d pentru cele de tip caracter. Numele unui obiect con ine de obicei numele clasei din care face parte, de aceea ar fi bine s se evite reluarea numelui clasei n numele date metodelor clasei. cerc.obtRaza(); // NU: cers.obtRazaCerc(); Inserarea numelui obiectului n numele metodelor pare natural n cadrul defini iei clasei, dar se dovedete de prisos la utilizarea efectiv, cum se poate vedea i din exemplul dat.

Conven ii specifice de nume


Termenii obtine/seteaza (obt/set, get/set) trebuie folosi i pentru metodele care acceseaz direct o dat membr a clasei. student.obtineNume(); matrice.obtElement(2, 4); angajat.seteazNume(nume); matrice.setElement(2, 4, val); Practic generalizat n comunitatea programatorilor C++. In Java aceast conven ie tinde s se standardizeze. Ar fi bine ca denumirile listelor de obiecte s con in sufixul List. stud (un student), studList (o list de studen i) Lizibilitatea programului crete de vreme ce numele unui obiect sugereaz imediat cititorului tipul i opera iile ce pot fi efectuate asupra lui. Ar fi bine de ataat prefixul nr variabilelor reprezentnd un numr de obiecte. nrPuncte, nrLinii Aceast nota ie este preluat din matematic. Ar fi bine ca variabilele iterative s fie numite i, j, k etc. Exemplu: for (int i = 0; i < nrLinii); i++) { ... } Aceast nota ie este preluat din matematic. Ar fi bine de ataat prefixul is variabilelor i func iilor booleene i de evitat nega iile din cadrul numelor acestora isSet, isVisible, isFinished, isFound, isOpen NU: isNotSet, isNotVisible, isNotFound etc. Practic generalizat n comunitatea programatorilor C++ i par ial impus n Java. Utilizarea acestui prefix mpiedic alegerea unor denumiri neinspirate de genul status sau flag pentru ac iunile booleene. Deoarece isStatus sau isFlag nu sun bine, programatorul va trebui s gseasc denumiri mai sugestive. De asemenea, apar confuzii atunci cnd un astfel de nume este folosit mpreun cu operatorul de nega ie logic, rezultnd o dubl nega ie. Opera iile opuse trebuie s aib denumiri antonime

31

obt/set, add/remove, creaza/distruge, start/stop, insert/delete, increment/decrement, old/new, begin/end, first/last, up/down, min/max, next/previous, old/new, open/close, show/hide, suspend/resume, etc. Complexitatea opera iei de asociere a unui nume cu semantica sa este redus datorit simetriei. Ar fi bine s fie evitate abrevierile n cadrul numelor. calculeazaMedia(); // NU: calcMed(); Trebuie avute n vedere dou tipuri de cuvinte. nti, cuvintele obinuite, care se gsesc n dic ionar. Acestea nu trebuiesc niciodat prescurtate. Nu scrie i niciodat: cmd n loc de comanda cp n loc de copie pt n loc de punct calc n loc de calculeaza init n loc de initializeaza etc. Apoi, expresiile din diferite domenii popularizate mai mult prin abrevieri/acronime ar fi bine de pstrat n aceste forme prescurtate ale lor. Nu scrie i niciodat: HypertextMarkupLanguage n loc de html CentralProcessingUnit n loc de cpu PriceEarningRatio n loc de pe etc. Constantele enumerative pot fi prefixate cu numele tipului lor comun. Exemplu: enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; Astfel sunt furnizate informa ii suplimentare despre locul unde poate fi gsit declara ia, setul de constante nrudite i conceptele reprezentate de constante.

class Student { public: float obtMedia () {return media} // NU! ... private: float media; } Astfel va fi uor de regsit fiierele asociate cu o clas dat. Con inutul unui fiier nu trebuie s depeasc 80 de coloane. 80 de coloane este o dimensiune generalizat pentru editoarele de text, emulatoarele de terminal, imprimante i debuggere, de aceea ar fi bine ca fiierele partajate de mai multe persoane s respecte aceast restric ie. Caracterele speciale de genul "TAB" sau "page break" trebuie evitate. Aceste caractere pot cauza probleme editoarelor de text, emulatoarelor de terminal, imprimantelor sau debuggerelor atunci cnd sunt folosite ntr-un mediu multi-programare sau multi-platform. Trebuie bine eviden iat faptul c o instruc iune se ntinde pe mai multe linii Atunci cnd o declara ie depete limita de 80 de coloane, ea este divizat pe mai multe linii. Este dificil de stabilit reguli rigide de divizare a liniilor, dar exemplele de mai sus dau o oarecare sugestie. n general: Se poate trece pe o linie nou dup o virgul Se poate trece pe o linie nou dup un operator Se aliniaz noua linie cu nceputul expresiei din linia precedent

Includerea de fiiere i includerea declara iilor


Fiierele antet trebuie s con in o construc ie care s previn incluziunile multiple. Conven ia este ca numele acestor construc ii s fie formate doar din litere mari i s fie compuse din numele modulului de program, numele fiierului i sufixul h. Exemple: #ifndef _LISTA_H #define _LISTA_H #endif Scopul este evitarea erorilor de compilare. Aceast conven ie de nume este deja generalizat. Ar fi bine ca aceast construc ie s fie plasat chiar la nceputul fiierului (naintea tuturor declara iilor). Astfel, se va renun a la parsarea fiierelor iar timpul de compilare va fi redus. Ar fi bine ca instruc iunile de includere s fie sortate (cresctor, dup pozi ia lor ierarhic n sistem) i grupate pe categorii (fiind lsat o linie liber ntre diversele grupe). Exemple:

Fiiere surs
Ar fi bine ca fiierele antet C++ s aib extensia .h. , iar fiierele surs extensia .cpp. 1_1.cpp, 1_1.h Acestea toate sunt standarde C++ adoptate deja pentru extensiile de fiiere. Ar fi bine ca o declara ia unei clase s se gseasc ntr-un fiier antet, iar defini ia ei - ntrun fiier surs, ambele cu un nume apropiat de cel al clasei. student.cpp, student.h Astfel va fi uor de regsit fiierele asociate cu o clas dat. Ar fi bine ca toate defini iile s se gseasc n fiiere surs.

32

#include <fstream> #include <iomanip> #include <Xm/Xm.h> #include <Xm/DateImp.h> #include "ui/ProprietatiDialog.h" #include "ui/FereastraPrincipala.h" Este sugerat astfel i ce module de program sunt implicate. Instruc iunile de includere trebuie s fie plasate doar la nceputul fiierului. Practic generalizat. Sunt evitate efectele secundare ale compilrii unor fiiere incluse datorit unor clauze #include ascunse printre liniile programului surs.

Tipuri de date
Tipurile de date locale unui singur fiier pot fi declarate n interiorul acelui fiier. Implic ascunderea informa iilor. Sec iunile unei clase trebuie s fie, n ordine, public, protected i private, fiecare trebuind eviden iat explicit. Celelalte eventuale sec iuni ar fi bine de lsat deoparte. Criteriul de ordonare este "cel mai public nti", astfel nct cei care doresc doar s utilizeze clasa tiu c e suficient s citeasc defini iile pn la ntnirea sec iunilor protected i private. Conversiile de tip trebuie fcute totdeauna explicit. Nu v ncrede i niciodat n conversiile implicite de tip. Exemple: medie = static_cast<float> nota // AA DA! valReala = valIntreaga; // AA NU! Prin aceasta programatorul indic folosirea contient a diferitelor tipuri i a amestecului lor.

Variabile
Ar fi bine ca variabilele s fie ini ializate acolo unde sunt declarate. Aceasta d siguran a c variabilele sunt valide n orice moment. Uneori este imposibil ca variabilele s fie ini ializate cu o valori valide chiar n momentul declarrii lor: int x, y, z; obtCentru (&x, &y, &z); n astfel de cazuri este preferabil varianta neini ializrii dect ini ializarea cu valori nepotrivite. Variabilele nu trebuie s aib niciodat un n eles dual. Asigurndu-se o reprezentare unic pentru fiecare concept, crete lizibilitatea programului i se reduce riscul erorilor datorate efectelor secundare Ar fi bine ca utilizarea variabilelor globale s fie minimizat. n C++ nu exist nici un motiv special pentru utilizarea acestor variabile. Acelai lucru este valabil pentru func iile globale i pentru variabilele statice. Ar fi bine ca variabilele membre ale unei clase s nu fie declarate niciodat public.

Conceptele C++ de ascundere a informa iilor i de ncapsulare sunt violate prin folosirea variabilelor public. n locul lor ar putea fi folosite variabile private i metode de accesare a acestora. Exist o singur excep ie de la aceast regul: n clasele reprezentnd structuri de date neomogene (echivalentul unor struct din C) este mai indicat declararea variabilelor drept public. Re ine i faptul c tipul struct este men inut n C++ doar din motive de compatibilitate cu C, iar evitarea lui va spori lizibilitatea programului. n loc de acesta ar putea fi folosi class. Variabilele nrudite de acelai tip pot fi declarate mpreun[3]. Ar fi bine ca pentru variabilele nenrudite s nu se foloseasc o aceeai declara ie. Exemplu: float x, y, z; int bursaIanuarie, bursaFebruarie, bursaMartie; Cerin a general de a scrie declara iile pe linii separate nu se aplic situa iilor de genul celor de mai sus. Grupndu-se variabilele astfel, crete lizibilitatea. Ar fi bine ca simbolul ce indic o referin sau un pointer C++ s fie scris lng numele variabilei i nu lng numele tipului de dat. Exemplu: float *x; // NU: float* x; int &y; // NU: int& y; Este discutabil dac un pointer este o variabil de un tip pointer (float* x) sau un pointer la un tip dat (float *x). Recomandarea de mai sus se bazeaz pe faptul c este imposibil s indici mai mult dect un pointer ntr-o declara ie de primul fel. De exemplu, float* x, y, z; este echivalent cu float *x; float y; float z;. Acelai lucru este valabil pentru referin e. Ar fi bine ca testele implicite de egalitate cu 0 s nu fie folosite dect pentru variabilele booleene i pointeri. Exemplu: if (nrLinii != 0) // NU: if (nrLinii) if (valoare != 0.0) // NU: if (valoare) Valorile 0 (nule) pentru variabilele ntregi i reale nu sunt n mod necesar implementate de compilator prin valoarea binar 0. De asemenea, un test explicit sugereaz imediat tipul testat. Pentru pointeri s-a generalizat practica testelor implicite de egalitate cu 0 (de ex. "if (line == 0)" n loc de "if (line)"), totui pot fi folosite i testele explicite. Ar fi bine ca variabilele s fie declarate cu cel mai mic domeniu de vizibilitate posibil. Astfel sunt mai uor de controlat ac iunile i efectele secundare ale variabilelor.

Bucle repetitive
n construc ia for() trebuiesc incluse doar instruc iuni de control a buclei repetitive. Exemplu:

33

sum = 0; // NU: for (i = 0, sum = 0; i < 100; i++) for (i = 0; i < 100; i++) sum += value[i]; Programul devine mai uor de ntre inut i de citit, fiind astfel clar care variabile controleaz bucla i care instruc iuni o alctuiesc. Ar fi bine ca variabilele iterative s fie ini ializate imediat nainte de bucla repetitiv. Exemplu: terminat = false; // NU: bool terminat = false; while (!terminat) { // ... } Aceste construc ii pot fi comparate cu instruc iunile goto i de aceea este bine s fie utilizate doar atunci cnd ofer o mai mare claritate dect corespondentele din programarea structurat. Pentru buclele infinite ar fi bine de folosit forma while(true). Exemplu: while (true) { } for (;;) { // NU! } while (1) { // NU! } while (1) nu este prea sugestiv i cu att mai pu in for (;;), care pare a se referi la o bucl infinit.

Exemplu: isError = readFile (fileName); if (!isError) { } else { } Asigura i-v c a i luat n calcul toate excep iile care ar putea mpiedica execu ia normal a programului. Este important att pentru claritate ct i pentru performan . Ar fi bine ca expresia condi ional s se gseasc pe o linie separat. Exemplu: if (isDone) // NU: if (isDone) doCleanup(); doCleanup(); Explica ia este legat de claritate i de ra iuni de debug: este mai greu de evaluat o expresie care se afl pe aceeai linie cu alte instruc iuni. Trebuie evitate instruc iunile executabile n interiorul expresiilor condi ionale. Exemplu: // Ru! if (!(fileHandle = open (fileName, "w"))) { } // Mult mai bine! fileHandle = open (fileName, "w"); if (!fileHandle) { } Mai ales pentru programatorii C++ nceptori astfel de expresii condi ionale ar fi foarte greoaie.

Expresii i instruc iuni condi ionale


Expresiile condi ionale complexe trebuie evitate. n locul lor se pot folosi variabile booleene temporare. Exemplu: if ((nrElem < 0) || (nrElem > maxElem)|| nrElem == ultElem) { } ar putea fi nlocuite prin: terminare = (nrElem < 0) || (nrElem > maxElem); repetare = (nrElem == ultElem); if (terminare || repetare) { } Asignnd variabile booleene (cu nume sugestive) expresiilor, programul devine mai explicit. Ar fi bine ca situa ia nominal (fireasc) s fie tratat pe ramura then iar excep ia pe ramura else a unei instruc iuni if [1].

Altele
Ar fi bine s fie evitate n program numerele "magice" (cu alte valori dect 0 sau 1), fiind indicat s se foloseasc n locul lor constante declarate la nceputul programului. Dac un numr nu are prin el nsui o semnifica ie evident, e indicat s fie nlocuit printrun nume de constant sau printr-o func ie care s-i acceseze valoarea. Trebuie totdeauna precizat explicit tipul returnat de o func ie. Exemplu: int getValue(){ // NU: getValue() } Dac nu este precizat explicit, C consider drept int tipul returnat de o func ie. Acest lucru poate s nu fie cunoscut ns de cei care vor citi programul. Ar fi bine s nu fie utilizat instruc iunea goto. 34

Instruc iunile goto contravin ideii de cod structurat. Doar n foarte pu ine cazuri pot fi avute n vedere (de exemplu pentru ieirea for at dintr-un set foarte adnc de stucturi imbricate) i doar dac nu pot fi rescrise ntr-un cod structurat mai clar. Trebuie utilizat "0" n loc de "NULL". NULL face parte din biblioteca C standard, ns n C++ este deja demodat.

if (condi ie){ instruc iuni; }

Macheta unei instruc iuni


Ar fi bine ca dimensiunea unei indentri s fie de 2 spa ii. Exemplu: for (i = 0; i < nrElem; i++) a[i] = 0; Indentarea cu 1 caracter este prea mic pentru a eviden ia macheta logic a codului. O indentare cu mai mult de 4 caractere ar ngreuia citirea structurilor imbricate i ar crea ansa ca o instruc iune s se ntind pe mai multe linii. Ar fi bine ca macheta unei instruc iuni s arate ca n exemplul 2 de mai jos (recomandat) sau ca n exemplul 1, ns n nici un caz nu trebuie s arate ca n exemplul 3. Exemple: while (!done) { doSomething(); done = moreToDo(); } while (!done) { done = moreToDodoSomething(); done = moreToDo(); } while (!done) { doSomething(); done = moreToDo(); } Exemplul 3 introduce un nivel suplimentar de indentare care nu eviden iaz la fel de clar ca primele dou exemple structura logic a codului. Emacs prefer varianta 3, VisualC varianta 2, iar nceptorii o prefer pe prima (mai ales cei care au lucrat n Pascal). Ar fi bine ca o instruc iune if-else s fie scris sub urmtoarea form: Exemple:

if (condi ie){ instruc iuni; } else{ instruc iuni; } Scrierea fiecrei pr i a instruc iunii if-else pe linii separate permite o mai uoar citire i manipulare a ei (de ex., renun area la clauza else). Ar fi bine ca o instruc iune for s fie scris sub urmtoarea form: Exemplu: for (ini ializare; condi ie; actualizare){ instruc iuni; } La fel, decurge par ial din regula general pentru structura unui bloc. Ar fi bine ca o instruc iune for cu bucla vid s fie scris sub urmtoarea form: Exemplu: for (ini ializare; condi ie; actualizare) { } Astfel este eviden iat faptul c instruc iunea for este construit n mod inten ionat cu bucla vid. Totui, ar fi bine ca buclele vide s fie evitate. Ar fi bine ca o instruc iune while s fie scris sub urmtoarea form: Exemplu: while (condi ie){ instruc iuni; } La fel, decurge par ial din regula general pentru structura unui bloc. Ar fi bine ca o instruc iune do-while s fie scris sub urmtoarea form: Exemplu: do{ instruc iuni; } while (condi ie); La fel, decurge par ial din regula general pentru structura unui bloc. Ar fi bine ca o instruc iune switch s fie scris sub urmtoarea form: Exemplu:

if (condi ie){ instruc iuni; } else if (condi ie){ instruc iuni; } else{ instruc iuni; }

35

switch (condi ie) { case ABC : instruc iuni; // Se execut i urmtoarele instruc iuni pn la primul break case DEF : instruc iuni; break; case XYZ : instruc iuni; break; default : instruc iuni; break; } Observa i faptul c fiecare cuvnt rezervat case este indentat relativ la cuvntul rezervat switch, ceea ce conduce la eviden ierea instruc iunii switch ca ntreg. Observa i, de asemenea, spa iul dublu care precede caracterul ":". Dac instruc iunea break lipsete de pe o ramur case, ar fi bine s apar n locul ei un comentariu pentru a se ti c ignorarea ei a fost inten ionat. Ar fi bine ca o instruc iune try-catch s fie scris sub urmtoarea form: Exemplu: try { instruc iuni; } catch (Exception excep ie) { instruc iuni; } La fel, decurge par ial din regula general pentru structura unui bloc. Ramurile instruc iunilor if-else i buclele intruc iunilor for sau while formate dintr-o singur instruc iune pot fi scrise fr paranteze acolade. Exemplu: if (condi ie) instruc iuni; while (condi ie) instruc iuni; for (ini ializare; condi ie; actualizare) instruc iuni; Exist recomadarea general (de ex., din partea firmei Sun) ca parantezele acolade s fie utilizate n toate cazurile. Totui, scopul parantezelor e acela de a grupa mai multe instruc iuni i nu una singur.

Spa iile albe


Ar fi bine ca: operatorii conven ionali s fie ncadra i de cte un caracter spa iu; dup fiecare cuvnt rezervat s urmeze un spa iu; virgulele s fie urmate de un spa iu; operatorul : s fie ncadrat de cte un caracter spa iu; dup fiecare operator ; s urmeze un spa iu. Exemplu: a = (b + c) * d; // NU: a=(b+c)*d while (true) {// NU: while(true) ... doSomething (a, b, c, d); // NU: doSomething (a,b,c,d); case 100 : // NU: case 100: for (i = 0; i < 10; i++) { // NU: for (i=0;i<10;i++){ Astfel, fiecare component individual a unei instruc iuni este pus n eviden , iar lizibilitatea programului n ansamblu crete. Ar fi bine ca n func iile care au parametri s fie plasat un caracter spa iu dup "(" i nainte de ")". Exemplu: doSomething( params ) // NU: doSomething(params); Astfel, fiecare nume n parte este eviden iat, crescnd lizibilitatea programului. Dac o func ie nu are parametri, spa iul poate fi omis (doSomething()) de vreme ce nu este posibil nici o confuzie asupra numelui n acest caz. Ar fi bine ca unit ile logice din cadrul unui bloc s fie separate printr-o linie goal. Crete astfel lizibilitatea programului. Ar fi bine ca, n cadrul declara iilor, variabilele s fie aliniate la stnga. Exemplu: AsciiFile *file; int nrPuncte; float x, y; Crete astfel lizibilitatea programului. Numele variabilelor sunt astfel mai uor de distins de numele tipurilor lor. Exist i opinia contrar c aceste constructii sunt "fragile" atunci cnd codul evolueaz i poate transforma programatorul ntr-o main de formatat. Recurge i la aliniere oriunde aceasta sporete lizibilitatea programului. Exemplu: 1. 2. 3. 4. 5.

36

If (a == lowValue) compueSomething(); else if (a == mediumValue) computeSomethingElse(); else if (a == highValue) computeSomethingElseYet();

while (true){ // Efectueaza ceva prelucrare(); } // NU: while (true) { // Efectueaza ceva prelucrare(); } Se evit astfel deteriorarea structurii logice a programului din cauza comentariilor.

value = (potential * oilDensity) / constant1 + (depth * waterDensity) / constant2 + (zCoordinateValue * gasDensity) / constant3;

minPosition = computeDistance (min, x, y, z); averagePosition = computeDistance (average, x, y, z);

switch (value) { case PHASE_OIL : strcpy (string, "Oil"); break; case PHASE_WATER : strcpy (string, "Water"); break; case PHASE_GAS : strcpy (string, "Gas"); break; } Exist mai multe locuri ntr-un program unde pot fi plasate spa ii (n general n scopul alinierii) pentru a se spori lizibilitatea, chiar dac astfel se contravine regulilor generale de scriere. Este dificil de formulat reguli privind alinierea codului, ns exemplele de mai sus ajut la formarea unei idei.

Bibliografie:
[1] Code Complete, Steve McConnel - Microsoft Press [2] Programming in C++, Rules and Recommendations, M Henricson, e. Nyquist, Ellemtel (Swedish telecom) [3] Wildfire C++ Programming Style, Keith Gabryelski, Wildfire Communications Inc. [4] C++ Coding Standard, Todd Hoff http://www.doc.ic.ac.uk/lab/cplus/c++.rules/ http://www.wildfire.com/~ag/Engineering/Development/C++Style/ http://www.possibility.com/Cpp/CppCodingStandard.html

Comentariile
Ar fi bine nu s comenta i codul care con ine capcane de programare, ci s-l rescrie i! n general, utilizarea comentariilor va fi minimizat la maxim dac se scrie codul ntr-un mod foarte clar, utilizndu-se nume sugestive i o structur logic explicit. Ar fi bine ca toate comentariile s fie scrise n limba englez. Engleza este limba preferat n orice mediu interna ional. Folosi i "//" pentru toate comentariile, inclusiv pentru cele care se ntind pe mai multe linii. Exemplu: // Comentariu ce se ntinde // pe mai multe linii. De vreme ce n limbajul C nu sunt permise comentariile avnd mai multe nivele, utilizarea simbolului // face posibil ataarea de comentarii tuturor sec iunilor programului. Simbolurile /* */ vor fi folosite n scopul depanrii (eng. debug) (pentru a se verifica func ionarea unei sec iuni a programului, celelalte sec iuni pot fi marcate temporar drept comentarii) etc. Ar fi bine s existe un spa iu ntre "//" i comentariul propriu-zis, care ar fi bine s nceap cu liter mare i s se termine cu punct. Ar fi bine s alinia i comentariile relativ la pozi ia codului la care ele se refer. Exemplu:

Anexe Elemente de algebr boolean


Generalit i
Transferul, prelucrarea i pstrarea datelor numerice sau nenumerice n interiorul unui calculator se realizeaz prin intermediul circuitelor de comutare. Aceste circuite se caracterizeaz prin faptul c prezint dou stri stabile care se deosebesc calitativ ntre ele. Strile sunt puse n coresponden cu valorile binare 0 i 1 sau cu valorile logice adevrat i fals (din acest motiv se mai numesc i circuite logice). Pornind de la aceste considerente, un domeniul al logicii matematice, (tiin a care utilizeaz metode matematice n solu ionarea problemelor de logic) numit algebra logicii i-a gsit o larg aplicare n analiza i sinteza circuitelor logice. Algebra logicii opereaz cu propozi ii care pot fi adevrate sau false. Unei propozi ii adevrate i se atribuie valoarea 1, iar unei propozi ii false i se atribuie valoarea 0. O propozi ie nu poate fi simultan adevrat sau fals, iar dou propozi ii sunt echivalente din punct de vedere al algebrei logice, dac simultan ele sunt adevrate sau false. Propozi iile pot fi simple sau compuse, cele compuse ob inndu-se din cele simple prin legturi logice de tipul conjunc iei , disjunc iei sau nega iei . 37

Bazele algebrei logice au fost puse de matematicianul englez George Boole (18151864) i ca urmare ea se mai numete i algebr boolean. Ea a fost conceput ca o metod simbolic pentru tratarea func iilor logicii formale, dar a fost apoi dezvoltat i aplicat i n alte domenii ale matematicii. n 1938 Claude Shannon a folosit-o pentru prima dat n analiza circuitelor de comuta ie.

Definirea axiomatic a algebrei booleene


Algebra boolean este o algebr format din: elementele {0,1}; }
Obs. Acestea se mai pot numi Adevrat (engl. True) respectiv Fals (engl. False), Pornit (engl. On) respectiv Oprit (engl. Off)

5. Dac mul imea M nu con ine dect dou elemente, acestea trebuie s fie obligatoriu elementul nul 0 i elementul unitate 1; atunci pentru x M exist un element unic notat cu x cu propriet ile: x x = 0 principiul contradic iei x + x = 1 principiul ter ului exclus x este inversul elementului x. n definirea axiomatic a algebrei s-au folosit diferite nota ii. n tabelul urmtor se dau denumirile i nota iile specifice folosite pentru diverse domenii: Matematic Prima lege de compozi ie x1 + x2 A doua lege de compozi ie x1 x2 Elementul invers Logic Disjunc ie x1 x2 Conjunc ie x1 x2 Negare x Tehnic SAU x1 + x2 SI x1 x2 NU

dou opera ii binare numite SAU (OR engl.) notat simbolic + sau respectiv I (AND engl.) notate simbolic prin sau ; opera ie unar numit NU nega ie, notat simbolic printr-o bar deasupra a ceea ce se neag sau cu simbolul . Opera iile se definesc astfel: i Sau Nu Sau exclusiv 0+0=0 00=0 0 = 1 0 0 = 0 0+1=0 01=0 1 = 0 0 1 = 1 1+0=0 10=0 1 0 =1 1+1=1 11=1 11 = 0 Axiomele algebrei booleene sunt urmtoarele: Fie o mul ime M compus din elementele x1, x2,xn, mpreun cu opera iile i +. Aceast mul ime formeaz o algebr dac: 1. Mul imea M con ine cel pu in 2 elemente distincte x1 x2 (x1,x2 M); 2. Pentru x1 M, x2 M avem: x1 + x2 M i x1 x2 M 3. Opera iile i + au urmtoarele propriet i: a. sunt comutative x1 x2 = x2 x1 x1 + x2 = x2 + x1 b. sunt asociative x1 (x2 x3) = (x1 x2) x3 x1 + (x2 + x3) = (x1 + x2) + x3 c. sunt distributive una fa de cealalt x1 (x2 + x3) = x1 x2 + x1 x3 x1 + (x2 x3) = (x1 + x2) (x1 + x3) 4. Ambele opera ii admit cte un element neutru cu proprietatea: x1 + 0 = 0 + x1 = x1 x1 1 = 1 x1 = x1 unde 0 este elementul nul al mul imii, iar 1 este elementul unitate al mul imii.

Propriet ile algebrei booleene


Plecnd de la axiome se deduc o serie de propriet i care vor forma reguli de calcul n cadrul algebrei booleene. Aceste propriet i sunt: 6. Principiul dublei nega ii x = x dubla nega ie duce la o afirma ie 7. Idempoten a xx=x x+x=x 8. Absorb ia x1 (x1 + x2) = x1 x1 + (x1 x2) = x1 9. Propriet ile elementelor neutre x0=0 x1=x x+0=x x+1=1 10. Formulele lui De Morgan

x1 x 2 = x1 + x 2

x1 + x 2 = x1 x 2
Aceste formule sunt foarte utile datorit posibilit ii de a transforma produsul logic n sum logic i invers. Formulele pot fi generalizate la un numr arbitrar de termeni: 38

x1 x 2 ... x n = x1 + x 2 + ... + x n x1 + x 2 + ... + x n = x1 x 2 ... x n


11. Principiul dualit ii dac n axiomele i propriet ile algebrei booleene se interschimb 0 cu 1 i + cu , sistemul de axiome rmne acelai, n afara unor permutri. Verificarea propriet ilor se poate face cu ajutorul tabelelor de adevr i cu observa ia c dou func ii sunt egale dac iau aceleai valori n toate punctele domeniului de defini ie. Prin tabelul de adevr se stabilete o coresponden ntre valorile de adevr ale variabilelor i valoarea de adevr a func iei. Obs. Comutativitatea i asociativitatea pot fi extinse la un numr arbitrar, dar finit, de termeni, indiferent de ordinea lor.

1 1

1 1

0 1

0 0

1 0

0 0

0 0

0 0

1 1

0 1

1 0

1 1

Baze de numera ie
Omul, din cele mai vechi timpuri ncerca s realizeze msurtori sau compara ii. Deoarece n elesurile "mai nalt ca" sau" mai mare ca" nu erau suficiente a trebuit s introduc numere pentru a putea exprima aceste lucruri. Era uor de spus c un obiect era de dou ori mai mic ca altul sau de trei ori mai valoros. Aceste compara ii sau msurtori se fceau uneori ntre obiecte destul de diferite ntre ele i erau specifice trocului. (ex. i dau 8 buc i mari de sare pentru un miel etc.). n vechime oamenii socoteau pe degetele de la mini, astfel c avnd zece degete erau capabili s realizeze opera ii cu valori pn la zece. Evident c, pentru a nu ine minte prea multe lucruri trebuiau s-i noteze calculate realizate. Exist mai multe solu ii care rezolvau problema. Cea mai simpl spunea c trebuie scris cte un semn pentru fiecare unitate (de ex. pentru 3 obiecte erau desenate fie | | |, fie ooo sau orice alt semn). Pentru a putea reprezenta valori mai mari, trebuiau pur si simplu scrise prea multe astfel de simboluri. Cu cat valoarea de reprezentat era mai mare rea nevoie de o repetare a mai multor simboluri de acelasi fel (v imaginati ct de fericiti a i fi sa desena i o suta de linii pentru a repezenta valoarea 100). Pentru a simplifica reprezentarea trebuiau nscocite alte simboluri care s reprezinte valorile mai mari. Astfel, romanii foloseau diferite simboluri pentru a indica diferite "ponderi" ale valorilor (ex. V pentru 5, X pentru 10, L pentru 50...). Aceast metod s-a dovedit a fi greoaie deoarece opera iile simple erau destul de greu de realizat (de exemplu aduna i MCLIV cu CMIX). O alt idee era de a folosi cte un simbol diferit pentru fiecare valoare de reprezentat (este ca si cum ai identifica grafic fiecare deget de la mna), scrierea arab (care de fapt este la origine chinezeasc i care este cea folosit n zilele noastre) este un astfel de exemplu. Astfel avem simbolurile 0, 1, 2, 3,, 9 (deci n total 10) care fiecare are o valoare diferit (de la 0 care nu are valoare pn la 9 practic fiecare deget de la mn avea un simbol primul deget 1 al doilea 2 etc. iar ultimul al zelelea 0). Scrierea pe acre o folosim noi (arab) este una pozitional adic de exemlu numerele mai mari ca 10 erau scrise pe pozi ia a doua sau mai mare n numr (astfel c de fapt 23 nu nsemna 2 obiecte i nc 3 ci de dou ori 10 obiecte i nc 3). Acest stil de a scrie valori este folosit i n zilele noastre i este cunoscut de ctre toat lumea. Un numr de mai multe cifre scris n baza 10 de forma:

Tabele de adevr
Unei func ii booleene cu n variabile i putem asocia un tabel care are 2n + 1linii care corespund celor 2n combina ii posibile ale variabilelor, precum a n+1 coloane care reprezint cele n variabile plus una care reprezint valorile corespunztoare ale func iei. De exemplu pentru func ia F(x,y)=x+y avem 2 variabile deci vom vrea un tabel cu 5 linii si 3 coloane x y F(x,y)=x+y 0 0 0 0 1 1 1 0 1 1 1 1 In cazul care func ia boolean este exprimat sub forma de expresie, pentru a ajunge la tabelul de adevr trebuie realizate mai multe calcule prin care s ne dm seama care este tabelul de adevr corespunztor func iei date. De exemplu func ia: f ( x, y , z ) = x y + x y + x z pentru a ajunge la tabelul de adevr trebuie s realizm mai multe calcule ntr-un mod asemntor unor calcule algebrice obinuite numai c folosind regulile si principiile algebrei booleene. Pentru c n formularea func iei apare negatul pentru z si pentru z n primul rnd vom calcula acele valori apoi succesiv vom construi tabelul de adevr pentru func ia dat. Pentru aceasta

x n x( n +1) ...x0
poate fi vzul ca o sum de produse de forma
x a 0 0 0 0 1 1 y b 0 0 1 1 0 0 z c 0 1 0 1 0 1
y

(1) (2)

xy

xy

x y + xy

x y + xy

xz
j = a e

xz
k = j

F
l =i+k

d 1 1 0 0 1 1

e 1 0 1 0 1 0

f = a b g = a d

h= f +g

i=h

x n * 10 n + x n +1 * 10 n 1 + ... + x0 * 10 0

0 0 1 1 1 1

0 0 0 0 1 1

0 0 1 1 1 1

1 1 0 0 0 0

1 0 1 0 0 1

0 1 0 1 1 0

1 1 0 1 1 0

Se observ c, n expresia de mai sus valoarea 10 este constant i de fapt reprezint baza de numera ie folosit. Baza de numera ie este o valoare care indic numrul de simboluri folosite pentru a reprezenta un numr. Un numr care este scris n baza de numera ie b 39

y n y ( n +1) ... y 0 (b )
are forma de mai jos.

(3)

Transformarea numerelor ntregi din baza 10 n alt baz de numera ie


Pentru aceast ac iune, inem cont de faptul c un numr scris n baza 10 de fapt reprezint o cantitate egal cu valoarea scris. El trebuie regrupat pentru a putea fi reprezentat n alt baz de numera ie. Opera ia se realizeaz prin mpr iri succesive ale cturilor rezultate la noua baz de numera ie. Procednd astfel vom ob ine rezultatul scontat, citind invers toate resturile ob inute Exemplu1: 292(10)=?(6) Rezultatul final este 1204(6) 292 6 24= 48 6 =52 48 8 6 =48 =0 6 1 6 ==4 2 0 0 1 Exemplul2: 2575(10)=?(16)
2575 16== =97= =96= ==15 ===0 ==15(F) 16 160 16 ==0 16 10 =0 10(A) 16 0

y n * b n + y n+1 * b n 1 + ... + y 0 * b 0 (4)


O baz de numera ie <10 va folosi mai pu ine simboluri (de exemplu baza de numera ie 7 va folosi doar 7 simboluri 0, 1, 2, 3, 4, 5, i 6), iar >10 va avea mai multe (de exemplu baza 15 are nevoie de 15 simboluri). Pentru c nu exist dect 10 simboluri pentru a reprezenta cifre i nu putem folosi dect un singur simbol pentru reprezentare (deoarece n caz contrar sar crea confuzie) pentru fiecare cifr n parte, dei putem folosi orice fel de simbol pentru a reprezenta cifre a cror valoare este mai mare ca 10, totui vom utiliza litere (majuscule sau minuscule de fapt nu conteaz) pentru a reprezenta simbolurile lips. Astfel pentru baza 15 vom avea 15 simboluri i anume 0, 1, 2, 3, 4, 5, 6,7, 7, 8, 9, A, B, C, D, E (A va nlocui un simbol care va avea valoarea 10 i va fi al unsprezecelea simbol de reprezentare, B-11, C-12, etc.). Exemple de numere corecte sunt 123(5), 7A3(11) etc. Exemple de numere scrise greit sunt 264(5), 73X2(16), deoarece simbolurile 6 respectiv X nu exist n bazele de numera ie 5 respectiv 16.

Transformarea numerelor ntregi din alt baz de numera ie n baza 10


Pentru aceast ac iune, plecm de la prezentarea unui numr n baza de numera ie b conform (4). Pentru a transforma un numr ntreg din orice baz de numera ie n baza zece trebuie s desfacem grupele prin care a fost scris numrul respectiv. Astfel nu avem nimic de fcut altceva dect s calculm n baza 10 valoarea final folosind pentru aceasta formula (4) Exemplu: 745(8)=7*82+4*81+5*80 adic =7*64+4*8+5=448+32+5=485(10) Un caz mai complicat este dac baza de numera ie este mai mare ca zece i cuprinde numere a cror valoare este mai mare ca zece Exemplu: 3CB(15)=3*152+C*151+B*150=3*225+12*15+ 11*1=675+180+11=866(10) 60B(16)=6*162+0*161+B*160=1536+0+11 =1547(10) Pentru aceste trasformri este important sa va reamintiti faptul cifrele din numr sunt pozi ionale i nu trebuie transformate individual n baza 10 de exemplu este gresit s realizm transformarea astfel: 60B(16)=6011(16)=6*163+0*162+1*161+1*160=

Observnd c 10 corespunde simbolului A i 15 simbolului F rezultatul final este A0F(16) Pentru aceste trasformri este important sa va reamintiti faptul cifrele din numr sunt pozi ionale i deci resturile mpr irii trebuie transformate individual n noua baz de numera ie de exemplu este gresit s realizm transformarea de mai sus 2575(10)=?(16) astfel: 2575(10)=10015(16)

Cazuri speciale de transformri


Se tie c, toate calculatoarele func ioneaz n baza de numera ie 2, adic simbolurile folosite de calculator sunt doar 0 i 1. Acest lucru deranjeaz destul de mult, deoarece oamenii sunt obinui i cu baza de numera ie 10 i le este foarte greu s foloseasc noua baz de numera ie. Pentru ca programarea s fie mai uoar trebuia gsit o cale de compromis. Aceast cale ar fi utilizarea bazelor de numera ie 8 sau 16 care sunt relativ apropiate de baza 10 i pe de alt parte permit o schimbare uoar de baz. Observm c 8=23 sau c 16=24. Acest lucru este foarte important pentru c puterile lui doi au o anumit semnifica ie (artat mai jos).

40

Se tie ca folosind o cifr, n baza b putem ob ine b valori diferite (adic dou pt. baza 2, cincisprezece pentru baza 15 etc.). Folosind dou cifre vom ob ine b2 valori deoarece vom ob ine pentru fiecare valoare posibila pentru a doua cifr b valori prin modificarea primei cifre adic b*b sau b2. De exemplu pentru baza 3 vom ob ine 9 valori, pentru baza 2 patru valori etc. Generaliznd, pentru o valoare de n cifre scris n baza b vom ob ine bn valori. Comparnd baza 8 cu baza 2 vom observa ca un numr de 3 cifre din baza doi are tocmai opt valori posibile (nici mai multe nici mai pu ine). La fel baza 16 se echivaleaz cu un numr de patru cifre n baza 2. Ne existnd alte valori, trecerea din baza 2 n baza 8 sau 16 se face doar prin grupri de cifre. Pentru uurin n calcul putem folosi dou tabele, cu ajutorul crora putem realiza direct echivalarea. Baza 2 Baza 8 Baza 2 Baza 16 000 0 0000 0 001 1 0001 1 010 2 0010 2 011 3 0011 3 100 4 0100 4 101 5 0101 5 110 6 0110 6 111 7 0111 7 1000 8 1001 9 1010 A 1011 B 1100 C 1101 D 1110 E 1111 F Exemple: 1100111000111011011101110010101(2)=?(8) pentru a realiza transformarea din baza 2 n baza 8 vom grupa tot cate trei cifre binare ncepnd de la dreapta spre stnga, iar dac pentru ultima grup nu sunt destule cifre atunci vom completa grupul cu zerouri. 001 100 111 000 111 011 011 101 110 010 101 1 4 7 0 7 3 3 5 6 2 5 =14707335625(8)
110.0111.0001.1101.1011.1010.0011.1001.0101(2)=?(16)

Tabela de Coduri ASCII


Caracterele SCII sunt mpr ite n: caractere grafice (adic acele caractere care pot fi reprezentate printr-un simbol grafic) intervalul [33,126] precum i caractere negrafice care cuprind valorile {[0,32], 127} Coduri ASCII n zecimal 000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 NUL SOH STX ETX EOT ENQ ACK BEL BS HT NL VT NP CR SO SI 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 SP ! " # $ % & ' ( ) * + , - . / 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 @ A B C D E F G H I J K L M N O 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 P Q R S T U V W X Y Z [ \ ] ^ _ 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 ` a b c d e f g h i j k l m n o 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 p q r s t u v w x y z { | } ~ DEL Coduri ASCII n hexazecimal 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F NUL SOH STX ETX EOT ENQ ACK BEL BS HT NL VT NP CR SO SI 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F SP ! " # $ % & ' ( ) * + , - . / 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ A B C D E F G H I J K L M N O 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F P Q R S T U V W X Y Z [ \ ] ^ _ 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F ` a b c d e f g h i j k l m n o 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F p q r s t u v w x y z { | } ~ DEL Coduri ASCII n octal 000 001 002 003 004 005 006 007 010 011 012 013 014 015 016 017 NUL SOH STX ETX EOT ENQ ACK BEL BS HT NL VT NP CR SO SI 020 021 022 023 024 025 026 027 030 031 032 033 034 035 036 037 41

pentru a realiza transformarea din baza 2 n baza 16 vom grupa tot cate patru cifre binare ncepnd de la dreapta spre stnga, completnd de asemenea ultimul grup cu zerouri. 0110 0111 0001 1101 1011 1010 0011 1001 0101 6 7 1 D B A 3 9 5 =671DBA395(16) Observa ie: Folosind combinat metoda descris mai sus este foarte uor de convertit un numr din baza 8 n baza 16 sau invers folosind baza 2 ca intermediar.

DLE DC1 DC2DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US 040 041 042 043 044 045 046 047 050 051 052 053 054 055 056 057 SP ! " # $ % & ' ( ) * + , - . / 060 061 062 063 064 065 066 067 070 071 072 073 074 075 076 077 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 100 101 102 103 104 105 106 107 110 111 112 113 114 115 116 117 @ A B C D E F G H I J K L M N O 120 121 122 123 124 125 126 127 130 131 132 133 134 135 136 137 P Q R S T U V W X Y Z [ \ ] ^ _ 140 141 142 143 144 145 146 147 150 151 152 153 154 155 156 157 ` a b c d e f g h i j k l m n o 160 161 162 163 164 165 166 167 170 171 172 173 174 175 176 177 p q r s t u v w x y z { | } ~ DEL

SYN ETB CAN EM SUB ESC FS GS RS US SP

22 23 24 25 26 27 28 29 30 31 32

16 17 18 19 1a 1b 1c 1d 1e 1f 20

26 27 30 31 32 33 34 35 36 37 40

Synchronous Idle End Of Transmission Block Sfrit Transmisie Bloc Cancel Anulare End Of Medium Sfrit De Mediu Substitute - nlocuire Escape File Separator Separator de Fiier Group Separator Separator de Grup Record Separator Separator de nregistrare Unit Separator Separator de Unitate Space - Spa iu

Cod NUL SOH STX ETX EOT ENQ ACK BEL BS HT NL VT NP CR SO SI DLE DC1 DC2 DC3 DC4 NAK

Numele simbolului ASCII Baza de numera ie Explica ie 10 16 8 0 0 0 Null Terminare ir C 1 1 1 Start Of Heading nceput De Antet 2 2 2 Start Of Text nceput De Text 3 3 3 End Of Text Sfrit De Text 4 4 4 End Of Transmission Sfrit De Transmisie 5 5 5 Enquiry Interogare 6 6 6 Acknowledge Acceptare 7 7 7 Bell Sunet 8 8 10 Backspace Spa iu napoi 9 9 11 Horiyontal Tab Tabulator Orizontal 10 a 12 New Line (Or LF, Line Feed) Linie Nou 11 b 13 Vertical Tab Tabulaor Vertical 12 c 14 New Page (Or FF, Form Feed) Pagin Nou 13 d 15 Carriage Return Retur De Car 14 e 16 Shift Out 15 f 17 Shift In 16 10 20 Data Link Escape 17 11 21 Device Control 1 Control Dispozitiv 1 18 12 22 Device Control 2 Control Dispozitiv 2 19 13 23 Device Control 3 Control Dispozitiv 3 20 14 24 Device Control 4 Control Dispozitiv 4 21 15 25 Negative Acknowledge Acceptare Negativ 42

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