+ All Categories
Home > Documents > Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú...

Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú...

Date post: 27-Dec-2019
Category:
Upload: others
View: 5 times
Download: 1 times
Share this document with a friend
153
Programarea calculatoarelor şi limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati Cristian Iosifescu Programarea calculatoarelor şi limbaje de programare Iniţiere în limbajul de programare C Lucrări de laborator Galaţi
Transcript
Page 1: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

Cristian Iosifescu

Programarea calculatoarelor şi limbaje de programare

Iniţiere în limbajul de programare C

Lucrări de laborator

Galaţi

Page 2: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

Cuprins

Bibliografie .................................................................................................................................. 4 1. Generalităţi ......................................................................................................................... 1

1.1 Tastatura ......................................................................................................................... 1 1.2 Ecranul aplicaţiei Borland C ........................................................................................ 2 1.3 Principalele meniuri şi comenzi ale aplicaţiei ........................................................... 3

2. Scheme logice şi pseudocod ............................................................................................ 6 2.1 Reprezentarea algoritmilor prin scheme logice ........................................................ 6 2.2 Reprezentarea algoritmilor prin pseudocod ............................................................. 6 2.3 Exemple ........................................................................................................................... 7

3. Noţiuni de bază................................................................................................................ 10 3.1 Structura unui program în C++ ................................................................................. 10 3.2 Principalele mesaje de avertizare şi eroare ale compilatorului............................. 11 3.3 Date în limbajului C .................................................................................................... 12 3.4 Exemple ......................................................................................................................... 14

4. Intrări/ieşiri în C/C++ ..................................................................................................... 15 4.1 Citirea/scrierea datelor............................................................................................... 15 4.2 Intrări/ieşiri în C++..................................................................................................... 15 4.3 Intrări/ieşiri în C ......................................................................................................... 16 4.4 Exemple ......................................................................................................................... 17 4.5 Probleme propuse ........................................................................................................ 20

5. Operatori şi expresii........................................................................................................ 21 5.1 Operatori ....................................................................................................................... 21 5.2 Prioritatea operatorilor ............................................................................................... 23 5.3 Conversia între bazele de numeraţie ........................................................................ 23 5.4 Exemple ......................................................................................................................... 24 5.5 Probleme propuse ........................................................................................................ 30

6. Structuri de decizie (alternative, de selecţie) ............................................................. 34 6.1 Structura de decizie: instrucţiunea if ...................................................................... 34 6.2 Structura de selecţie cu ramuri multiple: instrucţiunea switch ......................... 34 6.3 Exemple if, switch ........................................................................................................ 35 6.4 Probleme propuse ........................................................................................................ 36

7. Structura ciclică cu test iniţial ....................................................................................... 39 7.1 Instrucţiunea while.................................................................................................... 39 7.2 Exemple while ............................................................................................................ 39 7.3 Instrucţiunea for ........................................................................................................ 41 7.4 Exemple for ................................................................................................................ 41 7.5 Probleme propuse ........................................................................................................ 43

8. Structura ciclică cu test final ......................................................................................... 45 8.1 Instrucţiunea do - while........................................................................................ 45 8.2 Exemple do - while ...................................................................................................... 45 8.3 Prelucrarea numerelor ................................................................................................ 48 8.4 Facilităţi de întrerupere a unei secvenţe .................................................................. 50 8.5 Exemple break, continue ...................................................................................... 51 8.6 Probleme propuse ........................................................................................................ 52

ii

Page 3: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

9. Tablouri unidimensionale .............................................................................................. 54 9.1 Declaraţia de tablou ..................................................................................................... 54 9.2 Vectori ............................................................................................................................ 54 9.3 Exemple.......................................................................................................................... 55

10. Şiruri de caractere ............................................................................................................. 61 11. Tablouri multidimensionale .......................................................................................... 65

11.1 Exemple ........................................................................................................................ 65 11.2 Probleme propuse ....................................................................................................... 67

12. Pointeri şi adrese .............................................................................................................. 69 12.1 Exemple ........................................................................................................................ 69 12.2 Probleme propuse ....................................................................................................... 73

13. Funcţii - generalităţi, operaţii cu tablouri.................................................................... 75 13.1 Structura unei funcţii ................................................................................................. 75 13.2 Transferul parametrilor unei funcţii ........................................................................ 75 13.3 Funcţii definite de utilizator ...................................................................................... 76 13.4 Exemple ........................................................................................................................ 77 13.5 Probleme propuse ....................................................................................................... 86

14. Funcţii - analiză matematică, biblioteci de funcţii .................................................... 87 14.1 Exemple ........................................................................................................................ 87 14.2 Funcţii predefinite ...................................................................................................... 90 14.3 Biblioteci de funcţii scrise de către utilizator .......................................................... 95 14.4 Exemple ........................................................................................................................ 95

15. Funcţii recursive ............................................................................................................... 98 15.1 Exemple - Recursivitate directă ................................................................................ 98 15.2 Exemple - Recursivitate indirectă ........................................................................... 107 15.3 Probleme propuse ..................................................................................................... 108

16. Tipuri de date definite de utilizator ........................................................................... 110 16.1 Structuri ...................................................................................................................... 110 16.2 Uniuni ......................................................................................................................... 117 16.3 Exemple uniuni ......................................................................................................... 117 16.4 Enumerări .................................................................................................................. 123 16.5 Exemple ...................................................................................................................... 124 16.6 Declaraţii de tip ......................................................................................................... 124 16.7 Alocarea dinamică a memoriei ............................................................................... 125 16.8 Exemple ...................................................................................................................... 126 16.9 Probleme propuse ..................................................................................................... 127

17. Fişiere................................................................................................................................ 129 17.1 Deschiderea unui fişier ............................................................................................ 129 17.2 Închiderea unui fişier ............................................................................................... 130 17.3 Prelucrarea fişierelor text ......................................................................................... 131 17.4 Intrări/ieşiri binare ................................................................................................... 136 17.5 Poziţionarea într-un fişier ........................................................................................ 141 17.6 Funcţii utilitare pentru lucrul cu fişiere ................................................................ 142 17.7 Alte operaţii cu fişiere .............................................................................................. 143 17.8 Exemple ...................................................................................................................... 143 17.9 Probleme propuse ..................................................................................................... 148

iii

Page 4: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

Bibliografie

Cerchez, E., Şerban, M., Programarea în limbajul C/C++ pentru liceu - Editura Polirom, 2005.

Deaconu, A., Programare avansată în C şi C++, Univ. "Transilvania" Braşov, 2003. Iorga, V., Chiriţă, P., Opincaru, C., Stratan, C., Programare în C/C++ - culegere de

probleme - Editura Niculescu, 2003. Kernigham Brian W şi Ritchie Dennis M., The ANSI C programming language 2nd ed. -

Prentice Hall, 1998. Negrescu, L., Limbajele C şi C++ pentru începători. Vol. 1: Limbajul C, Editura

Microinformatica SRL, Cluj-Napoca, 1994. Novac, C., Limbajul Turbo C++, Universitatea "Dunărea de Jos", Galaţi, 1993; Pătruţ, B., Aplicaţii în C şi C++. Editura Teora, Bucureşti, 1998. Prisecaru, T., Ene, A.S., Limbajul de programare C++ - Noţiuni de bază, Editura Matrix

Rom B, Editura Bucureşti, 2000. Schildt, H., C - Manual complet, Editura Teora, Bucureşti, 1998. Stoilescu, D., Culegere de C/C++, Editura Radial, Galaţi, 1998. Ştefănescu, D., Segal, C., Iniţiere în limbajele C/C++, Editura Fundaţiei Univ., Galaţi,

2000. Vlad, S., Ursu, M.F., Informatica tehnică, Univ. Tehnică Cluj-Napoca, Cluj-Napoca,

1996.

iv

Page 5: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TASTATURA

1. GENERALITĂŢI

1.1 Tastatura

Tastatura este componentă hardware a calculatorului ce permite utilizatorului să introducă date prin apăsarea unor taste. Cele mai folosite tastaturi sunt cele QWERTY. Denumirea vine de la primele şase taste de pe rândul al treilea.

Ea cuprinde următoarele grupuri de taste:

1.1.1 Tastele funcţionale/rapide (Hotkeys)

Sunt simbolizate cu F1…F12, iar rolul lor este să lanseze în mod direct comenzi pentru calculator, comenzi care sunt diferite în funcţie de softul pe care îl folosim la un anumit moment.

1.1.2 Grupul principal de taste (QWERTY)

Acesta conţine tastele alfanumerice (litere, cifre, simboluri), dintre care enumerăm denumirile şi funcţiile tastelor speciale: Shift (⇑), Alt, Ctrl (două din fiecare) - Nu au efect singure (se apasă simultan cu altă tastă)

Tab - inserează mai multe spaţii în textul editat sau trece la câmpul următor din fereastra de dialog

Caps Lock - folosit la scrierea cu majuscule

Enter - lansează în execuţie o comandă

Backspace - şterge caracterul din stânga cursorului

Space (spaţiu) - introduce un blank

Esc - Escape Slash (/) Backslash (\) Tilda (~) Shift+ Asperand (@, "a" rond, ”coadă de maimuţă”) Shift+2

Diez (#) Shift+3

Procent (%) Shift+5 Căciuliţa (^) Shift+6 And (&) Shift+7 Apostrof (') Ghilimele (") - NU două apostrofuri ! Bară verticală (|)

1

Page 6: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

GENERALITĂŢI

1.1.3 Tastele de navigare

Insert = comută între modul inserare şi suprascriere Delete = şterge caracterul din dreptul cursorului Home = (acasă) mută cursorul la începutul rândului End = (sfârşit) mută cursorul la sfârşitul rândului curent Page up = deplasează conţinutul fişierului cu un ecran către începutul acestuia Page down (pereche) Ctrl + Home = mută cursorul la începutul ecranului (primul rând) Ctrl + End = mută cursorul la sfârşitul ecranului (ultimul rând) Ctrl + Page up = deplasează cursorul (şi implicit conţinutul afişat pe ecran) la

începutul fişierului Ctrl + Page down = deplasează cursorul la sfârşitul fişierului

1.1.4 Tastele numerice

Sunt active dacă led-ul lui Num Lock este aprins, altfel funcţionează ca Taste speciale

1.2 Ecranul aplicaţiei Borland C

Pentru Borland C++ versiunea 3.1, acesta conţine: Bara de meniuri (sus) - prezintă mai multe meniuri (System, File - fişiere, Edit -

editare, Search - căutare) care conţin grupuri de comenzi specifice. Activarea ei se face cu tasta rapida F10 - aşa cum se arată în bara de stare; deschiderea unui meniu se face apăsând simultan tastele Alt şi litera evidenţiată din numele meniului.

Zona de lucru (la mijloc) - conţine una sau mai multe ferestre, din care, la un moment dat, e activă una singură.

Elementele unei ferestre sunt: Rama ferestrei - dublă, dacă fereastra este activă, simplă dacă este inactivă Buton de închidere - în partea din stânga sus a ramei ([■]) Titlul ferestrei - pentru ferestrele de editare este numele fişierului deschis. Numărul ferestrei - automat Buton de maximizare/revenire - în partea din dreapta sus a ramei ([↑]) Bara de defilare verticală, ce conţine săgeţile de deplasare la extremităţi şi

butonul care indică poziţia conţinutului ecranului în „lungul” fişierului (început/sfârşit)

Bara de defilare orizontală, ce conţine săgeţile de deplasare la extremităţi şi butonul care indică poziţia conţinutului ecranului în „latul” fişierului (stânga/dreapta)

Poziţia cursorului - indicată prin numărul liniei şi cel al coloanei - în partea din stânga jos a ramei

Buton care indică modificarea conţinutului ferestrei după ultima salvare - în partea din stânga jos a ramei [*]

Bara de stare (jos) - conţine comenzile disponibile la un moment dat şi combinaţiile de taste pentru lansarea acestora. Conţinutul ei se modifică în funcţie de context (poziţia cursorului în diferitele zone ale ecranului).

2

Page 7: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRINCIPALELE MENIURI ŞI COMENZI ALE APLICAŢIEI

1.3 Principalele meniuri şi comenzi ale aplicaţiei

1. Meniul System [≡] - conţine comenzi de sistem şi pentru programe de transfer

2. Meniul File - conţine comenzi pentru gestiunea fişierelor (Deschidere, Salvare, Tipărire, etc.)

a. New - creează un nou fişier într-o nouă fereastră de editare b. Open (F3) - localizează şi deschide un fişiere (creat deja) c. Save (F2) - salvează fişierul din fereastra de editare activă d. Save as - salvează fişierul din fereastra de editare activă cu un nume nou e. Save all - salvează toate fişierele modificate f. Change dir - schimbă directorul de lucru curent g. Print - tipăreşte conţinutul ferestrei active h. DOS shell - iese temporar în sistemul de operare i. Quit (Alt+X) - iese din aplicaţia Borland C++

3. Meniul Edit - conţine comenzi pentru operaţii de editare, anulare şi acces la Clipboard

a. Undo (Alt+BkSpc) - anulează ultima comandă de editare (consecutiv) b. Redo (Shift+Alt+BkSpc) - reface ultima comandă anulată c. Cut (Shift+Del) - şterge textul selectat şi îl pune în Clipboard d. Copy (Ctrl+Ins)- copiază în Clipboard textul selectat e. Paste (Shift+Ins)- inserează conţinutul Clipboard-ului în fereastra curentă la

poziţia cursorului f. Clear (Ctrl+Del) - şterge textul selectat g. Copy example - copie în Clipboard exemplul dintr-o fereastră Help h. Show Clipboard - arată conţinutul Clipboard-ului

4. Meniul Search - conţine comenzi pentru căutarea textului şi erorilor a. Find - caută un text b. Replace - caută un text şi îl înlocuieşte cu unul nou c. Search again (Ctrl+L) - repetă ultima comandă de căutare sau căutare şi

înlocuire d. Go to line number - mută cursorul la linia specificată e. Previous error - mută cursorul la linia erorii anterioare

3

Page 8: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

GENERALITĂŢI

f. Next error - mută cursorul la linia erorii următoare g. Locate function - caută la depanare o declaraţie de funcţie

5. Meniul Run - conţine comenzi pentru lansarea în execuţie a programului integral sau pas cu pas

a. Run (Ctrl+F9) - lansează programului în execuţie b. Program reset (Ctrl+F2) - termină sesiunea de depanare c. Go to cursor (F4) - execută programul până la linia cursorului d. Trace into (F7) - execută instrucţiunea următoare; pătrunde în corpul funcţiilor e. Step over (F8) - execută instrucţiunea următoare; “păşeşte” peste corpul

funcţiilor f. Arguments - stabileşte parametrii liniei de comandă cu care va fi executat

programul 6. Meniul Compile - conţine comenzi pentru verificarea corectitudinii

(compilarea) programului a. Compile (Alt+F9) - compilează fişierul din fereastra de editare activă b. Make (F9) - Actualizează ţinta prin compilare şi legare, după caz c. Link - Leagă fişierele ţintei fără recompilare d. Build all - Reconstruieşte toate fişierele

7. Meniul Debug - conţine comenzi pentru inspectare, evaluare, stabilire de puncte de întrerupere şi urmărire a variabilelor

a. Inspect (Alf+F4) - deschide o fereastră inspector pentru a examina valorile unei date

b. Evaluate/Modify (Ctrl+F4) - evaluează o variabilă sau expresie şi afişează valoarea

c. Call stack (Ctrl+F3) - arată funcţiile apelate de program până în punctul curent d. Watches - adaugă, şterge sau editează variabile urmărite e. Toggle breakpoint (Ctrl+F8) - inserează sau şterge un punct de oprire

necondiţionată a programului la linia curentă f. Breakpoints - inserează puncte de oprire necondiţionată; vizualizează sau

editează aceste puncte 8. Meniul Project - conţine comenzi pentru gestiunea proiectelor: adăugare,

ştergere sau vizualizarea fişierelor proiect 9. Meniul Options - conţine comenzi pentru stabilirea opţiunilor mediului de

programare, a compilatorului şi depanatorului 10. Meniul Window - conţine comenzi pentru deschiderea, aranjarea şi afişarea

listei ferestrelor a. Size/Move (Ctrl+F5) - modifică dimensiunea sau poziţia ferestrei active b. Zoom (F5) - maximizează sau readuce fereastră activă la dimensiunea iniţială c. Cascade - dispune ferestrele din zona de lucru suprapuse d. Tile - dispune ferestrele din zona de lucru alăturat e. Next (F6) - activează fereastra următoare f. Close (Alt+F3) -închide fereastra activă g. Close all - închide toate ferestrele h. Message/Output/Watch/User screen (Alt+F5) - deschide una din ferestrele

speciale: de mesaje, de rezultate, de urmărire sau ecranul utilizatorului i. List all (Alt+0) - afişează lista tuturor ferestrelor deschise

11. Meniul Help - conţine comenzi pentru accesarea sistemului de ferestre de ajutor.

4

Page 9: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRINCIPALELE MENIURI ŞI COMENZI ALE APLICAŢIEI

a. Contents - arată cuprinsul sistemului de ajutor b. Index (Shift+F1) - arată index-ul sistemului de ajutor c. Topic search (Ctrl+F1) - arată informaţii despre cuvântul din dreptul

cursorului sau afişează index-ul d. Previous topic (Alt+F1) - arată din nou ultima fereastră de informaţii e. Help on help - arată modul de utilizare a sistemului de ajutor f. About - arată numărul versiunii programului

Obs.: 1. Selectarea unei porţiuni de text se face astfel:

a. Se poziţionează cursorul cu ajutorul săgeţilor la un capăt al textului de selectat; b. Ţinând tasta Shift apăsată, se deplasează cursorul cu ajutorul săgeţilor

(←,→,↑,↓) către celălalt capăt al textului de selectat. 2. Pentru a scurta durata etapei de redactare a programelor se poate proceda astfel:

a. textul de pe o linie de după //, precum şi cel de pe mai multe linii dintre /* şi */ reprezintă comentarii şi poate fi omis

b. instrucţiunile care afişează valorile variabilelor pe ecran (cout, printf) pot fi omise, iar valorile variabilelor pot fi urmărite în fereastra Watches din meniul Debug.

3. Programele au fost scrise cu editorul de texte al aplicaţiei Borland C, iar cartea a fost tehnoredactată cu ajutorul unui procesor de texte. Din acest motiv, uneori instrucţiunile sunt desparţite pe mai multe rânduri. La scrierea programelor la calculator nu se va respecta forma din carte a instructiunilor, ci ele vor fi scrise corect (din punct de vedere al limbajului), o instrucţiune (care se termină cu ";") fiind scrisă întotdeauna pe un singur rând.

5

Page 10: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

SCHEME LOGICE ŞI PSEUDOCOD

2. SCHEME LOGICE ŞI PSEUDOCOD

2.1 Reprezentarea algoritmilor prin scheme logice

Primitivele utilizate în schemele logice sunt simboluri grafice, cu funcţiuni (reprezentând procese de calcul) bine precizate. Aceste simboluri sunt unite prin săgeţi (arce) orientate care indică ordinea de execuţie a proceselor de calcul.

Simboluri de început şi sfârşit. Simbolul START desemnează începutul unui

program sau al unui subprogram. Simbolul STOP desemnează sfârşitul unui program sau al unui subprogram. Prezenţa lor este obligatorie.

Simbolul paralelogram: semnifică procese (operaţii) de intrare/ieşire (citirea sau scrierea-afişarea).

Simbolul dreptunghi: semnifică o atribuire (modificarea valorii unei date). Simbolul romb este utilizat pentru decizii. Se testează dacă condiţia din blocul de

decizie este adevărată (A) sau falsă (F). Cu ajutorul acestor simboluri grafice se poate reprezenta orice algoritm. Repetarea unei secvenţe se realizează prin combinarea simbolurilor de decizie şi de

atribuire.

2.2 Reprezentarea algoritmilor prin pseudocod

Pseudocodul este inspirat din limbajele de programare, nefiind însă atât de formalizat ca acestea. Pseudocodul reprezintă o punte de legătură între limbajul natural şi limbajele de programare. Nu există un standard pentru regulile lexicale. Limbajul pseudocod permite comunicarea între oameni, şi nu comunicarea om-maşină (precum limbajele de programare). Pseudocodul utilizează cuvinte cheie (scrise cu majuscule subliniate) cu următoarele semnificaţii:

Sfârşit algoritm: SFÂRŞIT Început algoritm: ÎNCEPUT Citire (introducere) date: CITEŞTE lista Scriere (afişare) date: SCRIE lista

CITEŞTE a,b AFIŞEAZĂ a,b

a←6 Condiţie A

START STOP

F

6

Page 11: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

Atribuire: ← Structura de decizie (alternativă): DACĂ condiţie ATUNCI acţiune1 ALTFEL acţiune2 Structuri repetitive cu test iniţial: CÂT TIMP condiţie REPETĂ acţiune sau: PENTRU contor=val_iniţ LA val_fin [PAS] REPETĂ acţiune Structuri repetitive cu test final: REPETĂ acţiune CÂT TIMP condiţie sau: REPETĂ acţiune PÂNĂ CÂND condiţie

Pe lângă cuvintele cheie, în reprezentarea algoritmilor în pseudocod pot apare şi

propoziţii nestandard a căror detaliere va fi realizată ulterior. În cazul în care se realizează un algoritm modularizat, pot apare cuvintele cheie: SUBALGORITM nume (lista_intrări) CHEAMĂ nume (lista_valori_efective_de_intrare)

2.3 Exemple

2.3.1 Maximul a trei numere

2.3.1.1 Pseudocodul 1. CITEŞTE a, b, c 2. DACĂ a>b ATUNCI max=a ALTFEL max=b 3. DACĂ c>max ATUNCI max=c 4. AFIŞEAZĂ max

2.3.2 Suma primelor n numere naturale

2.3.2.1 Pseudocodul 1. CITEŞTE n 2. suma=0 3.CÂT TIMP i<n 3.1 i++ 3.2 suma=suma+i 4. AFIŞEAZĂ suma

7

Page 12: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

SCHEME LOGICE ŞI PSEUDOCOD

2.3.3 Ecuaţia de gradul 2

2.3.3.1 Schema logică

Start

Dacă a=0

Dacă ∆>0

Dacă ∆<0

Scrie “Ec are rad dubla”

x1 = x2

Scrie “Ec are rad compl” x1,2 = re±i⋅im

Dacă b=0

Daca c=0

Scrie “Ec are doua rad dif”

x1 şi x2

re = -b2a

im = -∆

2a

Scrie “Ec e de gradul unu x1 = -c/b

x1,2 = -b± ∆

2a x1,2 = -b2a

∆ = b2 – 4ac

Citeşte a, b, c

Stop

Scrie “Ec are o infinit ate de solutii”

Scrie “Ec nu are nici o solutie”

A

A

A

F

F

F

F A

F A

8

Page 13: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

2.3.4 Maximul a 3 numere, calculul unei sume, etc - scheme logice

Start

Dacă i≤n

Citeşte n

Stop

fact*=i i++

A F

Scrie “n! =”, fact

i=1 fact=1

Start

Dacă a≠0, b≠0

Citeşte a,b

Stop

cmmmc=a*b r=a%b

a=b b=r

A

Scrie cmmdc, cmmmc

F

r=a%b a=b b=r

Dacă r≠0

cmmmc=a cmmdc= cmmmc/ cmmdc

A

F

cmmmc=0 cmmdc=0

Start

Dacă a>b

Dacă c>max

max=b

Citeşte a, b, c

Stop

max=a

max=c

A F

Scrie “Max =” , max

A F

Start

Dacă i≤m, j≤n

Citeşte a,b,m,n

Stop

s=s+sin(a+3*i)*cos(b+5*j)

max=c

A F

Scrie “S =” , s

i=1, j=1, s=0

9

Page 14: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

NOŢIUNI DE BAZĂ

3. NOŢIUNI DE BAZĂ

3.1 Structura unui program în C++

Un program C obişnuit are următoarea structură (textul dintre /* şi */ reprezintă comentarii): /*directive de preprocesare*/ #include <fisier> /*includeri de fişiere sau biblioteci*/ /*atribuirea de nume simbolice şi definiţii de macrocomenzi*/ #define <def.constante> /*directive de compilare condiţionată*/ /*definiţii de tipuri de date*/ typedef int intreg; /*declaraţii de variabile globale*/ /*definiţii de funcţii sau/şi descrierea unor functii*/ int main(void) /*antetul funcţiei principale main*/ { /*începutul corpului funcţiei main*/ /*declaraţii de variabile locale*/ /*instrucţiunile funcţiei principale*/ return 0; /*valoarea returnată de funcţia main*/ } /*sfârşitul corpului funcţiei main*/ /*descrierea funcţiilor care au definiţiile mai sus*/

Precizare: compilatoarele pentru C şi C++ fac distincţie între litere mari şi mici. Un program C++ constă în una sau mai multe funcţii din care numai una singură este

funcţia principală. Fiecare funcţie are un nume; al funcţiei principale este main. Celelalte funcţii au nume definite de utilizator.

Un nume (identificator) este o succesiune de litere şi eventual cifre, primul caracter fiind o literă. Literele pot fi a-z, A-Z sau caracterul de subliniere (_). Numai primele 32 caractere sunt luate în seamă.

Pentru ca un fişier text să poată fi considerat un program sursă în limbajul C, acesta

trebuie să conţină minim antetul şi corpul funcţiei principale main, adică: void main() { }

Aceste lucruri se găsesc în orice program C, indiferent de scopul acestuia.

10

Page 15: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRINCIPALELE MESAJE DE AVERTIZARE ŞI EROARE ALE COMPILATORULUI

3.2 Principalele mesaje de avertizare şi eroare ale compilatorului

Tabelul 3.1 Mesaje de avertizare şi eroare Text mesaj (alfabetic) Explicaţii

'…' is assigned a value that is never used

Avertisment: Valoarea calculată nu este folosită nicăieri în continuare

Bad file name format in include directive

Denumire greşită în directiva de preprocesare

Compound statement missing }

Caracter ”}” sau ”{” omis la o instrucţiune compusă

Declaration syntax error Eroare de sintaxă a declaraţiei Declaration terminated incorrectly

Declaraţie terminată incorect

Expression syntax Eroare de sintaxă For statement missing ; Caracter omis “;” la scrierea instrucţiunii "for" Function '…' should have a prototype

Funcţia “…” ar trebui să aibă un prototip; pentru a putea fi folosită, ea trebuie fie definită de utilizator, fie folosită o directivă de preprocesare (#include <…>)

Function should return a value

Funcţia ar trebui să returneze o valoare - lipsă "void" la tipul valorii returnate din antet sau lipsă instrucţiune "return" în corpul funcţiei

If statement missing ) Caracter “)” sau ”(” omis la scrierea instrucţiunii “if”

Illegal structure operation

Structură greşită a instrucţiunii (scriere/citire) - la >> sau <<

Incorrect number format Variabilă iniţializată cu un format numeric incorect

Misplaced else Ramura “else” din instrucţiunea “if” este poziţionată greşit

Multiple declaration for …

Variabila … este declarată de mai multe ori

No file name ending Caracter „>” omis la o directivă de preprocesare după numele bibliotecii

Statement missing ; Caracter “;”omis (la instrucţiunea precedentă) Unable to open include file '…'

Numele bibliotecii a fost scris greşit

Undefined symbol '…' Simbol '…' (variabilă sau funcţie) nedefinit Unexpected “…” Simbol neaşteptat - paranteză sau acoladă în plus Unterminated string or character constant

Şir de caractere sau constantă caracter neterminată - lipsă ' sau "

While statement missing )

Caracter “)”sau ”(” omis la scrierea instrucţiunii "while"

Pentru a obţine mai multe informaţii despre o anumită eroare, atunci când eroarea este selectată în fereastra cu mesaje (Message), se apasă tasta F1.

11

Page 16: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

NOŢIUNI DE BAZĂ

3.3 Date în limbajului C

3.3.1 Tipuri de date

Datele care intervin în programe sunt de mai multe tipuri. În acest laborator vom prezenta tipurile simple, iar tipurile compuse vor fi prezentate în alte laboratoare. Tabelul de mai jos va prezenta tipurile de bază:

Tabelul 3.2 Tipurile de bază de date Cuvânt cheie

Lungime în biţi

Format de reprezentare internă

int 16 Întreg binar reprezentat prin complement faţă de 2 pe 2 octeţi, cuprins în intervalul [-32768, 32767]

char 8 Caracter reprezentat prin codul ASCII, cuprins în intervalul [-128, 127]

float 32 Număr real reprezentat în virgulă flotantă în simplă precizie, cuprins între [3.4⋅10-38, 3.4⋅1038]

double 64 Număr real reprezentat în virgulă flotantă în dublă precizie, cuprins între [1.7⋅10-308, 1.7⋅10308]

short 16 Idem int long 32 Întreg binar reprezentat prin complement faţă de 2 pe 4

octeţi, cuprins în intervalul [-2.147.483.648 to 2.147.483.647] unsigned char

8 Caracter reprezentat prin codul ASCII, cuprins în intervalul [0, 255]

unsigned int

16 Întreg binar fără semn reprezentat prin complement faţă de 2 pe 2 octeţi, cuprins în intervalul [0, 65535]

unsigned long

32 Întreg binar reprezentat prin complement faţă de 2 pe 4 octeţi, cuprins în intervalul [0, 4.294.967.295]

3.3.2 Constante

Sunt caracterizate prin tip şi valoare. Atât tipul cât şi valoarea se definesc prin caracterele care o compun

Tabelul 3.3 Reprezentarea constantelor în C/C++ Tip dată Format de

reprezentare Mod de reprezentare Exemple

zecimal (în baza 10)

[- / +] <cifra de la 1 la 9> [<lista cifre de la 0 la 9>]

125 -11

întreg *)

octal (în baza 8)

[- / +] 0 <cifra de la 1 la 7> [<lista cifre de la 0 la 7>]

0127 -022

hexazecimal (în baza 16)

[- / +] 0 {x / X} <cifra 1-9 sau litera a-f sau A-F> [<lista cifre 0-7 sau litere a-f sau A-F>]

0xa12f -0Xad105

real

în virgulă fixă [- / +] <partea întreagă> . <partea zecimală> Aceasta este scrierea unui

123 123.7 .25

12

Page 17: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

DATE ÎN LIMBAJULUI C

Tip dată Format de reprezentare

Mod de reprezentare Exemple

număr raţional în baza zece, unde virgula zecimală este înlocuită de punctul zecimal. Partea zecimală poate fi vidă

(flotant) în virgulă mobilă [- / +] <partea întreagă> . <partea zecimală> {e sau E} [- / +] <nr. întreg zecimal> Aceasta reprezintă mantisa (ceea ce este înainte de E) înmulţită cu 10 la puterea dată de exponent (ceea ce este după E)

78E4 .1e-3 1234.567e-4

între apostroafe ‘<caracter>’ ‘a’ ‘A’ ‘\<codul ASCII>‘ ‘\65’ ‘\7’

‘\42’ ‘\140’ caracter cu secvenţe escape ‘\<caracter special>‘ \t Tab

\n Rând nou \a Alarm (sunet) \b Backspace \r Retur de car (poziţ cursorul în rândul curent col 1) \v Tabulator vertical \\ Backslash \’ Apostrof

şir de carac

între ghilimele “<şir>” “Acesta este un sir de caractere”

cu secvenţe escape “şir caractere şi secv.escape”

“Alte \tsecvente \tescape \nintr-un sir”

Obs.: *) Ceea ce am scris anterior era valabil pentru constantele întregi de până la 16

biţi. Constantele de 32 biţi sunt de tip long şi pentru a le nota le postfixăm una din: l sau L.

Pentru a specifica o constantă ca fiind de tip unsigned (fără semn) o postfixăm una din: u sau U. Dacă o constantă este long şi unsigned în acelaşi timp, o postfixăm cu una din:

ul, lu, UL, LU Ex: 123, 0123, 40000, 04000, 0123456, 123L, 0123l, 0x123, 0xa1b2c3, 0XABCFL

13

Page 18: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

NOŢIUNI DE BAZĂ

3.3.3 Variabile

3.3.3.1 Declararea variabilelor Modul general de declarare a variabilelor este:

tip_variabile listă_nume_variabile; Se specifică tipul variabilei(lor) şi o listă formată din unul sau mai mulţi identificatori ai variabilelor de tipul respectiv.

Ex.: int i, j; /*declararea var. simple i, j, de tip int. Se rezervă pentru i şi j câte 16 biţi (2 octeţi)*/ char c; /*declararea variabilei simple c, de tip char. Se rezervă un octet.*/ float lungime; /* declararea variabilei simple lungime de tip float; se rezervă 4 octeţi */

3.3.3.2 Iniţializarea variabilelor în declaraţii În momentul declarării unei variabile, acesteia i se poate atribui o anumită valoare. În acest caz, în memorie se rezervă numărul de locaţii corespunzător tipului variabilei respective, iar valoarea va fi memorată în acele locaţii. Forma unei declaraţii de variabile cu atribuire este:

tip_variabilă nume_variabilă=expresie; Se evaluează expresia, iar rezultatul acesteia este atribuit variabilei specificate.

3.4 Exemple

char backslash=’\\’; /*declararea şi iniţializarea variabilei simple de tip caracter backslash */ int a=7*9+2; /* declararea variabilei simple a, de tip int şi iniţializarea ei cu rezultatul unei expresii - valoarea 65*/ float pi=3.14; /*declararea şi iniţializarea variabilei pi*/ short int z=3; //declararea şi iniţializarea variabilei simple z char d=’\011’; char LinieNoua=’\n’; double x=9.8, y=0;

14

Page 19: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI ÎN C++

4. INTRĂRI/IEŞIRI ÎN C/C++

4.1 Citirea/scrierea datelor

Prin citirea datelor vom înţelege operaţia prin care una sau mai multe variabile primesc valori prin introducerea lor de la tastatură sau prin extragerea lor de pe un suport de memorare extern.

Prin scrierea datelor vom înţelege operaţia prin care rezultatele obţinute în urma prelucrării datelor de intrare sunt fie afişate pe ecranul monitorului, fie stocate pe un suport extern de memorare.

Aceste operaţii sunt denumite frecvent şi operaţii de intrare/ieşire. În acest capitol vom prezenta doar citirea datelor de la tastatură şi afişarea datelor pe ecran.

În limbajul C/C++ nu există instrucţiuni specializate pentru citirea/scrierea datelor. Aceste operaţii se realizează prin intermediul unor funcţii existente în bibliotecile standard ale limbajului.

Aceste operaţii de intrare/ieşire diferă în limbajul C++ faţă de limbajul C, diferenţele fiind majore, deoarece operaţiile de intrare/ieşire din C++ sunt proiectate din perspectiva programării orientate pe obiect.

4.2 Intrări/ieşiri în C++

Conceptul central în operaţiile de intrare/ieşire în limbajul C++ este fluxul de intrare/ieşire (denumirea originală fiind stream). Simplificând, putem privi un stream ca pe o succesiune de caractere. Dacă stream-ul este de intrare, secvenţa de caractere „curge" dinspre exterior (în cazul nostru, dinspre tastatură) către memoria calculatorului. Dacă stream-ul este de ieşire, secvenţa de caractere "curge" dinspre memoria calculatorului către exterior (în cazul nostru, ecranul monitorului).

În fişierul antet iostream.h sunt declarate două fluxuri standard: un flux de intrare de la tastatură, denumit cin (console input) şi un flux de ieşire către ecran, denumit cout (console output). Pentru a le utiliza trebuie să declarăm în program:

#include <iostream.h> Dacă dorim să scriem date pe ecran, vom utiliza operatorul de inserţie în fluxul de

ieşire “<<” (care poate fi utilizat înlănţuit atunci când dorim să scriem mai multe date). Instrucţiunea din C++ care scrie (pe ecran) valori şi/sau text este:

cout<<expr.1[<<var1<<expr.2 [...]] unde var.1, var.2 - reprezintă nume de variabile iar expr.1, expr.2 - reprezintă

expresii. Ex.: Pentru a afişa pe ecran pe o linie nouă, în cadrul unui mesaj, valorile a două

variabile a şi b folosim instrucţiunea: cout<<"\na="<<a<<"\tb="<<b;

Instrucţiunea are următorul efect: 1. se trece pe o linie nouă (\n)

15

Page 20: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI ÎN C/C++

2. se afişează textul a= 3. se afişează valoarea variabilei a 4. se lasă un spaţiu (tab) (\t) 5. se afişează textul b= 6. se afişează valoarea variabilei b

Dacă a=2 şi b=5, atunci rezultatul instrucţiunii este: a=2 b=5

Când dorim să citim date de la tastatură, le vom extrage din fluxul de intrare,

folosind operatorul de extragere “>>” (care poate fi utilizat înlănţuit atunci când dorim să citim succesiv mai multe variabile). Instrucţiunea care citeşte (de la tastatură) una sau mai multe variabile este:

cin >>var.1[>>var.2 [...]] Ex.: Pentru a citi de la tastatură valorile a două variabile a şi b folosim instrucţiunea:

cin>>a>>b;

4.3 Intrări/ieşiri în C

Citirile şi scrierile în limbajul C se realizează prin intermediul unor funcţii specifice.

4.3.1 Citirea datelor cu format specificat

Funcţia scanf (din biblioteca stdio.h) are următoarea sintaxă: scanf(sir_car_ctrl,adr_var.1[,adr_var.2 [...]])

unde: sir_car_ctrl - Şir de caractere de control ce indică tipul variabilelor ce se vor citi: %d - variabilă de tip decimal (întreg); %f - variabilă de tip float (real); %c - variabilă de tip caracter; %s - variabilă de tip sir de caractere; adr_var.1 - adresa variabilei 1 Obs.: Numărul caracterelor de control trebuie să coincidă cu cel al variabilelor care se

vor citi. Ex. Pentru a se citi de la tastatură variabilele denumite: car (de tip caracter - char),

intrg (de tip întreg - int), re (de tip real - float) şi sir (de tip şir de caractere) sintaxa instrucţiunii este: scanf("%c%d%f%s",&car,&intrg,&re,sir);

4.3.2 Afişarea datelor cu format specificat

Funcţia printf (din biblioteca stdio.h) are următoarea sintaxă: printf(sir_car_ctrl,var.1[,var.2 [...]])

unde:

16

Page 21: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

sir_car_ctrl - şir de caractere de control reprezentat de o succesiune de simboluri “%” urmate de caractere şi/sau cifre, ce indică tipul şi eventual formatul numeric al variabilelor ce se vor scrie. Caracterele de formatare au următoarea semnificaţie: c - variabilă de tip caracter d - variabilă de tip decimal (întreg) e - în format ştiinţific f - variabilă de tip float (real) g - cel mai scurt dintre f şi e o - în octal s - variabilă de tip şir de caractere x - în hexazecimal 0 - cu zerouri nesemnificative - - aliniere la stânga

Formatul numeric se indică prin numărul total şi numărul de zecimale pentru cifrele variabilelor numerice, separate prin “.”.

Obs.: Numărul caracterelor de control trebuie să coincidă cu cel al variabilelor care se vor scrie.

Ex. Pentru a se afişa pe ecran variabilele denumite: car (de tip caracter - char), intrg (de tip întreg - int), re (de tip real - float) - pe şase spaţii dintre care trei zecimale - şi sir (de tip şir de caractere) sintaxa instrucţiunii este: printf("%c %d %6.3f %s",car,intrg,re,sir);

Sintaxa lor detaliată şi completă poate fi obţinută din Help-ul aplicaţiei BC.

4.4 Exemple

4.4.1 cout

#include <iostream.h> void main(void) { cout<<"ACESTA ESTE PRIMUL PROGRAM\n"; }

4.4.2 cin, cout

#include <iostream.h> void main() //Citeste o data calendaristica sub forma zzllaaaa (ziua-2 cifre, luna-2 cifre, anul-4 cifre) si o rescrie in forma aaaa/ll/zz { int ziua, luna, anul; cin>>ziua>>luna>>anul; cout<<anul<<‘/‘<<luna<<‘/‘<<ziua; }

4.4.3 Operatorul sizeof

Să se scrie un program care ilustrează folosirea operatorului sizeof. #include <iostream.h> #include <values.h> #define PI 3.1415926 void main () { cout<<"tipul int memorat pe: "<<sizeof(int)<< " octeti\n";

17

Page 22: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI ÎN C/C++

cout<<"tipul int memorat pe: "<<sizeof(23)<<" octeti\n"; //23-const.zecimala int cout<<"int maxim="<<MAXINT<<'\n'; //const simbolice MAXINT,MAXLONG, ETC. -definite in<values.h> cout<<"Const. octala 077 are val decimala:"<<077<<'\n'; cout<<"Const. hexagesimala d3 are val decimala :"<<0xd3<<'\n'; cout<<"Tipul unsigned int memorat pe: "<<sizeof(unsigned int)<<" octeti\n"; cout<<"Tipul unsigned int memorat pe: "<<sizeof(23U)<<" octeti\n"; cout<<"Tipul unsigned int memorat pe: "<<sizeof(23u)<<" octeti\n"; cout<<"Tipul long int memorat pe: "<<sizeof(long int)<<" octeti\n"; cout<<"Tipul long int memorat pe: "<<sizeof(23L)<<" octeti\n"; cout<<"Tipul long int memorat pe: "<<sizeof(23l)<<" octeti\n"; //23 sau 23l-const. decimala long int cout<<"Long int maxim="<<MAXLONG<<'\n'; cout<<"Tipul unsigned long memorat pe: "<<sizeof(unsigned long int)<<" octeti\n"; cout<<"Tipul unsigned long memorat pe: "<<sizeof(23UL)<<" octeti\n"; cout<<"Tipul unsigned long memorat pe: "<<sizeof(23Ul)<<" octeti\n"; //23UL sau 23ul-const. decimala unsigned long int cout<<"Tipul unsigned long memorat pe: "<<sizeof(long long int)<<" octeti\n";long long int d; cout<<"Tipul unsigned long memorat pe: "<<sizeof(d)<<" octeti\n"; cout<<"Tipul short int memorat pe: "<<sizeof(short int)<<" octeti\n"; cout<<"Short int maxim="<<MAXSHORT<<'\n'; cout<<"Un char este memorat pe "<<sizeof('m')<<" octeti\n"; cout<<"sirul jhgkk este memorat pe "<<sizeof("jhgkk")<<" octeti\n"; cout<<"sirul j\thgkk este memorat pe "<<sizeof("j\thgkk")<<" octeti\n"; cout<<"Tipul float memorat pe: "<<sizeof(float)<<" octeti\n"; cout<<"Tipul float memorat pe: "<<sizeof(23.7f)<<" octeti\n"; //23.7f-const. decimala float cout<<"Float maxim="<<MAXFLOAT<<'\n'; cout<<"Float minim="<<MINFLOAT<<'\n'; cout<<"Tipul double memorat pe: "<<sizeof(double)<<" octeti\n"; cout<<"Tipul double memorat pe: "<<sizeof (23.7)<<" octeti\n"; //23.7-const. decimala double cout<<"Const. decim. doubla in notatie stiintifica: "<<23.7e-5<<'\n'; cout<<"Const. PI este:"<<PI<<'\n'; cout<<"Constanta PI este memorata pe: "<<sizeof(PI)<<"octeti\n"; cout<<"Double maxim="<<MAXDOUBLE<<'\n'<<"Double minim ="<<MINDOUBLE<<'\n';

18

Page 23: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

cout<<"Tipul long double memorat pe: "<<sizeof(long double)<<" octeti\n"; cout<<"Tipul long double memorat pe: "<<sizeof(23.7L)<<" octeti\n"; //23.7L-const. decimala long double cout<<"Cifra A din HEXA are val.: "<<0xA<<"\n"; cout<<"Cifra F din HEXA are val.: "<<0xF<<"\n"; cout<<"valoarea B+C din hexa in baza 10 este "<<0xB+0xc<<"\n"; cout<<"Val. const. hexa 0x7acle este: "<<0x7ac1e<<'\n'; cout<<"Val. const. octale 171 este: "<<0171<<'\n'; cout<<"O const. octala se memoreaza pe "<<sizeof(011)<<" octeti\n"; cout<<"O const.oct.long. se mem pe "<<sizeof(011L)<<" octeti\n"; cout<<"2<9:"<<(2<9)<<'\n'; }

4.4.4 Intrări-ieşiri standard (scanf, printf)

Să se scrie un program care ilustrează folosirea funcţiilor scanf, printf. //Intrari/iesiri standard #include<conio.h> #include<stdio.h> void main() { char c;int i;float f;char sir[10]; clrscr(); printf("Introduceti un char/intreg/float/sir: \n"); scanf("%c%d%f%s",&c,&i,&f,sir); //caracter si cod caracter printf("\nc=%c cod=%d",c,c); //intreg printf("\ni=%d",i); //cu lungime de cimp printf("\ni=%6d",i); //aliniat la stinga printf("\ni=%-6d;i=%d",i,i); //cu zerouri nesemnificative printf("\ni=%06d",i); //in octal printf("\ni in octal=%o",i); //in hexa printf("\ni in hexa=%x",i); //float printf("\nf=%f",f); //cu lungime si precizie impusa printf("\nf=%10.2f",f); //stiintific printf("\nf=%e",f); //stiintific cu precizie data printf("\nf=%.3e",f); //c m scurt dintre f si e

19

Page 24: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI ÎN C/C++

printf("\nf=%g",f); //sir cu lungime fixa printf("\nsir=%4.6s",sir); getch(); }

4.5 Probleme propuse

1. Să se scrie un program care să tipărească următoarele: ************************* * Bine ai venit la ore! * *************************

2. Care dintre programele de mai jos nu conţin erori şi afişează cuvintele pe câte un rând ?

#include <iostream.h> void main() ; {cout<<”Program”; cout<<” \n”<<”simplu”;}

#include <iostream.h> void main () {cout<<”Program \n”; cout<<”simplu”;}

#include <iostream.h> void main () {cout<<”Program \nsimplu”; cout<<” \n”;}

#include <iostream.h> void main () {cout<<”Program”; cout<<simplu”<<” \n”;}

20

Page 25: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI

5. OPERATORI ŞI EXPRESII

5.1 Operatori

Operatorul de atribuire: = În tabelul de mai jos sunt prezentate principalele variante ale instrucţiunii de atribuire.

Tabelul 5.1 Principalele variante ale instrucţiunii de atribuire operaţia sintaxa exemple observaţii

Atribuire simplă

<variabilă> = <expresie>;

x=y+z/3;

Atribuirea combinată cu un operator

<variabilă> <op> = <expresie>;

x+=y; i-=2; a*=ln(a); alfa /=n;

Este echivalentă cu: <variabilă> = <variabilă> op <expresie>;

Operatori aritmetici unari (3): -, ++ , --

“++” - Incrementare - Măreşte valoarea variabilei cu 1, “--“ - Decrementare - Micşorează valoarea variabilei cu 1. Pot fi în formă prefixată (Ex. ++a), sau postfixată (Ex. b--). În cazul în care un

operator de incrementare sau decrementare este prefixat, se foloseşte valoarea operandului la care s-a aplicat operatorul respectiv, iar în cazul în care un operator de incrementare sau decrementare este postfixat, se foloseşte valoarea operandului dinaintea aplicării operatorului respectiv.

Operatori aritmetici binari (5): +, -, *, /, % (restul împărţirii întregi). Obs.: În C, prin împărţirea a doi întregi se obţine tot un întreg Operatori aritmetici binari compuşi (cu atribuire) (5): +=, -=, *=, /=, %=

Semnificaţie: expr1 op = expr2 ⇔ expr1 = expr1 op expr2. Ex. a+=2 ⇔ a=a+2

Operatori relaţionali binari (6): >, >=, <, <=, == (egal cu), != (diferit de) Operatori logici pe cuvânt (3): && (ŞI), || (SAU), ! (NOT) Ordinea descrescătoare a priorităţii: !, >, >=, <, <=, &&, ||

Tabelul 5.2 Compunerea operatorilor logici pe cuvânt a b a&&b a||

b aXORb !a

0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0

Pentru aXORb nu există operator, dar se poate folosi (a||b)&&!(a&&b).

21

Page 26: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

Operatori logici pe bit (6): ~ (NOT), & (ŞI), | (SAU), ^ (XOR), <<, >> (deplasare biţi stânga/dreapta) Operatorul condiţional " ? :"

Este un operator ternar (necesită 3 operanzi), utilizat în construcţii de forma: expresie1 ? expresie2:expresie3

Se evaluează expresie1. Dacă aceasta are o valoare diferită de zero, atunci tipul şi valoarea întregii expresii vor fi aceleaşi cu tipul şi valoarea expresie2. Altfel (dacă expresie1 are valoarea zero), tipul şi valoarea întregii expresii vor fi aceleaşi cu tipul şi valoarea expresie3. Deci operatorul condiţional este folosit pentru a atribui întregii expresii tipul şi valoarea expresie2 sau a expresie3, în funcţie de o anumită condiţie. Acest lucru este echivalent cu:

DACĂ expresie1 ≠ 0 ATUNCI evaluează expresie2 ALTFEL evaluează expresie3

Tabelul 5.3 Prioritatea operatorilor Nr. Clasă de

operatori Operatori Asociativitate

1. Primari () [] . -> :: de la stânga la dreapta

2. Unari ! (NOT pe cuvânt) ~ (NOT pe bit) ++ -- sizeof (tip)

de la stânga la dreapta

-(unar) *(deferenţiere) &(referenţiere) de la dreapta la stânga

3. Multiplicativi * / % de la stânga la dreapta 4. Aditivi + - de la stânga la dreapta

5. Deplasare pe bit << >> de la stânga la dreapta

6. Relaţionali < <= > >= de la stânga la dreapta 7. De egalitate == != de la stânga la dreapta 8. & (ŞI logic pe bit) de la stânga la dreapta 9. ^ (XOR pe bit) de la stânga la dreapta 10. | (SAU logic pe bit) de la stânga la dreapta 11. && (ŞI logic pe cuvânt) de la stânga la dreapta

12. || (SAU logic pe cuvânt) de la stânga la dreapta

13. Condiţional ?: de la dreapta la stânga

14. De atribuire

= += -= *= %= &= ^= |= <<= >>=

de la dreapta la stânga

15. Virgulă , de la stânga la dreapta Operatorul de forţare a tipului sau de conversie explicită (expresie cast)

Adesea dorim să specificăm conversia valorii unui operand spre un tip dat. Acest lucru este posibil folosind o construcţie de forma:

22

Page 27: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

CONVERSIA ÎNTRE BAZELE DE NUMERAŢIE

(tip) operator Printr-o astfel de construcţie, valoarea operandului se converteşte spre tipul indicat

în paranteze. În construcţia de mai sus (tip) se consideră că este un operator unar. Îl vom numi operator de forţare a tipului sau de conversie explicită. Construcţia de mai sus o vom numi expresie cast. Exemplu: int x; float y; y= (float)n/2;

5.2 Prioritatea operatorilor

Tabelul 5.3 prezintă ierarhia tuturor operatorilor (grupaţi pe categorii) folosiţi în limbajul C cu priorităţile lor şi regulile de asociativitate. Operatorii dintr-o categorie au aceeaşi prioritate. Reţineţi că toţi operatorii, cu excepţia operatorilor unari, a acelor combinaţi cu atribuire şi a operatorului ?, se asociază de la stânga la dreapta. Operatorii unari (*, &, -) şi operatorul ? se asociază de la dreapta la stânga.

5.3 Conversia între bazele de numeraţie

5.3.1 Conversia zecimal-binar

Aceasta se realizează prin împărţiri succesive la doi până când câtul devine zero; şirul resturilor în ordine inversă formează numărul în baza doi.

Ex.: 2410 = 110002. Acest lucru s-a obţinut conform operaţiilor din tabelul alăturat.

5.3.2 Conversia binar-zecimal

Numărul în baza 10 este suma produselor dintre cifrele numărului în baza doi şi doi ridicat la o putere egală cu poziţia cifrei în număr; numerotarea începe din dreapta cu poziţia zero.

Ex.: 110102 = 1∙24 + 1∙23 + 0∙22 + 1∙21 + 0∙20 = 2610

5.3.3 Conversia hexazecimal-binar

Se scrie fiecare simbol al numărului hexazecimal sub formă binară. Ex.: DFH = 110111112 deoarece DH = 1310 = 11012, iar FH = 1510 = 11112

5.3.4 Conversia binar-hexazecimal

Numărul binar se împarte în grupuri de câte patru cifre, începând de la dreapta la stânga, iar apoi fiecare grup de cifre este scris în baza şaisprezece.

Ex.: 1101010 = 01101010 = 6AH deoarece 0110 = 610 = 6H, iar 1010 = 1010 = AH

Operaţie Cât Rest 24:2 12 0 12:2 6 0 6:2 3 0 3:2 1 1 1:2 0 1

23

Page 28: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

5.4 Exemple

5.4.1 Operatori aritmetici

//Program cu operatii aritmetice #include<iostream.h> void main(void) { float a,b,c,d,e; cout<<“Dati doua numere:”; cin>>a>>b; cout<<“Suma= “<<a+b<<“\nProdusul= ”<<a*b<<“\nDiferenta= ”<<a-b<<“\nCâtul= ”<<a/b; }

5.4.2 Aria şi perimetrul unui disc de rază r

Fie r un număr real, citit de la tastatură, care reprezintă lungimea razei unui cerc. Să se scrie un program care să calculeze şi să afişeze aria şi perimetrul discului de rază r.

5.4.2.1 Soluţie Vom citi valoarea razei în variabila r. Vom calcula aria discului după formula πr2, iar perimetrul, după formula 2πr. Numărul π este un număr iraţional. Calculatorul nu poate memora numere iraţionale (care au o infinitate de zecimale), ci doar aproximări ale acestora. În fişierul antet math.h este definită o constantă numită M_PI care reprezintă o aproximare a numărului iraţional π.

5.4.2.2 Programul //Cerc #include <iostream.h> #include <math.h> void main() { double r; cout<<"\nRaza r= "; cin>>r; cout<<"Aria=\t\t"<<M_PI*r*r <<"\nPerimetrul=\t" << 2*M_PI*r; }

5.4.3 Aria triunghiului - formula lui Heron

Să se calculeze aria S a unui triunghi cu laturile a,b,c citite de la tastatură folosind

formula lui Heron: S = p(p-a)(p-b)(p-c) , unde p = a+b+c

2 .

//Aria triunghiului- formula lui Heron #include <iostream.h> #include <math.h> main() { unsigned int a,b;

24

Page 29: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

float c,S,p; cout<<"\nIntroduceti prima latura a ";cin>> a; cout<<"\nIntroduceti a doua latura b ";cin>> b; cout<<"\nIntroduceti a treia latura c ";cin>> c; //c=hypot(a,b); p=(a+b+c)/2; S=sqrt(p*(p-a)*(p-b)*(p-c)); //cout<<"\nIpotenuza este "<<c; cout<<"\nSemiperimetrul este "<<p; cout<<"\nAria este "<<S; }

5.4.4 Rezolvarea unui sistem de două ecuaţii

Să se rezolve sistemul de 2 ecuaţii cu 2 necunoscute: a11⋅x + a12⋅y = b1

a21⋅x + a22⋅y = b2E

1.CITEŞTE a11,a12,a21,a22,b1,b2 2.det = a11*a22-a21*a12 3.detx = b1*a22-b2*a12 4.dety = a11*b2-a21*b1 5.x = detx/det; y = dety/det 6.SCRIE x,y

5.4.5 Incrementări/decrementări/atribuiri

Care sunt valorile variabilelor a,b şi după execuţia succesivă a următoarelor instrucţiuni (Valori iniţiale: a= 0; b= 0; c= 0):

a=(++b)+(++c) a=b+++c++ a=(++b)+c++ a=b--+--c a=(++c)+c a+=2 b-=3 c*=4 a/=2 Rezultatele programului se vor interpreta urmărind valorile variabilelor a, b şi c în

fereastra Watch

5.4.6 Operatori relaţionali şi logici - exemplul 1

//Operatori relationali si logici #include<conio.h> #include<stdio.h> void main () { int x1=1,x2=20,x,cond;

25

Page 30: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

printf("\nx= "); scanf("%d",&x); //verifica daca un nr indepl o conditie cond=x1<x&&x<x2||(x%2); printf("\nconditia x1<x&&x<x2||(x%%2) este %d",cond); cond=10>5&&!(10<9)||3<=4; printf("\nconditia 10>5&&!(10<9)||3<=4 este %d",cond); printf("\n!0&&0||0 este %d, dar",!0&&0||0); printf("\n!(0&&0)||0 este %d",!(0&&0)||0); getch(); }

5.4.7 Operatori relaţionali şi logici - exemplul 2

#include <iostream.h> void main() { int a=0, b=10, c=100, d=200; int rezult; rezult=a&&b; cout<<”a&&b=”<<rezult<<’\n’; //Afisare a&&b=0 rezult=a||b; cout<<”a||b=”<<rezult<<’\n’; //Afisare a||b=1 (sau valoare nenula) rezult=!a;cout<<”!a=”<<rezult<<’\n’; //Afisare !a=1 (sau valoare nenula) rezult=!b; cout<<”!b=”<<rezult<<’\n’; //Afisare !b=0 rezult= (a>b) || (b>c); cout<< ”(a>b) || (b>c)=” <<rezult<<’\n’; //Afisare (a>b) || (b>c) =1(sau valoare nenula) rezult=!(c<d);cout<<”!(c<d)=”<<rezult<<’\n’; //Afisare !(c>d)=0 rezult=(a-b)&&1;cout<<”(a-b)&&1=”<<rezult<<’\n’; //Afisare (a-b)&&1 =1(sau valoare nenula) rezult=d||b&&a;cout<<”d||b&&a=”<<rezult<<’\n’; //Afisare d||b&&a =1 }

5.4.8 An bisect

Să se scrie un program care citeşte un întreg din intervalul [1600, 4900], ce reprezintă un an calendaristic, afişează 1 dacă anul este bisect şi 0 în caz contrar sau dacă anul nu aparţine intervalului indicat mai sus.

Un an, din calendarul gregorian, este bisect dacă este multiplu de patru şi nu este multiplu de 100 sau dacă este multiplu de 400. Această regulă este valabilă pentru anii care nu sunt anteriori anului 1600.

Dacă notăm cu an anul calendaristic, atunci el este bisect dacă de exemplu: an%4==0 (an este multiplu de 4) an%100!=0 (an nu este multiplu de 100). Deci anul este bisect dacă expresia (1) an%4==0 && an%100!=0 este adevărată. De asemenea, anul este bisect şi în cazul în care expresia

26

Page 31: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

(2) an%400==0 (an este multiplu de 400) este adevărată. Deci anul este bisect dacă este adevărată expresia (1) sau (2), adică dacă este

adevărată expresia: an%4==0 && an%100! =0 || an%400==0

5.4.8.1 Programul //An bisect #include <stdio.h> void main ( ) { int an, bisect; printf("Anul: "); scanf("%d", &an); bisect=an>=1600 && an<=4900 && (an%4==0 && an%100!=0 || an%400==0); printf("an=%d\t%d\n",an,bisect); }

5.4.9 Operatori pe biţi

Programul afişează rezultatul următoarelor expresii: Val iniţială x= 7, în binar 00000111 Deplasare biţi x=x<<1 dă x= 14, în binar 00001110 x=x<<3 dă x= 112, în binar 01110000 x=x<<2 dă x= 192, în binar 11000000 x=x>>1 dă x= 96, în binar 01100000 x=x>>2 dă x= 24, în binar 00011000 x=~x dă x= 231, în binar 11100111 SI 7, în binar 00000111; 14, în binar 00001110 x=(7&14) dă x= 6, în binar 00000110 SAU 128, în binar 10000000; 3, în binar 00000011 x=(128|3) dă x= 131, în binar 10000011 XOR 127, în binar 01111111; 120, în binar 01111000 x=(127^120) dă x= 7, în binar 00000111

5.4.9.1 Programul //Operatii pe biti #include<conio.h> #include<iostream.h> //Functie de afisare a rezultatelor void dectobin(int x) { int i=8,bin,r[8]={0,0,0,0,0,0,0,0}; do

27

Page 32: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

{ r[i-1]=x%2; x/=2; i--; } while(x); for(i=0;i<8;i++) cout<<r[i]; } void main() { unsigned char x=7; clrscr(); cout<<"\n\t\tx= "<<int(x)<<"\tin binar ";dectobin(x); x=x<<1; cout<<"\nx=x<<1 dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); x=x<<3; cout<<"\nx=x<<3 dă\tx= "<<int(x)<<"\tin binar ";dectobin(x); x=x<<2; cout<<"\nx=x<<2 dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); x=x>>1; cout<<"\nx=x>>1 dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); x=x>>2; cout<<"\nx=x>>2 dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); x=~x; cout<<"\nx=~x dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); //SI cout<<"\n\nSI\t\t7\tin binar ";dectobin(7); cout<<"\n\t\t 14\tin binar ";dectobin(14); x=7&14; cout<<"\nx=(7&14) dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); //SAU cout<<"\n\nSAU\t\t128\tin binar "; dectobin(128); cout<<"\n\t\t 3\tin binar "; dectobin(3); x=128|3; cout<<"\nx=(128|3) dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); //SAU exclusiv cout<<"\n\nXOR\t\t127\tin binar "; dectobin(127); cout<<"\n\t\t120\tin binar "; dectobin(120); x=127^120; cout<<"\nx=(127^120) dă\tx= "<<int(x)<<"\tin binar "; dectobin(x); getch(); }

5.4.10 Operatorul ternar - maximul a două numere

Să se scrie un program care citeşte două numere şi afişează maximul dintre ele. // Operatorul ternar - maximul a 2 numere #include <stdio.h> void main () { double a,b; scanf("%lf %lf",&a,&b); printf("a=%g\tb=%g\tmax(a,b)=%g\n", a,b, a > b ? a : b); }

28

Page 33: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

5.4.11 Operatorul ternar - modulul unui număr

Să se scrie un program care citeşte un număr şi afişează valoarea lui absolută. //modulul unui numar #include <stdio.h> void main() { double a; scanf("%lf", &a); printf("a=%g\tabs(a)=%g\n",a, a < 0 ? -a : a ); }

5.4.12 Operatorul cast - rădăcina pătrată a unui număr

Să se scrie un program care citeşte un întreg şi afişează rădăcina pătrată din numărul respectiv. #include <stdio.h> #include <math.h> void main( ) {/* - citeste pe n; - calculează si afisează rădăcina pătrata din n * long n; scanf("%ld", &n); printf("n=%ld\tsqrt(n)=%g\n",n, sqrt((double)n)); }

Obs.: în acest program, pentru extragerea rădăcinii pătrate s-a utilizat funcţia sqrt. Ea are prototipul: double sqrt(double). Acest prototip este definit în fişierul math.h.

5.4.13 Operatorul cast - calculul unei expresii

Să se scrie un program care citeşte pe n de tip întreg şi afişează valoarea expresiei n/(n+1) cu 15 zecimale. #include <stdio.h> void main( ) { long n; scanf("%ld", &n); printf("n=%ld\tn/(n+1)=%.15g\n", n, (double)n/(n+1)); }

Obs.: Expresia n/(n+1) realizează împărţirea întreagă a lui n la n + 1. Pentru a obţine câtul împărţirii cu 15 zecimale, este necesar să se efectueze împărţirea neîntreagă. În acest scop s-a convertit operandul n spre tipul double. În felul acesta, conform regulii conversiilor implicite, se converteşte spre double şi cel de al doilea operand şi apoi se face împărţirea celor doi operanzi flotanţi.

29

Page 34: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

5.4.14 Operatorul virgulă

Să se scrie un program care citeşte doi întregi şi afişează maximul dintre valorile lor absolute. #include <stdio.h> void main( ) { int a,b,c,d; scanf("%d%d", &a,&b); printf("a=%d\tb=%d\tmax(abs(a),abs(b))=%d\n", a, b, ((c=a<0 ?-a:a), (d=b<0 ? -b : b), (c>d)) ? c : d); }

Obs.: Expresia: (c = a<0 ?-a), (d = b<0 ?-b:b), (c>d) se compune din trei expresii care se evaluează de la stânga la dreapta.

Prima atribuie lui c valoarea absolută a lui a, a doua atribuie lui d valoarea absolută a lui b, iar a treia testează relaţia c>d. Valoarea întregii expresii coincide cu 1 dacă c>d şi cu zero în caz contrar.

5.5 Probleme propuse

1. Să se scrie declaraţiile pentru definirea constantelor simbolice: pi, g (acceleraţia gravitaţională), unghi_drept, dimensiune_MAX.

2. Care va fi rezultatul afişat pe ecran în urma execuţiei următoarelor secvenţe de instrucţiuni:

double a=9/2; cout<<a*5<<’\n’; double a=9.7, b=5.6; cout<<(a+6<b)<<’\n’; double a=9/4; cout<<a*6<<’\n’; double x=3;int y=++x+5;cout<<y<<’\n’; int a=7; cout<<(!a)<<’\n’; int a=10.5; cout<<a++<<’\n’; cout<<a<<’\n’; int a=7; cout<<++a<<’\n’; cout<<a<<’\n’; int a=10; cout<<a++<<’\n’; cout<<a<<’\n’; double a=7/2; cout<<a<<’\n’; int x=3; int y=x++-2; cout<<y<<’\n’; int x=3; int y=++x+5; cout<<y<<’\n’; double a=5.6, b=7.45; cout<<(a>b)<<’\n’;

3. Să se verifice corectitudinea următoarelor secvenţe. Pentru cele incorecte, explicaţi sursa erorilor.

double a=9.7, b=5.2; int c=(a+6<b)++; cout<<c<<’\n’; double a=7/5; double c=a*5++; cout<<c<<’\n’; double a=9.7, b=5.6; int c=(a%6<b)++; cout<<c<<’\n’; double a=5.6, b=7.45; cout<<++(a+5>b)<<’\n’; double a=9.8; double b=9.7; cout<<a%b<<’\n’; cout<<&(a+8)<<'\n'; int I=8; cout<<(I+10)++<<'\n'; double a=8.7; A=(a+8)/56; cout<<A<<'\n'; int x=3/5; int y=x++; char x='J'; cout<<"y="<<y<<'\n'; char a='X'; const int b=89; b+=8; cout<<"b="<<b<<"

a="<<a<<'\n'; 4. Să se scrie un program care afişează următoarele mesaje:

30

Page 35: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

Sirul "este dupa-amiaza" este memorat pe .... octeti. marime intreaga este memorata pe ... octeti. marime reala, in simpla precizie este memorata pe ... octeti! marime reala, in dubla precizie este memorata pe ... byti! Constanta caracter 'Q' memorata pe ... octeti! Sirul "a\n\n" este memorat pe ... octei! Sirul "\n" este memorat pe ... biti! Caracterul '\' este memorat pe .... biti.

5. Să se evalueze expresiile, ştiind că: int i=1; int j=2; int k=-7; double x=0; double y=2.3;

-i - 5 * j >= k + 1 3 < j < 5 i + j + k == -2 * j x && i || j - 3

6. Ce operaţie logică şi ce mască trebuie să folosiţi pentru a converti codurile ASCII ale literelor mici în litere mari ? Dar pentru conversia inversă ?

7. Să se seteze pe 1 toţi biţii dintr-un octet, cu excepţia bitului cel mai semnificativ. 8. Să se scrie un program care citeşte o valoare întreagă. Să se afişeze un mesaj care să

indice dacă numărul citit este par sau impar. 9. Să se citească două valori întregi. Să se calculeze şi să se afişeze restul împărţirii

celor două numere. 10. Să se realizeze programe care execută următoarele acţiuni:

a. Se citeşte un unghi în grade; se cere să se transforme în radiani (360° = 2π rad);

b. Calculează perimetrul şi aria unui cerc de rază r citită de la tastatura; c. Calculează perimetrul şi aria unui triunghi de laturi date; d. Calculează expresia: -3∙x2 + x∙y - y/x.

11. Să se scrie un program care să convertească o temperatură în grade Celsius în echivalentul ei în grade Fahrenheit. Formula de conversie este F = 32 + 9/5 C. Programul trebuie să tipărească ambele valori ale temperaturii (în grade Celsius şi grade Fahrenheit) cu mesaje corespunzătoare.

12. Care dintre variabilele care intervin în secvenţa de operaţii următoare îşi vor păstra valoarea avută iniţial?

a ← b+c; a şi c; c ← a-c; b şi c b ← c; b şi a; c ← a-b; a, b şi c

13. Care dintre operaţiile următoare atribuie variabilei întregi x una din cifrele sale, ştiind că x > 10000:

x ← x mod 100; x ← x mod 10; x ← x div 10 mod 10; x ← x div 100 mod 10; x ← x mod 10 div 1; x ← x mod 50;

14. Fie a, b, c şi d patru variabile reale. Care dintre următoarele instrucţiuni atribuie variabilei d media aritmetică a valorilor variabilelor a, b şi c?

d=(a+b+c)/2; d=a/3+b/3+c/3; d=a+b+c/3; d=(a+b+c)/4-1;

15. Care dintre următoarele declaraţii de variabile sunt eronate sintactic şi de ce? float a=b=0; double z=x/2;

31

Page 36: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

OPERATORI ŞI EXPRESII

char d=120; int k;i; long a=0, b=a+3; unsigned float a;

16. Care dintre următoarele expresii sunt adevărate dacă şi numai dacă numărul întreg x este impar negativ?

x%2==l) && (x<0) (x%2!=0) || (x<0) !((x%2==0) || (x>=0)) !((x%2==0) && (x>=0)) x%2=l && x<0

17. Care dintre următoarele expresii sunt adevărate dacă şi numai dacă valorile variabilelor x şi y sunt numere naturale consecutive?

x-y==1 (x==1) && (y==2) (x-y==1) && (y-x==1) y==x±1 (x-y==1) || (y-x==1)

18. Să considerăm următoarele declaraţii de variabile: int x=0XF0A8, v=0XFFFD; unsigned y=0XF0A8, z=1; float a=s.5, b=4; char c=8;

Evaluaţi următoarele expresii: a+z/2 -1 > z (v+z)/2 c>='0' && c <= '9' ? "da" : "nu" (v+1) /2 x>>3&z<<4 c-'0' y>>10|z

19. În contextul declaraţiilor de variabile de la exerciţiul precedent, care sunt erorile din următoarele expresii?

(a+z)%2 a+++x b*b-4ac x=(a»2) c=a?"da" : "nu" x&&=10

20. În condiţiile următoarelor declaraţii şi iniţializări de variabile: unsigned char x=250, z=x+7, a='8';

Care este valoarea expresiei: z | (a-' 0') ? Expresia nu se poate evalua, deoarece este eronată sintactic, 1 265 0 true 9

21. Se consideră x, y şi z trei variabile întregi. Care dintre următoarele expresii are valoarea diferită de 0 dacă şi numai dacă y=max (x, y, z) ?

x>z?y>=x?1:0:y>=z?1:0

32

Page 37: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

!(y<x || y<z) !(y<x && y<z) x>z && y>x || z>x && y>z y>x && y>z

22. Pentru a atribui variabilei reale x rezultatul expresiei A

2ab - c2

0.25 E A,unde a, b şi c

desemnează variabile reale, se utilizează instrucţiunea: x=(2*a*b)-(c*c)/0.25; x=2*a*b-c*c/0.25; x=(2*a*b)-(c*c)*4; x=(2*a*b-c*c)*4;

23. Fie A şi B două puncte în plan, specificate prin coordonatele lor carteziene. Să se scrie un program care să calculeze şi să afişeze lungimea segmentului AB.

33

Page 38: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECŢIE)

6. STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECŢIE)

6.1 Structura de decizie: instrucţiunea if

Aceasta corespunde cazurilor când în algoritmul problemei intervine o decizie. Este instrucţiunea principală în C care descrie structura alternativă. Pentru un

pseudocod de forma: DACĂ (<condiţie>) ATUNCI <instrucţiune>

instrucţiunea if este: if (<condiţie>) <instrucţiune>;

iar pentru un pseudocod de forma: DACĂ (<condiţie>) ATUNCI <instr1> ALTFEL <instr2>

instrucţiunea if este: if (<condiţie>) <instr1>; else <instr2>;

Obs.: Dacă una din instrucţiunile de pe ramura "if" sau "else" este o instrucţiune compusă, atunci ea se încadrează între acolade: { <instr1>; <instr2>; ... }

şi nu se mai termină cu punct-virgulă. În caz contrar, programul va executa numai prima instrucţiune de pe ramură.

6.2 Structura de selecţie cu ramuri multiple: instrucţiunea switch

În unele cazuri este necesară o decizie multiplă specială. Instrucţiunea switch permite acest lucru.

DACĂ expresie=expr_const_1 instrucţiune1; [ieşire;] ALTFEL DACĂ expresie=expr_const_2 instrucţiune2; [ieşire;] … ALTFEL DACĂ expresie=expr_const_n-1 instrucţiune_n-1; [ieşire;] ALTFEL instrucţiune_n; Se testează dacă valoarea pentru expresie este una dintre constantele specificate

(expr_const_1, expr_const_2, etc.) şi se execută instrucţiunea de pe ramura corespunzătoare. În schema logică, test_expresie este una din condiţiile: expresie=expr_const_1, expresie=expr_const_2, etc.

Sintaxa: switch (expresie) { case expresie_const_1: instructiune_1; [break;]

34

Page 39: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE IF, SWITCH

case expresie_const_2: instructiune_2; [break;] . . . . . . . . . . . . . . case expresie_const_n-1: instructiune_n-1;[break;] [ default: instructiune_n; ] }

Instrucţiunea switch este o generalizare a instrucţiunii if. Spre deosebire de if, care permite selectarea unei alternative din maximum două posibile, switch permite selectarea unei alternative din maximum n+1 posibile. O altă diferenţă majoră constă în faptul că în if se execută instrucţiunea corespunzătoare valorii expresiei şi atât, în timp ce în switch se execută şi toate secvenţele de instrucţiuni ale alternativelor case următoare.

6.3 Exemple if, switch

6.3.1 Maximul a trei numere

6.3.1.1 Pseudocodul 1.CITEŞTE a,b,c 2.DACĂ a>b ATUNCI max=a ALTFEL max=b 3.DACĂ c>max ATUNCI max=c 4.SCRIE max

6.3.1.2 Programul #include<iostream.h> main() { int a,b,c,max; cout<<"Dati a b c"; cin>>a>>b>>c; if(a>b) max=a; else max=b; if(c>max) max=c; cout<<"maximul="<<max; }

6.3.2 Calculator de buzunar

//Instruc de selectie switch #include<stdio.h> void main() { float x,y,z; char op; printf("\nIntroduceti expresia (valoare operator valoare): "); scanf("%f %c %f",&x,&op,&y); switch(op) { case '+':z=x+y; break; case '-':z=x-y; break;

35

Page 40: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECŢIE)

case '*':z=x*y; break; case '/':z=x/y; break; default: printf("\nOperator eronat"); z=0; } printf("%.2f %c %.2f= %.2f",x,op,y,z); }

6.3.3 Sumă

Orice sumă de bani S (S>7) poate fi plătită numai cu monede de 3 lei şi de 5 lei. Dat fiind S>7, scrieţi un program care să determine o modalitate de plată a sumei S numai cu monede de 3 lei şi de 5 lei. Cum se poate obţine numărul minim de monede ?

6.3.3.1 Soluţie Problema cere, de fapt, să găsim două numere naturale x şi y, astfel încât s să poată fi scris sub forma S = 3*x+5*y.

Vom analiza următoarele trei cazuri: 1. S%3 (restul împărţirii lui S la 3) este 0. În acest caz, x = S/3, iar y = 0. 2. S%3 este 1. Deoarece S>7, vom considera x = S/3 - 3 şi y = 2, pentru că S = 3 * S/3

+ l = 3 * (S/3 - 3) + 3*3 + 1 = 3*(S/3 - 3) + 10 = 3*(S/3 - 3) + 5*2. 3. S%3 este 2. În acest caz vom considera x = S/3 - l şi y = l, deoarece S = 3*S/3 + 2 =

3*(S/3 - l) + 3 + 2 = 3*(S/3 - l) + 5.

6.3.3.2 Programul #include <stdio.h> int main (void) { int S, x, y, r; printf("Introduceti suma S: "); scanf("%d", &S); r=S%3; switch (r) { case 0: x=S/3; y=0; break; case 1: x=S/3-3; y=2; break; case 2: x=S/3-1; y=1; } printf("%d = 3*%d + 5*%d\n",S,x,y); return 0; }

6.4 Probleme propuse

Să se alcătuiască programe care să rezolve următoarele probleme: 1. Calculul valorii unei funcţii - Să se calculeze şi să se afişeze valoarea funcţiei f pentru

un x dat: 4x3 + 5x2 - 2x + 1, x<0 f(x)= 100, x=0 ex - ln x, x>0

36

Page 41: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

2. Ecuaţia de gradul 2 (vezi şi schema logică). Pseudocodul: 1.CITEŞTE a,b,c 2.DACĂ a=0 ATUNCI 2.1.DACĂ b=0 ATUNCI 2.1.1.DACĂ c=0 ATUNCI 2.1.1.1 SCRIE "ec.are o infinitate de sol." 2.1.1.2 ALTFEL SCRIE "ec.nu are sol" 2.1.2 ALTFEL SCRIE "ec.are sol.unică x=",-c/b ALTFEL 2.2 d=b*b-4*a*c 2.2.1 DACĂ d>0 ATUNCI 2.2.1.1. x1=(-b- A dE A)/(2*a) 2.2.1.2. x2=(-b+A dE A)/(2*a) 2.2.1.3. SCRIE "x1=",x1,"x2=",x2 ALTFEL 2.2.1.2 DACĂ d=0 ATUNCI 2.2.1.2.1 SCRIE "ec.are rad.dubla x=",-b/(2*a) ALTFEL 2.2.1.2.2 re = -b/(2*a), im = A -dE A/(2*a) SCRIE "ec.are sol.complexe re = ", re," im = ",im

3. Modulul şi argumentul unui număr complex. Pseudocodul: 1.CITEŞTE re,im 2.modul = A re*re+im*im E 3.DACĂ re=0 ATUNCI 3.1 DACĂ im>=0 ATUNCI 3.1.1 arg=pi/2 ALTFEL 3.1.2 arg = -pi/2 3.2 ALTFEL DACĂ re>0 ATUNCI 3.2.1 arg=arctg(im/re) ALTFEL 3.2.2 arg=-arctg(im/re) 4.SCRIE modul, arg

4. Calculul volumului unui corp geometric - Să se scrie un program care afişează un mesaj de tip meniu şi în funcţie de un caracter citit de la tastatură (1 - paralelipiped, 2 - cilindru, 3 - con, 4 - sferă, 0 - terminare program), citeşte dimensiunile necesare şi calculează şi afişează în cadrul unui mesaj volumul corpului respectiv (Vp = H·B·L; Vcil = π·R2·H; Vcon = π·R2·H/3; Vsf = π·D3/6).

5. Care este efectul următoarei secvenţe de instrucţiuni? int a, b, c, x; a=3; b=5; c=7; if (a-b/2<0) x=1; else if (a+b-c/2<b) x=2; else if (a%b+c>b) x=3;

37

Page 42: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECŢIE)

else x<-4; cout<<x;

6. Ce valoare iniţială ar putea avea variabila x, astfel încât la sfârşitul execuţiei următoarei secvenţe de instrucţiuni variabila y să aibă valoarea 2? if (x>3) if (x<7) if (x%2==0) y=1; else y=2; else y=3; else

y=4; 7. Fie x şi y două numere reale, citite de la tastatură. Scrieţi un program care calculează

şi afişează valoarea funcţiei:

A

x + y5xy E A dacă x, y > 0

f(x,y)= min (x, y), dacă x = 0 sau y = 0

A

1

x + 1Ey E AA

1

x + 1Ey + x2 + y2

E A, altfel 8. Fie x un număr natural de trei cifre. Scrieţi un program care să elimine una dintre

cifrele numărului astfel încât numărul de două cifre rămas să fie maxim.

38

Page 43: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE WHILE

7. STRUCTURA CICLICĂ CU TEST INIŢIAL

Aceasta corespunde cazurilor când în algoritmul problemei intervine iteraţia unei acţiuni până la o condiţie de oprire.

7.1 Instrucţiunea while

Este principala instrucţiune în C++ care descrie structura ciclică cu test iniţial. Pentru un pseudocod de forma:

CÂT TIMP (<condiţie>) EXECUTĂ <instrucţiune> instrucţiunea while este:

while (<condiţie>) <instrucţiune>;

7.2 Exemple while

7.2.1 Algoritmul lui Euclid

7.2.1.1 Pseudocodul (vezi şi schema logică de la 2.3.4) 1.CITEŞTE a,b 2.cmmmc=a*b 3.CÂT TIMP b<>0 2.5.1.r = a%b //restul 2.5.2.a = b 2.5.3.b = r 2.6.cmmdc = a 2.7.cmmmc = cmmmc/cmmdc 2.8.SCRIE cmmmc, cmmdc

7.2.1.2 Programul //Algoritmul lui Euclid #include<iostream.h> int main() { long int a,b,rest,cmmmc,cmmdc; cout<<"\na=";cin>>a; cout<<"b=";cin>>b; cmmmc=a*b; while(b) { rest=a%b; cout<<"\n"<<a<<" = "<<b<<" * "<<a/b<<" + "<<rest; a=b; b=rest; } cmmdc=a; cmmmc=cmmmc/cmmdc;

39

Page 44: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST INIŢIAL

cout<<"\n\ncmmmc= "<<cmmmc<<" cmmdc= "<<cmmdc; return 0; }

Obs.: Nu se verifică dacă iniţial a > b; acest lucru nu este necesar, deoarece, dacă iniţial a < b, după prima executare a instrucţiunii compuse subordonate instrucţiunii while, valorile lui a şi b vor fi schimbate.

7.2.2 Produsul primelor “n” numere naturale (factorialul)

#include <iostream.h> void main() {int prod=1,i=0,n; char c; cout << "\nSpecificati numarul n:"; cin >> n; while(i<n) { i++; prod=prod*i; } cout << "\nFactorial de " << n << "=" << prod << "\n"; cin >> c; }

7.2.3 Suma primelor “n” numere naturale

#include <iostream.h> void main() {int suma=0,i=0,n; cout << "\nSpecificati numarul n:"; cin >> n; while(i<n) { i++; suma=suma+i; } cout << "\nSuma primelor " << n << " numere naturale=" << suma << "\n"; }

7.2.4 Descompunerea unui număr în factori primi

7.2.4.1 Pseudocodul 1. CITEŞTE n 2. n=abs(n) 3. f=2 //factorul prim de testat 4. CÂT TIMP (f<=n) 4.1.e=0 //exponentul la care apare factorul în descompunere 4.2.CÂT TIMP (n%f==0) //n se divide la f 4.2.1.n=n/f

40

Page 45: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE FOR

4.2.2.e=e+1 4.3.DACĂ (e≠0) SCRIE f," la ",e 4.4.DACĂ (f=2) f=f+1 ALTFEL f=f+2

7.3 Instrucţiunea for

În majoritatea limbajelor de programare de nivel înalt, instrucţiunea for implementează structura ciclică cu număr cunoscut de paşi. În limbajul C, instrucţiunea for poate fi utilizată într-un mod mult mai flexibil. Reprezentare în pseudocod: evaluare expresie1 CÂT TIMP expresie2 REPETĂ ÎNCEPUT instructiune evaluare expresie3 SFÂRSIT

Sintaxa: for (expresie1; expresie2; expresie3)

instructiune; unde: expresie1 - reprezintă iniţializarea contorului; expresie2 - condiţia de rămânere în ciclu; expresie3 - modificarea contorului şi/sau instrucţiuni. Nu este obligatorie prezenţa expresiilor, ci doar a instrucţiunilor vide.

7.4 Exemple for

7.4.1 Calculul factorialului

//Calculul factorialului #include<iostream.h> #include<conio.h> void main() { long int i,n,fact=1; clrscr(); cin>>n; for(i=1;i<=n;i++) fact*=i; cout<<fact; getch(); }

41

Page 46: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST INIŢIAL

7.4.2 Calculul unei sume duble

Să se calculeze suma dublă A∑i=1

m

∑j=1

n sin(a+3*i)*cos(b+5*j).

7.4.2.1 Pseudocodul 1.CITEŞTE a,b,m,n 2.i=1 3.j=1 4.s=0 5.CÂT TIMP (i<=m) 5.1.CÂT TIMP (j<=n) 5.1.1.s=s+ sin(a+3*i)*cos(b+5*j) 5.1.2.j=j+1 5.2.i=i+1 6.SCRIE s

7.4.2.2 Programul #include<iostream.h> #include<math.h> main() { float s=0,a,b; int m,n,i,j; cout<<"a="; cin>>a; cout<<"b="; cin>>b; cout<<"m="; cin>>m; cout<<"n="; cin>>n; for(i=1,j=1; i<=m,j<=n; i++,j++) s=s+sin(a+3*i)*cos(b+5*j); cout<<"Suma="<<s; }

7.4.3 Şirul lui Fibonacci, termenii < n.

Dacă n=0: f0=0, n=1: f1=1, altfel: fi = fi-2 + fi-1

7.4.3.1 Pseudocodul 1. CITEŞTE n 2. DACĂ n>=2 2.1.PENTRU f0=0 şi f1=1, CÂT TIMP f1≤n, f0=f1, f1=fi, REPETA 2.1.1.fi=f0 + f1 2.1.2.SCRIE fi

7.4.3.2 Programul //Genereaza numerele Fibonacci #include<stdio.h> #include<conio.h> void main() {

42

Page 47: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

int f0,f1,fi,n; clrscr(); printf("Introd n: "); scanf("%d",&n); if(n>=2) { for(f0=0,f1=1,fi=1;fi<=n;f0=f1,f1=fi,fi=f0+f1) {printf("\nf0=%d; \tf1=%d; \tfi=%d;",f0,f1,fi); } } getch(); }

7.4.4 Afişarea codurilor ASCII ale caracterelor

//Coduri ASCII caractere #include<conio.h> #include<stdio.h> void main() { int i,j; clrscr(); // printf("\ncaracASCII\tcod zecimal\tcod octal"); for(i=0;i<=255;i+=10) { printf("\n"); for(j=1;j<=10;j++) if(i+j<=255) printf("%d: %c ",i+j,i+j); //if(!(i%25)) getch(); } getch(); }

7.5 Probleme propuse

1. Se consideră următoarea secvenţă de instrucţiuni: int n, d=2; cin>>n; while (n>l) if (n%d==*0) n/=d; cout<<d;

a. Ce valoare va fi afişată dacă valoarea citită pentru variabila n este 720? b. Daţi exemplu de valori (cel puţin două) care ar putea fi introduse pentru variabila n, astfel încât valoarea afişată să fie 11. c. Care este efectul acestei secvenţe de instrucţiuni?

2. Se consideră următoarea secvenţă de instrucţiuni: int x, a, b, i; cin>>a>>b; i=a; x=0; while (i<=b) { x+=i;i++; } cout<<x;

43

Page 48: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST INIŢIAL

a. Ce valoare va fi afişată pe ecran dacă se introduc valorile 1 şi 10? b. Ce valori ar putea fi introduse pentru a şi b astfel încât programul să afişeze valoarea 22? c. Daţi exemplu de valori distincte care ar putea fi introduse astfel încât programul să afişeze valoarea 0. d. Scrieţi un program echivalent mai eficient.

3. Care dintre următoarele secvenţe de instrucţiuni atribuie variabilei întregi u valoarea primei cifre a numărului natural reprezentat de variabila x ?

u=x/10; u=x; while (u>=10) u=u%10; u=x%10; while (x>=10) x=x/10; u=x;

4. Ce valoare iniţială ar trebui să aibă variabila x astfel încât după execuţia următoarei secvenţe de instrucţiuni să se afişeze valoarea 640?

d=2; while (d<50) { x=x*d; d=d*d;} cout«x;

5. Numere prietene - Două numere naturale a şi b se numesc prietene dacă a este egal cu suma divizorilor lui b (exclusiv b), iar b este egal cu suma divizorilor lui a (exclusiv a). De exemplu, a=220 şi b=284 sunt prietene. Scrieţi un program care să determine primele trei perechi de numere prietene, cu a<b.

6. Plata sumei - Se citesc de la tastatură două numere naturale S şi x (0<S<10000, 0<x<l00). S reprezintă o sumă pe care trebuie să o plătim, utilizând un număr minim de bancnote. Bancnotele au ca valori numai puteri ale lui x (1, x, x2, x3, ...) şi presupunem că dispunem de un număr suficient de mare de bancnote. Scrieţi un program care afişează pe ecran o modalitate de a plăti suma, utilizând un număr minim de bancnote. De exemplu, pentru S=107 şi x=5, veţi afişa:

4 bancnote cu valoarea 25 1 bancnote cu valoarea 5 2 bancnote cu valoarea 1

44

Page 49: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE DO - WHILE

8. STRUCTURA CICLICĂ CU TEST FINAL

8.1 Instrucţiunea do - while

Pentru un pseudocod de forma: <instrucţiune 1>

CÂT TIMP (<condiţie>) EXECUTĂ <instrucţiune 1> instrucţiunile C++ sunt:

<instrucţiune 1>; while (<condiţie>) <instrucţiune 1>; Aceste instrucţiuni se pot înlocui cu o singură instrucţiune do-while astfel:

do <instrucţiune 1> while (<condiţie>); Aceasta nu reprezintă decât structura iterativă cu test final, "repetă instrucţiune cât

timp condiţie".

8.2 Exemple do - while

8.2.1 Calculul sumei unor numere citite de la tastatură până la introducerea numărului zero

8.2.1.1 Pseudocodul 1.s=0 2.REPETĂ 2.1. CITEŞTE x 2.2. s=s+x CÂT TIMP (x!=0) 3. SCRIE s

8.2.1.2 Programul #include<iostream.h> void main() { float s,x; s=0; cout<<"Dati numerele de adunat (0-oprire)"; do { cin>>x; s+=x;} while (x!=0); cout<<"suma este: "<<s; }

8.2.2 Calculul unei sume cu o precizie impusă

Să se calculeze suma S = ∑k=1

(-1)k·xk

k! până când |T/S| < ε.

45

Page 50: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST FINAL

Obs.: Tk = -Tk-1·x/k, iar Sk = Sk-1 + Tk

8.2.2.1 Pseudocodul 1. CITEŞTE x, eps, 2. T = S = k = 1, 3. REPETĂ 3.1. T = -T·x/k, 3.2. S = S + T, 3.3. k = k + 1 CÂT TIMP |T/S| ≥ ε 4. SCRIE S

8.2.2.2 Programul //Calculul unei sume #include<conio.h> #include<math.h> #include<stdio.h> void main() { int k=1; float x,T,S,eps=1e-05; //clrscr(); printf("\nIntroduceti val x: "); scanf("%f",&x); T=S=1; do { printf("\nk= %d;\tT= %12.4f;\tS= %14.10f;\t|T/S|= %14.10f;",k,T,S,fabs(T/S)); T=-T*x/k; S+=T; k++; } while(fabs(T/S)>=eps); getch(); }

8.2.3 Radical de ordinal 3

Fie x un număr real. Să se calculeze 3 x (radical de ordin 3 din x), folosind relaţia de recurenţă:

r1 = 1 ; ri = (2*ri - 1 + x/(ri-1 * ri-1))/3, dacă i>1 Rezultatul trebuie să fie obţinut cu o precizie mai bună decât 10-4.

8.2.3.1 Soluţie Observăm că pentru a calcula termenul i din acest şir recurent este necesar numai termenul i-1. Prin urmare, vom utiliza două variabile r1 (în care reţinem termenul calculat la pasul precedent) şi r2 (în care reţinem termenul pe care urmează să îl calculăm).

46

Page 51: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE DO - WHILE

Pentru a obţine precizia cerută în problemă, vom calcula termeni din şir până când diferenţa în valoare absolută dintre doi termeni consecutivi este mai mică decât precizia specificată. Pentru a calcula diferenţa în valoare absolută dintre doi termeni consecutivi, vom utiliza funcţia fabs() din biblioteca de funcţii matematice (această funcţie calculează modulul unui număr de tip double specificat ca parametru).

8.2.3.2 Programul //Radical de ord 3 #include <iostream.h> #include <math.h> #define EPS 0.0001 void main() { double x, r1, r2=1; cout<<"\nx= "; cin>>x; do { r1=r2; r2=(2*r1+x/(r1*r1))/3; } while (fabs(r2-r1)>=EPS); cout<<"Radical de ord 3: "<<r2; }

8.2.4 Funcţii pentru ridicarea lui 2 la o putere întreagă şi pentru calculul radicalului de ordinul doi

Să se alcătuiască un program în care să fie implementate o funcţie pentru ridicarea lui 2 la o putere întreagă şi una pentru calculul radicalului de ordinul 2 pe baza şirului lui Newton.

8.2.4.1 Strategia de rezolvare Funcţia care va calcula puterea întreagă a lui 2 se bazează pe efectul de deplasare a biţilor din reprezentarea binară a unui număr. Astfel, o deplasare la stânga a lui a de b ori (a<<b) presupune o înmulţire a lui a cu 2 de b ori: a<<b este echivalentă cu a⋅2b. La fel, o deplasare la dreapta la nivel de bit, a lui a cu b poziţii (a>>b) presupune o împărţire a lui a cu 2 de b ori (a⋅2-b).

Construcţia funcţiei ce calculează rădăcina pătrată a unui număr x are la bază şirul

lui Newton, dat prin relaţia de recurenţă an+1 = 0.5

an +

xan

, unde primul element a1 = 1,

iar n>2. Funcţia calculează termenii succesivi ai şirului până când diferenţa, în valoare absolută, dintre doi termeni succesivi este mai mică decât eroarea acceptată pentru calcul.

8.2.4.2 Programul /*Calculul ridicarii lui 2 la o putere intreaga -i calculul radacinii patrate fara utilizarea funct sqrt */ #include<iostream.h> #include<conio.h>

47

Page 52: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST FINAL

#include<math.h> void main() { int a; float p, q=1, err=1e-6; char Exit; do { clrscr(); cout<<"\nDati un numar A ="; cin>>a; cout<<"\n2^"<<a<<" = "<<(1<<a); //Se calculeaza radacina patrata a lui x. do { p=q; q=(p+a/p)/2; //cout<<"\n"<<p<<'\t'<<q; } while(fabs(q-p)>err); cout<<"\nRadical din "<<a<<"="<<q; cout<<"\nPentru iesire apasati-> e.."; Exit=getch(); } while(Exit!='e'); }

8.3 Prelucrarea numerelor

Programele următoare se bazează pe următoarele instrucţiuni: 1. împărţire întreagă (modulo) a unui număr întreg la 10 prin care se obţine cifra unităţilor numărului. Ex: 1234%10 → 4

2. împărţire propriu-zisă a unui număr întreg la 10 prin care se obţine tot un întreg. Ex: 1234/10 → 123 şi NU 123.4

Secvenţele următoare descriu strict metoda prezentată şi nu întreg programul !

8.3.1 Suma cifrelor unui număr "n"

s=0;nl=n; do { s+=nl%10; //se obtine pe rind fiecare cifra nl/=10; //incepind cu cea a unitatilor } while(nl); cout<<"\nSuma cifrelor nr. "<<n<<" = "<<s;

8.3.2 Ştergerea unei cifre "a" dintr-un număr "n"

nl=0;

48

Page 53: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRELUCRAREA NUMERELOR

do { if (n%10!=a) nl=nl*10+n%10; n/=10; } while(n); do { n=n*10+nl%10; nl/=10; } while(nl); cout<<"\nNoul numar: "<<n;

8.3.3 Oglindirea unui număr "n"

n_o=0;nl=n; do { n_o=n_o*10+nl%10; nl/=10; } while(nl); cout<<"\nOglinditul lui "<<n<<" este "<<n_o;

8.3.4 Trecerea unui număr "n" din baza 10 în baza b∈[2…9]

n_b=0; ord=1; aux=n; do { c=aux%b; n_b+=c*ord; ord*=10; aux/=b; } while(aux); cout<<"\nNumarul "<<n<<" in baza "<<b<<" este "<<n_b;

8.3.5 Trecerea unui număr "n" din baza b∈[2…9] în baza 10

n_10=0;p=l; do { n_10=n_10+n%10*p; n/=10; p*=b; } while(n); cout<<n_10;

8.3.6 Apariţia unei cifre "a" într-un număr "n"

nr=0;nl=n;

49

Page 54: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST FINAL

do { if(nl%10==a) nr++; nl/=10; } while(nl); cout<<"\nCifra "<<a<<" apare de "<<nr<<" ori";

8.3.7 Inserarea unei cifre "a" pe o poziţie "k" a unui număr "n"

nl=0;i=0;//poz.se numără de la sfârsit while(i++<k) { nl=nl*10+n%10; n/=10; } nl=nl*10+a; do { n=n*lD+nl%10; nl/=10; } while(nl); cout<<"\nNoul numar este: "<<n;

8.3.8 Cifra maximă "cmax" a unui număr "n"

cmax=0;nl=n; do { if(cmax<n%10) cmax=nl%10; nl/=10; } while (nl) ; cout<<"\ncmax="<<cmax;

8.4 Facilităţi de întrerupere a unei secvenţe

8.4.1 Instrucţiunea break

Utilizată în cadrul instrucţiunilor ciclice, instrucţiunea break "forţează" ieşirea din acestea. Fără a se mai testa valoarea expresiei (condiţia) care determină repetarea corpului instrucţiunii ciclice, se continuă execuţia cu instrucţiunea care urmează instrucţiunii ciclice. Astfel, se întrerupe repetarea corpului instrucţiunii ciclice, indiferent de valoarea condiţiei de test.

Utilizarea în cadrul instrucţiunii switch: în situaţia în care s-a ajuns la o valoare a unei expresii constante egală cu cea a expresiei aritmetice, se execută instrucţiunea corespunzătoare acelei ramuri. Dacă se întâlneşte instrucţiunea break, parcurgerea este întreruptă (nu se mai compară valoarea expresiei aritmetice cu următoarele constante), deci se va trece la execuţia primei instrucţiuni de după switch. Dacă nu este întâlnit

50

Page 55: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE BREAK, CONTINUE

break, parcurgerea continuă. Instrucţiunea break cauzează deci, ieşirea imediată din switch.

8.4.2 Instrucţiunea continue

Întâlnirea instrucţiunii continue determină ignorarea instrucţiunilor care o urmează în corpul instrucţiunii ciclice şi reluarea execuţiei cu testarea valorii expresiei care determină repetarea sau nu a corpului ciclului.

8.4.3 Modul de utilizare a instrucţiunilor break şi continue

do { instructiune1; instructiune2; if (expresie2) break; else continue; instructiune3; } while (expresie1); …

while (expresie1) { instructiune1; instructiune2; if (expresie2) break; else continue; instructiune3; } …

for (expr1;expr2;expr3) { instructiune1; instructiune2; if (expresie2) break; else continue; instructiune3; } …

8.5 Exemple break, continue

8.5.1 break - ziua din săptămână

Să se scrie un program care citeşte o cifră din intervalul [1,7] şi afişează denumirea zilei din săptămână corespunzătoare cifrei respective (1-luni, 2-marţi, etc.). #include <stdio.h> #include <stdlib.h> void main( ) { int i; scanf("%d", &i); switch(i) { case 1: puts("luni");break; case 2: puts("marti");break; case 3: puts("miercuri"); break; case 4: puts("joi"); break; case 5: puts("vineri"); break; case 6: puts("simbata"); break; case 7: puts("duminica"); break; default: puts("Valoare gresita !");exit(1); }

51

Page 56: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURA CICLICĂ CU TEST FINAL

}

8.5.2 continue - inversele unor numere

Să se calculeze inversele unor numere reale introduse pe rând de la tastatură #include<iostream.h> void main() { float n; for(int i=0; i<=3; i++) { cout<<"\nn= "; cin>>n; if(n==0) continue; cout<<”1/”<<n<<”= "<<1/n; } }

8.6 Probleme propuse

1. Să se calculeze aria unui triunghi, cunoscându-se mărimea laturilor sale. Numerele care reprezintă mărimile laturilor vor fi introduse de utilizator. Se va testa mai întâi dacă cele 3 numere reprezentând mărimea laturilor pot forma un triunghi (a <= b+c, b <= c+d, c <= a+b).

2. Să se rescrie următoarea secvenţă, folosind o singură instrucţiune if. if (n<0)

if (n>=90) if (x!=0) int b= n/x;

3. Să se găsească toate numerele de două cifre care satisfac relaţia: xy¯¯ = (x+y)2 4. Să se citească un şir de numere reale, până la întâlnirea numărului 800 şi să se

afişeze valoarea minimă introdusă, suma şi produsul elementelor şirului. 5. Scrieţi un program care să verifice inegalitatea 1/(n+1) < ln[(n+1)/n] < 1/n, unde n

este un număr natural pozitiv, introdus de la tastatură. 6. Fie funcţia

ex-3 , x ∈ [0, 1) f(x)= sin(x)+cos(x) , x ∈ [1, 2) 0,9·ln(x+3) , x ∈ [2, 100] Să se calculeze f(x), unde x e citit de la tastatură. 7. Să se scrie un program care calculează şi afişează maximul şi minimul a 3 numere

reale (a, b şi c) citite de la tastatură. 8. Să se citească 2 caractere care reprezintă 2 litere mari. Să se afişeze caracterele citite

în ordine alfabetică. 9. Să se citească 3 caractere care reprezintă 3 litere mici. Să se afişeze caracterele citite

în ordine alfabetică. 10. Să se calculeze valoarea polinomului Cebîşev de ordin n într-un punct x dat,

cunoscând relaţia:

52

Page 57: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

T0(x)=1, T1(x)=x şi Tk+1(x) - 2xTk(x) + Tk -1(x) = 0 11. Să se citească câte 2 numere întregi, până la întâlnirea perechii (0, 0). Pentru

fiecare pereche de numere, să se calculeze şi să se afişeze cel mai mare divizor comun.

12. Se citesc câte 3 numere reale, până la întâlnirea numerelor 9, 9, 9. Pentru fiecare triplet de numere citit, să se afişeze maximul.

13. Se citeşte câte un caracter până la întâlnirea caracterului @. Să se afişeze numărul literelor mari, numărul literelor mici şi numărul cifrelor citite; care este cea mai mare (lexicografic) literă mare, literă mică şi cifră introdusă.

14. Se citesc câte 2 numere întregi, până la întâlnirea perechii de numere 9, 9. Pentru fiecare pereche de numere citite, să se afişeze cel mai mare divizor comun al acestora.

15. Să se calculeze suma seriei 1 + x3/3 - x5/5 + x7/7 - … cu o eroare mai mică decât ε (citit de la tastatură). Să se afişeze şi numărul de termeni ai sumei.

16. Să se citească un număr întreg format din 4 cifre ( abcd ¯¯¯¯ ). Să se calculeze şi să se afişeze valoarea expresiei reale: 4*a + b/20 -c + 1/d.

17. Să se scrie un program care afişează literele mari ale alfabetului în ordine crescătoare, iar literele mici - în ordine descrescătoare.

18. Să se scrie un program care generează toate numerele perfecte până la o limită dată, LIM. Un număr perfect este egal cu suma divizorilor lui, inclusiv 1 (exemplu: 6=1+2+3).

19. Să se calculeze, pentru 0<=x<=1, x citit de la tastatură, valoarea sumei următoare, cu o eroare ε < 0.0001:

S=1+(x+1)/ 2! + (x+2)/ 3! + (x+3)/ 3! + ... , 20. Să se genereze toate numerele naturale de 3 cifre pentru care cifra sutelor este

egală cu suma cifrelor zecilor şi unităţilor. 21. Să se citească câte un număr întreg, până la întâlnirea numărului 90. Pentru

fiecare număr, să se afişeze un mesaj care indică dacă numărul este pozitiv sau negativ. Să se afişeze cel mai mic număr din şir.

22. Să se genereze toate numerele naturale de 3 cifre pentru care cifra zecilor este egală cu diferenţa cifrelor sutelor şi unităţilor.

23. Să se calculeze suma: (1 + 2!) / (2 + 3!) - (2+3!) / (3+4!) + (3+4!) / (4+5!) - .....

53

Page 58: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI UNIDIMENSIONALE

9. TABLOURI UNIDIMENSIONALE

Numim tablou o colecţie (grup, mulţime ordonată) de date, de acelaşi tip, situate într-o zonă de memorie continuă (elementele tabloului se află la adrese succesive şi pot fi referite prin indici.).

Unui tablou i se dă un nume; tipul comun al elementelor este şi tipul tabloului respectiv. De exemplu, o mulţime ordonată de întregi reprezintă un tablou de tip întreg.

În cazul în care elementele care se grupează într-un tablou sunt ele însele tablouri vom avea nevoie de mai mulţi indici pentru a ne referi la ele; în acest caz avem un tablou multidimensional (n-dimensional, n fiind numărul de indici), altfel - tablou unidimensional.

Exemple simple de tablouri unidimensionale sunt vectorii cu componentele de acelaşi tip. O matrice este un tablou bidimensional.

Referirea la elementele unui tablou se face printr-o variabilă cu indici. O variabilă cu indici se compune din numele tabloului urmat de valorile indicilor, fiecare indice fiind reprezentat de o expresie inclusă între paranteze pătrate.

Valoarea inferioară a indicilor este 0, iar cea superioară este (dimensiunea-1). De exemplu, dacă vect este un tablou cu 10 elemente (de dimensiune 10), atunci ne referim la elementele lui cu ajutorul variabilelor cu indici:

vect[0] primul element ............ vect[9] ultimul element Dacă mat este o matrice de 3 linii a două coloane fiecare, atunci elementele vor fi

referite prin: mat[0][0] mat[0][1] prima linie mat[1][0] mat[1][1] a doua linie mat[2][0] mat[2][1] a treia linie

9.1 Declaraţia de tablou

Un tablou, ca orice variabilă simplă, trebuie declarat înainte de a fi utilizat. Declaraţia de tablou în forma cea mai simplă conţine tipul comun elementelor sale, numele tabloului şi limitele superioare pentru fiecare indice incluse între paranteze pătrate:

tip nume_tabl [lim_1][lim_2]...[lim_n] = {lista valori} unde tip este tipul de bază al tabloului, iar lim_i este limita superioară a celui de-al i-

lea indice; înseamnă că indicele al i-lea poate lua valorile: 0, 1,..., lim_n-1 (lim_n - sunt expresii constante).

La întâlnirea unei declaraţii de tablou, compilatorul alocă o zonă de memorie necesară păstrării valorii elementelor sale.

9.2 Vectori

Vectorii sunt tablouri unidimensionale. Declararea (şi eventual iniţializarea) lor se face astfel:

54

Page 59: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

tip nume_tabl[lim_1] = {lista valori} Ex.:

int v[3]; float vec[2] = {66.1, 39.7} //Tablou unidimensional numit vec[2] cu 2 elemente reale, initializat

9.3 Exemple

9.3.1 Citirea primelor n elemente ale unui vector

for(i=0; i<n; i++) cin>>a[i];

9.3.2 Scrierea primelor n elemente ale unui vector

for(i=0; i<n; i++) cout<<a[i];

9.3.3 Operaţii cu elementele unui vector

Să se alcătuiască un program care să determine valoarea minimă, maximă, suma şi media elementelor unui şir de numere reale.

9.3.3.1 Strategia de rezolvare Va fi citit mai întâi numărul curent de elemente ale şirului, iar apoi vor fi citite succesiv elementele şirului folosind o variabilă intermediară temp.

Pentru determinarea valorii minime şi maxime a şirului se iniţializează atât minimul, cât şi maximul cu prima poziţie din şir, după care, succesiv, vor fi comparate elementele şirului cu minimul curent şi respectiv cu maximul curent. Dacă valoarea comparată a elementului şirului este mai mare decât maximul curent, atunci această valoare devine maximul curent. Similar se petrec lucrurile pentru valoarea minimă.

Pentru calculul sumei elementelor şirului, variabila suma se iniţializează cu zero, după care fiecare element al şirului se adaugă la valoarea curentă a sumei, conform relaţiei: suma= suma + a[i], relaţie ce poate fi scrisă simplificat astfel: suma+=a[i]. Media aritmetică se calculează prin raportarea sumei elementelor la numărul de elemente din şir.

9.3.3.2 Programul /* Operaţii cu elementele unui vector*/ #include<stdio.h> #include<conio.h> void main() { int i,N; float temp,suma,media,min,max,a[100]; clrscr(); printf("Dati nr. de elem ale sirului N="); scanf("%2d",&N); for(i=0;i<N;i++) {

55

Page 60: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI UNIDIMENSIONALE

printf("A[%2d]=",i); scanf("%f",&temp); a[i]=temp; } min=a[0];max=a[0]; for(i=1;i<N;i++)//de la al doilea element { if(a[i]<min) min=a[i]; if(a[i]>max) max=a[i]; } suma=0; for(i=0;i<N;i++) suma+=a[i]; media=float(suma)/N; printf("Valoarea minima a sirului MIN =%g\n",min); printf("Valoarea maximii a siruJui MAX =%g\n",max); printf("Suma elementelor sirului SUMA =%g\n",suma); printf("Valoarea medie a sirului MED =%g\n",media); N=getche(); }

9.3.4 Produsul scalar a doi vectori

9.3.4.1 Programul #include<iostream.h> void main() { unsigned n,i; float a[100],b[100],p; cout<<“\nDati dimensiunea:“;cin>>n; for (i=0;i<n;i++) { cout<<“a[“<<i<<“]“; cin>>a[i]; } for (i=0;i<n;i++) { cout<<“b[“<<i<<“]“; cin>>b[i]; } p=0; for (i=0;i<n;i++) p+=a[i]*b[i]; cout<<“Produsul=“<<p; }

9.3.5 Sortarea crescătoare a elementelor unui vector

9.3.5.1 Pseudocodul 1. CITEŞTE n 2. PENTRU i=0,n-1 CITEŞTE v[i] 3. m=n, sort=0 4. CÂT TIMP (m>0) ŞI (sort=0) 4.1. sort=1 4.2. PENTRU i=0,m-1 DACĂ (v[i]>v[i+1]) 4.2.1. sort=0

56

Page 61: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

4.2.2. aux=v[i] 4.2.3. v[i]=v[i+1] 4.2.4. v[i+1]=aux 4.3. m=m-1 5. PENTRU i=0,n-1 SCRIE v[i]

9.3.5.2 Programul //Sortarea elementelor unui vector #include<iostream.h> void main() { int i,n,m,sort=0,v[10],aux; cout<<"\nDati dimens vect n: ";cin>>n; for(i=0;i<n;i++) { cout<<"Elem v["<<i<<"]= "; cin>>v[i]; } m=n; while((m>0)&&(sort==0)) { sort=1; for(i=0;i<m-1;i++) if(v[i]>v[i+1]) { sort=0; aux=v[i]; v[i]=v[i+1]; v[i+1]=aux; } m--; } for(i=0;i<n;i++) cout<<"\nv["<<i<<"]= "<<v[i]; }

9.3.6 Casierul automat

Să se scrie algoritmul pentru "casierul automat" care citeşte de pe mediul de intrare suma (întreagă) datorată de un client şi calculează "restul" pe care acesta îl primeşte în număr minim de bancnote şi monezi de 100000, 50000, 10000, 5000, 1000, 500, 100, 50, 25, 10, 5, 3 şi 1 leu considerând că suma plătită este cel mai mic multiplu de 100000 mai mare decât suma datorată.

9.3.6.1 Rezolvare: Vom folosi o metodă care întoarce cel mai mic multiplu de 100000 mai mare decât suma datorată (pentru a afla suma plătită). Plata se va face "iterativ": se vor da cât mai multe bancnote de 100000 posibile, apoi cât mai multe bancnote de 50000 posibile, apoi de 10000, etc. până se epuizează suma datorată.

9.3.6.2 Programul //Casier automat #include <stdio.h>

57

Page 62: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI UNIDIMENSIONALE

#include <stdlib.h> #include <conio.h> #include <math.h> void main (void) { long suma; int i ; // Valorile monezilor const long valori[13] = {100000, 50000, 10000, 5000, 1000, 500, 100, 50, 25, 10, 5, 3, 1}; // Cantitatile din fiecare moneda int cantitati[13]; // Cel mai mic multiplu de 100000 al sumei de plata long platit; // Restul de plata long rest; clrscr(); printf ("Introduceti suma de plata: "); scanf ("%ld", &suma); // Prelucrarea datelor // Calculeaza cel mai mic multiplu de 100000 al sumei date platit = ((suma / 100000) + 1) * 100000; rest = platit - suma; printf ("Restul de plata de la %ld este: %ld\n", platit, rest); // Resetam cantitatile din fiecare bancnota for (i = 0; i < 13; i++) cantitati [i] = 0; // Calculam cantitatile din fiecare bancnota for (i = 0; (i < 13) && (rest > 0); i++) { cantitati[i] = rest / valori[i] ; rest %= valori[i]; } for(i=0; i<13; i++) if(cantitati[i]) printf ("Avem %d bancnote de valoare %ld\n", cantitati[i], valori[i]); getch(); }

9.3.7 Valoarea unui polinom într-un punct, unde coeficienţii polinomului sunt memoraţi într-un vector

9.3.7.1 Pseudocodul 1 CITEŞTE g,x 2 i=0 3 CÂT TIMP i<n 3.1 CITEŞTE p[i] 3.2 i=i+1

58

Page 63: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

4 v=p[0], xi=x, i=1 // v - valoarea, xi - xi 5 CÂT TIMP i<n 5.1 xi=xi*x 5.2 v=v+xi*p[i] 5.3 i=i+1 6 SCRIE v

9.3.8 Produsul a două polinoame

9.3.8.1 Pseudocodul 1 CITEŞTE g1,g2 2 i=0 3 CÂT TIMP i<g1 3.1 CITEŞTE p1[i] 3.2 i=i+1 4 i=0 5 CÂT TIMP i<g2 5.1 CITEŞTE p2[i] 5.2 i=i+1 6 i=0 7 CÂT TIMP i<(g1+g2) 7.1 q[i]=0 7.2 i=i+1 8 i=0 9 CÂT TIMP i<g1 9.1 j=0 9.2 CÂT TIMP j<g2 9.2.1 q[i+j]= q[i+j]+p1[i]*p2[j] 9.2.2 j=j+1 9.3 i=i+1 10 i=0 11 CÂT TIMP i<g1+g2 10.1 SCRIE q[i] 10.2 i=i+1

9.3.9 Numărul din an al unei zile

Dându-se trei numere întregi reprezentând data unei zile (an, lună, zi), să se stabilească a câta zi din an este aceasta.

9.3.9.1 Rezolvare Definim doi vectori ce conţin numărul de zile din fiecare lună şi numele fiecărei luni (de fapt, vom defini trei vectori, deoarece numărul de zile din luna februarie este diferit în anii normali şi cei bisecţi). Nu rămâne decât să facem o simplă adunare.

9.3.9.2 Programul #include <stdio.h>

59

Page 64: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI UNIDIMENSIONALE

#include <stdlib.h> #include <conio.h> #include <math.h> void main (void) { // Numarul de zile din fiecare luna (an normal si bisect) const int zile[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int zile_b[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Numele fiecarei luni

const char nz[12][15] = {"Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"}; int an, luna, zi; int nr_zilei = 0; int index; // Indexul lunii curente // Citim datele de intrare

printf("Introduceti anul:"); scanf("%d",&an); printf("Introduceti luna:"); scanf("%d",&luna); printf("Introduceti ziua:"); scanf("%d",&zi); // Testam daca anul este bisect

if((an%4==0) && ((an%100!=0)||(an%400==0))) { // Adaugam lunile anterioare for(index=0;index<luna-1;index++) nr_zilei += zile_b[index]; // Adaugam numarul zilei din luna curenta

nr_zilei += zi; } else { // Adaugam lunile anterioare for(index=0; index<luna-1;index++) nr_zilei += zile[index]; // Adaugam numarul zilei din luna curenta

nr_zilei += zi; } // Afisare rezultate printf("Ati introdus ziua de %d %s, a %d-a zi din %d\n", zi, nz[luna-1], nr_zilei, an); getch();}

60

Page 65: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

10. ŞIRURI DE CARACTERE

Şirurile sunt tablouri unidimensionale de caractere, care au ca ultim element un terminator de şir, caracterul NULL (zero ASCII), ’\0’.

10.1.1 Prefixele unui cuvânt Fiind dat un cuvânt, să se afişeze toate prefixele acestuia.

Se va determina mai întâi lungimea cuvântului folosind funcţia strlen. Întrucât nu se cere o anumită ordine a prefixelor, le vom genera de la cel mai lung (întregul cuvânt) la cel mai scurt (prima literă). Pentru a reduce dimensiunea, vom înlocui la fiecare pas ultima literă cu terminatorul de şir.

10.1.1.1 Programul #include<stdio.h> #include<string.h> void main() { int n; char cuv[128]; printf("\nIntroduceti cuvantul: ");scanf ("%s",cuv); n=strlen(cuv); while(n--) {printf ("\n%s",cuv); cuv[n]=0; } }

10.1.2 Palindrom

Să se verifice dacă un număr este palindrom. Un număr este considerat palindrom dacă citit de la stânga la dreapta sau invers, are

aceeaşi valoare. Exemple: 1221, 121, 50905. Numărul se va converti într-un şir de caractere cu ajutorul funcţiei ltoa din biblioteca standard, apoi şirul se caractere se va compara cu inversul său. Pentru obţinerea inversului unui şir se va folosi funcţia strrev din biblioteca string.h.

10.1.2.1 Programul #include <string.h> #include <stdio.h> #include <stdlib.h> void main() { long n; char sir1[100], sir2[100]; printf("Introduceti numarul: "); scanf("%ld",&n); ltoa(n,sir1,10); //transforma numarul in sir

61

Page 66: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

ŞIRURI DE CARACTERE

strcpy(sir2,sir1); strrev(sir2); //inverseaza ordinea caracterelor din sir if(strcmp(sir1,sir2)==0) puts("\nNumarul este palindrom!"); else puts("\nNumarul nu este palindrom!"); }

10.1.3 Rime cuvinte

Fiind date n şiruri de caractere care reprezintă n cuvinte, să se determine toate perechile de rime formate.

Pentru aceasta se vor compara cu ajutorul funcţiei strcmp pe rând ultimele două litere ale fiecărui cuvânt cu ultimele două litere ale celorlalte cuvinte. Dacă acestea coincid, atunci se va tipări perechea de şiruri găsită.

10.1.3.1 Programul #include<string.h> #include<stdio.h> void main() { char a[20][20]; int i,n,j; printf("Numarul de cuvinte: ");scanf("%d",&n); puts("Cuvintele: "); for(i=0;i<n;i++) scanf("%s", &a[i]); puts("Se formeaza rimele:"); for(i=0;i<n-1;i++) for (j=i+1;j<n;j++) if(strcmp(&a[i][strlen(a[i])-2], &a[j][strlen(a[j])-2]) == 0) printf("%s------------%s\n",a[i],a[j]); }

10.1.4 Cel mai lung cuvânt citit Să se scrie un program care citeşte o succesiune de cuvinte şi îl afişează pe cel mai lung dintre ele.

Prin cuvânt înţelegem o succesiune de caractere diferite de spaţii. Vom presupune că un cuvânt nu are mai mult de 100 de caractere. Cuvintele sunt separate prin spaţii. La sfârşit se tastează sfârşitul de fişier (Ctrl+Z) pentru a termina succesiunea de cuvinte.

10.1.4.1 Programul #include <stdio.h> #include <string.h> #define MAX 100 void main () /* citeste o succesiune de cuvinte si-l afiseaza pe cel mai lung dintre ele */ { int max=0,i; char cuvant[MAX+1]; char cuvant_max[MAX+1];

62

Page 67: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

printf("\nIntroduceti cuvintele urmate de Ctrl-Z: \n"); while(scanf("%100s",cuvant) != EOF) if(max < (i=strlen(cuvant))) { max = i; strcpy(cuvant_max,cuvant);} if(max) printf("Cel mai lung cuvant: %s", cuvant_max); }

Obs.: 1. Cuvântul citit se păstrează în tabloul cuvant de MAX+1 elemente. La citire se

utilizează specificatorul de format: %100s care permite să se citească cel mult 100 de caractere diferite de cele albe. Funcţia scanf păstrează caracterul NULL după ultimul caracter citit. Deci, un cuvânt de 100 de caractere ocupă 101 octeţi.

2. După citirea unui cuvânt, se apelează funcţia strlen pentru a determina numărul caracterelor citite prin scanf şi păstrate în tabloul cuvant. În acest caz s-a utilizat expresia: i = strlen(cuvant)

Apoi se compară lungimea cuvântului citit cu max. Variabila max are ca valoare lungimea maximă a cuvintelor citite înaintea celui

curent. Iniţial max = 0, deoarece nu există nici un cuvânt citit. Dacă max este mai mic decât lungimea cuvântului citit curent, atunci lui max i se atribuie această valoare, iar cuvântul citit este transferat în zona de memorie alocată tabloului cuvânt_max. În acest scop se apelează funcţia strcpy:

strcpy(cuvant_max, cuvant);

10.1.5 Citire şi ordonare cuvinte Să se scrie un program care citeşte două cuvinte şi le afişează în ordine crescătoare.

Cuvântul se defineşte ca o succesiune de cel mult 100 de caractere care nu sunt albe. Cuvintele sunt separate prin spaţii (caractere albe).

10.1.5.1 Programul #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 100 void main () /* citeste doua cuvinte si le afiseaza in ordine crescatoare */ { char cuv1[MAX+1]; char cuv2[MAX+1] ; if(scanf("%100s",cuv1) != 1) { printf("nu s-a tastat un cuvant\n"); exit(1); } if(scanf("%100s",cuv2) != 1) { printf("nu s-a tastat un cuvant\n"); exit(1); } if(strcmp(cuv1,cuv2) < 0) { /* primul cuvant tastat este mai mic decit cel de-al doilea */ printf("%s\n",cuv1) ; printf("%s\n",cuv2); } else { printf("%s\n",cuv2) ; printf("%s\n",cuv1); }

63

Page 68: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

ŞIRURI DE CARACTERE

}

10.1.6 Cel mai mare cuvânt Să se scrie un program care citeşte o succesiune de cuvinte şi îl afişează pe cel mai mare. Prin cuvânt înţelegem o succesiune de cel mult 100 de caractere care nu sunt albe. Cuvintele sunt separate prin caractere albe. Succesiunea de cuvinte se termină cu sfârşitul de fişier.

10.1.6.1 Programul #include <stdio.h> #include <string.h> #define MAX 100 void main() /* citeste o succesiune de cuvinte si-l afiseaza pe cel mai mare */ { char cuv_crt[MAX+1]; char cuv_max[MAX+1]; cuv_max[0] = '\0'; /* cuv_max se initializeaza cu cuvintul vid */ while(scanf("%100s",cuv_crt) != EOF) if(strcmp(cuv_crt,cuv_max) > 0) /* cuvintul curent este mai mare decit cel pastrat in cuv_max */ strcpy(cuv_max,cuv_crt); printf("cel mai mare cuvant este\n"); printf("%s\n", cuv_max); }

64

Page 69: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

11. TABLOURI MULTIDIMENSIONALE

11.1 Exemple

11.1.1 Declararea unui tablou bidimensional

int mat1[2][3]; //Tablou bidimensional numit mat1 cu 2x3 elemente intregi float mat2[10][10]; //Tablou bidimensional numit mat2 cu 10x10 elemente reale

11.1.2 Citirea primelor m linii şi n coloane ale unei matrice

for(i=0; i<m; i++) for(j=0; j<n; j++) cin>>a[i][j];

11.1.3 Scrierea primelor m linii şi n coloane ale unei matrice

for(i=0; i<m; i++,cout’\n’) for(j=0; j<n; j++) cout<<a[i][j];

11.1.4 Rearanjarea liniilor unei matrice

Să se facă rearanjarea liniilor unei matrice astfel încât elementele de pe diagonala principală să fie elementele de maxim ale fiecărei linii. Se consideră că elementele matricei sunt distincte.

Vom determina mai întâi coloanele elementelor de maxim ale fiecărei linii într-un vector c. Apoi vom verifica dacă valorile coloanelor sunt distincte, în caz contrar nu este posibilă rearanjarea liniilor conform cerinţelor problemei.

Exemplu: Dimensiunea matricei: 3. Elementele matricei:

2 1 8

9 2 05 7 6

. O soluţie este:

9 2 0

5 7 62 1 8

.

11.1.4.1 Programul #include<stdio.h> int c[5], mat1[5][5], mat[5][5],i, j, poz, max1, n=3; void main() {// Citire dimensiune printf("Dimensiunea matricei: "); scanf("%d",&n); // Citire matrice

65

Page 70: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI MULTIDIMENSIONALE

printf("Elementele matricei: "); for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&mat[i][j]); // Aflarea maximelor pe linii for(i=1;i<=n;i++) { // Se determina coloana poz a unui element de maxim al liniei i poz=1; max1=mat[i][1]; for(j=2;j<=n;j++) { if(mat[i][j]>max1) { max1=mat[i][j]; poz=j; } c[i]=poz; } } // Se verifica daca coloanele obtinute sunt unice for(i=1;i<n;i++) for(j=i+1;j<=n;j++) if(c[i]==c[j]) {puts ("Problema nu are solutie"); return; } // Copierea liniilor cu maximul pe diagonala principala in alta matrice for(i=1;i<=n;i++) for(j=1;j<=n;j++) mat1[c[i]][j]=mat[i][j]; puts("O solutie este: "); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) printf ("%5d",mat1[i][j]); puts(" "); } }

11.1.5 Suma a două matrice

11.1.5.1 Programul #include<iostream.h> void main() { unsigned m,n,j,i; float a[10][10],b[10][10],c[10][10]; cout<<“nr de linii:”;cin>>m; cout<<“nr de coloane:”;cin>>n; for (i=0;i<m;i++) for (j=0;j<n;j++) { cout<<“a[“<<i<<“,”<<j<<“]= ”; cin>>a[i][j]; } for (i=0;i<m;i++) for (j=0;j<n;j++) { cout<<“b[“<<i<<“,”<<j<<“]= ”; cin>>b[i][j]; } for (i=0;i<m;i++)

66

Page 71: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

for (j=0;j<n;j++) c[i][j]=a[i][j]+b[i][j]; for (i=0;i<m;i++,cout<<’\n’) for (j=0;j<n;j++) cout<<c[i][j]<<’\t’; }

11.1.6 Produsul a două matrice

11.1.6.1 Pseudocodul 1. CITEŞTE m, n, p 2. PENTRU i=1,m PENTRU j=1,n CITEŞTE a[i][j] 3. PENTRU i=1,n PENTRU j=1,p CITEŞTE b[i][j] 4. PENTRU i=1,m PENTRU j=1,p 4.1 c[i][j]=0 4.2 PENTRU k = 1,n c[i][j]= c[i][j] + a[i][k]*b[k][j] 5. PENTRU i=1,m PENTRU j=1,p SCRIE c[i][j]

11.2 Probleme propuse

Să se alcătuiască programe care să rezolve următoarele probleme: 1. Se citesc de la tastatura elementele unei matrice de caractere (nr. linii=nr. coloane),

A(NxN), N<=10. a) Să se afişeze matricea A; b) Să se formeze şi să se afişeze cuvântul format din caracterele de pe diagonala

principală a matricei A; c) Să se calculeze şi să se afişeze numărul de litere mari, litere mici şi cifre din

matrice; d) Să se afişeze cuvântul format din caracterele de pe diagonala secundară; e) Să se afişeze procentul literelor mari, al literelor mici şi al cifrelor de pe cele 2

diagonale; f) Să se afişeze caracterele comune aflate pe liniile p şi q (p, q < N, p şi q citite de

la tastatură); g) Să se afişeze în ordine alfabetică, crescătoare, literele mari aflate pe coloanele

impare. 2. Se citesc de la tastatură elementele unei matrice cu elemente reale, B (NxN), N<=8.

a) Să se afişeze matricea B;

67

Page 72: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TABLOURI MULTIDIMENSIONALE

b) Să se calculeze şi să se afişeze produsul elementelor de pe coloanele impare; c) Să se calculeze şi să se afişeze matricea A, unde: A = ( B + BT)2; d) Să se formeze şi să se afişeze vectorul V, ale cărui elemente sunt elementele

pozitive din matricea A; e) Să se calculeze şi să se afişeze sumele şi produsele elementelor matricei A,

aflate în triunghiurile haşurate: f) Să se calculeze procentul elementelor pozitive aflate pe diagonala secundară; g) Să se calculeze şi să se afişeze matricea C, unde: C = 3 * BT + B2; h) Să se calculeze şi să se afişeze matricea D, unde: D = B + B2+ B3 + B4; i) Să se interschimbe coloanele matricei A astfel: prima cu ultima, a doua cu

antepenultima, etc. 3. Se citesc de la tastatură elementele unei matrice de numere întregi C (NxN), N<=10.

a) Să se afişeze matricea C; b) Să se calculeze şi să se afişeze procentul elementelor impare de pe liniile pare; c) Să se calculeze şi să se afişeze matricea B, unde: B = C2; d) Să se calculeze şi să se afişeze matricea E, unde: E = (C + CT)2 + I, unde I este

matricea unitate; e) Să se afle elementul minim din matricea C; f) Să se înlocuiască elementul maxim din matricea C cu valoarea val, introdusă

de la tastatură; g) Să se afişeze elementele matricei C care sunt numere prime; h) Să se calculeze şi să se afişeze sumele şi produsele elementelor matricei A,

aflate în triunghiurile haşurate:

68

Page 73: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

12. POINTERI ŞI ADRESE

Există doi operatori unari care permit utilizarea variabilelor pointer: & - operatorul adresă (de referenţiere) - pentru aflarea adresei din memorie a unei

variabile; * - operatorul de indirectare (de deferenţiere) - care furnizează valoarea din zona de

memorie spre care pointează pointerul operand. Sintaxa declaraţiei unui pointer de date este:

tip *identificator_pointer; Simbolul * precizează că identificator_pointer este numele unei variabile

pointer de date, iar tip este tipul obiectelor a căror adresă o va conţine. Ex.: int u, v, *p, *q; // *p, *q sunt pointeri de date (către int) double a, b, *p1, *q1; // *p1, *q1 sunt pointeri către date de tip double

Operatorul "*" se numeşte operatorul de referenţiere şi este aplicat unei adrese,

întorcând valoarea memorată la acea adresă. De exemplu, în declaraţia:

int *n; n este adresa unei variabile de tip întreg, iar *n este valoarea memorată la adresa n. Obs.: Orice adresă este memorată sub forma unui număr întreg, pe 2, 4 sau 8 octeţi

(în mod implicit 2). Operatorul invers se notează "&" şi se numeşte operatorul de dereferenţiere

(operatorul adresă). De exemplu, instrucţiunea: &x=y are semnificaţia: adresa lui x ia valoarea y.

12.1 Exemple

12.1.1 Pointeri

//Pointeri - exemple #include<iostream.h> void main() { int x=5, y, *ptr; // ptr - variabila pointer catre un int; x,y-variabile predefinite, simple, de tip int cout<<"\n\nValoarea lui x: "<<x<<"\nAdresa variabilei x este: "<<&x<<'\n'; ptr=&x;// atribuire: variabila ptr contine adresa variabilei x

69

Page 74: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

POINTERI ŞI ADRESE

cout<<"Variabila pointer ptr are valoarea: "<<ptr<<" si adreseaza obiectul: "<< *ptr<<'\n'; y=*ptr; cout<<"y="<<y<<'\n'; // y=5 x=4; cout<<"x= "<<x<<'\n'; cout<<"*ptr= "<<*ptr<<'\n'; // x si *ptr reprezinta acelasi obiect, un intreg cu valoarea 4 x=70; // echivalenta cu *ptr=70; y=x+10; // echivalenta cu y=*ptr+10 int *q; q=&x; *q=8; // echivalenta cu x=8; //q=&5; // invalida - constantele nu au adresa //*x=9; // invalida - x nu este variabila pointer //x=&y; //invalida: x nu este variabila pointer, deci nu poate fi folosita cu operatorul de indirectare y=*q+3; // echivalenta cu y=x+3; q=0; // seteaza x pe 0 q+=1; // echivalenta cu ( q)++ sau cu x++ int *r; r=q; /* copiaza continutul lui q(adresa lui x) in r, deci r va pointa tot catre x (va conîine tot adresa lui x)*/ double w=3.5, *r1, *r2; r1= &w; r2=r1; cout<<"r1="<<r1<<'\t'; //afiseaza valoarea pointerului r1(adresa lui w) cout<<"&r1="<<&r1<<'\t'; // afiseaza adresa variabilei r1 cout<<"*r1= "<<*r1<<'\n'; double z=*r1; // echivalenta cu z=w cout<<"z="<<z<<'\n'; }

12.1.2 Legătura pointeri - şiruri de caractere

Să se scrie următorul program şi să se urmărească rezultatele execuţiei acestuia. //Pointeri si siruri de caractere #include <iostream.h> #include<conio.h> void main(void) { textmode(3); int a=-5, b=12, *pi=&a; double v=-2.24, *pd=&v; char sir1[]="Sirul 1", sir2[]="Sirul 2", *psir=sir1; cout<<"a="<<a<<"\t&a="<<&a<<"\tb="<<b<<"\t&b="<<&b<<'\n'; cout<<"*pi="<<*pi<<"\tpi="<<pi<<"\t&pi="<<&pi<<'\n'; cout<<"*pd="<<*pd<<"\tpd="<<pd<<"\t &pd="<<&pd<<'\n';

70

Page 75: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

cout<<"*sir1="<<*sir1<<"\tsir1="<<sir1<<"\t&sir1="<<&sir1<<'\n'; // *sir1=s sir1=Sirul 1 &sir1=0xffd6 cout<<"*sir2="<<*sir2<<"\tsir2="<<sir2<<"\t&sir2="<<&sir2<<'\n'; // *sir2=s sir2=Sirul 2 &sir1=0xffce cout<<"*psir="<<*psir<<"\tpsir="<<psir<<"\t&psir="<<&psir<<'\n'; // *psir=s psir=Sirul 1 &sir1=0xffcc cout<<"sir1+2="<<(sir1+2)<<"\tpsir+2="<<(psir+2)<<'\n'; // sir1+2=rul 1 psir+2=rul 1 cout<<"*(sir1+2)="<< *(sir1+2)<<'\n'; // *(sir1+2)=r valoarea elementului de indice 2 void *pv1, *pv2; pv1=psir; pv2=sir1; cout<<"pv1="<<pv1<<"\t&pv1="<<&pv1<<'\n'; cout<<"pv2="<<pv2<<"\t&pv2="<<&pv2<<'\n'; pi=&b; pd=&v; psir=sir2; cout<<"*pi="<<*pi<<"\tpi="<<pi<<"\t&pi="<<&pi<<'\n'; cout<<"*pd="<<*pd<<"\tpd="<<pd<<"\t&pd="<<&pd<<'\n'; cout<<"*psir="<<*psir<<"\tpsir="<<psir<<"\t&psir="<<&psir<<'\n'; }

În limbajul C, cazul parametrilor tablou constituie o excepţie de la regula transferului parametrilor prin valoare. Numele unui tablou reprezintă, de fapt, adresa tabloului, deci a primului element din tablou.

12.1.3 Pointer la vector - exemplul 1

Să se scrie următorul program (care ilustrează legătura dintre pointeri şi vectori) şi să se urmărească rezultatele execuţiei acestuia. #include <iostream.h> void main(void) {int a[10] = {0,1,2,3,4,5,6,7,8,9}; int *pi1 = a; int *pi2 = &a[0]; int *pi3; cout<<"a="<<a<<"&a="<<&a<<"*a="<<*a<<'\n'; cout<<"a+1="<<(a+1)<< " &a[1]="<< &a[1]<<'\n'; cout<<"a[1]="<<a[1]<< " *(a+1)="<< *(a+1)<<'\n'; cout<<"pi1="<<pi1<<"pi2="<<pi2<<'\n'; int x=*pi1; /* x primeste valoarea locatiei a carei adresa se afla in variabila pointer pi1, deci valoarea lui a[0] */ cout<<"x="<<x<<'\n'; x=*pi1++; // x = *pi1 = a[0] = 0, iar apoi *pi1= a[1] = 1 cout<<"x="<<x<<'\n'; x=(*pi1)++; /* x = 1: intai atribuirea, apoi incrementarea valorii spre care indica pi1.

71

Page 76: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

POINTERI ŞI ADRESE

In urma incrementarii, valoarea lui a[1] devine 2 */ cout<<"x="<<x<<'\n'; cout<<*pi1<<'\n'; x=*++pi1; //echivalent cu *(++pi1) cout<<"x="<<x<<'\n'; x=++(*pi1); cout<<"x="<<x<<'\n'; pi1=a; pi3=pi1+3; cout<<"pi1="<<pi1<<"*pi1="<<*pi1<<"&pi1="<<&pi1<<'\n'; cout<<"pi3="<<pi3<<"*pi3="<<*pi3<<"&pi3="<<&pi3<<'\n'; cout<<"pi3-pi1="<<(pi3-pi1)<<'\n'; //pi3-pi1=3 }

12.1.4 Pointer la vector - exemplul 2

//Pointer la vector #include <iostream.h> #define DIM 3 void main() { int i; float tablou[DIM], *ptablou; ptablou=tablou; cout<<"Introduceti elementele tabloului\n"; for(i=0;i<DIM;i++) { cout<<"a("<<(i+1)<<")="; cin>>tablou[i]; } cout<<"Elementele tabloului sunt:\n"; for(i=0;i<DIM;i++) cout<<"a("<<(i+1)<<")="<<*(ptablou+i)<<"\n"; }

12.1.5 Pointer la matrice - exemplul 1

#include<iostream.h> #include<conio.h> void main() {int a[3][3]={{5,6,7}, {55,66,77}, {555,666,777}}; clrscr(); cout<<"a="<<a<<" &a="<<&a<<" &a[0]="<<&a[0]<<'\n'; cout<<"Pointeri catre vectorii linii\n"; for (int i=0; i<3; i++){ cout<<" *(a+"<<i<<")="<<*(a+i); cout<<" a["<<i<<"]="<<a[i]<<'\n'; } // afişarea matricei for (int i=0; i<3; i++){ for (int j=0; j<3; j++) cout<<*(*(a+i)+j)<<'\t'; //sau: cout<<*(a[i]+j)<<'\t'; cout<<'\n';

72

Page 77: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

} }

12.1.6 Pointer la matrice - exemplul 2

//Pointer la matrice #include <iostream.h> #define DIM1 3 #define DIM2 2 float cere_element(int i,int j) { float elem; cout<<"a("<<(i+1)<<","<<(j+1)<<")="; cin>>elem;cout<<"\n"; return elem; } void afis_tablou(float **ptablou) { int i,j; for(i=0;i<DIM1;i++) for(j=0;j<DIM2;j++) cout <<"a(" <<(i+1) <<"," <<(j+1)<< ")=" << *((*ptablou)+i*DIM2+j)<< "\n"; } void main() { float tablou[DIM1][DIM2]; int i,j; float *ptablou; ptablou=*tablou; cout<<"Introduceti elementele tabloului\n"; for(i=0;i<DIM1;i++) for(j=0;j<DIM2;j++) tablou[i][j]=cere_element(i,j); cout<<"Elementele tabloului sunt:\n"; afis_tablou(&ptablou); }

12.2 Probleme propuse

1. Analizaţi următoarele secvenţe de instrucţiuni. Identificaţi secvenţele incorecte (acolo unde este cazul) şi sursele erorilor: int a,b,*c; a=7; b=90; c=a; double y, z, *x=&z; z=&y; char x, **p, *q; x = 'A'; q = &x; p = &q;

cout<<”x=”<<x<<’\n’; cout<<”**p=”<<**p<<’\n’; cout<<”*q=”<<*q<<’\n’; cout<<”p=”<<p<<” q=”<<q<<”*p=”<<*p<<’\n’;

73

Page 78: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

POINTERI ŞI ADRESE

char *p, x[3] = {'a', 'b', 'c'}; int i, *q, y[3] = {10, 20, 30}; p = &x[0]; for (i = 0; i < 3; i++) { cout<<”*p=”<<*p<<” p=”<<p<<’\n’; p++; } q = &y[0]; for (i = 0; i < 3; i++) { cout<<”*q=”<<*q<<”q=”<<q<<’\n’; q++; }

const char *sirul=”să programăm”; *(sirul)++; double a, *s; s=&(a+89); cout<<”s=”s<<’\n’; double a1, *a2, *a3; a2=&a1; a2+=7.8; a3=a2; a3++; int m[10], *p;p=m;

for (int i=0; i<10; i++) cout<<*m++;

void *p1; int *p2; int x; p2=&x; p2=p1; char c=’A’; char *cc=&c; cout<<(*cc)++<<’\n’;

74

Page 79: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TRANSFERUL PARAMETRILOR UNEI FUNCŢII

13. FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

13.1 Structura unei funcţii

O funcţie este formată din antet şi corp: antet_functie { corp_functie }

Sau: tip_val_return nume_func (lista_declaratiilor_param_ formali) { declaratii_variabile_locale instructiuni [return valoare] //optional }

Antetul funcţiei conţine deci următoarele 3 elemente obligatorii: • tipul valorii returnate de funcţie • numele funcţiei • lista declaraţiilor parametrilor formali

O funcţie poate fi apelată printr-o construcţie urmată de punct şi virgulă, numită

instrucţiune de apel, de forma: nume_functie (lista_parametrilor_efectivi);

Parametrii efectivi trebuie să corespundă cu cei formali ca ordine şi tip.

13.2 Transferul parametrilor unei funcţii

Funcţiile comunică între ele prin argumente (parametri). Există următoarele moduri de transfer (transmitere) a parametrilor către funcţiile apelate:

13.2.1 Transferul prin valoare

Exemplul devenit clasic este cel al funcţiei de permutare (interschimbare) a două variabile. Fie funcţia schimb_v definită astfel: void schimb_v (float x, float y) { float t=x; x=y; y=t; } void main() { float a=4.7, b=9.7; . . . . . . . . . . . schimb_v(a, b); // apel functie . . . . . . . . . . . }

75

Page 80: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

Parametri funcţiei schimb_v sunt transmişi prin valoare: parametrilor formali x, y li se atribuie (la apel) valorile parametrilor efectivi a, b. Funcţia schimb_v permută valorile parametrilor formali x şi y, dar permutarea nu are efect asupra parametrilor efectivi a şi b.

13.2.2 Transferul prin pointeri

Pentru ca funcţia de interschimbare să poată permuta valorile parametrilor efectivi, în limbajul C/C++ parametrii formali trebuie să fie pointeri către valorile care trebuie interschimbate: void schimb_p(float *x, float *y) { float t=*x; *x=*y; *y=t; } void main() { float a=4.7, b=9.7; . . . . . . . . . . . schimb_p(&a, &b); // apel functie /* SAU: float *pa, *pb; pa=&a; pb=&b; schimb_p(pa, pb);*/ . . . . . . . . . . . }

Se atribuie pointerilor x şi y valorile pointerilor pa, pb, deci adresele variabilelor a şi b. Funcţia schimb_p permută valorile spre care pointează pointerii x şi y, deci valorile lui a şi b.

13.2.3 Transferul prin referinţă

În limbajul C++, aceeaşi funcţie de permutare se poate defini cu parametri formali de tip referinţă. void schimb_r(float &x, float &y) { float t=x; x=y; y=t; } void main() { float a=4.7, b=9.7; . . . . . . . . . . . . schimb_r(a, b); // apel funcţie . . . . . . . . . . . }

În acest caz, x şi y sunt sinonime cu a şi b (nume diferite pentru aceleaşi grupuri de locaţii de memorie). Interschimbarea valorilor variabilelor x şi y înseamnă interschimbarea valorilor variabilelor a şi b.

13.3 Funcţii definite de utilizator

În afară de funcţiile predefinite existente în header-ele <stdlib.h>, <math.h>, <iostream.h>, <string.h> - există posibilitatea de a se construi noi funcţii de către programator (utilizator).

76

Page 81: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

Sintaxa definiţiei unei funcţii este: <tip valoare returnată> <nume funcţie> (<tip parametru> [*] <nume parametru> [,...]) { <lista variabile auxiliare>; <instructiuni>; [return <variabila>;] }

unde: • <tip valoare returnată> - poate fi oricare din tipurile de bază sau void (tipul vid) • <tip parametru> - poate avea orice tip cu excepţia lui void • [*] - este un parametru opţional, utilizat numai pentru parametrii a căror valoare

se modifică (spunem că funcţia are efecte laterale) • <instrucţiuni> - au aceeaşi sintaxă cu cele dintr-un program, servesc la calculele

intermediare din corpul funcţiei • <lista variabile auxiliare> - sunt variabile locale funcţiei, nu sunt văzute în afara

funcţiei Instrucţiunea return este folosită pentru întoarcerea de către funcţie a rezultatului

care va fi transmis programului principal sau altei funcţii care o apelează; ea este obligatorie în toate funcţiile cu excepţia celor de tip void.

Sintaxa apelului unei funcţii este:

<nume funcţie> ( <nume parametru> [,...]) deci numele funcţiei urmat de lista parametrilor între paranteze; aceştia poartă

numele de parametrii actuali, iar parametrii din definiţia funcţiei se numesc parametrii formali. Este necesar ca parametrii actuali să corespundă ca număr şi tip cu parametrii formali.

Obs.: De obicei, funcţiile se declară şi se definesc la începutul programului, dar se mai pot declara şi astfel: se declară la început prototipul şi apoi la sfârşit definirea, adică descrierea detaliată (inclusiv prototipul).

13.4 Exemple

13.4.1 Funcţie pentru calculul maximului a două numere reale

float max(float x, float y) { float a; if (x>y) a=x; else a=y; return a; }

13.4.2 Schimbarea valorilor a două variabile - transferul parametrilor unei funcţii

//Transferul parametrilor unei functii #include<iostream.h>

77

Page 82: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

//Transfer prin valoare void schimb_v (float x, float y) { float t=x; x=y; y=t; } //Transfer prin pointeri void schimb_p(float *x, float *y) { float t=*x; *x=*y; *y=t; } //Tansfer prin referinta void schimb_r(float &x, float &y) { float t=x; x=y; y=t; } void main() { float a=4.5, b=9.3; cout<<"\nInitial\ta= "<<a<<"\tb= "<<b; schimb_v(a, b); // apel functie cout<<"\nValoare\ta= "<<a<<"\tb= "<<b; schimb_p(&a, &b); // apel functie cout<<"\nPointer\ta= "<<a<<"\tb= "<<b; schimb_r(a, b); // apel functie cout<<"\nRef\ta= "<<a<<"\tb= "<<b; }

13.4.3 Cel mai mare pătrat perfect mai mic sau egal cu un număr dat

De la tastatură se citesc n valori întregi pozitive. Pentru fiecare element să se indice cel mai mare pătrat perfect mai mic sau egal cu el.

13.4.3.1 Rezolvare Definim o funcţie int patrat(int), care introduce pătratul perfect cel mai mare, mai mic sau egal cu numărul dat.

13.4.3.2 Programul //Cel mai mare patrat perfect mai mic sau egal cu un nr #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <math.h> // Calculeaza cel mai mare patrat perfect mai mic sau egal cu a int patrat (int a) { int i=0; while(i*i<=a) i += 1; return (i*i>a)?(i-1)*(i-1):i*i; } void main (void) { int n, a;

78

Page 83: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

clrscr () ; printf("Introduceti nr de valori: "); scanf("%d",&n); // Prelucrare date si afisare rezultate for(int i=0;i<n;i++) { printf("Introduceti elementul %d: ",i+1); scanf("%d", &a); printf("Patratul perfect mai mic sau egal cu %d este: %d\n", a, patrat(a)); } getch(); }

13.4.4 Perechi

Se citeşte un întreg n şi n perechi (a, b) de întregi. Să se afişeze, acele perechi al căror cmmdc este un număr prim.

13.4.4.1 Programul #include<stdio.h> #include<conio.h> //cmmdc cu algoritmul lui Euclid int cmmdc(int a, int b) { int r; do { r = a % b; a=b; b=r;} while (r); return a; } // stabileste daca n este prim int prim(int n) { int div; for (div=2; div*div<=n; (div==2) ? div=3 : div+=2) if(n%div==0) return 0; return 1; } void main (void) { int n; int a, b; // Citire date de intrare printf ("Introduceti numarul de perechi: "); scanf ("%d", &n); for(int i=0; i<n; i++) { printf (" Introduceti perechea %d: ", i); scanf("%d%d", &a, &b);

79

Page 84: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

if (prim(cmmdc(a, b))) printf("cmmdc(%d,%d)=%d\n", a, b, cmmdc(a,b)); } getch(); }

13.4.5 Elementul de valoare minimă al unui tablou

13.4.5.1 Programul //Minimul elementelor unui tablou #include <iostream.h> #define DIM 5 float min2v(float a,float b) {return (a<b?a:b);} int sorttab(float tablou[DIM]) { int i,indmin; float valmin; valmin=tablou[0]; indmin=0; for(i=1;i<DIM;i++) { valmin=min2v(valmin,tablou[i]); if(valmin==tablou[i]) indmin=i; } return indmin; } void tiptab(float tablou[DIM]) { int i; for(i=0;i<DIM;i++) cout<<"tabl("<<i<<")="<<tablou[i]<<"\n"; } void main() { float tabl [DIM]; int imin,i; cout<<"introduceti elementele tabloului\n"; for(i=0;i<DIM;i++) { cout<<"tabl ("<<i<<")="; cin>>tabl[i]; cout<<"\n"; } cout<<"Tabloul initial\n"; tiptab(tabl); imin=sorttab(tabl); cout<<"Elementul minim din tablou este: tabl("<<imin<<")="<<tabl[imin]<<"\n"; }

80

Page 85: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

13.4.6 Operaţii cu matrice cu ajutorul unor funcţii

13.4.6.1 Programul //Operatii cu matrice realizate cu functii #include<iostream.h> #include<stdio.h> #define DIM 10 void citire(int nl,int nc,int mat[DIM][DIM]) { int i,j; for(i=0;i<nl;++i) { cout<<"\n ***** Linia "<<i<<"\n"; for(j=0;j<nc;++j) { cout<<"Introduceti elementul ["<<i<<","<<j<<"]: "; cin>>mat[i][j]; } } } int suma(int mat1[DIM][DIM], int mat2[DIM][DIM],int nl,int nc,int summat[DIM][DIM]) { int i,j; for(i=0;i<nl;++i) { for(j=0;j<nc;++j) summat[i][j]=mat1[i][j]+mat2[i][j]; } return 0; } void prod(int mat1[DIM][DIM], int mat2[DIM][DIM], int m,int n,int p,int prodmat[DIM][DIM]) { int i,j,k; for(i=0;i<m;++i) for(j=0;j<n;++j) { prodmat[i][j]=0; for(k=0;k<p;++k) prodmat[i][j]=prodmat[i][j]+mat1[i][k]*mat2[k][j]; } } void afisare(int nl,int nc,int mat[DIM][DIM]) { int i,j; for(i=0;i<nl;++i) { for(j=0;j<nc;++j)

81

Page 86: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

cout<<mat[i][j]<<" "; cout<<"\n"; } } void main() { int m1[DIM][DIM], m2[DIM][DIM], sum[DIM][DIM]; int a,b,c,d,i,j; char selector; cout<<"\nIntr. nr-le de linii si coloane pentru prima matrice, m: ";cin>>a; cout<<" si n: ";cin>>b; cout<<"\nIntr. nr-le de linii si coloane pentru a doua matrice, m: ";cin>>c; cout<<" si n: ";cin>>d; cout<<"\n\nPrima matrice:\n"; citire(a,b,m1); cout<<"\n\nA doua matrice:\n"; citire(c,d,m2); printf("Tastati:'s' pentru suma\n 'd' pentru diferenta\n 'p' pentru produs\nAici: "); cin>>selector; switch (selector) { case's': { if ((a==c)&&(b==d)) { suma(m1,m2,a,b,sum); afisare(a,b,m1); cout<<"\n +\n\n"; afisare(c,d,m2); cout<<"\n=\n"; afisare(c,d,sum); } else cout<<"Nu se poate efectua suma deoarece numerele de linii si coloane au nereguli"; break; } case'd': { cout<<"FACETI VOI DIFERENTA"; break; } case'p': { if(b==c) { prod(m1,m2,a,d,b,sum); afisare(a,b,m1); cout<<"\n*\n\n";

82

Page 87: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

afisare(c,d,m2); cout<<"\n=\n\n"; afisare(a,d,sum); } break; } default: cout<<"Nu s-a introdus una din literele cerute !"; } }

13.4.7 Calculul puterii şi transpusei unei matrice pătrate

Să se alcătuiască un program pentru ridicarea la putere a unei matrice pătratice şi pentru calculul transpusei acesteia.

13.4.7.1 Strategia de rezolvare În cazul matricelor pătratice A(n,n) numărul de linii şi de coloane este egal cu ordinul matricei. Transpusa se obţine prin interschimbarea elementelor din partea dreaptă a diagonalei principale cu cele având indicii liniei şi coloanei inversaţi.

13.4.7.2 Programul /* Ridicarea la o putere a unei matrice patratice. Calculul transpusei unei matrice patratice.*/ #define NMAX 20 //Nr maxim de linii/coloane al matricelor #include <stdio.h> #include <conio.h> /*Functia citeste valorile elementelor unei matrice */ void citire (float ta[NMAX][NMAX], int ordin, char numev) { float temp; printf("\nElementele matricei %c\n",numev); for (int i = 1,j; i<ordin+1; i++) for(j=1; j<ordin+1; j++) { printf("%c[%d,%d]= ",numev,i,j); scanf ("%f",&temp); ta[i][j]=temp; } } /*Functia scrie valorile elementelor unei matrice */ void scriere(float ta[NMAX][NMAX], int ordin, char numev) { int trec; printf("\nAfisarea valorii elementelor pentru matricea %c:\n",numev); trec=1; for(int i=1,j; i<ordin+1; i++) for(j=1; j<ordin+1; j++) { printf("%c[%d,%d]= %f",numev, i,j,ta[i][j]); if(trec++==ordin) {printf("\n"); trec=1;}

83

Page 88: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

else printf("\t"); } printf("\nApasa orice tasta!");getch(); } /*Functia efect ridicarea la patrat, a unei matrice */ void patrat(float ta[NMAX][NMAX],float tb[NMAX][NMAX], int ordin) { for (int i=1,j,k; i<ordin+1; i++) for(k=1; k<ordin+1; k++) { tb[i][k]=0.0; for(j=1; j<ordin+1; j++) tb[i][k]+=ta[i][j]*ta[j][k]; } } /*Functia calculeaza transpusa unei matrice*/ void transpusa(float ta[NMAX][NMAX], int ordin) { float temp; for(int i=1,j; i<ordin; i++) for(j=i+1; j<ordin+1; j++) { temp=ta[i][j]; //interschimba valorile a doua variabile de tip float ta[i][j]=ta[j][i]; ta[j][i]=temp; } } void main(void) { //Functia principala float a[NMAX][NMAX], b[NMAX][NMAX]; int n; clrscr(); printf("Ordinul matricei A = "); scanf("%d",&n); citire(a,n,'A'); patrat(a,b,n); puts("\nMatricea B=A*A: "); scriere(b,n,'B'); transpusa(b,n); puts("\nMatricea transpusa:"); scriere(b,n,'B'); }

Pentru ca elementele matricei să nu se piardă în timpul operaţiei de transpunere, se utilizează o variabilă intermediară care stochează valoarea uneia dintre variabilele ce trebuie interschimbate:

temp=ta[i][j]; ta[i][j]=ta[j][i]; ta[j][i]=temp;

84

Page 89: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

Dacă am fi aplicat direct relaţia: ta[i][j]=ta[j][i];

valoarea variabilei ta[i][j] s-ar fi pierdut, fiind înlocuită cu cea a variabilei ta[j][i] şi astfel (valoarea variabilei ta[j][i] nefiind modificată) matricea ar fi fost alterată, devenind simetrică faţă de diagonala principală.

În apelul funcţiei pătrat o scriere de tipul: patrat(a,a,n); nu ar fi dus la calculul pătratului matricei a, ci la alterarea valorilor elementelor acesteia. În cazul şirurilor, aceeaşi variabilă şir nu poate constitui pentru o funcţie şi argument "valoare" şi argument "variabilă".

13.4.8 Funcţie cu pointer la tablou unidimensional

//Pointer la vector #include <iostream.h> #define DIM 3 float cere_element(int i) {float elem; cout<<"a("<<(i+1)<<")="; cin>>elem; cout<<"\n"; return elem; } void afis_tablou(float *ptablou) {int i; for(i=0;i<DIM;i++) cout<<"a("<<(i+1)<<")="<<*(ptablou+i)<<"\n"; } void main() { float tablou[DIM]; int i; float *ptablou; ptablou=tablou; cout<<"Introduceti elementele tabloului\n"; for(i=0;i<DIM;i++) tablou[i]=cere_element(i); cout<<"Elementele tabloului sunt:\n"; afis_tablou(ptablou); }

13.4.9 Funcţie cu pointer la tablou bidimensional

//Pointer la matrice #include <iostream.h> #define DIM1 3 #define DIM2 2 float cere_element(int i,int j) { float elem; cout<<"a("<<(i+1)<<","<<(j+1)<<")=";

85

Page 90: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - GENERALITĂŢI, OPERAŢII CU TABLOURI

cin>>elem;cout<<"\n"; return elem; } void afis_tablou(float **ptablou) { int i,j; for(i=0;i<DIM1;i++) for(j=0;j<DIM2;j++) cout <<"a("<<(i+1)<<","<<(j+1)<<")="<<*((*ptablou)+i*DIM2+j)<<"\n"; } void main() { float tablou[DIM1] [DIM2]; int i,j; float *ptablou; ptablou=*tablou; cout<<"Introduceti elementele tabloului\n"; for(i=0;i<DIM1;i++) for(j=0;j<DIM2;j++) tablou[i][j]=cere_element(i,j); cout<<"Elementele tabloului sunt:\n"; afis_tablou(&ptablou); }

13.5 Probleme propuse

1. Să se realizeze un program care implementează operaţii cu vectori utilizând funcţii (citire, scriere, produs scalar, sortare).

2. Să se realizeze un program care calculează valoarea unui polinom utilizând o funcţie pentru calculul puterii.

86

Page 91: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

14. FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

14.1 Exemple

14.1.1 Calculul derivatei unei funcţii

Derivata unei funcţii într-un punct reprezintă panta tangentei la graficul funcţiei în punctul respectiv, adică:

f'(x) = limh→0 h

f(x) - f(x-h)

14.1.1.1 Programul //Calculul derivatei unei functii #include <stdio.h> #include <math.h> double fd(double); double deriv(double,double,double(*)(double)); void main() { double d,x,h; printf("\nx= "); scanf("%lf",&x); for(h=0.1;h>=1e-06;h/=10) { d=deriv(x,h,fd); printf("\nx=%f; h= %f; d= %lf",x,h,d); } printf("\nx=%f; d= %lf",x,-sin(x)); } double deriv(double x,double h,double (*f)(double)) { double it; it=((*f)(x)-(*f)(x-h))/h; return it; } double fd(double x) { return cos(x); }

14.1.2 Calculul integralei definite a unei funcţii prin metoda trapezelor

Relaţia de calcul:

87

Page 92: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

I = ⌡⌠a

bf(x) dx = h 2 +f(a+h) +f(a+2h)+…f(a+(n-1)h)

f(a)+f(b) ,

unde: h = b-an , n fiind numărul de diviziuni

f(x)

a x1 x2 xn-1 b

x h

14.1.2.1 Programul //Calculul integralei prin metoda trapezelor #include <stdio.h> #include <math.h> double fc(double); double ing(double,double,double(*)(double)); void main() { double i,a,b; printf("\nLimitele a,b: "); scanf("%lf %lf",&a,&b); i=ing(a,b,fc); printf("\na=%f; b=%f; i= %lf",a,b,i); } double ing(double x,double y,double (*f)(double)) { int n=120,k; double it,h,S; h=(y-x)/n; for(k=1,S=0.0;k<n;k++) S=S+(*f)(x+k*h); it=(h/2)*((*f)(x)+(*f)(y))+h*S; return it; } double fc(double x) { return x*x; }

88

Page 93: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

14.1.3 Rezolvarea ecuaţiilor neliniare prin metoda bisecţiei

Să se rezolve ecuaţia neliniară cos(x)-x = 0 prin metoda bisecţiei.

14.1.3.1 Algoritmul DATE DE INTRARE: • a, b {capetele intervalului} • ε {eroarea maximă admisibilă}

DATE DE IEŞIRE: • x {rădăcina} • zero {variabilă logică de control}

1. CITEŞTE a, b, ε 2. zero = adevărat {există o rădăcină} 3. x = a; fa = f(x);

DACĂ |fa| ≤ ε ATUNCI EXIT {rădăcina este x=a} 4. x = b; fb = f(x);

DACĂ |fb| ≤ ε ATUNCI EXIT {rădăcina este x=b} 5.

DACĂ fa ⋅ fb < 0 ATUNCI {există rădăcină în intervalul (a,b)} REPETĂ

x = (a+b)/2; fx = f(x) {f((a+b)/2)} DACĂ fa ⋅fx < 0 ATUNCI b = x ALTFEL a = x dx = b-a; DACĂ x ≠0 ATUNCI dx = dx/x {eroarea}

PÎNĂ CÂND |dx|≤ ε sau |fx|≤ ε {testează convergenţa} ALTFEL zero = fals {nu există rădăcină}

6. STOP

14.1.3.2 Programul /*Rezolvarea ecuatiilor neliniare prin metoda injumatatirii intervalului xs,xd - limitele intervalului in care se presupune ca se afla solutia; eps - toleranta admisa; it_lim - limita numarului de iteratii;*/ #include<conio.h> #include<math.h> #include<stdio.h> float xs=0,xd=5,sol,eps=1e-05; float f(float x) { return cos(x)-x;} float bisec(float xs, float xd, float eps, float (*f)(float)) { float x,ys,y,yd; int it=0,it_lim=100,gata=0; ys=f(xs); yd=f(xd); if(ys*yd>0) { printf("f(xs)*f(xd) > 0"); x=0;}

89

Page 94: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

else { while(!gata) { gata=0; it++; x=(xs+xd)/2; y=f(x); printf("%2d %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n",it,xs,x,xd,ys,yd,fabs((yd-ys)/2)); if(it>it_lim) {printf("\nS-a depasit numarul maxim de iteratii !"); gata=1; } else if(fabs(x-xs)<eps) gata=1; else {if(ys*y<=0) {xd=x; yd=y;} else {xs=x; ys=y;} } } } return x; } void main() { clrscr(); printf(" it xs x xd f(xs) f(xd) |f(xd)-f(xs)|/2\n"); printf("--------------------------------------------------------------\n"); sol=bisec(xs, xd, eps, f); printf("\nRadacina aproximata= %g",sol); }

14.2 Funcţii predefinite

14.2.1 Biblioteca matematică (math.h)

Este bibliotecă care conţine toate funcţiile matematice. Unele dintre cele mai utilizate sunt prezentate în următorul tabel:

Tabelul 14.1 Funcţii matematice Nume Sintaxa Ce

returneaza Exemplu

abs double abs (double x)

valoarea absolută a unui număr real

#include <iostream.h> #include <math.h> void main(void) { int number = -1234; cout<<"valoarea absoluta a nr."<<number<<‘=‘<<abs(number));}

sqrt double sqrt (double x) radical

90

Page 95: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII PREDEFINITE

Nume Sintaxa Ce returneaza Exemplu

acos double acos (double x) arccosinus

asin double asin (double x) arcsinus

cos double cos (double x)

cosinus (la toate funcţiile trigonometrice argumentul e în radiani)

#include <iostream.h> #include <math.h> void main(void) { double result, x = 0.5; result = cos(x); cout<<"cos("<<x<<”)=“<<result);}

cosh double cosh (double x)

cosinus hiperbolic

exp double exp (double x) exponenţiala

floor double floor (double x)

rotunjire prin lipsă

#include <stdio.h> #include <math.h> void main(void) { double number=123.54; double down, up; down=floor(number); up=ceil(number); cout<<"numarul original="<<number<<"nr.rotunjit prin lipsa”<<down<<"nr.rotunjit prin adaus”<<up;}

ceil double ceil (double x)

rotunjire prin adaus

fmod double fmod (double x,double y)

restul împărţirii lui x la y

#include <stdio.h> #include <math.h> void main(void) { double x=5.0, y = 2.0; double result; result=fmod(x,y); cout<<"restul lui"<<x<<“la”<<y<<‘=‘<<result;}

hypot double hypot (double x,double y)

ipotenuza triunghiului de catete x şi y

91

Page 96: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

Nume Sintaxa Ce returneaza Exemplu

ldexp double ldexp(double x, int exp);

calculează produsul dintre primul parametru şi 2 la puterea dată de cel de al doilea parametru

#include <stdio.h> #include <math.h> int main(void) { double value; double x=7; /* ldexp ridica 2 la puterea 3 apoi inmulteste rezultatul cu 7*/ value = ldexp(x,3); cout<<"ldexp="<<value;}

log double log(double x);

logaritm natural

log10 double log10(double x);

logaritm zecimal

pow double pow(double x, double y);

puterea unui număr la alt număr

pow10 double pow10(int p);

puterea lui 10 la un număr întreg

sin double sin(double x);

sinus

sinh double sinh(double x);

sinus hiperbolic

sin_hyp = sinh(x); sin_hyp = (exp(x) - exp(-x))/2

tan double tan(double x);

tangenta

tanh double tanh(double x);

tangenta hiperbolică

14.2.2 Biblioteca pentru şiruri de caractere (string.h)

Conţine funcţii pentru şiruri de caractere

Tabelul 14.2 Funcţii pentru şiruri de caractere Nume Sintaxa Ce face Exemplu

strcat strcat(s1,s2)

Concatenează şirul s2 la sfârşitul şirul s1

#include <string.h> #include <stdio.h> int main(void) { char destination[25]; char *blank = " ", *c = "C++", *turbo = "Turbo"; strcpy(destination,

92

Page 97: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII PREDEFINITE

Nume Sintaxa Ce face Exemplu turbo); strcat(destination, blank); strcat(destination, c); printf("%s\n", destination); }

strcmp strcmp(s1,s2)

Comparare de şiruri; dă valoarea 0 dacă s1=s2, negativ dacă s1<s2 şi pozitiv dacă s1>s2.

#include <string.h> #include <stdio.h> int main(void) { char *buf1 = "aaa", *buf2 = "bbb", *buf3 = "ccc"; int ptr; ptr = strcmp(buf2, buf1); if (ptr > 0) printf("buffer 2 is greater than buffer 1\n"); else printf("buffer 2 is less than buffer 1\n"); ptr = strcmp(buf2, buf3); if (ptr > 0) printf("buffer 2 is greater than buffer 3\n"); else printf("buffer 2 is less than buffer 3\n"); }

strcpy strcpy(s1,s2) Copiază şirul s2 în s1

#include <stdio.h> #include <string.h> int main(void) { char string[10]; char *str1 = "abcdefghi"; strcpy(string, str1); printf("%s\n", string); }

strlen strlen(s1) Determina lungimea sirului s1

#include <stdio.h> #include <string.h> int main(void) { char *string = "Borland Internat"; printf("%d\n", strlen(string)); }

93

Page 98: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

14.2.3 Biblioteca standard (stdlib.h)

Aceasta conţine funcţiile de conversie pe care le vom prezenta în următorul tabel:

Tabelul 14.3 Funcţii de conversie Nume Sintaxa Ce face Exemplu

atof double atof(const char *s);

conversia unui şir la real dublă precizie

atol long atol(const char *s);

conversia unui şir la întreg long

#include <iostream.h> #include<stdlib.h> void main (void) { long l; char* str=“9876”; l=atol(str); cout<<“atol(“<<str<<“)=“<<l;}

atoi int atoi(const char *s);

conversia unui şir la întreg simplu

itoa

char* itoa(int value;char* string;int radix);

conversia unui întreg la şir de caractere cu lungimea dată de al treilea parametru

#include <stdlib.h> #include <iostream.h> void main(void) { int n=123; char str[5]; itoa(n,str,4); cout<<“itoa(“<<n<<“)=“<<str;}

ltoa

char* ltoa(long value;char* string;int radix);

conversia unui întreg long la şir de caractere cu lungimea dată de al treilea parametru

ultoa

char* ultoa(unsigned long value;char* string;int radix);

conversia unui întreg unsigned long la şir de caractere cu lungimea dată de al treilea parametru

ftoa

char* ftoa(float value;char* string;int radix);

conversia unui real dublă precizie la şir de caractere cu lungimea dată de al treilea parametru

rand int rand(void) generează un număr aleator cuprins între 0

#include <stdlib.h> #include <iostream.h> void main(void) { int i;

94

Page 99: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

Nume Sintaxa Ce face Exemplu şi 10000 cout<<“zece nr aleatoare de

la 0 la 99”; for (i=0; i<10; i++) cout<<rand()%100<<‘\n’;}

random int rand(int num)

generează un număr aleator cuprins între 0 şi num-1

system void system(char* string)

lansează în execuţie o comandă DOS

#include <stdlib.h> #include <iostream.h> void main(void) { cout<<“Continutul directorului curent:\n”; system("dir");}

14.3 Biblioteci de funcţii scrise de către utilizator

În cazul folosirii mai frecvente a anumitor funcţii, acestea pot fi scrise grupat într-un fişier bibliotecă, şi apelate apoi ori de câte ori este nevoie.

Programul următor apelează funcţia suma, care se găseşte într-un fişier header User_Lib.H //Biblioteci de functii #include "USER_LIB.H" void main() { int a=2,b=3,c; //functia suma se gaseste in fisierul antet USER_LIB.H c=suma(a,b); }

Biblioteca de funcţii este un fişier header/antet (cu extensia h) scris de către utilizator, căruia îi pot fi adăugate funcţii după nevoie. #ifndef _USER_LIB_ #define _USER_LIB_ int suma(int x,int y) {return x+y;} #endif

14.4 Exemple

14.4.1 Funcţii din biblioteca matematică

//Functii din biblioteca matematica #include<math.h> #include<iostream.h>

95

Page 100: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII - ANALIZĂ MATEMATICĂ, BIBLIOTECI DE FUNCŢII

#include<stdio.h> main() { float a,b,c,d; cout<<"introduceti a: ";cin>>a; cout<<"introduceti b: ";cin>>b; cout<<"\nvaloarea lui "<<a<<" la puterea "<<b<<" este: "<<pow(a,b); cout<<"\nvaloarea lui "<<10<<" la puterea "<<b<<" este: "<<pow10(b); cout<<"\nvaloarea log nat din "<<b<<" este: "<<log(b); cout<<"\nvaloarea log zecimal din "<<b<<" este: "<<log10(b); cout<<"\nvaloarea lui e la puterea "<<b<<" este: "<<exp(b); cout<<"\nvaloarea lui "<<a<<"*2 la "<<b<<" e: "<<ldexp(a,b); cout<<"\nvaloarea absoluta a nr real "<<b<<" este: "<<fabs(b); cout<<"\nvaloarea partii intregi a nr real "<<b<<" este: "<<floor(b); }

14.4.2 Operaţii cu şiruri de caractere utilizând funcţii predefinite

#include <iostream.h> #include <string.h> void main() { char sir1[] = ”abcd”, sir2[] = ”abcde”, sir3 = "abcdef”, sir4 = "de”; cout<<strcmp(sir1, sir2)<<’\n’; // afisare:-101 // ’e’ = 101, ’a’ = 97, ’d’ = 100 //’0’ - ’e’ = -101 cout<<strcmp(sir2, sir1)<<’\n’; //afisare: 101 cout<<strcmp(sir1, "")<<’ '; //compararea variabilei sir1 cu constanta sir vid char str1[20]=”hello”; char str2[20]=”goodbye”; char str3[20]; int difer, lungime; cout<<”str1=”<<str1<<” str2=”<<str2<<’\n’; difer=strcmp(str1, str2); if (difer == 0) cout<<”Siruri echivalente!\n”; else if (difer>0) cout<<str1<<” mai mare (lexicografic) decât “<<str2<<’\n’; else cout<<str1<<” mai mic (lexicografic) decât “<<str2<<’\n’; cout<<”str1=”<<str1<<’\n’; cout<<”str3=”<<str3<<’\n’; strcpy (str3, str1); cout<<”str1=”<<str1<<’\n’; cout<<”str3=”<<str3<<’\n’; strcat (str3, str1); cout<<”str1=”<<str1<<’\n’;

96

Page 101: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

cout<<”str3=”<<str3<<’\n’; }

97

Page 102: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

15. FUNCŢII RECURSIVE

O funcţie este numită funcţie recursivă dacă ea se autoapelează, fie direct (în definiţia ei se face apel la ea însăşi), fie indirect (prin apelul altor funcţii).

În cadrul acestui capitol vom aborda ambele tipuri de recursivitate: ■ recursivitate directă ■ recursivitate indirectă. Vă reamintim câteva observaţii fundamentale de care e bine să ţineţi cont: a) Studiaţi felul în care apare recursivitatea într-un program şi dacă sunt şi alte

moduri de elaborare a programului. Dacă sunt, atunci verificaţi dacă scrierea lor este mai eficientă şi dacă în cele din urmă optaţi pentru recursivitate.

b) Puneţi în evidenţă modul în care o problemă se apelează pe ea însăşi. c) Fiţi atenţi la modul în care definiţi parametrii funcţiilor recursive, variabilele

interne şi globale. Unele definiţii sunt fundamentale pentru execuţia programului. Spre exemplu, variabilele folosite pentru a parcurge valorile permise ale componentelor unei soluţii trebuie să fie locale funcţiei, altfel nu se generează corect soluţia. Unele definiţii bine alese pot optimiza destul de mult spaţiul alocat pe stivă şi timpul de execuţie.

d) Pentru corectitudinea recursivităţii realizate, fiţi atenţi la modul în care se păstrează valorile datelor la ieşirea dintr-un apel recursiv. Aveţi grijă ca după ieşirea din apelul recursiv al unei funcţii să refaceţi datele modificate pentru noul apel.

e) Aveţi grijă la stocarea datelor intermediare. Dacă este necesară o determinare a unui optim, se va lucra cu două seturi de date: unul pentru stocarea optimului şi unul pentru generarea soluţiei curente. În acest caz, tipărirea soluţiei nu se face în interiorul recursivităţii, ci după terminarea tuturor apelurilor.

f) Aveţi grijă să puneţi corect condiţiile de ieşire din recursivitate. Fără acestea, programul nu se va opri niciodată.

g) Faceţi pregătirile necesare şi stabiliţi valorile parametrilor pentru primul apel. Atragem atenţia că orice nerespectare a uneia dintre observaţiile enumerate mai sus

poate determina erori.

15.1 Exemple - Recursivitate directă

15.1.1 Calculul permutărilor, aranjamentelor şi combinărilor:

Pn = n! ; Anm = n!

(n-m)! ; Cnm = n!

m!·(n-m)!

15.1.1.1 Programul //Analiza combinatorica #include<stdio.h> int fact (int n) { if (n==0) return 1.0; else return n*fact(n-1);

98

Page 103: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE - RECURSIVITATE DIRECTĂ

} void main() { int n,m,p,A,C; printf("\nintroduceti n="); scanf("%d",&n); printf("introduceti m="); scanf("%d",&m); p=fact(n); A=fact(n)/fact(n-m); C=fact(n)/(fact(m)*fact(n-m)); printf ("%d! =%d",n,p); printf ("\nA(%d,%d) = %d",n,m,A); printf ("\nC(%d,%d) = %d",n,m,C); }

15.1.2 Funcţia recursivă Ackerman

Să se calculeze matricea A(LxL), L≤10 unde: ACK2(i,j), dacă i>j, a(i,j)= 1, dacă i=j, sqrt(ACK(j,i)), dacă i<j, unde funcţia ACK(m,n) este o funcţie recursivă Ackerman definită pentru m≥0 şi

n≥0 prin: ACK(0,n) = n+1; ACK(m,0) = ACK(m-1,1); ACK(m,n) = ACK(m-1, ACK(m,n-1);

15.1.2.1 Programul: //Functii recursive - Ackerman #include<conio.h> #include<stdio.h> #include<math.h> #define DIM 4 double ack(int m, int n);//prototipul void scrie(double mat[DIM][DIM]);//prototipul void main() { double a[DIM][DIM]; int i,j; clrscr(); for(i=0;i<DIM;i++) for(j=0;j<DIM;j++) if(i>j) a[i][j]=ack(i,j)*ack(i,j); else if(i==j) a[i][j]=1; else a[i][j]=sqrt(ack(j,i));

99

Page 104: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

scrie(a); getch(); } //Definirea functiilor double ack(int m, int n) { if(m==0) return n+1; else if(n==0) return ack(m-1,1); else return ack(m-1,ack(m,n-1)); } void scrie(double mat[DIM][DIM]) { int i,j; for(i=0;i<DIM;i++) { printf("\n"); for(j=0;j<DIM;j++) printf("A[%d,%d]= %5.2f;",i,j,mat[i][j]); } }

15.1.3 CMMDC

Să se se scrie un program care citeşte doi întregi pozitivi m şi n, de tip long, calculează şi afişează pe cel mai mare divizor comun al lor. Programul va folosi o funcţie care are ca parametri doi întregi m şi n de tip long şi care calculează şi returnează cel mai mare divizor comun al lor.

Notăm cu: (m,n) cel mai mare divizor comun al numerelor m şi n. Calculul celui mai mare divizor comun a două numere se poate realiza recursiv astfel:

(m,n) = m dacă n = 0; (m,n) = n dacă m = 0; (m,n) = (n,m%n) dacă atît m, cât şi n sunt diferiţi de zero şi m > n (prin m%n s-a

notat restul împărţirii lui m la n). #include <stdio.h> #include <stdlib.h> //FUNCTIA long cmmdc(long m, long n) /* calculeaza si returneaza pe cel mai mare divizor comun al numerelor m si n */ { if(m==0) return n; else if(n==0) return m; else if(m>n) return cmmdc(n, m%n); else return cmmdc(m, n%m); }

100

Page 105: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE - RECURSIVITATE DIRECTĂ

void main() /* citeste pe m si n de tip long, calculeaza si afiseaza (m,n) */ { long m,n; printf("\nValorile lui m si n: "); if(scanf("%ld %ld", &m, &n)!=2 || m<0 || n<0) { printf("nu s-au tastat doi intregi pozitivi\n"); exit(1); } printf("m=%ld\tn=%ld\t(m,n)=%ld\n",m,n,cmmdc(m,n)); }

15.1.4 Generarea tuturor permutărilor unei mulţimi

În prima variantă vom defini funcţia recursivă permutare. Aceasta va genera permutările verificând la fiecare poziţie dacă elementul curent a fost deja selectat sau nu. Dacă nu este selectat, el poate fi folosit pentru această poziţie. Ieşirea din recursivitate se va face în momentul când s-au generat toate cele n componente. #include<stdio.h> int k,n,poz[20],p[20]; void permutare(int i); void main () { printf("Numarul de elemente: "); scanf("%d",&n); permutare(1); } void permutare(int i) { int j; for(j=1;j<=n;j++) if(poz[j]==0) { p[i]=j; poz[j]=1;/* selectam elementul j pe pozitia i */ if(i==n)/*Daca s-au generat toate pozitiile se afiseaza solutia*/ { for(k=1;k<=n;k++) printf("%d",p[k]); printf("\t"); } else permutare(i+1); poz[j]=0; /* deselectam elementul j */ } }

Varianta a doua va defini funcţia recursivă permuta de generare a permutărilor, care face generarea tuturor permutărilor prin interschimbarea elementului de pe poziţia

101

Page 106: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

curentă k, pe rând cu elementele din poziţiile anterioare, de la 1 la k-1. Când se ajunge la prima poziţie, se tipăreşte permutarea generată. //Generarea tuturor permutarilor unei multimi. #include <stdio.h> int a[100] ; int n, k, i ; void tipareste(int n) { int i; for (i=1;i<=n;i++) printf ("%d ", a[i]); putchar('\n'); } void permuta(int k) { int i; if (k==1) tipareste (n); else { permuta(k-1) ; for (i=1;i<k;i++) { a[i] ^=a[k] ^=a[i] ^=a[k] ; permuta(k-1); a[i] ^=a[k] ^=a[ i] ^=a[ k] ; } } } void main() { printf("Introduceti n :" ) ; scanf(" %d" , &n) ; for(i=1; i<=n; i++) a[i] =i; permuta(n); }

15.1.5 Problema reginelor

Să se afişeze toate posibilităţile de aranjare a n regine pe o tablă de şah de dimensiuni n x n astfel încât ele să nu se atace.

Pentru a simplifica determinarea configuraţiilor corecte, vom folosi pentru fiecare linie o regină. Coloanele pentru fiecare regină se vor stoca în vectorul r. Generarea reginelor se face cu ajutorul funcţiei recursive regina care va avea ca parametru numărul liniei.

Pentru a accepta poziţia curentă, se verifică dacă regina aşezată acum se atacă pe coloană sau pe diagonală cu reginele plasate anterior.

Pentru aceasta vom defini funcţia ataca pentru a verifica dacă la adăugarea reginei de pe linia i aceasta se atacă cu una din reginele 1, 2,..., i-1. Ea va returna valoarea 0,

102

Page 107: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE - RECURSIVITATE DIRECTĂ

dacă regina i nu atacă nici o regină şi valoarea 1 în caz contrar. Două regine se atacă dacă sunt pe aceeaşi coloană sau pe aceeaşi diagonală. A doua condiţie revine la a verifica dacă diferenţa dintre liniile pe care sunt situate reginele este egală cu diferenţa dintre coloanele acestora, în valoare absolută.

Pentru afişarea unei table de şah şi a configuraţiei reginelor am folosit funcţia scrie. Pentru numărarea soluţiilor generate am folosit variabila nr.

15.1.5.1 Programul //Problema reginelor #include<stdio.h> #include<conio.h> #include<stdlib.h> int r[20],n,nr; int ataca(int); void regina(int); void scrie(void); void main() { textmode(C80); textcolor(YELLOW); printf("\nNumarul de regine: "); scanf("%d",&n); regina(1); } void regina(int i) { int j; for(j=1;j<=n;j++) { r[i]=j; if(!ataca(i)) if(i<n) regina(i+1); else scrie(); } } int ataca(int i) { int j; for(j=1;j<=i-1;j++) if(r[i]==r[j]||abs(r[i]-r[j])==abs(i-j)) return 1; return 0; } void scrie() { int i,j; textbackground(BLACK); clrscr(); printf("Solutia %d:\n",++nr); for(i=1;i<=n;i++) {

103

Page 108: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

printf("\t"); for(j=1;j<=n;j++) { if(i%2==j%2) textbackground(WHITE) ; else textbackground(BLACK); if(r[i]==j) cprintf("R"); else cprintf(" "); } cprintf("\n\r"); } printf("Ptr continuare apasati orice tasta!"); getch(); }

15.1.6 Problema rucsacului

O persoană are un rucsac cu care poate transporta o greutate maximă G. Persoana are la dispoziţie n obiecte diferite şi cunoaşte pentru fiecare obiect greutatea şi câştigul care se obţine în urma transportului său la destinaţie. Se cere să se precizeze care obiecte trebuie să le transporte persoana astfel încât câştigul să fie maxim.

Varianta recursivă a problemei va utiliza funcţia rucsac. Aceasta va calcula pentru fiecare obiect dacă selecţia sa duce la depăşirea greutăţii maxime admisibile. Dacă nu, se verifică dacă actuala configuraţie are o valoare maximă. În caz afirmativ, se stochează obiectele care dau pentru selecţie o valoare maximă. Tipărirea obiectelor care au împreună valoarea maximă se va face la ieşirea din recursivitate.

15.1.6.1 Programul //Problema rucsacului #include<stdio.h> #include<stdlib.h> #include<conio.h> #define DIM 10 float gx, vx, gmax=9, vmax, g[DIM] = {0,1,2,4,5,8}, v[DIM] = {0,5,9,12,15,25}; int s[DIM],smax[DIM],n=4; void rucsac(int i) //i - nr curent max de obiecte { int j,k; for(j=0;j<=1;j++) /* Daca nu se depaseste greutatea maxima obiectul este selectat */ if(gx+j*g[i]<=gmax) { /* Se actualizeaza greutatea si valoarea */ s[i]=j; gx+=j*g[i]; vx+=j*v[i]; /* Daca valoarea selectiei actuale este mai mare decat maximul de pana acum se actualizeaza selectia de maxim */ if(vx>vmax)

104

Page 109: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE - RECURSIVITATE DIRECTĂ

{ vmax=vx; printf("\nvmax=%5.2f: ",vmax); for(k=1;k<=i;k++) { smax[k]=s[k]; printf("%2d*%4.2f(%4.2f)",smax[k],v[k],g[k]); } for(k=i+1;k<=n;k++) { smax[k]=0; printf("%2d*%4.2f",smax[k],v[k]); } } /*Apelul recursiv pentru trecerea la urmatorul obiect*/ if(i<n) rucsac(i+1); /*Refacerea starii dupa iesirea din recursivitate*/ gx-=j*g[i]; vx-=j*v[i]; } } void main() { int i; FILE *f; clrscr(); /* Introducerea datelor */ //Citire din fisier /* f=fopen("rucsac.txt","r"); fscanf(f,"%d",&n); fscanf(f,"%g",&gmax); for(i=1;i<=n;i++) fscanf(f,"%g %g",&g[i],&v[i]); fclose(f);*/ gx=vx=0; vmax=-1; /* Apelul recursiv */ rucsac(1); /* Tiparirea solutiei maxime obtinute */ printf("\nValoarea maxima:\t%g \nGreut max:\t%g \nObiectele:\t",vmax, gmax); for(i=1;i<=n;i++) if(smax[i]==1) printf("%d, ",i); }

Observaţi modul în care s-a modificat programul atunci când se cere o configuraţie de optim:

1. în interiorul funcţiei recursive se face doar verificarea de optim şi stocarea în cazul îndeplinirii condiţiilor de optim a datelor intermediare într-un set de date separat;

2. tipărirea soluţiei s-a făcut la ieşirea din apelul recursiv şi nu în interior.

105

Page 110: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

15.1.7 Prăjituri

Fiind date n tipuri de prăjituri cu costul c[1], c[2], ..., c[n], să se determine toate modurile posibile de a cumpăra m prăjituri care să nu depăşească suma s. Se consideră că pot fi cumpărate oricâte prăjituri de un anumit tip.

Notaţii făcute: x, stochează câte prăjituri s-au cumpărat din fiecare tip; suma, valoarea prăjiturilor cumpărate în momentul de faţă; nr, numărul de prăjituri cumpărate în momentul de faţă. În procedura recursivă rec, numărul maxim de prăjituri care se pot cumpăra este

minimul dintre numărul de prăjituri rămase de cumpărat, m, şi numărul posibil de cumpărat cu suma rămasă din prăjiturile de tipul i, adică (s-suma)/c[i]. Datele se citesc din fişierul "prajitur.in", iar soluţiile se scriu în fişierul "prajitur.out".

15.1.7.1 Programul //Prajituri #include<iostream.h> #include<fstream.h> long x[100] ,c[100]; short k,i,j,n,m,nr; unsigned nr_sol; unsigned long s,suma; fstream f; void rec(int i) { int max,j; max=(s-suma)/c[i] ; if(max>m-nr) max=m-nr; for(j=0;j<=max;j++) { suma+=c[i]*j; nr+=j; x[i]=j ; if(suma<=s) if(nr<m&&i<n) rec(i+1); else if(nr==m) { //Tip ?rire nr_sol++; f<<"Suma totala: "<<suma<<endl; for(k=1;k<=i;k++) if(x[k]>0) f<<"prajitura "<<k<<" de "<<x[ k]<<" ori\n"; f<<"-------------------------------------------\n"; } nr-=j; suma-=c[i]*j; } } void main() {

106

Page 111: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE - RECURSIVITATE INDIRECTĂ

f.open("prajitur.in",ios::in); f>>n; // Numarul de tipuri de prajituri: f>>s; // suma data f>>m; // numarul de prajituri pentru cumparat for(i=1;i<=n;i++) f>>c[i]; //costul fiecarei prajituri f.close(); // Se deschide fisierul "prajitur.out" pentru scrierea solutiilor f.open("prajitur.out",ios::out); nr_sol=0; rec(1); f<<"Numarul de solutii: "<<nr_sol ; f.close(); }

15.2 Exemple - Recursivitate indirectă

15.2.1 N din 4

Se ştie că din numărul 4 se obţine orice număr natural n scris în baza zece prin aplicarea următoarelor operaţii:

• se scrie la sfârşit cifra 4; • se adaugă cifra 0; • se împarte la doi dacă numărul este par.

Se cere să se scrie un program care produce un şir de numere conform regulilor precedente în care primul număr este 4 iar ultimul este n.

Se pleacă de la numărul n şi se generează operaţiile inverse celor menţionate. Programul este format din 2 funcţii între care se face recursivitatea indirectă: proc2 - se înmulţeşte numărul cu 2. Dacă ultima cifră este 0 sau 4, se apelează

proc0, altfel se apelează proc2. proc0 - se şterge ultima cifră dacă este 0 sau 4. Apelul recursiv este asemănător cu

proc0: dacă ultima cifră este 0 sau 4 se apelează proc0, altfel se apelează proc2. #include<conio.h> #include<stdio.h> int n,a[100]; /*numarul initial si sirul de transformari*/ void proc2(int k);/*proceduri de transformare*/ void procO(int k); void proc2(int k) /* se inmulteste numarul cu 2 */ { int x; if(k!=4) { a[++a[0]]=k*=2; x=k%10; if(x==0||x==4) procO(k); else proc2(k);

107

Page 112: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FUNCŢII RECURSIVE

} } void procO(int k) /* se elimina ultima cifra */ { int x; if(k!=4) { a[++a[0]]=k/=10; x=k%10; if(x==0||x==4) procO(k); else proc2(k); } } void main(void) { int p; printf("\nNumarul care se obtine: ") ; scanf("%d",&n) ; a[1]=n;a[0]=1; if(n!=4) { p=n%10; if(p==0||p==4 ) procO(n); else proc2(n); } printf("Sirul de numere este: "); for(p=a[0];p>=1;p--) printf(" %d ",a[p]); getch(); }

15.3 Probleme propuse

1. Să se scrie un program care citeşte câte două numere, până la întâlnirea perechii de numere 0, 0 şi afişează, de fiecare dată, cel mai mare divizor comun al acestora, folosind o funcţie care îl calculează.

2. Se introduce de la tastatura un număr întreg. Să se afişeze toţi divizorii numărului introdus. Se va folosi o funcţie de calcul a celui mai mare divizor comun a 2 numere.

3. Secvenţele următoare sunt corecte din punct de vedere sintactic ? Dacă nu, identificaţi sursele erorilor.

void a(int x, y) {cout<<"x="<<x<<" y="<<y<<'\n';} void main( ) { int b=9; a(6, 7); }

void main( ) { int x=8; double y=f(x); cout<<"y="<<y<<'\n';} int f(int z) {return z+z*z;}

4. Scrieţi o funcţie găseste_cifra care returnează valoarea cifrei aflate pe poziţia k în cadrul numărului n, începând de la dreapta (n şi k vor fi argumentele funcţiei).

5. Să se calculeze valoarea funcţiei g, cu o eroare EPS (a, b, EPS citite de la tastatură):

108

Page 113: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

g(x)=⌡⌠a

bx2 + x + 1 *ln|x+a|dx +

⌡⌠

a

b

x*arctg

b

b+x dx

6. Implementaţi funcţii iterative şi recursive pentru calculul valorilor polinoamelor Hermite Hn(y), ştiind că: H0(y) = 1, H1(y) = 2y, Hn(x) = 2yHn-1(y)-2Hn-2(y) dacă n>1. Comparaţi timpul de execuţie al celor două funcţii.

7. Să se scrie un program care generează toate numerele palindrom, mai mici decât o valoare dată, LIM. Un număr palindrom are cifrele simetrice egale (prima cu ultima, a doua cu penultima, etc). Se va folosi o funcţie care testează dacă un număr este palindrom.

8. Fie matricea C (NXN), N<=10, ale cărei elemente sunt date de relaţia:

j! +∑=

j

kkx

0)sin( , dacă i<j

Ci,j = xi, dacă i=j

i! + ∑=0

)cos(k

kxi , dacă i>j

unde x∈[0,1], x introdus de la tastatură. a) Să se implementeze următoarele funcţii: de calcul a elementelor matricei; de

afişare a matricei; de calcul şi de afişare a procentului elementelor negative de pe coloanele impare (de indice 1, 3, etc);

b) Să se afişeze matricea B, unde: B = C - C2 + C3 - C4 + C5. 9. Să se creeze o bibliotecă de funcţii pentru lucrul cu matrice, care să conţină funcţiile

utilizate frecvent (citirea elementelor, afisarea matricei, adunare a două matrice, etc). Să se folosească această bibliotecă.

10. Să se creeze o bibliotecă de funcţii pentru lucrul cu vectori, care să conţină funcţiile utilizate frecvent. Să se folosească această bibliotecă.

109

Page 114: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

16. TIPURI DE DATE DEFINITE DE UTILIZATOR

16.1 Structuri

Structurile grupează date de tipuri diferite, constituind definiţii ale unor noi tipuri de date. Componentele unei structuri se numesc membrii (câmpurile) structurii. La declararea unei structuri se pot preciza tipurile, identificatorii elementelor componente şi numele structurii.

Forma generală de declarare a unei structuri: struct identificator_tip_structura

{ lista_de_declaratii_membri;

} lista_identificatori_variabile; în care: • struct este un cuvânt cheie (obligatoriu); • identificator_tip_structura reprezintă numele noului tip (poate lipsi); • lista_de_declaratii_membri este o listă în care apar tipurile şi

identificatorii membrilor structurii; • lista_identificatori_variabile este o listă cu identificatorii variabilelor

de tipul declarat. Membrii unei structuri pot fi de orice tip, cu excepţia tipului structură care se

declară.

16.1.1 Punctul mediu

Să se găsească coordonatele x şi y ale punctului mediu situat la jumătatea distanţei dintre două puncte date dintr-un plan. //Structuri #include <iostream.h> typedef struct{float x,y;} punct2D; punct2D punct_mediu(punct2D p1, punct2D p2) { punct2D pm, ptemp; pm.x=(p1.x+p2.x)/2; pm.y=(p1.y+p2.y)/2; return pm; } void main () { punct2D a={0,3}, b={6,4}, c; c=punct_mediu(a,b); cout<<"\na("<<a.x<<","<<a.y<<")"; cout<<"\nb("<<b.x<<","<<b.y<<")";

110

Page 115: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI

cout<<"\nc("<<c.x<<","<<c.y<<")"; }

16.1.2 Punctul în oglindă

Să se găsească imaginea în oglindă a unui punct A(x,y) faţă de axa Oy. //Structuri-pointer #include <iostream.h> struct punct2D {float x,y;}; void oglinda_oy(struct punct2D *pct) { //in cazul utilizarii pointerilor catre structuri accesarea campurilor structurii se face cu ajutorul operatorului "->" pct->x=-pct->x; } void main () { struct punct2D A={5,3}; cout<<"\nPunctul original A are x="<<A.x<<" si y= "<<A.y; oglinda_oy(&A); cout<<"\nPunctul oglindit A' are x="<<A.x<<" si y=" <<A.y; }

16.1.3 Modulul unui număr complex

Să se calculeze modulul unui număr complex folosind o funcţie. //Functie cu structuri #include<math.h> #include<stdio.h> #include<conio.h> typedef struct{ double real; double imag; } COMPLEX; double modul(COMPLEX *);//prototipul void main() { COMPLEX nr; clrscr(); while(scanf("%lf %lf",&nr.real,&nr.imag)==2) printf("\nreal=%.2f imag=%.2f modul=%.2f",nr.real,nr.imag,modul(&nr)); getch(); } double modul(COMPLEX *z)//definitie

111

Page 116: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

{ return sqrt(z->real*z->real+z->imag*z->imag);}

16.1.4 Modul şi argument

Să se scrie un program care citeşte numere complexe şi le afişează împreună cu modulul şi argumentul lor.

Programul foloseşte o funcţie care calculează şi returnează modulul unui număr

complex z. Dacă: z = x + iy atunci modulul numărului complex este rădăcina pătrată din: x*x +

y*y. Programul mai foloseşte şi o funcţie care calculează şi returnează argumentul unui

număr complex. Dacă: z = x + iy atunci arg z se calculează astfel: a. DACĂ x = y = 0, arg z = 0. b. DACĂ y = 0 şi x ≠ 0, ATUNCI DACĂ x > 0, arg z =0; ALTFEL arg z = π = 3.14. c. DACĂ x = 0 şi y ≠ 0, ATUNCI DACĂ y > 0, arg z = π/2; ALTFEL arg z = 3*pi/2. d. DACĂ x şi y ≠ 0, ATUNCI fie:

a = arctg(y/x) d1. DACĂ x > 0 şi y > 0, ATUNCI arg z = a. d2. DACĂ x > 0 şi y < 0, ATUNCI arg z = 2*π + a. d3. DACĂ x < 0 şi y > 0, ATUNCI arg z = π + a. d4. DACĂ x < 0 şi y < 0, ATUNCI arg z = π + a. Se observă că pentru x < 0 şi y ≠ 0:

arg z = pi + a; ALTFEL, DACĂ x > 0 şi y < 0, ATUNCI arg z = 2*π + a

#include <stdio.h> #include <math.h> typedef struct { double x; double y; } COMPLEX; double d_modul(COMPLEX *z) /*calculeaza si returneaza modulul numarului complex z */ { return sqrt(z->x*z->x+z->y*z->y) ;} /* functia foloseste constanta M_PI=3.1415... definita in headerul math.h */ double d_arg(COMPLEX *z) { double a; if(z->x==0 && z->y==0) return 0.0; if(z->y==0) if(z->x>0) return 0.0; else /*y=0 si x<0 */ return M_PI; if(z->x==0)

112

Page 117: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI

if(z->y>0) return M_PI/2; else /*x=0 si y<0*/ return (3*M_PI)/2; /*x!=0 si y!=0 */ a=atan(z->y/z->x); if(z->x<0) /*x<0 si y!=0*/ return a+M_PI; else /*x>0*/ if(z->y<0) /*x>0 si y<0*/ return 2*M_PI+a; else /*x>0 si y>0*/ return a; } void main() /* citeste numere complexe si le afiseaza impreuna cu modulul si argumentul corespunzator */ { COMPLEX complex; printf("Introduceti elementele nr complex: "); while(scanf("%lf %lf", &complex.x, &complex.y) == 2) { printf("a+ib= %g + i*(%g)\n", complex.x, complex.y); printf("modul=%g\targ=%g\n", d_modul(&complex),d_arg(&complex)); } }

16.1.5 Ordinea a două date calendaristice

Scrieţi o funcţie având ca parametri două date calendaristice (precizate prin an, lună şi zi), care stabileşte una din situaţiile:

•Prima dată o precede pe cea de-a doua •Cele două date sunt egale •A două dată o precede pe prima Funcţia va întoarce una din valorile -1,0, 1.

#include <stdio.h> typedef struct { unsigned int an; unsigned int luna; unsigned int zi; } Data; /* vector in care retinem ultima zi pentru fiecare luna: */ int zile[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* verificare daca anul este bisect (daca da, se intoarce o valoare nenula): */ int bisect(int an) { return ((an%4==0 && an%100!=0) || an%400==0); } /* verifica daca o data este valida (daca da, se intoarce o valoare nenula):*/

113

Page 118: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

int e_valida(Data d) { /* daca anul este bisect si luna este februarie: */ if (bisect(d.an) && d.luna==2) return (d.zi <= 29); /* anul nu este bisect sau luna nu este februarie: */ return (d.zi <= zile[d.luna-1]); } /* Functie care compara 2 date calendaristice * Rezultat intors. -1 daca d1 precede d2 * 1 daca datele sunt egale * 1 daca d2 precede d1 */ int compara_date(Data d1, Data d2) { if(d1.an<d2.an) return -1; if(d1.an>d2.an) return 1; /* d1.an = d2.an : */ if(d1.luna<d2.luna) return -1; if(d1.luna>d2.luna) return 1; /* d1.an = d2.an si d1.luna = d2.luna */ if(d1.zi<d2.zi) return -1; if(d1.zi>d2.zi) return 1; /* d1.an = d2.an si d1.luna = d2.1una si d1.zi=d2.zi */ return 0; } void main(void) { Data d1, d2; do { printf("introduceti data d1 (zi luna an):\n"); scanf("%d %d %d", &d1.zi, &d1.luna, &d1.an); if(!e_valida(d1)) printf("Data nu este valida, introduceti una corecta:\n"); } while(!e_valida(d1)); do { printf("introduceti data d2 (zi luna an):\n"); scanf("%d %d %d", &d2.zi, &d2.luna, &d2.an); if(!e_valida(d2)) printf("Data nu este valida, introduceti una corecta:\n"); } while(!e_valida(d2)); switch(compara_date(d1,d2)) { case -1: printf("d1 precede d2\n"); break; case 0: printf("Datele sunt egale\n"); break;

114

Page 119: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

STRUCTURI

case 1: printf("d1 urmeaza dupa d2\n"); } }

16.1.6 Prelucrare informaţii elevi

Să se citească (cu ajutorul unei funcţii de citire) următoarele informaţii despre elevii participanţi la un concurs de admitere: nume, numărul de înscriere şi cele trei note obţinute. Să se afişeze, printr-o funcţie, informaţiile citite. Să se afişeze o listă cu elevii participanţi la concurs, ordonaţi alfabetic, notele şi media obţinută (funcţie de ordonare, funcţie de calculare a mediei). Să se afişeze lista elevilor înscrişi la concurs, în ordinea descrescătoare a mediilor.

#include <stdio.h> #include <string.h> #include <iostream.h> #include <conio.h> #define DIM_PAG 24 // dimensiunea paginii de afisare #define FALSE 0 #define TRUE 1 struct elev{ char nume[20];int nr_matr;int note[3]; }; //definirea tipului elev void cit_elevi(elev *a, int n) { for (int i=0; i<n; i++){ cout<<"Nume elev:"; cin>>(a+i)->nume; //sau cin>>(*(a+i)).nume; cout<<"Nr. inscriere:"; cin>>(a+i)->nr_matr; for (int j=0; j<3; j++){ do{ cout<<"Nota :"<<(j+1)<<" ="; cin>>(a+i)->note[j]; if((a+i)->note[j]<0 || (a+i)->note[j]>10) cout<<"Nota incorecta!....Repeta!\n"; }while ((a+i)->note[j]<0 || (a+i)->note[j]>10); } } } void ord_medii(elev *a, int n) { int gata =FALSE;int i;double med1, med2;elev aux; while (!gata){ gata=TRUE; for(i=0; i<=n-2; i++){ med1=0;med2=0; for (int j=0; j<3; j++){

115

Page 120: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

med1+=(a+i)->note[j]; med2+=(a+i+1)->note[j];// calculul mediilor pentru elementele vecine } med1/=3; med2/=3; if (med1<med2){ aux=*(a+i); *(a+i)=*(a+i+1);*(a+i+1)=aux; gata=FALSE;} } } } void ord_alf(elev *a, int n) { int gata =FALSE; int i; double med1, med2; elev aux; while(!gata){ gata=TRUE; for (i=0; i<=n-2; i++){ if(strcmp((a+i)->nume,(a+i+1)->nume) >0) {aux=*(a+i); *(a+i)=*(a+i+1);*(a+i+1)=aux; gata=FALSE;} } } } //void cit_elevi(elev *a, int n); // functie implementata anterior void antet_afis(const char *s) {printf("%s\n", s); } void afis_elev(elev *a, int n, char c) {clrscr(); if(c=='A') antet_afis(" LISTA INSCRISILOR\n"); if(c=='O') antet_afis(" LISTA ALFABETICA\n"); if(c=='R') antet_afis(" LISTA MEDII\n"); printf("Nr.crt. | Nr. Matricol | NUME | Nota1 | Nota2 | Nota3 | MEDIA |\n"); printf("------------------------------------------\n"); int lin=3; for(int i=0; i<n; i++){ printf("%7d|%12d|%-20s|",i+1,(a+i)->nr_matr,(a+i)->nume); double med=0; for (int j=0; j<3; j++){ printf("%-5d|", (a+i)->note[j]); med+=(a+i)->note[j]; } med/=3;printf("%-9.2f|\n", med);lin++; if (lin==(DIM_PAG-1)){ printf(" Apasa o tasta...."); getch(); clrscr(); if(c=='A') antet_afis(" LISTA INSCRISILOR\n"); if(c=='O') antet_afis(" LISTA ALFABETICA\n"); if(c=='R') antet_afis(" LISTA MEDII\n");

116

Page 121: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE UNIUNI

printf("Nr.crt.| NUME |Nota1|Nota2|Nota3| MEDIA\ |\n"); printf("------------------------------------------\n"); int lin=3; } } printf(" Apasa o tasta...."); getch(); } void main() { int nr_elevi; clrscr(); cout<<"Nr. elevi:";cin>>nr_elevi; elev *p; p=new elev[nr_elevi]; cit_elevi(p, nr_elevi); afis_elev(p, nr_elevi, 'A');// afisarea înscrisilor ord_medii(p, nr_elevi); afis_elev(p, nr_elevi, 'R');// afisarea în ordinea descrescatoare a mediilor ord_alf(p, nr_elevi); //ordonare alfabetica afis_elev(p, nr_elevi, 'O');// afisarea în ordinea descrescatoare a mediilor }

16.1.7 Media notelor la un examen

Să se calculeze media notelor la un examen pentru mai mulţi studenţi şi media notelor la toate examenele pentru un singur student. Se vor folosi date de tip structură (denumită student) cu următoarele câmpuri: Nume, nota1, nota2, nota3.

16.2 Uniuni

Aceeaşi zonă de memorie poate fi utilizată pentru păstrarea unor obiecte (date) de diferite tipuri, prin declararea uniunilor. Uniunile sunt similare cu structurile, singura diferenţă constând în modul de memorare. Declararea uniunilor:

union identificator_tip_uniune { lista de declaratii_membri;

} lista_identificatori_variabile; Spaţiul de memorie alocat corespunde tipului membrului de dimensiune maximă. Tipul

uniune foloseşte aceeaşi zonă de memorie, care va conţine informaţii organizate în mai multe moduri, corespunzător tipurilor membrilor.

16.3 Exemple uniuni

16.3.1 Dată de tip dublu

//Uniuni #include <iostream.h> #include<conio.h>

117

Page 122: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

union tip_dublu { int i; float f; } ddata; void main () {//ddata.f=1234.56e+5; ddata.i=1234; cout<<"ddata.f="<<ddata.f<<"\n"; cout<<"ddata.i="<<ddata.i<<"\n"; getch(); }

16.3.2 Citirea şi afişarea datelor despre mai multe persoane

Să se exemplifice folosirea uniunilor (union) pentru citirea şi afişarea datelor despre mai multe persoane de ambele sexe.

Vom folosi o structură pentru a memora numele, vârsta şi sexul unei persoane, indiferent dacă aceasta este femeie sau bărbat. Dar, în funcţie de sex, persoana respectivă va avea un soţ (dacă e femeie), respectiv o soţie (dacă e bărbat). O înregistrare de tip union va fi folosită, aşadar, pentru a memora partenerul unei persoane oarecare.

O înregistrare union este similară cu o înregistrare de tip struct, cu excepţia faptului că union va permite să definiţi variabile (câmpuri) care să-şi împartă acelaşi spaţiu de memorare.

#include<stdio.h> #include<conio.h> #include<stdlib.h> union partener { char sotie[20]; char sot[20]; }; struct persoana { char nume[20]; char sex; int varsta; union partener p; }; void Citeste(int nr_p, struct persoana *x) { int vs; char sx; printf("Se citesc datele persoanei a %d-a:\n",nr_p); fflush(stdin); //goleste fluxul de date printf("Dati numele: "); gets(x->nume);

118

Page 123: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE UNIUNI

printf("Dati varsta: "); scanf("%d",&vs); x->varsta=vs; fflush(stdin) ; printf("Dati sexul: "); scanf("%c",&sx) ; x->sex=sx; fflush(stdin); if (x->sex=='F'|| x->sex=='f') { printf("Dati numexe sotului: "); gets(x->p.sot); } else { printf("Dati numele sotiei: "); gets(x->p.sotie); } } void Scrie(int nr_p, struct persoana x) { if (wherey()==20) { printf("\nApasati o tasta ...\n"); getch(); } printf("Datele persoanei a %d-a:\n",nr_p); printf("Numele: %s.\n",x.nume); printf("Varsta: %d.\n",x.varsta); printf("Sexul: %c. \n",x.sex); if(x.sex=='F'|| x.sex=='f') printf("Numele sotului: %s.\n",x.p.sot); else printf("Numele sotiei: %s.\n",x.p.sotie); } void main() { struct persoana om[20]; int i,n; // textmode(C80); clrscr(); printf("Dati numarul de persoane: "); scanf("%d",&n); for(i=0; i<n; i++) Citeste(i+1,&om[i]); printf("\n Rezultate:\n"); for(i=0; i<n; i++) Scrie(i+1,om[i]); getch(); }

16.3.3 Arii figuri

Fie tipul FIG declarat ca mai jos:

119

Page 124: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

typedef struct { int tip; /* tipul figurii */ union { double raza; /* cerc */ double lat_p; /* patrat */ double lat_d[2 ];/* dreptunghi */ double lat_t[3]; /* triunghi */ } fig; } FIG;

O dată de tip FIG conţine elementele unei figuri necesare pentru a calcula aria figurii respective. Figurile avute în vedere sunt:

o cerc o pătrat o dreptunghi o triunghi.

În cazul primelor două figuri, data de tip FIG conţine o valoare de tip double care, în cazul cercului reprezintă lungimea razei acestuia, iar în cazul pătratului, lungimea laturii pătratului. În cazul dreptunghiului, data conţine două elemente de tip double: lungimea şi lăţimea. În sfirşit, în cazul triunghiului, data conţine trei valori de tip double care reprezintă lungimile celor trei laturi ale triunghiului.

Componenta tip defineşte elementele (figura) prezente într-o dată de tip FIG şi are valorile:

0 Pentru cerc 1 Pentru pătrat 2 Pentru dreptunghi 3 Pentru triunghi -1 Pentru eroare. În locul acestor valori, considerăm constantele simbolice: #define EROARE -1 #define CERC 0 #define PATRAT 1 #define DREPTUNGHI 2 #define TRIUNGHI 3 Funcţia aria din program are ca parametru o dată de tip FIG, calculează şi

returnează aria figurii ale cărei elemente sunt conţinute în zona definită de parametru. Funcţia returnează 0 în cazul în care datele sunt eronate.

La calculul arici unui triunghi se foloseşte formula lui Heron. Funcţia citire_fig din program are ca parametru un pointer spre o dată de tip

FIG şi citeşte şi păstrează elementele figurii definite de componenta tip a datei de tip FIG.

#include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct { int tip; union { double raza; double lat_p; double lat_d[2]; double lat_t[3]; } fig;

120

Page 125: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE UNIUNI

} FIG; #define EROARE -1 #define CERC 0 #define PATRAT 1 #define DREPTUNGHI 2 #define TRIUNGHI 3 #define PI 3.14159265358979 double aria(FIG *p) /* calculeaza si returneaza aria figurii definite de elementele prezente in zona spre care pointeaza p; la eroare returneaza 0 */ { double sp,a,b,c; switch(p->tip) { case CERC: return PI*p->fig.raza*p->fig.raza; case PATRAT: return p->fig.lat_p*p->fig.lat_p; case DREPTUNGHI: return p->fig.lat_d[0]*p->fig.lat_d[1]; case TRIUNGHI: sp=(p->fig.lat_t[0] + p->fig.lat_t[1] + p->fig.lat_t[2])/2; if((a=sp - p->fig.lat_t[0]) > 0 && (b=sp - p->fig.lat_t[1]) > 0 && (c=sp - p->fig.lat_t[2]) > 0 ) return sqrt(sp*a*b*c); else { /* cele 3 valori nu reprezinta lungimile laturilor unui triunghi */ printf("a= %g\tb= %g\tc= %g\tnu\ formeaza un triunghi\n", p->fig.lat_t[0], p->fig.lat_t[1], p->fig.lat_t[2] ); return 0; } default:/* eroare */ return 0; }/*switch*/ } int citire_fig(FIG *p) /* - citeste elementele figurii definite de p->tip; - returneaza: 0 - la intilnirea sfirsitului de fisier sau la eroare; 1 - altfel. */ { char t[255]; switch(p->tip) { case CERC: for( ; ; ) { printf("raza= "); if(gets(t) == 0 ) return 0; if(sscanf(t,"%lf",&p->fig.raza)== 1 && p->fig.raza>0) return 1;

121

Page 126: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

printf("nu s-a tastat un numar pozitiv\n"); } case PATRAT: for( ; ; ) { printf("latura patratului= "); if(gets(t) == 0 ) return 0; if(sscanf(t,"%lf",&p->fig.lat_p)==1 && p->fig.lat_p>0) return 1; printf("nu s-a tastat un numar pozitiv\n"); } case DREPTUNGHI: for( ; ; ) { printf("lungimea si latimea pe aceeasi linie: "); if(gets(t)==0) return 0; if(sscanf(t,"%lf %lf",&p->fig.lat_d[0], &p->fig.lat_d[1])==2 && p->fig.lat_d[0] > 0 && p->fig.lat_d[1] > 0) return 1; printf("nu s-au tastat 2 numere pozitive\n"); } case TRIUNGHI: for( ; ; ) { printf("laturile triunghiului pe aceeasi linie: "); if(gets(t) == 0 ) return 0; if(sscanf(t,"%lf %lf %lf",&p->fig.lat_t[0], &p->fig.lat_t[1], &p->fig.lat_t[2])==3 && p->fig.lat_t[0]>0 && p->fig.lat_t[1]>0 && p->fig.lat_t[2]> 0 ) return 1; printf("nu s-au tastat 3 numere\ pozitive\n"); } default: return 0; } } void main () /* citeste o litera mare care defineste o figura geometrica, apoi citeste elementele figurii respective; - calculeaza si afiseaza aria acelei figuri. */ { char t[255]; char er[]="s-a tastat EOF\n"; char lit[2]; FIG f; double a; for( ; ; ) { printf("Tastati una din literele mari: C\tD\tP\tT\n"); if(gets(t)==0) { printf(er); exit(1); } sscanf(t,"%ls",lit); switch(lit[0]) { case 'C': /* cerc */ f.tip = CERC; break; case 'D': /* dreptunghi */ f.tip = DREPTUNGHI; break;

122

Page 127: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

ENUMERĂRI

case 'P': /* patrat */ f.tip = PATRAT; break; case 'T': /* triunghi */ f.tip = TRIUNGHI; break; default: /* eroare */ printf("Nu s-a tastat una din literele mari C,D,P sau T\n"); f.tip = EROARE; } if(f.tip != EROARE) break; } /* sfirsit for */ /* citeste elementele figurii */ if(citire_fig(&f)==0) { printf(er); exit(1); } /* calculeaza si afiseaza aria figurii */ if((a=aria(&f))==0) exit(1); printf("Aria figurii= %g\n", a); }

16.4 Enumerări

Tipul enumerare permite programatorului să folosească nume sugestive pentru valori numerice. De exemplu, în locul numărului unei luni calendaristice este mai sugestiv să folosim denumirea lunii respective sau eventual o prescurtare:

ian - Pentru ianuarie în locul cifrei 1 feb - Pentru februarie în locul cifrei 2 şi aşa mai departe. Un alt exemplu se referă la posibilitatea de a utiliza cuvintele FALS şi ADEVĂRAT

pentru valorile 0, respectiv 1. În felul acesta se obţine o mai mare claritate în programele sursă, deoarece valorile numerice sunt înlocuite prin sensurile atribuie lor într-un anumit context.

În acest scop se utilizează tipul enumerare. Un astfel de tip se declară printr-un format asemănător cu cel utilizat în cadrul structurilor. Un prim format general este:

enum nume {nume0, nume1, nume2,..., numek} d1,d2,...,dn; unde: nume - este numele tipului de enumerare introdus prin această declaraţie. nume0, nume1,..., numek - sunt nume care se vor utiliza în continuare în locul

valorilor numerice şi anume numei are valoarea i. d1,d2,...,dn - sunt date care se declară de tipul nume. Aceste date sunt similare

cu datele de tip int. Ca şi în cazul structurilor, în declaraţia de mai sus nu sînt obligatorii toate

elementele. Astfel, poate lipsi nume, dar atunci va fi prezent cel puţin d1. De asemenea, poate lipsi în totalitate lista d1, d2, ..., dn, dar atunci va fi prezent nume. În acest caz, se vor defini ulterior date de tip nume folosind un format de forma:

enum nume d1,d2,...,dn;

123

Page 128: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

16.5 Exemple

16.5.1 Exemplul 1 - enumerare nume luni

enum { ileg, ian, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec } luna;

Prin această declaraţie, numărul lunii poate fi înlocuit prin denumirea prescurtată a lunii respective. De exemplu, o atribuire de forma: luna = 3 se poate înlocui cu una mai sugestivă: luna = mar deoarece, conform declaraţiei de mai sus, mar are valoarea 3.

În mod analog, o expresie de forma: luna == 7 este identică cu expresia: luna == iul

Dacă în locul declaraţiei de mai sus s-ar fi utilizat declaraţia de tip enumerare: enum dl {ileg, ian, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec };

atunci putem declara ulterior data luna de tip dl astfel: enum dl luna;. Data luna declarată în acest fel este o dată identică cu data luna declarată la început.

16.5.2 Exemplul 2 - enumerare tip Boolean

Fie tipul enumerare Boolean declarat astfel: enum Boolean {false, true};

Declarăm data bisect de tip Boolean: enum Boolean bisect;

Atribuirea: bisect = an%4 == 0&&an%100 || an%400 ==0;

atribuie variabilei bisect valoarea 1 sau 0, după cum anul definit de variabila an este bisect sau nu (se presupune că anul aparţine intervalului [1600,4900]).

În continuare se pot folosi expresii de forma: bisect == false

sau bisect == true

16.6 Declaraţii de tip

Limbajul C permite atribuirea unui nume pentru un tip (predefinit sau utilizator) de date. Pentru aceasta se folosesc declaraţiile de tip. Forma generală a acestora este:

typedef tip nume_tip; Nume_tip poate fi folosit la declararea datelor în mod similar cuvintelor cheie

pentru tipurile predefinite. Exemplu: //1

typedef int INTREG; INTREG x, y; INTREG z=4;

//2

124

Page 129: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

ALOCAREA DINAMICĂ A MEMORIEI

typedef struct{ double parte_reală; double parte_imaginară; } COMPLEX; COMPLEX x, y;

16.7 Alocarea dinamică a memoriei

Alocarea memoriei se poate realiza în următoarele moduri: alocare statică; alocare dinamică; alocare pe stivă.

Se alocă static memorie în următoarele cazuri: o pentru instrucţiunile de control propriu-zise; o pentru variabilele globale şi variabilele locale declarate în mod explicit static. Se alocă memorie pe stivă pentru variabilele locale. Se aloca dinamic memorie în mod explicit, cu ajutorul funcţiilor de alocare dinamica,

aflate în headerul <alloc.h>. În limbajul C, alocarea memoriei în mod dinamic se face cu ajutorul funcţiilor

malloc, calloc, realloc; eliberarea zonei de memorie se face cu ajutorul funcţiei free. Funcţiile de alocare/dezalocare a memoriei au prototipurile în header-ele <stdlib.h> şi <alloc.h>.

16.7.1 Funcţia malloc

Sintaxa: void *malloc(size_t nr_octei_de_alocat);

Funcţia malloc necesită un singur argument (numărul de octeţi care vor fi alocaţi) şi returnează un pointer generic către zona de memorie alocată (pointerul conţine adresa primului octet al zonei de memorie rezervate).

16.7.2 Funcţia calloc

Sintaxa: void *calloc(size_t nr_elemente, size_t mărimea_în_octeti_

a_unui_elem); Funcţia calloc alocă memorie pentru un tablou de nr_elemente, numărul de octeţi

pe care este memorat un element este mărimea_în_octeţi_a_unui_elem şi returnează un pointer către zona de memorie alocată.

16.7.3 Funcţia realloc

void *realloc(void *ptr, size_t mărime); Funcţia realloc permite modificarea zonei de memorie alocată dinamic cu ajutorul

funcţiilor malloc sau calloc.

125

Page 130: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

Obs.: În cazul în care nu se reuşeşte alocarea dinamică a memoriei (memorie insuficientă), funcţiile malloc, calloc şi realloc returnează un pointer null. Deoarece funcţiile malloc, calloc, realloc returnează un pointer generic, rezultatul poate fi atribuit oricărui tip de pointer. La atribuire, este indicat să se utilizeze operatorul de conversie explicită (vezi exemplu).

Eliberarea memoriei (alocate dinamic cu una dintre funcţiile malloc, calloc sau

realloc) se realizează cu ajutorul funcţiei free. void free(void *ptr);

16.8 Exemple

16.8.1 malloc

#include <iostream.h> #include <malloc.h> #include <string.h> #include <stdlib.h> void main() {char *sirstoc="SIR DE STOCAT IN MEMORIE"; char **psir; int nrart=5,i; char ch; if((psir=(char **) malloc(nrart*sizeof(char*)))==NULL) {cout << "Alocare esuata!\n"; exit(1);} else {for(i=0;i<nrart;i++) if( (psir[i] = (char *) malloc((strlen(sirstoc) + 1) * sizeof(char)))== NULL ) {cout << "Alocare esuata!\n"; exit(1);} else strcpy(psir[i],sirstoc); } cout << "Sirul " << sirstoc << " a fost alocat in " << nrart << "blocuri distincte.\n" for (i=0;i<nrart;i++)cout << psir[i] <<"\n"; cout << "Memoria pentru cele " << nrart << " blocuri " << sirstoc << \n";va fi eliberata apasind o tasta\n"; cin >> ch; for(i=0;i<nrart;i++)free(psir[i]); free(psir); }

16.8.2 calloc

//calloc #include <iostream.h> #include <malloc.h>

126

Page 131: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

float cere_element(int i) {float elem; cout << "a(" << (i+1) << ")="; cin >> elem; cout << "\n"; return elem; } void afis_tablou(int n,float *tablou) {int i; for(i=0;i<n;i++) cout << "a(" << (i+1) << ")=" << *(tablou+i) << "\n"; } void main() {int n,i; float *tablou; cout << "Specificati numarul de elemente ale tabloului, n="; cin >> n; tablou=(float *)calloc(n,sizeof(float)); if(tablou!=NULL) {cout << "\nIntroduceti elementele tabloului\n"; for(i=0;i<n;i++) *(tablou+i)=cere_element(i); cout << " Elementele tabloului sunt:\n"; afis_tablou(n,tablou); free(tablou); } else cout << "Alocare esuata!\n"; }

16.9 Probleme propuse

1. Realizaţi următoarele modificări la exemplul 16.1.6: a. Completaţi cu o funcţie de calcul şi afişare a mediei notelor tuturor candidaţilor

pentru fiecare probă (media tuturor elevilor la proba1, media la proba2, etc); b. Modificaţi lista alfabetică, astfel încât la elevii cu medie peste 5, să apară (alături

de medie) mesajul "Promovat", iar la ceilalţi, mesajul "Nepromovat"; c. Considerând că rezultatelor obţinute sunt utilizate la un concurs de admitere, la

care există N locuri (N introdus de la tastatură), şi de faptul că pentru a fi admis media trebuie să fie cel puţin 5, să se afişeze lista admişilor şi lista respinşilor, în ordinea descrescătoare a mediilor, în limita locurilor disponibile.

2. Să se scrie un program care să permită memorarea datelor privitoare la angajaţii unei firme mici: nume angajat, adresă, număr copii, sex, data naşterii, data angajării, calificare, salariul brut. Se vor implementa următoarele funcţii: a. Citirea informaţiilor despre cei N angajaţi (N introdus de la tastatură); b. Căutarea - după nume - a unui angajat şi afişarea informaţiilor despre acesta; c. Modificarea informaţiilor despre un anumit angajat; d. Lista alfabetică a angajaţilor, în care vor apare: nume, adresă, data angajării,

calificare, salariu; e. Lista angajaţilor în ordine descrescătoare a vechimii; f. Lista angajatilor cu un anumit numar de copii, C, introdus de la tastatură;

127

Page 132: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

TIPURI DE DATE DEFINITE DE UTILIZATOR

g. Lista angajaţilor cu vârsta mai mare decât V (V introdus de la tastatură); h. Salariul minim, salariul mediu şi cel maxim din firmă; i. Lista de salarii, în care vor apare: numele, calificarea, salariul brut şi salariul net.

La sfârşitul listei vor apare totalurile pentru salariile brute, impozite, salarii nete. Pentru calculul salariului net se aplică următoarele reguli de impozitare:

i. I=15% pentru salariul brut (SB)<600 ii. I=50+20% pentru 600<=SB<1500 (20% din ceea ce depăşeşte

600) iii. I=100+30% pentru 1500<=SB<3000 iv. I=250+40% pentru 3000<=SB<15000 v. I=45% pentru SB>=1500

128

Page 133: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

DESCHIDEREA UNUI FIŞIER

17. FIŞIERE

Noţiunea de fişier desemnează o colecţie de informaţii memorată pe un suport permanent (de obicei discuri magnetice), percepută ca un ansamblu, căreia i se asociază un nume (în vederea conservării şi regăsirii ulterioare).

Operaţiile care pot fi realizate asupra fişierelor sunt: deschiderea unui fişier, scrierea într-un fişier, citirea dintr-un fişier, poziţionarea într-un fişier, închiderea unui fişier.

17.1 Deschiderea unui fişier

17.1.1.1 Funcţia fopen Crează un flux de date între fişierul specificat prin numele extern (nume_fisier) şi

programul C. Parametrul mod specifică sensul fluxului de date şi modul de interpretare a acestora. Funcţia returnează un pointer spre tipul FILE, iar în caz de eroare - pointerul NULL (prototip în stdio.h).

FILE *fopen(const char *nume_fisier, const char *mod); Parametrul mod este o constantă şir de caractere, care poate conţine caracterele cu

semnificaţiile: r: flux de date de intrare; deschidere pentru citire; w: flux de date de ieşire; deschidere pentru scriere (crează un fişier nou sau

suprascrie conţinutul anterior al fişierului existent); a: flux de date de ieşire cu scriere la sfârşitul fişierului, adăugare, sau crearea

fişierului în cazul în care acesta nu există; +: extinde un flux de intrare sau ieşire la unul de intrare/ieşire; operaţii de

scriere şi citire asupra unui fişier deschis în condiţiile r, w sau a; b: date binare; t: date text (modul implicit).

Exemple: "r+" – deschidere pentru modificare (citire şi scriere); "w+" – deschidere pentru modificare (citire şi scriere); "rb" – citire binară; "wb" – scriere binară; "r+b" – citire/scriere binară.

17.1.1.2 Funcţia freopen (stdio.h) FILE *freopen(const char*nume_fis,const char*mod,FILE

*flux_date); Asociază un nou fişier unui flux de date deja existent, închizând legătura cu vechiul

fişier şi încercând să deschidă una nouă, cu fişierul specificat. Funcţia returnează pointerul către fluxul de date specificat, sau NULL în caz de eşec (prototip în stdio.h).

17.1.1.3 Funcţia open int open(const char *nume_fisier, int acces [,int mod]);

129

Page 134: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

Deschide fişierul specificat conform cu restricţiile de acces precizate în apel. Returnează un întreg care este un indicator de fişier sau -1 (în caz de eşec) (prototip în io.h).

Restricţiile de acces se precizează prin aplicarea operatorului "|" (disjuncţie logică la nivel de bit) între anumite constante simbolice, definite în fcntl.h, cum sunt :

O_RDONLY - citire O_WRONLY - scriere O_RDWR - citire şi scriere O_CREAT - creare O_APPEND - adăugare la sfârşitul fişierului O_TEXT - interpretare CR-LF O_BINARY - nici o interpretare

Restricţiile de mod de creare se realizează cu ajutorul constantelor: S_IREAD - permisiune de citire din fişier S_IWRITE - permisiune de scriere din fişier, eventual legate prin

operatorul "|"

17.1.1.4 Funcţia creat int creat(const char *nume_fişier, int un_mod);

Crează un fişier nou sau îl suprascrie în cazul în care deja există. Returnează indicatorul de fişier sau -1 (în caz de eşec). Parametrul un_mod este obţinut în mod analog celui de la funcţia de deschidere (prototip în io.h).

17.1.1.5 Funcţia creatnew int creatnew(const char *nume_fişier, int mod);

Crează un fişier nou, conform modului specificat. Returnează indicatorul fişierului nou creat sau rezultat de eroare (-1), dacă fişierul deja există (prototip în io.h).

După cum se observă, informaţia furnizată pentru deschiderea unui fişier este aceeaşi în ambele abordări, diferenţa constând în tipul de date al entitaţii asociate fişierului. Implementarea din io.h oferă un alt tip de control la nivelul comunicării cu echipamentele periferice (furnizat de funcţia ioctrl), asupra căruia nu vom insista, deoarece desfăşurarea acestui tip de control este mai greoaie, dar mai profundă.

17.2 Închiderea unui fişier

17.2.1.1 Funcţia fclose int fclose(FILE *pf);

Funcţia închide un fişier deschis cu fopen şi eliberează memoria alocată (zona tampon şi structura FILE). Returnează valoarea 0 la închiderea cu succes a fişierului şi -1 în caz de eroare (prototip în stdio.h).

17.2.1.2 Funcţia fcloseall int fcloseall(void);

Închide toate fluxururile de date şi returnează numărul fluxurilor de date închise (prototip în stdio.h).

17.2.1.3 Funcţia close

130

Page 135: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRELUCRAREA FIŞIERELOR TEXT

int close(int indicator); Închide un indicator de fişier şi returnează 0 (în caz de succes) sau -1 în caz de eroare

(prototip în io.h).

17.3 Prelucrarea fişierelor text

17.3.1 Prelucrarea unui fişier la nivel de caracter

Fişierele pot fi scrise şi citite caracter cu caracter folosind funcţiile putc (pentru scriere) şi getc (citire).

17.3.1.1 Funcţia putc int putc (int c, FILE *pf);

c – este codul ASCII al caracterului care se scrie în fişier; pf – este pointerul spre tipul FILE a cărui valoare a fost returnată de funcţia fopen. Funcţia putc returnează valoarea lui c (valoarea scrisă în caz de succes), sau –1

(EOF) în caz de eroare sau sfârşit de fişier.

17.3.1.2 Funcţia getc int getc (FILE *pf);

Funcţia citeşte un caracter dintr-un fişier (pointerul spre tipul FILE transmis ca argument) şi returnează caracterul citit sau EOF la sfârşit de fişier sau eroare.

17.3.2 Exemplul 1

Să se scrie un program care crează un fişier text în care se vor scrie caracterele introduse de la tastatură (citite din fişierul standard de intrare), până la întâlnirea caracterului ^Z = Ctrl+Z. #include <stdio.h> #include <process.h> void main() { int c, i=0; FILE *pfcar; char mesaj[]="\nIntrodu caractere urmate de Ctrl+Z (Ctrl+D sub Linux):\n"; char eroare[]="\n Eroare deschidere fisier \n"; while(mesaj[i]) putchar(mesaj[i++]); pfcar=fopen("f_car1.txt","w"); // crearea fişierului cu numele extern f_car1.txt if(pfcar==NULL) { i=0; while(eroare[i]) putc(eroare[i++],stdout); exit(1); } while((c=getchar())!=EOF)// sau while((c=getc(stdin))!= EOF) putc(c,pfcar); // scrierea caracterului în fişier fclose(pfcar); // închiderea fişierului

131

Page 136: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

}

17.3.3 Exemplul 2

Să se scrie un program care citeşte un fişier text, caracter cu caracter, şi afişează conţinutul acestuia. #include <stdio.h> #include <process.h> void main() { int c, i=0; FILE *pfcar; char eroare[]="\n Eroare deschidere fisier \n"; pfcar=fopen("f_car1.txt","r"); //deschiderea fişierului numit f_car1.txt în citire if(pfcar==NULL) { i=0; while(eroare[i])putc(eroare[i++],stdout); exit(1); } while((c=getc(pfcar))!=EOF) //citire din fişier, la nivel de caracter putc(c,stdout); //scrierea caracterului citit în fişierul standard de ieşire (afişare pe monitor) fclose(pfcar); }

17.3.4 Exemplul 3

#include <stdio.h> #include <process.h> void main() { int c, i=0; FILE *pfcar; char mesaj[]="\nIntrodu caractere urmate de Ctrl+Z (Ctrl+D sub Linux):\n"; char eroare[]="\n Eroare deschidere fisier \n"; while(mesaj[i]) putchar(mesaj[i++]); pfcar=fopen("f_car1.txt","w"); // crearea fisierului cu numele extern f_car1.txt if(pfcar==NULL) { i=0; while(eroare[i]) putc(eroare[i++],stdout); exit(1); }

132

Page 137: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRELUCRAREA FIŞIERELOR TEXT

while((c=getchar())!=EOF) // sau: while ((c=getc(stdin)) != EOF) putc(c,pfcar); // scrierea caracterului in fisier fclose(pfcar); // Inchiderea fisierului }

17.3.5 Prelucrarea unui fişier la nivel de cuvânt

Funcţiile putw şi getw (putword şi getword) sunt echivalente cu funcţiile putc şi getc, cu diferenţa că unitatea transferată nu este un singur octet (caracter), ci un cuvânt (un int).

int getw(FILE *pf); int putw(int w, FILE *pf);

Se recomandă utilizarea funcţiei feof pentru a testa întâlnirea sfârşitului de fişier.

17.3.6 Exemplul 1

int tab[100]; FILE *pf; // . . . deschidere fisier while (!feof(pf)){ for (int i=0; i<100; i++){ if (feof(pf)) break; tab[i]=getw(pf); //citire din fisier la nivel de cuvânt si memorare în vectorul tab // . . . } } printf("Sfarsit de fisier\n");

17.3.7 Prelucrarea unui fişier la nivel de şir de caractere

Într-un fişier text, liniile sunt considerate ca linii de text separate de sfârşitul de linie ('\n'), iar în memorie, ele devin şiruri de caractere terminate de caracterul nul ('\0'). Citirea unei linii de text dintr-un fişier se realizează cu ajutorul funcţiei fgets, iar scrierea într-un fişier - cu ajutorul funcţiei fputs.

Funcţia fgets este indentică cu funcţia gets, cu deosebirea că funcţia gets citeşte din fişierul standard de intrare (stdin). Funcţia fputs este indentică cu funcţia puts, cu deosebirea că funcţia puts scrie în fişierul standard de ieşire (stdout).

17.3.7.1 Funcţia fputs int fputs(const char *s, FILE *pf);

Funcţia scrie un şir de caractere într-un fişier şi primeşte ca argumente pointerul spre zona de memorie (buffer-ul) care conţine şirul de caractere (s) şi pointerul spre structura FILE. Funcţia returnează ultimul caracter scris, în caz de succes, sau -1 în caz de eroare.

17.3.7.2 Funcţia fgets

133

Page 138: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

char *fgets(char *s, int dim, FILE *pf); Funcţia citeşte maximum dim-1 octeţi (caractere) din fişier, sau până la întâlnirea sfârşitului de linie. Pointerul spre zona în care se face citirea caracterelor este s. Terminatorul null ('\0') este plasat automat la sfârşitul şirului (buffer-lui de memorie). Funcţia returnează un pointer către buffer-ul în care este memorat şirul de caractere, în caz de succes, sau pointerul NULL în cazul eşecului.

17.3.8 Exemplul 1

Să se scrie un program care crează un fişier text în care se vor scrie şirurile de caractere introduse de la tastatură. #include <stdio.h> void main() { int n=250; FILE *pfsir; char mesaj[]="\nIntrodu siruri car.urmate de Ctrl+Z(Ctrl+D sub Linux):\n"; char sir[250],*psir; fputs(mesaj,stdout); pfsir=fopen("f_sir.txt","w"); //deschiderea fisierului f_sir.txt pentru scriere psir=fgets(sir,n,stdin); // citirea sirurilor din fisierul standard de intrare while(psir!=NULL) { fputs(sir,pfsir); // scrierea în fisierul text psir=fgets(sir,n,stdin); } fclose(pfsir); }

17.3.9 Exemplul 2

Să se scrie un program care citeşte un fişier text, linie cu linie, şi afişează conţinutul acestuia. #include <stdio.h> void main() { int n=250; FILE *pfsir; char sir[250],*psir; pfsir=fopen("f_sir.txt","r"); psir=fgets(sir,n,pfsir); while(psir!=NULL) { fputs(sir,stdout); //sau: puts(sir); //afisarea (scrierea în fisierul standard de iesire) sirului (liniei) citit din fisierul text psir=fgets(sir,n,pfsir); //citirea unei linii de text din fisier } fclose(pfsir);}

134

Page 139: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PRELUCRAREA FIŞIERELOR TEXT

17.3.10 Exemplul 3

Să se scrie un program care creează un fişier text “tabel”. #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #define PI 3.1415926 void main() { const n=250; int i,j,dec,sg; FILE *pfsir; char all[n],sir[n],*psir,*tab="\t",*cr="\n"; float x; pfsir=fopen("f_tab.xls","w"); //deschiderea fisierului f_tab.txt pentru scriere fputs("i\tsin\tcos\n",pfsir); // scrierea antetului fisierului text for(i=0;i<=90;i+=10) // for(j=0;j<=90;j+=10) { gcvt(i,5,sir); //conversie valoare reala->sir caractere strcpy(all,sir); //copiere caractere in sirul de scris strcat(all,tab); //concatenare caracter TAB x=sin(PI/180*i); gcvt(x,5,sir); strcat(all,sir); strcat(all,tab); x=cos(PI/180*i); gcvt(x,5,sir); strcat(all,sir); printf("\n%s",all); strcat(all,cr); fputs(all,pfsir); // scrierea în fisierul text } fclose(pfsir); }

17.3.11 Exemplul 4

Scrieţi un program care să facă o copie (caracter cu caracter) a unui fişier text dat. #include <stdio.h> void main(void) { FILE *in, *out; char sursa[13], dest[13]; fflush(stdin); printf("Dati sursa: "); scanf("%s",&sursa); fflush(stdin) printf("Dati destinatia: "); scanf("%s",&dest); if ((in = fopen (sursa, "rt")) == NULL)

135

Page 140: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

{ printf("Nu se poate deschide fisierul sursa.\n"); return; } if ((out = fopen(dest, "wt")) == NULL) { printf("Nu se poate crea fisierul destinatie.\n"); return; } // se copiaza caracterele din "in" in "out" while (!feof(in)) fputc(fgetc(in),out); fclose(in); fclose(out); }

17.4 Intrări/ieşiri binare

17.4.1 Exemplul 1

Să se scrie un program care creează un fişier binar în care se vor introduce numere reale, nenule. #include <iostream.h> #include <stdio.h> int main() { FILE *f; double nr; int x; if ((f= fopen("test_nrb.dat", "wb")) == NULL) //deschidere flux binar, scriere { cout<<"\nNu se poate deschide fisierul test_nrb.dat"<<'\n'; return 1; } cout<<"\nIntroduceti numere(diferite de 0) terminate cu un 0:"<<'\n'; cin>>nr; while(nr!=0) { x=fwrite(&nr, sizeof(nr), 1, f); //scriere în fisier cin>>nr; } fclose(f); return 0; }

17.4.2 Exemplul 2

Să se scrie un program care citeşte dintr-un fişier binar numere reale, nenule. #include <iostream.h> #include <stdio.h> int main()

136

Page 141: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI BINARE

{ FILE *f; double buf; if ((f= fopen("test_nrb.dat", "rb")) == NULL) { cout<<"\nNu se poate deschide fisierul test_nrb.dat"<<'\n'; return 1; } cout<<"\nNumerele nenule citite din fisier sunt:"<<'\n'; while((fread(&buf, sizeof(buf), 1, f))==1) // functia sizeof(buf) care returneaza numarul de octeti necesari variabilei buf. cout<<buf<<" "; fclose(f); cout<<'\n'; return 0; }

17.4.3 Fişier binar cu structuri

Să se scrie un program pentru crearea unui fişier binar, având articole structuri cu următoarele câmpuri:

• Nume depunător - şir de maxim 30 de caractere; • Data depunerii - o structură având câmpurile întregi: zi, lună, an; • Suma depusă - o valoare reală. Articolele sunt grupate pe zile în ordine cronologică. Datele se introduc de la consolă,

fiecare pe trei linii. Să se afişeze apoi conţinutul fişierului.

17.4.3.1 Rezolvare Vom introduce mai întâi datele într-o ordine aleatoare, apoi le vom sorta după dată. În final, vectorul de structuri va fi scris în fişierul "output.dat".

17.4.3.2 Programul //Fisiere binare - Depuneri #include <stdio.h> #include <stdlib.h> #include <conio.h> void main (void) { // Cream un vector de articole pentru a le sorta ulterior dupa data depunerii. // Articolul suplimentar este necesar la sortare. // In plus, vom citi ceea ce am scris in fisier intr-un vector separat de articole. struct { char nume[30]; struct { int zi, luna, an; } data; double suma; } articole [20], articol, citite[20];

137

Page 142: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

FILE *f; int n; // Numarul de articole int found;// Folosit la sortare // Citire date de intrare printf("Introduceti numarul de articole: "); scanf ("%d", &n); for (int i=0; i<n; i++) { printf ("Introduceti numele depunatorului: "); scanf ("%s", articole[i].nume); printf ("Introduceti data depunerii <ZZ/LL/AAAA>: ") ; scanf ("%d/%d/%d", &articole[i].data.zi, \ &articole[i].data.luna, &articole[i].data.an); printf("Introduceîi suma depusa: "); scanf ("%lf", &articole[i].suma); } // Sortam dupa data depunerii do { found=0; for (i=0; i<n-1; i++) // Testam cazurile in care data articolului curent este 'mai mare' decat data articolului urmator if ( (articole[i].data.an > articole[i+1].data.an) \ || (articole[i].data.an == articole[i+1].data.an \ && articole[i].data.luna > articole[i+1].data.luna) \ || (articole[i].data.an == articole[i+1].data.an \ && articole[i].data.luna == articole[i+1].data.luna \ && articole[i].data.zi > articole[i+1].data.zi) ) { articol = articole[i]; articole[i] = articole[i+1]; articole[i+1] = articol; found = 1; } } while (found); // Deschidere fisier if((f=fopen("output.dat","wb")) == NULL) { printf(" Eroare la deschiderea fisierului! "); exit (1); } // Scriem in fisier si il inchidem // Scriem intai numarul de articole fwrite(&n, sizeof(int), 1, f) ; fwrite(&articole, sizeof(articol), n, f); fclose(f); if ((f=fopen ("output.dat","rb")) == NULL ) { printf (" Eroare la deschiderea fi-ierului! "); exit (1); }

138

Page 143: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

INTRĂRI/IEŞIRI BINARE

fread (&n, sizeof(int), 1, f); fread (&citite, sizeof(articol), n, f); for (i=0; i<n; i++) printf (" Articolul %d: %s, %d/%d/%d, %lf\n", i+1, \ citite[i].nume, citite[i].data.zi, \ citite[i].data.luna, citite[i].data.an, \ citite[i].suma); fclose(f); getch(); }

17.4.4 Fisier cu structuri - linie de comanda cu parametri

Un fişier conţine articole cu structura: cod (şir de caractere), nume (şir de caractere) şi cantitate (real). Să se scrie un program care permite:

creare; consultare; ştergere. Opţiunea se introduce ca argument al liniei de comandă, prin numele complet al

operaţiei: • Creare Nume_fisier - Se creează fişierul Nume_fisier prin citirea de la tastatură a

articolelor. După fiecare linie introdusă se interoghează dacă se continuă; • Consultare Nume_fisier - Conţinutul fişierului Nume_fisier este listat pe ecran, câte

20 de linii. Pentru continuarea afişării se apasă ENTER; • Ştergere Nume_fisier cod_articol - Este căutat articolul în fişier şi se marchează

punându-i codul xxx.

17.4.4.1 Programul #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define FALSE 0 #define TRUE 1 struct ARTICOL { char cod[10]; char nume[30]; float cantitate; }; // Executa functia de creare fisier void creare(char *fisier) { FILE *f; struct ARTICOL a; // Deschid fisierul pentru scriere in mod binar if ((f=fopen(fisier,"wb")) == NULL) { printf (" Nu pot deschide fisierul. \n"); exit (1); } do

139

Page 144: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

{ //Articolele citite unul cate unul si scrise in fisier printf (" Introduceti codul, numele si cantitatea: "); scanf("%s %s %f", &a.cod, &a.nume, &a.cantitate); fwrite(&a,sizeof(ARTICOL),1,f); printf("Doriti sa continuati ? (d/n)\n"); } while (getch()=='d'); fclose(f); } // Executa functia de consultare fisier void consultare(char *fisier) { FILE *f; struct ARTICOL a; int i=1; // Deschid fisierul pentru citire in mod binar if ((f=fopen(fisier,"rb")) == NULL) { printf("Nu pot deschide fisierul. \n"); exit (1) ; } while(fread(&a,sizeof(ARTICOL),1,f)>0) // Am grija sa nu afisez articolele care au fost sterse if(strcmp(a.cod,"xxx")!=0) { printf("%10s %30s %10.2f\n",a.cod,a.nume,a.cantitate); // Daca am afisat 20 de articole, ma opresc si intreb if (i++%20==0) { printf("Doriti sa continuati ? (d/n)\n"); if (getch()=='n') break; } } fclose(f); } // Executa functia de stergere void stergere(char *fisier,char *cod) { FILE *f; struct ARTICOL a; int gasit=FALSE; // Fisierul este deschis pentru citire/scriere in mod binar f=fopen(fisier,"r+b"); while(fread(&a,sizeof(ARTICOL),1,f)>0) if(strcmp(a.cod,cod)==0) { // Marchez articolul ca fiind sters strcpy(a.cod,"xxx") ; //Ma pozitionez cu o Inregistrare inainte pentru a suprascrie articolul fseek(f,ftell(f)-sizeof(ARTICOL),SEEK_SET); fwrite(&a,sizeof(ARTICOL),1,f);

140

Page 145: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

POZIŢIONAREA ÎNTR-UN FIŞIER

gasit=TRUE; break; } if (!gasit) printf("Eroare: Articolul nu a fost gasit\n"); fclose(f); } void main(int argc, char **argv) { if(strcmp(argv[1],"Creare")==0) creare(argv[2]); if (strcmp(argv[1],"Consultare")==0) consultare(argv[2]); if (strcmp(argv[1],"Stergere")==0) stergere(argv[2],argv[3]); }

17.5 Poziţionarea într-un fişier

Pe lângă mecanismul de poziţionare implicit (asigurat prin operaţiile de citire şi scriere) se pot folosi şi operaţiile de poziţionare explicită.

17.5.1.1 Funcţia fseek int fseek(FILE *pf, long deplasament, int referinta);

Funcţia deplasează capul de citire/scriere al discului, în vederea prelucrării înregistrărilor fişierului într-o ordine oarecare. Funcţia setează poziţia curentă în fluxul de date la n octeţi faţă de referintă. deplasament – defineşte numărul de octeţi peste care se va deplasa capul discului; referinta – poate avea una din valorile: 0 - începutul fişierului (SEEK_SET); 1 - poziţia curentă a capului (SEEK_CUR); 2 - sfârşitul fişierului (SEEK_END). Funcţia returnează valoarea zero la poziţionarea corectă şi o valoare diferită de zero

în caz de eroare (prototip în stdio.h).

17.5.1.2 Funcţia lseek int lseek(int indicator, long n, int referinta);

Seteaza poziţia curentă de citire/scriere în fişier la n octeţi faţa de referintă. Returnează valoarea 0 în caz de succes şi diferită de zero în caz de eroare (prototip în io.h).

17.5.1.3 Funcţia fgetpos int fgetpos(FILE *flux_date, fpos_t *pozitie);

Determină poziţia curentă (pointer către o structură, fpos_t, care descrie această poziţie în fluxul de date). Înscrie valoarea indicatorului în variabila indicată de pozitie. Returnează 0 la determinarea cu succes a acestei poziţii sau valoare diferită de zero în caz de eşec. Structura care descrie poziţia poate fi transmisă ca argument funcţiei fsetpos (prototip în stdio.h).

141

Page 146: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

17.5.1.4 Funcţia fsetpos int fsetpos(FILE *flux_date, const fpos_t *pozitie);

Setează poziţia curentă în fluxul de date (atribuie indicatorului valoarea variabilei indicate pozitie), la o valoare obţinută prin apelul funcţiei fgetpos. Returnează valoarea 0 în caz de succes, sau diferită de 0 în caz de eşec (prototip în stdio.h).

Există funcţii pentru modificarea valorii indicatorului de poziţie şi de determinare a poziţiei curente a acestuia.

17.5.1.5 Funcţia ftell long ftell(FILE *pf);

Indică poziţia curentă a capului de citire în fişier. Funcţia returnează o valoare de tip long int care reprezintă poziţia curentă în fluxul de date (deplasamentul în octeţi a poziţiei capului faţă de începutul fişierului) sau -1L în caz de eroare (prototip în stdio.h).

17.5.1.6 Funcţia tell long tell(int indicator);

Returnează poziţia curentă a capului de citire/scriere în fişier (exprimată în număr de octeţi faţă de începutul fişierului), sau -1L în caz de eroare (prototip în io.h).

17.5.1.7 Funcţia rewind void rewind(FILE *flux_date);

Poziţionează indicatorul la începutul fluxului de date specificat ca argument (prototip în stdio.h).

17.6 Funcţii utilitare pentru lucrul cu fişiere

17.6.1 Funcţii de testare a sfârşitului de fişier

17.6.1.1 Funcţia feof int feof(FILE *flux_date);

Returnează o valoare diferită de zero în cazul întâlnirii sfârşitului de fişier sau 0 în celelalte cazuri (prototip în stdio.h).

17.6.1.2 Funcţia eof int eof(int indicator);

Returnează valoarea 1 dacă poziţia curentă este sfârşitul de fişier, 0 dacă indicatorul este poziţionat în altă parte, sau -1 în caz de eroare (prototip în io.h).

17.6.2 Funcţii de golire a fluxurilor de date

17.6.2.1 Funcţia fflush int fflush(FILE *flux_date);

Goleşte fluxul de date specificat ca argument. Returnează 0 în caz de succes şi -1 (EOF) în caz de eroare (prototip în stdio.h).

17.6.2.2 Funcţia flushall

142

Page 147: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

int flushall(void); Goleşte toate fluxurile de date existente, pentru cele de scriere efectuând şi scrierea în

fişiere. Returnează numărul de fluxuri asupra cărora s-a efectuat operaţia (prototip în stdio.h).

17.7 Alte operaţii cu fişiere

Funcţii care permit operaţii ale sistemului de operare asupra fişierelor

17.7.1.1 Funcţia remove int remove(const char *nume_fisier);

Şterge un fişier. Returnează valoarea 0 pentru operaţie reuşită şi -1 pentru operaţie eşuată (prototip în stdio.h).

17.7.1.2 Funcţia rename int rename(const char *nume_vechi, const char *nume_nou);

Redenumeşte un fişier. Returnează 0 pentru operaţie reuşita şi -1 în cazul eşecului (prototip în stdio.h).

17.7.1.3 Funcţia unlink int unlink(const char *nume_fisier);

Şterge un fişier. Returnează 0 la operaţie reuşită şi -1 la eşec; dacă fişierul are permisiune read-only, funcţia nu va reuşi operaţia (prototip în io.h, stdio.h).

17.8 Exemple

17.8.1 Fişier despre angajaţii unei întreprinderi

Să se creeze un fişier binar, care va conţine informaţiile despre angajaţii unei întreprinderi: nume, marca, salariu. Să se afişeze apoi conţinutul fişierului. #include<iostream.h> #include <stdio.h> #include <ctype.h> typedef struct { char nume[20];int marca;double salariu; }angajat; union {angajat a;char sbinar[sizeof(angajat)];}buffer; int main() {angajat a; FILE *pf; char cont;char *nume_fis; cout<<"Nume fisier care va fi creat:"; cin>>nume_fis; if ((pf= fopen(nume_fis, "wb")) == NULL) { cout<<"\nEroare creare fisier "<<nume_fis<<"!\n"; return 1; } do {cout<<"Marca : ";cin>>a.marca; cout<<"Nume : ";cin>>a.nume;

143

Page 148: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

cout<<"Salariu :";cin>>a.salariu; buffer.a=a; fwrite(buffer.sbinar,1,sizeof(angajat),pf); cout<<"Continuati introducerea de date (d/n) ?"; cin>>cont; } while(toupper(cont)!='N'); fclose(pf); //citirea informaţiilor if ((pf= fopen(nume_fis, "rb")) == NULL) { cout<<"\nEroare citire fisier "<<nume_fis<<"!\n"; return 1; } for(;;) { fread(buffer.sbinar,1,sizeof(a),pf); a=buffer.a1; if(feof(pf)) exit(1); cout<<" Marca : "<<a.marca; cout<<" Numele : "<<a.nume<<'\n'; cout<<" Salariul : "<<a.salariu<<'\n'; } fclose(pf); }

17.8.2 Aplicaţie pentru gestiunea materialelor dintr-un depozit

Aplicaţia va avea un meniu principal şi va permite gestiunea următoarelor informaţii: codul materialului (va fi chiar "numărul de ordine"), denumirea acestuia, unitatea de măsură, preţul unitar, cantitatea contractată şi cea recepţionată (vectori cu 4 elemente). Memorarea datelor se va face într-un fişier de date (un fişier binar cu structuri), numit "material.dat". Aplicaţia conţine următoarele funcţii: help() - informare privind opţiunile programului Funcţii pentru fişierele binare, care să suplinească lipsa funcţiilor standard pentru

organizarea directă a fişierelor binare: citireb() - citire în acces direct din fişier; scrieb() - scriere în acces direct în fişier; citmat() - citirea de la terminal a informaţiilor despre un material; afismat() - afişarea informaţiilor despre un material (apelată de list); lungfisis() - determinarea lungimii fişierului existent; crefis() - creare fişier. Funcţii pentru adăugarea, modificarea, ştergerea şi listarea de materiale.

#include <process.h> #include <iostream.h> #include <stdio.h> #include <ctype.h> typedef struct material { int codm,stoc,cant_c[4],cant_r[4]; char den_mat[20],unit_mas[4]; float pret; }; material mat; FILE *pf;

144

Page 149: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

void crefis(),adaug(),modif(),sterg(),list(),help(); void main() { char optiune; do //afisarea unui meniu de optiuni si selectia optiunii { cout<<'\n'<<"Optiunea Dvs. de lucru este"<<'\n' <<"(c|a|m|s|l|e|h pentru help) : "; cin>>optiune; switch(optiune) { case 'c':case 'C':crefis();break; case 'a':case 'A':adaug();break; case 'm':case 'M':modif();break; case 's':case 'S':sterg();break; case 'l':case 'L':list();break; case 'h':case 'H':help();break; case 'e':case 'E': break; default:help(); break; } }while(toupper(optiune)!='E'); } void help() // afisare informatii despre utilizarea meniului si optiunile acestuia {cout<<"Optiunile de lucru sunt :"<<'\n'; cout<<" C,c-creare fisier"<<'\n'; cout<<" A,a-adaugare"<<'\n'; cout<<" M,m-modificare"<<'\n'; cout<<" L,l-listare"<<'\n'; cout<<" S,s-stergere"<<'\n'; cout<<" H,h-help"<<'\n'; cout<<" E,e-exit"<<'\n'; } long int lungfis(FILE *f) // returnează lungimea fisierului {long int posi,posf; posi=ftell(f); fseek(f,0,SEEK_END); posf=ftell(f); fseek(f,posi,SEEK_SET); return posf; } void scrieb(int nr,void *a,FILE *f) //scriere în fisierul binar {long depl=(nr-1)*sizeof(material); fseek(f,depl,SEEK_SET); if(fwrite(a,sizeof(material),1,f)!=1) {cout<<"Eroare de scriere in fisier !"<<'\n'; exit(1); } } void citireb(int nr,void *a,FILE *f) //citire din fisierul binar {long depl=(nr-1)*sizeof(material);

145

Page 150: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

fseek(f,depl,SEEK_SET); if(fread(a,sizeof(material),1,f)!=1) {cout<<"Eroare de citire din fisier !"<<'\n'; exit(2); } } void afismat(material *a) //afisarea informatiilor despre un anumit material { int i; if(a->codm) {cout<<"Cod material : "<<a->codm<<'\n'; cout<<"Denumire material: "<<a->den_mat<<'\n'; cout<<"Cantitati contractate:"<<'\n'; for(i=0;i<4;i++) cout<<"Contractat "<<i<<" : "<<a->cant_c[i]<<'\n'; cout<<"Cantitati receptionate:"<<'\n'; for(i=0;i<4;i++) cout<<"Receptionat "<<i<<" : "<<a->cant_r[i]<<'\n'; cout<<"Stoc : "<<a->stoc<<'\n'; cout<<"Unitate de masura: "<<a->unit_mas<<'\n'; cout<<"Pret unitar : "<<a->pret<<'\n'; } else cout<<"Acest articol a fost sters !"<<'\n'; } void citmat(material *a) //citirea informatiilor despre un anumit material { int i;float temp; cout<<"Introduceti codul materialului (0=End): ";cin>>a->codm; if(a->codm==0) return; cout<<"Introduceti denumirea materialului : ";cin>>a->den_mat; cout<<"Introduceti unitatea de măsură : ";cin>>a->unit_mas; cout<<"Introduceti pretul : ";cin>>temp;a->pret=temp; cout<<"Introduceti cantitatile contractate : "<<'\n'; for(i=0;i<4;i++) {cout<<"Contractat "<<i+1<<" : ";cin>>a->cant_c[i]; } cout<<"Introduceti cantitatile receptionate : "<<'\n'; for(i=0;i<4;i++) {cout<<"Receptionat "<<i+1<<" : ";cin>>a->cant_r[i]; } } void crefis() //deschidere fisier { if((pf=fopen("material.dat","r"))!=NULL) cout<<"Fisierul exista deja !"<<'\n'; else pf=fopen("material.dat","w"); fclose(pf); }

146

Page 151: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

EXEMPLE

void adaug() //adăugare de noi materiale { int na; pf=fopen("material.dat","a");//deschidere pentru append na=lungfis(pf)/sizeof(material); do {citmat(&mat); if(mat.codm) scrieb(++na,&mat,pf); } while(mat.codm); fclose(pf); } void modif() //modificarea informatiilor despre un material existent { int na; char ch; pf=fopen("material.dat","r+"); do {cout<<"Numarul articolului de modificat este (0=END): ";cin>>na; if(na) {citireb(na,&mat,pf); afismat(&mat); cout<<"Modificati articol (D/N) ? :"; do { cin>>ch; ch=toupper(ch); } while(ch!='D' && ch!='N'); if(ch=='D') {citmat(&mat); scrieb(na,&mat,pf); } } }while(na); fclose(pf); } void sterg() //stergerea din fisier a unui material { int n;long int na; pf=fopen("material.dat","r+"); mat.codm=0; na=lungfis(pf)/sizeof(material); do { do {cout<<"Numarul articolului de sters este (0=END): ";cin>>n; if(n<0||n>na) cout<<"Articol eronat"<<'\n'; }while(!(n>=0 && n<=na)); if(n) scrieb(n,&mat,pf); }while(n); fclose(pf); } void list() //afisare informatii despre un anumit material

147

Page 152: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

FIŞIERE

{ int na; pf=fopen("material.dat","r"); do {cout<<"Numarul articolului de listat este (0=END): ";cin>>na; if(na) {citireb(na,&mat,pf); afismat(&mat); cout<<'\n'; } }while(na); fclose(pf); }

17.9 Probleme propuse

1. Scrieţi un program de tipărire a conţinuturilor mai multor fişiere, ale căror nume se transmit ca parametri către funcţia main. Tipărirea se face pe ecran (lungimea paginii = 22) sau la imprimantă (lungimea paginii = 61). Conţinutul fiecărui fişier va începe pe o pagină nouă, cu un titlu care indică numele fişierului. Pentru fiecare fişier, paginile vor fi numerotate (cu ajutorul unui contor de pagini).

2. Scrieţi un program care citeşte un fişier text. Pornind de la conţinutul acestuia, se va crea un alt fişier, prin înlocuirea spaţiilor consecutive cu unul singur. Se vor afişa pe ecran conţinutul fişierului de la care s-a pornit şi conţinutul fişierului obţinut.

3. Să se consulte conţinutul unui fişier şi să se afişeze următoarele informaţii statistice: numărul de cuvinte din fişier, numărul de caractere, numărul de linii, numărul de date numerice (nu cifre, numere!).

4. Scrieţi un program care să compare conţinutul a două fişiere, şi afişaţi primele linii care diferă şi poziţia caracterelor diferite în aceste linii.

5. Scrieţi un program care citeşte conţinutul unui fişier sursă scris în limbajul C şi afişează în ordine alfabetică fiecare grup al numelor de variabile care au primele n caractere identice (n este citit de la tastatură).

6. Scrieţi un program care consultă un fişier text şi afişează o listă a tuturor cuvintelor din fişier. Pentru fiecare cuvânt se vor afişa şi numerele liniilor în care apare cuvântul.

7. Scrieţi un program care citeşte un text introdus de la tastatură şi afişează cuvintele distincte, în ordinea crescătoare a frecvenţei lor de apariţie. La afişare, fiecare cuvânt va fi precedat de numărul de apariţii.

8. Scrieţi un program care citeşte un text introdus de la tastatură, ordonează alfabetic liniile acestuia şi le afişează.

9. Scrieţi o aplicaţie pentru gestiunea informatiilor despre cărţile existente într-o bibliotecă. Aplicaţia va avea un meniu principal care va permite:

• Memorarea datelor într-un fişier (un fişier binar cu structuri), al cărui nume se introduce de la tastatură. Fişierul va conţine informaţiile: nume carte, autor, editura, anul apariţiei, preţ. Pentru fiecare carte, se va genera o cotă (un număr unic care să constituie cheia de căutare).

• Adăugarea de noi cărţi; • Afişarea informaţiilor despre o anumită carte;

148

Page 153: Cristian Iosifescu ú i limbaje - University of Galați+/Lab/2017-PCLP-Lab... · 2019-04-28 · ú i limbaje de programare Cristian Iosifescu Universitatea "Dunarea de Jos" Galati

Programarea calculatoarelor

şi limbaje de programare

Cristian Iosifescu

Universitatea "Dunarea de Jos"

Galati

PROBLEME PROPUSE

• Căutarea titlurilor după un anumit autor; • Modificarea informaţiilor existente; • Lista alfabetică a tuturor autorilor; • Ştergerea unei cărţi din bibliotecă; • Ordonarea descrescătoare după anul apariţiei; • Numele celei mai vechi cărţi din bibliotecă; • Numele celei mai scumpe cărţi din bibliotecă; • Numele autorului cu cele mai multe cărţi; • Valoarea totală a cărţilor din bibliotecă.

149


Recommended