De ce sa invat un limbaj de programare? Programele comerciale sunt scumpe Nu exista un program (comercial sau gratis) pentru fiecare problema

Σχετικά έγγραφα
III. Reprezentarea informaţiei în sistemele de calcul

Sisteme de numeraţie

(a) se numeşte derivata parţială a funcţiei f în raport cu variabila x i în punctul a.

Curs 10 Funcţii reale de mai multe variabile reale. Limite şi continuitate.

Esalonul Redus pe Linii (ERL). Subspatii.

Metode iterative pentru probleme neliniare - contractii

MARCAREA REZISTOARELOR

Limbaje de Programare Curs 3 Iteraţia. Reprezentare internă. Operatori pe biţi

Curs 1 Şiruri de numere reale

Subiecte Clasa a VIII-a

III. Serii absolut convergente. Serii semiconvergente. ii) semiconvergentă dacă este convergentă iar seria modulelor divergentă.

Laborator 4 suport teoretic Tipuri de date utilizate în limbajul de programare C.

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor X) functia f 1

5. FUNCŢII IMPLICITE. EXTREME CONDIŢIONATE.

Functii definitie, proprietati, grafic, functii elementare A. Definitii, proprietatile functiilor

R R, f ( x) = x 7x+ 6. Determinați distanța dintre punctele de. B=, unde x și y sunt numere reale.

Curs 14 Funcţii implicite. Facultatea de Hidrotehnică Universitatea Tehnică "Gh. Asachi"

5.4. MULTIPLEXOARE A 0 A 1 A 2

Metode de interpolare bazate pe diferenţe divizate

Aplicaţii ale principiului I al termodinamicii la gazul ideal

DISTANŢA DINTRE DOUĂ DREPTE NECOPLANARE

Seminar 5 Analiza stabilității sistemelor liniare

Curs 4 Serii de numere reale

Analiza în curent continuu a schemelor electronice Eugenie Posdărăscu - DCE SEM 1 electronica.geniu.ro

Integrala nedefinită (primitive)

Criptosisteme cu cheie publică III

Laborator 1: INTRODUCERE ÎN ALGORITMI. Întocmit de: Claudia Pârloagă. Îndrumător: Asist. Drd. Gabriel Danciu

Mulțumim anticipat tuturor acelora care vor transmite critici/observații/sugestii

CARACTERISTICILE LIMBAJULUI DE PROGRAMARE

III.2.2. Reprezentarea în virgulă mobilă


Planul determinat de normală şi un punct Ecuaţia generală Plane paralele Unghi diedru Planul determinat de 3 puncte necoliniare

SEMINAR 14. Funcţii de mai multe variabile (continuare) ( = 1 z(x,y) x = 0. x = f. x + f. y = f. = x. = 1 y. y = x ( y = = 0

Instructiunea while. Forma generala: while (expresie) instructiune;

a n (ζ z 0 ) n. n=1 se numeste partea principala iar seria a n (z z 0 ) n se numeste partea

Seminariile Capitolul X. Integrale Curbilinii: Serii Laurent şi Teorema Reziduurilor

1. Reprezentarea numerelor şi operaţii aritmetice în sisteme de calcul.

COLEGIUL NATIONAL CONSTANTIN CARABELLA TARGOVISTE. CONCURSUL JUDETEAN DE MATEMATICA CEZAR IVANESCU Editia a VI-a 26 februarie 2005.

riptografie şi Securitate

Laborator 11. Mulţimi Julia. Temă

a. 11 % b. 12 % c. 13 % d. 14 %

Subiecte Clasa a V-a

Subiecte Clasa a VII-a

V.7. Condiţii necesare de optimalitate cazul funcţiilor diferenţiabile

SERII NUMERICE. Definiţia 3.1. Fie (a n ) n n0 (n 0 IN) un şir de numere reale şi (s n ) n n0

2. Circuite logice 2.5. Sumatoare şi multiplicatoare. Copyright Paul GASNER

Teme de implementare in Matlab pentru Laboratorul de Metode Numerice

Sisteme diferenţiale liniare de ordinul 1

Declaraţii de variabile, tipuri, funcţii

5.5. REZOLVAREA CIRCUITELOR CU TRANZISTOARE BIPOLARE

1.7. AMPLIFICATOARE DE PUTERE ÎN CLASA A ŞI AB

Lucrarea de laborator nr. 2

PROGRAMAREA CALCULATOARELOR Note de curs

28. SUPRADEFINIREA OPERATORILOR

Codificatorul SN74148 este un codificator zecimal-bcd de trei biţi (fig ). Figura Codificatorul integrat SN74148

Definiţia generală Cazul 1. Elipsa şi hiperbola Cercul Cazul 2. Parabola Reprezentari parametrice ale conicelor Tangente la conice

2. Circuite logice 2.4. Decodoare. Multiplexoare. Copyright Paul GASNER

Curs 2 Şiruri de numere reale


RĂSPUNS Modulul de rezistenţă este o caracteristică geometrică a secţiunii transversale, scrisă faţă de una dintre axele de inerţie principale:,

Asupra unei inegalităţi date la barajul OBMJ 2006

Lucrare. Varianta aprilie I 1 Definiţi noţiunile de număr prim şi număr ireductibil. Soluţie. Vezi Curs 6 Definiţiile 1 şi 2. sau p b.

Conice. Lect. dr. Constantin-Cosmin Todea. U.T. Cluj-Napoca

Valori limită privind SO2, NOx şi emisiile de praf rezultate din operarea LPC în funcţie de diferite tipuri de combustibili

P R E F A Ţ Ă Algoritmul Programul Programarea

prin egalizarea histogramei

Ecuatii exponentiale. Ecuatia ce contine variabila necunoscuta la exponentul puterii se numeste ecuatie exponentiala. a x = b, (1)

2. Circuite logice 2.2. Diagrame Karnaugh. Copyright Paul GASNER 1

Erori si incertitudini de măsurare. Modele matematice Instrument: proiectare, fabricaţie, Interacţiune măsurand instrument:

Examen AG. Student:... Grupa:... ianuarie 2011

V O. = v I v stabilizator

Componente şi Circuite Electronice Pasive. Laborator 4. Măsurarea parametrilor mărimilor electrice

Sortare. 29 martie Utilizarea şi programarea calculatoarelor. Curs 16

Fig Impedanţa condensatoarelor electrolitice SMD cu Al cu electrolit semiuscat în funcţie de frecvenţă [36].

Curs Programarea Calculatoarelor si Limbaje de Programare PRELEGEREA 1 ETAPELE REZOLVĂRII UNEI PROBLEME CU AJUTORUL UNUI SISTEM DE CALCUL

Subiecte Clasa a VIII-a

Editura EduSoft Bacău

Problema a II - a (10 puncte) Diferite circuite electrice

Curs 2 DIODE. CIRCUITE DR

Componente şi Circuite Electronice Pasive. Laborator 3. Divizorul de tensiune. Divizorul de curent

2.1 Sfera. (EGS) ecuaţie care poartă denumirea de ecuaţia generală asferei. (EGS) reprezintă osferă cu centrul în punctul. 2 + p 2

EDITURA PARALELA 45 MATEMATICĂ DE EXCELENŢĂ. Clasa a X-a Ediţia a II-a, revizuită. pentru concursuri, olimpiade şi centre de excelenţă

INTRODUCERE ÎN PROGRAMAREA MATLAB

Studiul elementelor de bază din limbajul C++ - continuare

Subiectul III (30 de puncte) - Varianta 001

Arhitectura Calculatoarelor. Fizică - Informatică an II. 2. Circuite logice. Copyright Paul GASNER 1

4. Măsurarea tensiunilor şi a curenţilor electrici. Voltmetre electronice analogice

Capitolul 4 PROPRIETĂŢI TOPOLOGICE ŞI DE NUMĂRARE ALE LUI R. 4.1 Proprietăţi topologice ale lui R Puncte de acumulare

Lucrarea de laborator nr. 1

10 REPREZENTAREA DIGITALĂ

Universitatea din Bucureşti Facultatea de Matematică şi Informatică. Algebră (1)

Laborator 6. Integrarea ecuaţiilor diferenţiale

Profil informatică Teste pentru licenţă

Profesor Blaga Mirela-Gabriela DREAPTA

Progresii aritmetice si geometrice. Progresia aritmetica.

Să se arate că n este număr par. Dan Nedeianu

BARAJ DE JUNIORI,,Euclid Cipru, 28 mai 2012 (barajul 3)

Matrice. Determinanti. Sisteme liniare

Ecuatii trigonometrice

Aparate de măsurat. Măsurări electronice Rezumatul cursului 2. MEE - prof. dr. ing. Ioan D. Oltean 1

Transcript:

De ce sa invat un limbaj de programare? Programele comerciale sunt scumpe Nu exista un program (comercial sau gratis) pentru fiecare problema particulara Dezvoltarea gandirii logice, algoritmice Intelegerea mai profunda a functionarii dispozitivelor electronice Cresterea numarului optiunilor pentru obtinerea unui job Foarte multe probleme de fizica pot fi rezolvate (numai) cu ajutorul computerelor => necesitatea unui program Echipamentele de cercetare folosesc rutine de calcul pentru prelucrarea datelor => intelegerea modului de lucru si folosirea eficienta a infrastructurii Cresterea productivitatii folosirii pachetelor software disponibile (de ex. Macros in Excel)

Pentru ca exista in planul de invatamant...

De ce C? Exista de peste 30 de ani o multe programe disponibile o probleme legate de limbaj au fost rezolvate Limbaj puternic si versatil Precursor pentru C++, Java, C# Folosit pe scara larga de catre comunitatea stiintifica Eficienta sporita in programare (pointeri, lucrul pe biti, alocare dinamica a memoriei, etc.) Resurse bibliografice multiple, numar mare de librarii existente Multe instrumente stiintifice sunt programate in C (de ex. Camere CCD) Compilatoare free http://www-pnp.physics.ox.ac.uk/~tseng/teaching/lab/handbook_c.pdf De ce nu C++? Programarea orientata obiect este o complicatie ne-necesara pentru calculul stiintific in fizica

Evaluare: acordarea notei 2.5 p proba orala teoretica (in sesiune) 2.5 p proba practica (in sesiune) 2.0 p doua teste pe parcurs (saptamana 5 (29.10) si saptamana 10 (03.12), 1 p pt. fiecare) 1.0 p bonus prezenta si activitate la curs si laborator 1.0 p teme 1.0 p proiect individual, la alegere (optional) Syllabus FLR1304

Link-uri utile Functii matematice: Functii grafice: http://en.wikipedia.org/wiki/c_mathematical_functions http://www.programmingsimplified.com/c/graphics.h

CURS 1 Definitii Dell, i7-2600 3.4GHz, 8 cores 6GB RAM 1TB HDD Fujitsu-Siemens Server 4 procesoare Intel Xeon MP@3.00GHz, 16 cores 40GB RAM 538 GB HDD HPC@UBB Intel Xeon @ 2.2 GHz ~ 2000 cores ~ 80 TB RAM ~ 2000 TB HDD 7.2K

48 51 24 N 2 21 03 E

Se va tine cont de situatii neuzuale!!

int cmmdc( int a, int b) int r, cmmdc; do r=a%b; cmmdc=b; a=b; b=r; while(r!=0); return cmmdc; //functia fact cu instructiune for double fact(int n) double f=1.0; int i; if(n>1) for(i=2;i<=n;i++) f=f*i; return f;

CURS 2 Reprezentarea numerelor intregi si reale F.Boian, Bazele matematice ale calculatoarelor, UBB Cluj-Napoca, 2002 Sistem de numeraţie - totalitatea regulilor folosite pentru scrierea numerelor cu ajutorul unor simboluri (cifre). Palatul Josika (Casa cu picioare) este înălţat pe locul fostei reşedinţe clujene a principilor Transilvaniei. Clădirea a devenit reşedinţa lui Anton Josika, comite al Clujului, la mijlocul secolului al XVIII-lea. Clădirea în stil neoclasicist a căpătat înfăţişarea de astăzi în anul 1828, când a fost refăcută de Josika Janos, guvernator al Transilvaniei. Elementul caracteristic în faţadă este porticul sobru cu coloanele dorice. Atica poartă inscripţia MDCCCXXVIII (1828), anul renovării clădirii.

2. Sistemul de numeraţie arab - sistem poziţional - aportul unei cifre în stabilirea valorii unui număr depinde de valoarea cifrei şi de poziţia ocupată în şirul de cifre folosit.

Trebuie cunoscute cifrele numărului care se transformă!

Bit - unitatea de informaţie folosita pentru stocarea si transmiterea informatiei Mbps (Mb) unitatea de masura pentru viteza de transmisie (download si upload) in internet Byte (octet) - unitatea de adresare (8 biţi) 1KB = 2 10 (1024) biti 1MB = 2 20 (1048576) biti etc. MB Mb 01000001 =? 65 A. etc. Depinde de codificare si dispozitivul catre care se trimite data

Locaţie de memorie - unitatea de reprezentare a unei date, formată din unul sau mai mulţi octeţi Word număr de octeţi prelucraţi simultan de către procesor - numerele reale se reprezintă de obicei pe un cuvânt = lăţimea de bandă Nyble - grup de 4 biti (jumatate de octet) - poate stoca 16 valori (0-15) - corespunde unei cifre hexa ("hex digit" sau "hexit )

În memoria computerelor, numerele sunt reprezentate ca şi numere binare, pe un anumit număr (finit) de biţi. Valorile care pot fi reprezentate depind de numărul de biţi folosiţi pentru respectiva reprezentare. Exemple 2 biti 0 0 0 1 1 0 1 1 valoarea maxima: 3 8 biti 1 1 1 1 1 1 1 1 valoarea maxima: 255 Dacă trebuie reprezentate numere întregi cu semn, atunci un bit din numărul total de biţi ai reprezentării va fi folosit pentru semnul numărului ->bitul de rang maxim (cel mai din stânga):

Reprezentarea numerelor pozitive in complement fata de 2

Reprezentarea numerelor negative in complement fata de 2 Pentru a reprezenta în complement faţă de 2 un număr întreg negativ - se reprezintă modulul său - începând de la bitul de ordin zero spre stânga toţi biţii 0 şi primul bit 1 se păstrează - toţi ceilalţi îşi inversează valoarea (0->1 şi 1->0)

2 7 numere pozitive 2 7 numere negative Cel mai mare nr. pozitiv Cel mai mic nr. pozitiv Cel mai mare nr. negativ Cel mai mic nr. negativ Se obtine din cel mai mare nr. pozitiv reprezentabil, prin rasturnarea tuturor bitilor

Alte coduri de reprezentare a valorilor întregi sunt: 1. Codul direct Bitul de rang n-1 (cel mai din stânga) este rezervat pentru semn. Un număr negativ se reprezintă în cod direct reprezentând modulul său după care bitul de semn ia valoarea 1. 2. Codul invers Bitul de rang n-1 (cel mai din stânga) este rezervat pentru semn. Un număr negativ se reprezintă în cod invers reprezentând modulul său după care se inversează valorile tuturor biţilor reprezentării. Avantajele codului complementar - circuitele electronice pentru adunare şi scădere nu trebuie să examineze semnul numărului (vor efectua întotdeauna adunări) - valoarea 0 (zero) are reprezentare unică.

Reprezentarea numerelor reale în virgulă fixă în virgulă mobilă Reprezentarea numerelor reale în virgulă fixă - se foloseşte bitul cel mai semnificativ ca bit de semn. Modulul părţii întregi şi partea fracţionară au un număr prefixat de biţi pe care se reprezintă şi se aplică următoarele reguli: alinierea în locaţia de memorie se face la virgula virtuală. dacă valoarea părţii întregi este mai mică decât valoarea maximă ce poate fi reprezentată pe biţii alocaţi părţii întregi se adaugă la stânga zerouri suplimentare. dacă valoarea părţii întregi este mai mare decât valoarea maximă ce poate fi reprezentată pe biţii alocaţi părţii întregi se pierd cifrele cele mai semnificative. dacă valoarea părţii fracţionare este mai mică decât valoarea maximă ce poate fi reprezentată pe biţii alocaţi părţii fracţionare se adaugă la dreapta zerouri nesemnificative. dacă valoarea părţii fracţionare este mai mare decât valoarea maximă ce poate fi reprezentată pe biţii alocaţi părţii fracţionare se pierd cifrele cele mai nesemnificative.

Reprezentarea numerelor reale în virgulă mobilă - un tip superior de reprezentare, astfel concepută încât la depăşire se pierd cifrele cele mai puţin semnificative. - se bazează pe faptul că orice număr real x se poate scrie sub forma: x 0.m b unde 0.m este mantisa numărului, b este baza de numeraţie, iar e este exponentul. e

Pentru reprezentarea valorilor reale în virgulă flotantă trebuie folosit un anumit număr de biţi, care să permită reprezentarea: 1. semnului numărului 2. mantisei 3. exponentului 4. semnului exponentului (de fapt semnul exponentului se include în valoarea reprezentată pe biţii alocaţi, ţinându-se cont de caracteristica reprezentării) standardul IEEE (Institute of Electrical and Electronics Engineers), pentru reprezentarea numerelor în simplă precizie (pe 32 biţi) sau în dublă precizie (pe 64 biţi)

Bitul de semn: - 0 corespunde unui număr pozitiv şi 1 corespunde unui număr negativ Exponentul - trebuie reprezentate atât numere pozitive cât şi negative. - exponentului propriu-zis al numărului care se reprezintă i se adaugă o anumită valoarea care depinde de tipul de precizie folosită (simplă sau dublă), numită caracteristică. IEEE simplă precizie: 127 (2 7-1) IEEE dublă precizie: 1023 (2 10-1). 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 Pentru un număr al cărui exponent este 0, pe biţii alocaţi exponentului se stochează valoarea 127 (în binar 01111111). O valoare de 200 (în binar 11001000) stocată pe biţii exponentului înseamnă de fapt exponentul 200-127=73. Exponenţii cu toţi biţii 0 sau toţi biţii 1 sunt rezervaţi pentru numere speciale (, 0, NaN). Pentru standardul dublă precizie se alocă 11 biţi pentru exponent, iar caracteristica este 1023. Reprezentarea exponentului în simplă precizie:

Mantisa - biţii de precizie ai unui număr - compusă dintr-un bit implicit principal (întotdeauna 1 în scrierea cu mantisă între 1 şi 2) şi biţii fracţiei. Pentru a afla bitul implicit principal se ţine cont de faptul că în notaţia ştiinţifică orice număr poate fi reprezentat în mai multe feluri. Astfel, numărul 5 poate fi reprezentat într-unul din modurile următoare: 5.00 10 0 0.05 10 2 5000 10-3 În scopul maximizării cantităţii de numere reprezentabile, numerele floating point sunt stocate în formă normalizată, formă care se obţine punând punctul zecimal după prima cifră nenulă. În formă normalizată, numărul 5 este reprezentat sub forma: 5 10 0. In baza 2, singura cifră nenulă nu poate fi alta decât cifra 1, astfel încât nu este necesar ca ea să fie reprezentată explicit şi în simplă precizie de exemplu, toţi cei 23 de biţi sunt folosiţi pentru reprezentarea părţii fracţionare a mantisei, obţinându-se practic o precizie de 24 biţi folosind doar 23 de biţi. 1/2^24= 1.19209-07 1/2^52= 2.22045E-16

Diferenta: 2-23 0 = 0.0000001192 = 1.192 10-7 Numerele reale nu sunt reprezentate continuu ci discret! Pasul: 1.19210-7 http://www.h-schmidt.net/floatconverter/ieee754.html

Valoarea "Not A Number" - folosită pentru a reprezenta valori care nu reprezintă un număr real. - reprezentate printr-o succesiune de biţi cu exponentul având toţi biţii 1 şi o fracţie nenulă. Există două feluri de valori Nan: QNaN (Quiet NaN) şi SNaN (Signalling NaN). QNaN este un NaN cu cei mai semnificativi biţi ai fracţiei setaţi şi rezultă din operaţii aritmetice când rezultatul matematic nu este definit -> operaţie nedeterminată SNaN este un NaN cu cei mai semnificativi biţi a fracţiei şterşi şi astfel de valori sunt folosite pentru a semnala excepţii -> operaţie invalidă. CORE-STREPTAVIDIN MUTANT W120A IN COMPLEX WITH BIOTIN AT PH 7.5

Exemplu: Care va fi reprezentarea numărului -10.375, în virgulă flotantă, simplă precizie? 1. Numărul pozitiv se transformă în binar şi se obţine: 1010.011 2. Se scrie numărul obţinut în binar sub formă normalizată: 1.010011 2 3 3. Se determină valoarea exponentului: 3+127=130 4. Se transformă noul exponent în binar: (130) 10 =10000010 5. Se determină bitul de semn al mantisei: 1 6. Se scrie numărul: Exercitii Ce valoare au numerele a caror reprezentare este: Tema Care este diferenta dintre valoarea 2 si primul numar > 2 reprezentat in standardul IEEE, simpla precizie? http://homepage.cs.uiowa.edu/~atkinson/m170.dir/overton.pdf

CURS 3 Limbajul C - dezvoltat între anii 1969-1973 (D.M.Ritchie), o dată cu dezvoltarea sistemului de operare Unix. (Ken Thompson & D.M.Ritchie); - 1972 - anul "naşterii" limbajului C. - 1973 - elementele esenţiale ale limbajului C au fost complete - 1977-1979 schimbari majore - 1978 apare cartea "The C programming language" scrisă de către B.W.Kernighan, D.M.Ritchie - 1983 incepe standardizarea limbajului C de către ANSI (American National Standards Institute) - 1989 - a apărut ANSI C.

Avantaje 1. limbaj de programare de scop general => dezvoltarea de aplicaţii diverse: soft ştiinţific, soft pentru gestiunea bazelor de date, editoare de texte, jocuri, etc. - nu este specializat pe un domeniu particular de aplicaţii - control modern al funcţiilor şi al structurilor de date - set bogat de operatori 2. permite o foarte bună portabilitate a programelor 3. permite programarea structurată (modulară) 4. permite scrierea softului de bază (programare de sistem) 5. oferă posibilitatea lucrului pe biţi şi a calculului adreselor

Elementele limbajului C Exemple

Categorii de elemente Comentarii - note explicative (adnotări) în program - complet ignorate de către compilator - şiruri de caractere (pot fi şi caractere speciale sau cuvinte cheie) cuprinse între /* */ sau care se găsesc pe un singur rând după caracterele //

Cuvinte cheie - cuvinte rezervate limbajului de programare, cu utilizare predefinită - nume cu destinaţii speciale - se scriu cu litere mici Exemple

Identificatori (nume) - folosiţi pentru a denumi variabile, constante, funcţii, structuri de date, etc. - = succesiuni de caractere alfanumerice, primul caracter trebuind să fie literar - in C, de ex., S s - un identificator poate conţine oricâte caractere dar sunt luate în considerare doar primele 32 caractere - nu pot conţine caractere speciale: + - / ^ < > ( ) [ ]., : ; ' # $ @ - spatiu Recomandare - sa fie sugestivi - x 2 : x2, xx, xla2, xp, etc. Exemple: a, suma, SUMA, m2, nr_stud_an1f, NrStudAn1F 2x, a*b, if Obs. Identificatorii care încep cu _ sau conţin sunt folositi pentru implementare şi pentru librăriile standard în C şi C++.

Variabile - nume simbolice asociate unor locaţii de memorie - valorile lor pot fi modificate prin instrucţiuni ale programului - declararea (definirea) variabilelor constă în precizarea tipului şi numelui lor. Exemple:

Variabile globale - variabile declarate in afara functiei main - se initializeaza automat cu zero Exercitiu Scrieti programul pentru transformarea oc->of

Constante - valori care nu pot fi modificate în decursul programului constante simbolice constante obiect Constante simbolice - se definesc cu directiva define - constante fara tip Directiva define - stabileşte (defineşte) un nume simbolic pentru o anumită valoare - se compune din: cuvântul cheie #define, o denumire simbolică, o valoare - nu se termină cu ; - autorizează substituţia pe care o defineşte din punctul în care este scrisă până la sfârşitul fişierului sursa sau până la întâlnirea unei directive undef.

Constantele obiect - constante cu tip - Se declara folosind cuvântul cheie const urmat de tipul constantei şi de un identificator iniţializat. - declararea acestor constante se termină cu caracterul ; Exemplu O constantă de tip char (caracter) este un întreg, scris ca un singur caracter între două simboluri '. Valoarea constantei caracter este valoarea caracterului respectiv în setul de caractere ASCII (American Standard Code for Information Interchange). Astfel, de exemplu, '0' are valoarea 48, 'A' are valoarea 65, iar 'a' are valoarea 97.

Instrucţiuni - părţi (linii) de program care prin compilare produc acţiuni (coduri) executabile - se termină cu caracterul ; - terminator de instrucţiune - lipsa caracterului ; este semnalata la începutul liniei următoare

Exemple In urma execuţiei programului se tipăresc valorile de la 5 la 105 Dacă nu se pun acolade la while se va tipări doar valoarea 105

Expresii - construcţii formate din operanzi şi operatori. - au valori şi tipuri - valorile şi tipurile expresiilor sunt determinate de către valorile şi tipurilor operanzilor şi de către operatorii care compun expresia. Exemplu b*b-4*a*c expresie a, b, c operanzii expresiei *, - operatorii expresiei delta = b*b - 4*a*c ; instrucţiune prin care se atribuie variabilei delta rezultatul evaluarii expresiei b 2-4ac Operanzii pot fi : - constante - identificatori (nume) de variabile - nume de tipuri de date - apeluri de funcţii - expresii cuprinse între paranteze rotunde

Funcţii - grupuri de instrucţiuni recunoscute sub un anumit nume - realizează acţiuni şi întorc (returnează) valori programului principal (funcţiei principale) sau altei funcţii apelante. - se apelează prin nume şi lista lor de parametri. Parametrii funcţiilor sau valorile cu care sunt apelate transferă informaţia din exteriorul funcţiilor în interiorul lor. Valorile pe care le returnează funcţiile nu trebuie folosite în mod obligatoriu (vezi de ex. funcţiile scanf() şi printf()) Funcţia principală returnează valori sistemului de operare, acesta fiind programul apelant al ei. Anumite funcţii standard sunt gata scrise şi prototipurile lor se găsesc în bibliotecile limbajului (header files). <stdio.h> - conţine funcţii standard de intrare ieşire (I/O): printf, scanf, getch,... <stdlib.h> - conţine funcţii standard precum: abort, exit, rand, atoi, itoa,... <string.h> - conţine funcţii pentru prelucrarea şirurilor de caractere: strcpy, strlen, strcmp, strcat,... <math.h> - conţine funcţii matematice: cos, sin, pow, fabs, abs,... <graphics.h> - conţine funcţii pentru gestiunea ecranului în mod grafic (initgraph, putpixel, line, outtext, outtextxy, cleardevice,...) <conio.h> - conţine funcţii standard de intrare ieşire de la consolă (clrscr, getch, getche, gotoxy, putch, wherex, wherey,...) <time.h> - conţine funcţii pentru gestiunea orei şi a datei sistemului de calcul (gettime, settime, ctime,...) <dos.h> - conţine funcţii pentru interacţiunea cu sistemul de operare DOS (setdrive, inport, outport) etc.

Funcţia itoa (nu este suportată de toate compilatoarele)

Structura funcţiilor Antetul - tipul valorii pe care o returnează funcţia + numele funcţiei + lista parametrilor funcţiei (tipul şi numele variabilelor funcţiei) Corpul de instructiuni - grupul de instrucţiuni care se execută la apelul funcţiei respective.

Apelul functiilor - prin nume şi lista de parametri. La apelul funcţiei, controlul programului este pasat acelei funcţii. La întâlnirea instrucţiunii return în interiorul unei funcţii se face saltul în afara funcţiei, controlul fiind preluat de către funcţia main, din locul imediat următor celui în care a fost apelată funcţia din care se face saltul.

Funcţia main - partea principală a unui program C - este apelată şi lansată în execuţie de către sistemul de operare. Funcţii recursive - functii care se autoapelează - se folosesc la definirea proceselor recursive. Proces este recursiv - proces care are o parte care se defineşte prin el însuşi.

Exemple Funcţia factorial dacă n==0 fact(n)=1 altfel fact(n)=n*fact(n-1) <- aceasta este partea apelului recursiv care nu se defineşte prin el însuşi (partea definită direct) <- se defineşte funcţia fact prin ea însăşi Funcţia fact recursivă: Cel mai mare divizor comun dacă a%b==0 cmmdc(a,b)=b altfel cmmdc(a,b)=cmmdc(b,a%b) Funcţia cmmdc recursivă: Recursivitatea nu conduce la coduri mai rapide şi nici la necesităţi de memorie mai mici. - convenabila pentru structuri de date definite recursiv (arbori) Codurile recursive sunt mai compacte şi uneori mai uşor de înţeles.

Tablouri - colecţii de valori de acelaşi tip - plasate in zone contigue de memorie - elementele - pot fi referentiate si accesate individual folosind un index - sunt indexate de la 0 la n-1 unde n reprezintă dimensiunea tabloului Exemple Este declarat un tablou unidimensional de 5 elemente şi elementele tabloului sunt apoi iniţializate cu valoarea 0. int a[5]; int i; for(i=0;i<5;i++) a[i]=0; float medii[10]; medii[10]=9.85; float x[6]; x[1] = 12; x[2]=34; x[5] = 14; //x[0] = nedefinit!! float x[6] = 12, 34, 1, 9, 14 //rezultă: x[0] = 12;... x[4] = 14; şi x[5] = nedefinit!!

Care va fi output-ul urmatorului program

Care va fi output-ul urmatorului program Fara _kbhit() si fara <conio.h>

Tema: Modificati programul de mai sus astfel incat sa se tipareasca notatia tablei de sah:

Şiruri de caractere - tablouri cu elemente de tip char (caractere). Exemple: char nume[20], prenume[20]; char nume[20] = "Popescu"; Şirurile de caractere trebuie cuprinse între " ". Dacă avem declaraţia: char nume[20] = "Popescu" Citirea şi tipărirea şirurilor - cu funcţiile gets( ) şi puts( ) #include <string.h>... char nume[20];... gets(nume);... puts(nume);... Atunci o reiniţializare de forma: nume = "Ionescu" va produce o eroare. Iniţializare şirurilor: - la declararea lor - folosind funcţia strcpy (string copy) # include <stdio.h>... char nume[20] = "Popescu";... strcpy (nume, "Ionescu");...

Un şir de caractere este terminat cu caracterul NULL (caracterul '\0'). Exemplu Sirul de caractere "Programare" este stocat în tabloul de caractere sircar[] după cum urmează: char sircar[dim] sircar[0]='p'; sircar[1]='r'; sircar[2]='o ; sircar[3]='g sircar[4]='r' sircar[5]='a'; sircar[6]='m'; sircar[7]='a'; sircar[8]='r sircar[9]='e'; sircar[10]='\0'; Caracterul NULL - este scris folosind secvenţa escape '\0 - este definit în <stdio.h> - valoarea sa ASCII este 0. Exemple printf("string1:\t"); strcpy(s1,"testare\0siruri"); // \0 = NULL printf("\n%s",s1); l1=strlen(s1); printf("\nlungimea sirului 1: %d\n",l1); printf("string1:\t"); strcpy(s1,"testare\\0siruri"); // \0 = NULL printf("\n%s",s1); l1=strlen(s1); printf("\nlungimea sirului 1: %d\n",l1);

Exemplificare strcmp() si strlen() http://www.cplusplus.com/reference/ int strcmp ( const char * str1, const char * str2 ); Compare two strings Compares the C string str1 to the C string str2. This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached. This function performs a binary comparison of the characters. Parameters str1 C string to be compared. str2 C string to be compared. Return Value Returns an integral value indicating the relationship between the strings: A zero value indicates that both strings are equal. A value greater than zero indicates that the first character that does not match has a greater value in str1 than instr2; And a value less than zero indicates the opposite. strcmp este utila la ordonarea alfabetica a cuvintelor!

http://www.cplusplus.com/reference/ strlen size_t strlen ( const char * str ); Get string length Returns the length of the C string str. The length of a C string is determined by the terminating nullcharacter: A C string is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself). This should not be confused with the size of the array that holds the string. For example: char mystr[100]="test string"; defines an array of characters with a size of 100 chars, but the C string with which mystr has been initialized has a length of only 11 characters. Therefore, while sizeof(mystr) evaluates to 100, strlen(mystr) returns 11. In C++, char_traits::length implements the same behavior. Parameters str C string. Return Value The length of string.

Secvenţe escape - coduri de control (spaţii albe), folosite pentru specificarea formatelor de scriere a datelor - constau din combinaţii dintre un caracter backslash \ urmat de o literă sau de o combinaţie de cifre. Setul de secvente escape în C: Unele secvenţe escape sunt specifice perifericelor folosite. \v (tabulator vertical) şi \f (pagină nouă la imprimantă) nu afectează formatul de ieşire al datelor pe monitor ci numai la imprimantă. Exemple: printf("\nsuma celor %d numere este %g\t\a,n,s); Suma celor 5 numere este 43.75 _ (cursor)

printf("\n\tsem I\t\tSem II"); for(i=1; i<=nrstud; i++) printf("\n%d:\t%5.2f\t\t%5.2f",i,medsem1[i],medsem2[i]); Sem I Sem II 1: 8.75 5.25 2: 10.00 10.00 3: 5.30 6.67... #define fis_intrare "d:\\fiz1r\\centru.dat Pentru despărţirea directoarelor într-o cale de directoare scrisă într-un program C trebuie folosite două caractere backslash (\\).

Codul ASCII (American Standard Code for Information Interchange) - cod standard de reprezentare a caracterelor ca valori întregi pe 7 biţi. - introdus pentru a se obţine o compatibilitate între tipuri diferite de echipamente folosite la procesarea datelor. - ASCII standard - constă din 128 de numere întregi (reprezentate pe 7 biţi, cu valori între 0 şi 127) atribuite unor caractere (cele englezeşti), numere, semne de punctuaţie, celor mai uzuale caractere speciale şi unor coduri de control (comenzi) netipăribile (primele 32 de caractere). - Codul ASCII extins - constă de asemenea din 128 numere întregi, cu valori între 128 şi 255 (pentru reprezentarea lor folosindu-se toţi cei 8 biţi ai unui octet), care reprezintă caractere suplimentare din alte limbi, simboluri matematice, grafice, caractere speciale sau sau simboluri ale unor monede străine. - Folosirea acestor coduri face posibilă şi prelucrarea caracterelor, nu numai a numerelor.

Codul ASCII standard

Codul ASCII extins

CURS 4 Structura generală a unui program " C Program - ansamblu de instrucţiuni incluse în una sau mai multe funcţii, care specifică operaţiile ce trebuie efectuate asupra unor date pentru a fi prelucrate în sensul dorit de către utilizator. Program C 0. Documentatie 1. Directive de preprocesare a) Includeri de fişiere cu text sursă b) Macrosubstituiri c) Includeri conditionate 2. Sectiunea de declaratii a) variabile b) tipuri utilizator c) functii... 3. Functia principala int main()... return 0; 4. Definirea functiilor utilizator

0. Documentatii - set de comentarii care conţin numele programului şi alte detalii utile programatorului. Exemple //Program: easycalc //Calculator pentru operatii elementare //Exemplu de folosire a instructiunii switch //Introducerea functiei system //system("c:\\windows\\system32\\calc.exe"); // - apeleaza aplicatia calc.exe

1. Directive de preprocesare a) Includeri de fişiere cu text sursă b) Macrosubstituiri c) Includeri conditionate Preprocesare - prelucrarea unui fişier sursă înainte de a fi supus compilării => un fişier temporar care conţine un cod sursă provenit în urma traducerii directivelor de preprocesare. Preprocesorul C - program separat, invocat de către compilator în prima parte a procesului de compilare a) Includeri de fişiere cu text sursă - se fac cu directiva # include printr-o construcţie de forma : #include <nume_fisier.h> #include "nume_fisier.c nume_fisier = fişier cu text sursă păstrat pe disc

În faza de preprocesare textul fişierului inclus se substituie construcţiei #include şi apoi ia parte la compilare împreună cu textul fişierului în care a fost inclus #include <nume_fisier.h> - se foloseşte pentru includerea fişierelor standard care conţin prototipuri pentru funcţiile de bibliotecă (librării). - instruiesc preprocesorul să trateze fişierele header ca şi cum ar face parte din codul sursă care se compilează. Librăriile sunt coduri gata compilate care se adaugă programului sursă C la compilarea acestuia. Parantezele unghiulare instruiesc compilatorul să caute fişierele care trebuie incluse în directorul cu fişiere antet (de exemplu, C:\BorlandC\include). Exemple: #include <stdio.h> #include <math.h> Construcţia #include "nume_fisier.c" se utilizează la includerea fişierelor nestandard care conţin prototipuri ale eventualelor funcţii definite de către utilizator. Fişierul care trebuie inclus se caută în directorul curent dacă nu este specificată nici o cale. Exemple: # include "factorial.c" # include "C:\\BORLANDC\\PERSLIB\\persmat.c"

b) Macrosubstituiri -substituirea unor nume prin succesiuni de caractere şi se fac cu directiva #define sub forma: #define succesiune_de_caractere (vezi constante simbolice). Macroprocesorul poate efectua şi substituţii de argumente în macrodefiniţii. Exemplu: #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) #define grade_rad (x) ((x)*m_pi/180.0)

Program exemplu: macrodefiniţii #include <stdio.h> #include<conio.h> #define max2(a,b) (a>b?a:b) #define min2(a,b) (a<b?a:b) #define max3(a,b,c)(max2(a,b)>c?max2(a,b):c) #define schimb(a,b) t=a;a=b;b=t; #define moddif(a,b) ((a>b)?(a-b):(b-a)) #define suma(a,b) (a+b) int main() int a,b,t; printf("a= "); scanf("%d",&a); printf("b= "); scanf("%d",&b); printf("\nmaximul este %d",max2(a,b)); printf("\nminimul este %d",min2(a,b)); printf("\nmodulul diferentei este %d",moddif(a,b)); printf("\nsuma numerelor este %d",suma(a,b)); schimb(a,b); printf("\ndupa schimbare valorile a si b sunt %d si %d",a,b); while(!_kbhit()); return 0;

c) Includeri condiţionate - se folosesc pentru includerea unor fişiere numai atunci când este îndeplinită o anumită condiţie Exemplu: #if SYSTEM == MSDOS // daca sistemul de operare este MS-DOS #include <dos.h> // se foloseste headerul <dos.h> #else #include <windows.h> // altfel, se foloseste headerul <windows.h> #endif Includerile condiţionate se mai pot folosi pentru construirea grupurilor condiţionate sub forma: #ifdef MACRO text controlat #endif /* MACRO */ Textul controlat va fi inclus numai dacă este definită macrocomanda MACRO şi acest text poate include directive de preprocesare. Exemplu: #ifdef TURBOC #define INT_SIZE 16 #else #define INT_SIZE 32 #endif // in TurboC valorile intregi // se stocheaza pe 16 biti iar in SO Unix // acestea se stocheaza pe 32 biti // orice includere condiţionată se încheie cu #endif.

2. Sectiunea de declaratii a) variabile b) tipuri utilizator c) functii... În această secţiune se stabilesc numele şi atributele variabilelor, a tipurilor de date utilizator sau ale funcţiilor 3. Functia principala int main()... return 0; 4. Definirea functiilor utilizator

Tipuri de date în C -descriu tipurile valorilor diverselor variabile, constante, funcţii, etc. ale unui program. - fiecare variabilă folosită într-un program C trebuie să fie declarată compilatorului. - declaraţia va conţine numele variabilelor şi tipul acestora. Exemplu:... int zi,luna,an:... zi = 14; luna = 11; an = 2013; float medie;... medie = 11; //variabilele zi, luna şi an au valori diferite dar au acelaşi tip //variabilele luna şi medie au aceeaşi valoare dar tipuri diferite 1) Fiecarui tip de dată îi corespunde o denumire (un cuvânt cheie) care este utilizată pentru crearea în memorie a obiectelor ce vor conţine valori corespunzătoare tipului respectiv. 2) Fiecărui tip de date îi corespunde o anumită mărime a zonei de memorie în care se păstrează valoarea unei date de tipul respectiv. 3) Fiecărui tip de date îi corespunde o anumită gamă de valori, determinată de mărimea locaţiei de memorie corespunzătoare datelor de tipul respectiv.

Tipuri de date de bază (tipuri predefinite) - puse la dispozitie de catre limbajul de programare Tipuri de date derivate (tipuri utilizator) - se construiesc cu ajutorul tipurilor de bază

Tipuri de date de bază - tipurile predefinite in C: char - tip de date ale căror valori sunt reprezentate pe un singur octet (byte) int - tip de date ale căror valori sunt reprezentate pe 2 octeţi float - tip de date reale reprezentate în virgulă mobilă, în simplă precizie double - tip de date reale reprezentate în virgulă mobilă, în dublă precizie În plus, există câţiva calificatori care pot fi aplicaţi acestor tipuri de bază: unsigned, short şi long

Structura functiilor Functii in C - încapsulează una sau mai multe instrucţiuni, variabile şi parametri într-un pachet unificat care poate fi apelat din interiorul programului - împart sarcinile mari de calcul ale unui program în sarcini de complexitate mai mică Definirea functiilor tip nume (listă parametri formali) declaraţii instrucţiuni tip = tip de baza sau tipul void Funcţiile pot returna valori având ca tip: tipuri de bază pointeri structuri pointeri la structuri pointeri la tablouri Funcţiile nu pot returna: tablouri

Parametrii functiilor -o funcţie poate avea unul sau mai mulţi parametri, dar poate de asemenea să nu aibă nici un parametru. - sunt folosiţi pentru a face transferuri de date între funcţii - sunt de două feluri: a) parametri formali - nu reprezintă valori concrete ci ţin doar locul unor valori pentru a se putea exprima procesul de calcul realizat de către funcţie în momentul apelului ei - vor fi înlocuiţi de către cei actuali în momentul apelului funcţiei. b) parametri actuali - parametrii transmişi unei funcţii şi care reprezintă valori concrete cu care sunt apelate funcţiile. - pot fi constante, variabile, expresii - nu este obligatoriu ca numele parametrilor actuali să fie identice cu cele ale parametrilor formali. Transmiterea parametrilor între funcţii

Exemple: char ascii (int valoare) char c; c = (char) (valoare) return c; int cod (char c) int codc; codc = (int) (c) return codc; int cod (char c) return (int) (c); Variabilele din interiorul unei funcţii se numesc variabile locale şi aparţin clasei automatic. - sunt "vizibile" numai în corpul funcţiei în care au fost declarate şi există doar atâta timp cât funcţia în care au fost declarate se află în execuţie - la ieşirea din funcţie valorile lor sunt şterse din memorie (sunt volatile) Exemple: Variabile c este de tip automatic şi va fi alocată în memorie de fiecare dată când se execută funcţia suma. Compilatorul va crea un cod pentru alocarea dinamică a variabilei, pentru iniţializarea ei şi pentru eliminarea ei din memorie la încetarea execuţiei funcţiei suma.

Variabile statice - variabile locale care nu se alocă pe stivă ci într-o zonă specială de memorie, rezervată acestui tip de variabile - trebuie să fie precedate la declarare de cuvântul cheie static - spre deosebire de variabilele automatic ele există tot timpul şi nu numai atunci când este executată funcţia (nu îşi pierd valoarea între două apeluri ale funcţiei în care sunt declarate) Exemplu: static int c; Variabilele globale - variabile declarate în afara oricărei funcţii a programului - sunt iniţializate automat cu zero şi pot fi utilizate de către orice funcţie a programului - sunt variabile externe, adică pot fi utilizate într-o anumită funcţie a programului chiar dacă nu au fost declarate în funcţia respectivă - au tipul static automat. Recomandare: 1. Este recomandabilă folosirea variabilelor locale deoarece acest lucru conduce la urmărirea mai uşoară a codului unei funcţii particulare. 2. Dacă folosirea variabilelor locale conduce la transmiterea multor parametri sau la reproducerea inutilă a mai multor variabile, atunci este recomandabil să fie folosite variabile globale.

Apelul funcţiilor O funcţie se apelează printr-o construcţie de forma: nume (listă parametri efectivi) Parametrii efectivi - argumentele funcţiei (adică parametrii cu care se apelează funcţia) - trebuie să corespundă cu cei formali (folosiţi la declararea funcţiei) în ordine şi tip. - sunt pasati funcţiilor prin valoare, astfel încât funcţia primeşte o copie a argumentului şi deci ea poate modifica argumentul său fără a modifica originalul. Pentru ca o funcţie să poate modifica argumentul original i se va transmite un pointer la acesta. Valorile returnate de către funcţii pot fi folosite ca şi argumente ale altor funcţii # include <stdio.h> int f(int n) return 2*n; int g(int n) return n*n; int main() int m; printf("introduceti o valoare intreaga: "); scanf("%d",&m); printf("f(x)=%d \t f(g(x))= %d", f(m),f(g(m))); printf("\nf(x)=%d \t g(f(x))= %d", f(m),g(f(m))); return 0;

Program exemplu: calculul mediei valorilor unui şir de elemente //exemplu functie avand ca parametru un tablou #include<stdio.h> #include<conio.h> float medie (int n, float sir[]) int i; float m,s=0; for(i=0;i<n;i++) s=s+sir[i]; m=s/n; return m; int main() int n,i; float note[10],med; printf("n= "); scanf("%d",&n); for(i=0;i<n;i++) printf("n%d: ",i); scanf("%f",&note[i]); med=medie(n,note); printf("\nmedia: %.2f",med); return 0; Dimensiunea şirului poate fi omisă în prototipul funcţiei. De asemenea, valoarea primei dimensiuni a unui tablou multidimensional este opţională deoarece compilatorul nu are nevoie de valoarea primei dimensiuni pentru a calcula adresele elementelor tabloului ci numai de dimensiunile următoare. Astfel, dacă avem declaraţia: char Mat[6][8]; Adresa elementului Mat[2][3] va fi adresa lui Mat+2*8+3 deoarece Mat (numele tabloului) este un pointer având ca valoare adresa primului sau element.

Prototipul funcţiilor O funcţie poate fi apelată într-un anumit punct al unui program dacă a fost în prealabil definită în acel program. Totuşi, o funcţie poate fi apelată şi în cazul în care corpul de instrucţiuni urmează apelului ei. In acest caz, în secţiunea de declaraţii a programului trebuie declarat prototipul functiei. Prototipul unei funcţii = antetul ei urmat de ; - se foloseşte pentru declararea unei funcţii înainte de definirea ei - poate conţine doar tipul parametrilor formali ai funcţiei, fără numele lor Compilatorul utilizează datele din prototip pentru a verifica tipul parametrilor de la apel. În cazul în care un parametru efectiv are un alt fel de tip decât cel din prototip compilatorul converteşte automat valoarea parametrului efectiv spre tipul indicat în prototip. Fişierele header sunt fişiere cu astfel de prototipuri de funcţii predefinite ale limbajului.

Exemplu: int main ( ) long n, k, cnk ; double fact (long val); cnk = fact(n)/(fact(k)*fact(n-k)); return 0; // prototip fact // 3 apeluri ale lui fact //exemplu de funcţie factorial mai rapidă decât cele prezentate anterior double fact (long val) long rez=val; // antet fact // corp fact while(--val>1) rez*=val; return rez;

int decidebisect(...) int i;... i=(an%4==0 && an%100!=0)an%400==0); //un an este bisect dacă este divizibil cu 400 //sau dacă este divizibil cu 4 dar nu şi cu 100 //anii de sfârşit de secol nu sunt bisecţi chiar dacă urmează la 4 ani după un an bisect, //cu excepţia celor care sunt divizibili cu 400 //ani bisecţi "obişnuiţi": 1872, 1912, 1960, 1996, 2008... anii divizibili cu 4 //excepţii: 1800, 1900, 2100, 2200... anii de sfârşit de secol divizibili cu 100 //sunt totuşi ani bisecţi: 2000, 2400... anii de sfârşit de secol divizibili cu 400 int b, an; FILE *f; f=fopen("d:\\anibis.dat","w"); for(an=1872;an<=2110;an++) if(an%400==0) b=1; else if(an%100==0) b=0; else if(an%4==0) b=1; else b=0; fprintf(f,"\nan: %d\tbisect: %s",an,b==1? DA : NU );

CURS 5 Funcţii de intrare/ieşire Funcţia printf - folosită pentru a scrie date la dispozitivul standard de ieşire (monitor), sub un anumit format. - converteşte, formatează şi tipăreşte argumentele cu care este apelată, în conformitate cu formatul specificat - returnează numărul de caractere tipărite. Şirul care defineşte formatul funcţiei conţine două tipuri de obiecte: a) caractere ordinare - copiate ca atare la ieşirea standard b) specificatoare de conversie şi formatare Prototipul funcţiei printf - se găseşte în <stdio.h> int printf(char *format, arg1, arg2,...); Apelul functiei printf printf("control",arg1,arg2,...,argn); arg1, arg2,...,argn - variabile sau expresii ale căror valori se tipăresc în conformitate cu specificatorii de format prezenţi în parametrul "control" al funcţiei. Parametrul control - şir de caractere care defineşte textele şi formatele datelor care se scriu. - poate conţine fie numai specificatori, fie numai carcatere.

1. Numărul specificatorilor din parametrul control trebuie să fie egal cu numărul argumentelor funcţiei şi să corespundă tipului acestora. 2. Datele tipărite se încadrează într-un câmp (un anumit număr de caractere) şi se aliniază implicit în dreapta acestui câmp. Specificator de format [ - ] - începe întotdeauna cu caracterul % şi se termină cu una sau două litere, dar mai poate conţine: - are ca efect încadradrea datelor scrise în stânga câmpului [şir de cifre zecimale] - defineşte dimensiunea minimă a câmpului în care se afişează datele

Litera g este folosită ca şi litera f pentru conversia valorilor care se afişează la tipul real şi tipărirea valorilor respective fără zerourile nesemnificative. [.şir de cifre zecimale] - defineşte precizia datei care se scrie, adică numărul de cifre zecimale sau numărul de caractere care se scriu dacă data este un şir de caractere

% [ -, 0, cifre.cifre ]l [l] Litera c este folosită pentru afişarea unui caracter. Litera s este folosită pentru afişarea unui şir de caractere. Litera d se foloseşte pentru afişarea valorilor variabilelor de tip întreg, în sistemul de numeraţie zecimal. Litera o se foloseşte pentru afişarea valorilor variabilelor de tip întreg, în sistemul de numeraţie octal. Literele x şi X se folosesc pentru convertirea şi afişarea valorilor unor variabile de tip întreg în sistemul de numeraţie hexazecimal. Litera u este folosită pentru conversia valorilor la tipul întreg unsigned şi tipărirea lor. Litera f este folosită pentru conversia la tipul float şi afişarea valorilor cu 6 cifre zecimale. Literele e şi E sunt folosite pentru tipărirea valorilor de tip float, double sau long double în format ştiinţific. Literele g şi G sunt folosite pentru afişarea datelor de tip float, double sau long double pe un număr minim de caractere (fără zerouri nesemnificative). Literele l şi L realizează conversii la tipul long, respectiv la tipul long double şi se folosesc împreună cu literele f, e, E, g sau G. lf, Lf realizează afişarea datelor fără exponent, cu 6 cifre zecimale. le, le, Le, LE realizează tipărirea valorilor în format ştiinţific. lg, lg, Lg, LG realizează tipărirea datelor într-unul din formatele precedente care asigură o afişare cu un număr minim de caractere.

Specificatorul %c este folosit pentru citirea unui caracter. Specificatorul %s este folosit pentru citirea unui şir de caractere. Un şir citit cu specificatorul %s se încheie la primul caracter citit după care urmează un caracter alb (spaţiu, tab (\t), rând nou (\n), carriage return, tab vertical (\v) şi avans de pagină la imprimantă (\f)) sau la caracterul prin care se ajunge la lungimea maximă de caractere indicată de specificatorul de format.

Funcţia scanf - folosită pentru citirea datelor introduse de la dispozitivul standard de intrare (tastatura) ş - converteste datele în conformitate cu formatul specificat - returnează numărul câmpurilor citite corect, adică în conformitate cu tipul specificat. Prototipul funcţie scanf se găseşte în <stdio.h> int scanf(char *format, arg1, arg2,...argn) Apelul funcţiei scanf scanf("control",&par1, &par2,...,&parn); &par1, &par2,..., &parn sunt adresele de început ale locaţiilor de memorie în care se păstrează valorile corespunzătoare lui par1, par2,..., parn. Astfel, dacă v este o variabilă, atunci &v reprezintă adresa primului octet al locaţiei de memorie la care se stochează valoarea variabilei v. Şirul control conţine specificatori de tip folosiţi pentru controlul conversiei datelor citite.

Specificatori de tip Specificatorul %c este folosit pentru citirea unui caracter. Specificatorul %s este folosit pentru citirea unui şir de caractere. - citirea sirului se încheie la primul caracter citit după care urmează un caracter alb (spaţiu, tab (\t), rând nou (\n), carriage return, tab vertical (\v) şi avans de pagină la imprimantă (\f)) sau la caracterul prin care se ajunge la lungimea maximă de caractere indicată de specificatorul de format. Specificatorul %d permite citirea unor valori şi conversia acestora spre tipul întreg - citirea se încheie la primul caracter citit după care urmează un caracter alb sau la caracterul prin care se ajunge la lungimea maximă de caractere indicată de specificatorul respectiv. Specificatorul %o este folosit pentru citirea unor valori întregi în sistemul de numeraţie octal. Specificatorul %u se foloseşte pentru citirea întregilor de tip unsigned. Specificatorul %f este folosit la citirea unor date de tip real şi conversia acestora spre tipul float. Litera l poate precede literele d, o, x, X, u sau f şi converteşte datele citite spre tipul long (în cazul d, o, x, X, u) sau spre tipul double dacă precede litera f. Litera L poate precede litera f şi are ca efect convertirea datelor citite spre tipul long double.

Alte functii de intrare iesire Intrare: getch, getche, getc, gets, getchar Ieşire: printf, putch, putc, puts, putchar.

Operatori - folosiţi la construcţia expresiilor matematice şi logice - exercită diferite acţiuni asupra operanzilor expresiilor şi sunt de două feluri: a) operatori unari, care se aplică unui singur operand b) operatori binari, care se aplică la doi operanzi Clase de operatori operatori aritmetici operatori de relaţie operatori de forţare a tipului operatori de atribuire operatori logici operatorii paranteze operatori de incrementare şi decrementare operatorul adresă operatorul * operatori de dimensiune operatorul virgulă operatori logici pe biţi operatori condiţionali operatorul -> operatorul operatori de egalitate

Operatori aritmetici - folosiţi la efectuarea calculelor aritmetice cu date de diferite tipuri - se împart în următoarele categorii: 1) operatorii unari + şi ; operatorul unar + nu are nici un efect, iar operatorul unar negativează valoarea operandului căruia i se aplică. 2) operatorii binari aditivi + şi 3) operatorii binari multiplicativi *, / şi %. operatorul * realizează produsul operanzilor operatorul / realizează împărţirea operanzilor operatorul % (modulo) se aplică numai la operanzi întregi şi returnează restul împărţirii întregi a operanzilor. Operatorii unari sunt mai prioritari decât cei binari, iar cei multiplicativi sunt mai prioritari decât cei aditivi. Dacă un operator se aplică la doi operanzi cu tipuri diferite, operandul de tip inferior se converteşte spre tipul superior al celuilalt operand şi rezultatul este de tipul superior. Dacă un operator se aplică la doi operanzi de acelaşi tip atunci tipul rezultatului coincide cu tipul comun al operanzilor. Dacă rezultatul are o valoare ce depăşeşte limitele tipului respectiv, atunci rezultatul este imprevizibil.

Exemple (1) float a; double b; int i; b = 3*a-i; Valoarea 3 (de tip int) se converteşte la float (adică valoarea 3 se extinde pe 4 octeţi) şi rezultatul este de tip float. Apoi se converteşte i la float şi apoi se scade din rezultat. In final, rezultatul se converteşte la double. (2) int a, b, c;... a = 30000; b = 29000; c = a+b; Valoarea lui c este imprevizibilă deoarece depăşeşte limitele tipului int.

Operatori de relaţie (relaţionali) ==, >, >=, <, <= - acţiunea lor constă în a compara în sens algebric valorile a doi operanzi întregi sau în virgulă mobilă - au aceeaşi prioritate (mai mică decât a operatorilor aditivi) E1 operator relaţional E2 unde E1 şi E2 sunt expresii, are valoarea 0 (fals) sau 1 (adevărat). În C şi C++ se consideră că o expresie este falsă dacă valoarea ei este 0 şi se consideră că este adevărată dacă valoarea ei este diferită de zero (este egală cu 1). Exemple #include <stdio.h> int main( ) float a, b; scanf("%f %f",&a,&b); printf("%g\t%g\t%d", a, b, a>b); return 0; printf("\n%g\t%g\t%d",a,b,(a>b)*10); printf("\n%g\t%g\t%d",a,b,(a>b)+1)

Operatori de egalitate == (egal) şi!= (diferit) - verifică dacă valorile a doi operanzi sunt egale sau nu - au aceeaşi prioritate (mai mică decât a operatorilor de relaţie) E1 operator de egalitate E2 unde E1 şi E2 sunt expresii, are valoarea 0 sau 1. Exemple b == a*a are valoarea 1 dacă b=a 2 şi 0 dacă b a 2 a%4!=0 are valoarea 1 dacă a nu este multiplu de 4 şi 0 în caz contrar getchar()==eof are valoarea 1 dacă s-a citit caracterul de sfârşit de fişier şi 0 dacă s-a citit un alt caracter. float x; scanf("%f",&x)==1 are valoarea 1 (adevărat) dacă funcţia scanf a citit o valoare de tip float (sau convertibilă la float) şi zero în caz contrar int m, x, y, z; scanf("%d%d%d%d",&m,&x,&y,&z)==4 are valoarea 1 dacă s-au citit 4 valori de tip întreg şi zero în caz contrar

Operatorul de atribuire = - atribuie valoarea unei expresii la o anumită variabilă (dacă este cazul se face şi conversia necesară) - are cea mai mică prioritate - se foloseşte sub forma: v = expresie; v poate fi o variabilă simplă, un element de tablou sau de structură, un apel de funcţie, etc. În limbajul C este permis: V1=V2= expresie; sau V1=V2=...Vi=Vn= expresie; Operatorul de atribuire - poate fi însoţit de un operator binar aritmetic sau logic pe biţi => operatori prescurtaţi sau operatori compuşi +=, -=, *=, /=, %=, >>=, <<=, &=, =, ^=, ~= - produc conciziune în scrierea expresiilor V op=(expresie) V = V op (expresie)

Exemple int a; a=10; // variabilei a i se atribuie valoarea 10 a+=10; // variabilei a i se atribuie vechea sa valoare la care s-a adăugat 10 i=i+1; // este echivalentă cu expresia i+=1; a*=(b/c)+d // este echivalentă cu expresia a=a*((b/c)+d) a&=0x00ff // este echivalentă cu expresia a=a&0x00ff //vezi operatori logici pe biţi (FF) 16 =(255) 10 sir[i*j]=sir[i*j]*5; // elementului de pe poziţia i*j al tabloului şir i se multiplică valoarea cu 5 sir [i*j]*=5; // această expresie este echivalentă cu cea de mai sus dar în //acest caz compilatorul crează un cod mai eficient // deoarece multiplicarea i*j se efectuează o singură dată

Operatori logici! - operator unar de negaţie logică && - şi logic - sau logic - folosiţi pentru construirea unor expresii relaţionale Negaţia logică (!) - are aceeaşi prioritate ca şi ceilalţi operatori unari, imediat mai mare decât a operatorilor multiplicativi. Expresia:! operand are valoarea 0 (fals) dacă operand 0 şi valoarea 1 (adevărat) dacă operand = 0 (fals). Şi logic (&&) - are prioritate mai mică decât a operatorilor de egalitate Expresia: E1 && E2 are valoarea 1 (adevărat) dacă E1 şi E2 au simultan valori diferite de zero şi are valoarea 0 (fals) dacă E1 şi/sau E2 au valoarea 0.

Sau logic ( ) - are prioritate imediat mai mică decât &&. Expresia: E1 E2 unde E1 şi E2 sunt expresii, are valorile: 1 (adevărat) dacă E1 şi/sau E2 0 0 (fals) dacă E1 şi E2 = 0 Exemple Operatorii logici (&& şi ) se evaluează de la stânga la dreapta. Dacă la evaluarea unei expresii se ajunge într-un punct în care se poate cunoaşte valoarea de adevăr a întregii expresii, atunci restul expresiei (aflată în dreapta) nu se mai evaluează. a&&b = 1 dacă a 0 şi b 0!a&&b = 1 dacă a = 0 şi b 0 (prima dată se evaluează!a) Fie atribuirea: d=c>='0'&&c<='9'; În acest caz d are valoarea 1 dacă c este cifră şi d are valoarea 0 dacă c nu este cifră.

Program exemplu: convertirea unui şir de cifre într-un număr întreg #include <stdio.h> int atoi(char s[]) int i,n=0; for(i=0;s[i]>='0'&&s[i]<='9';i++) n=10*n+(s[i]-'0'); return n; int main( ) char s[20]; int n; gets(s); printf("%d",atoi(s)); return 0; #include <stdio.h> double x; int main ( ) printf("introduceti o valoarea reala: "); scanf("%lf",&x); printf("x = %lg\t %d",x,(x>=500)&&(x<=800)); return 0;

Operatori de incrementare şi decrementare - operatori unari - operatorul ++ - operator de incrementare - măreşte valoarea operandului căruia i se aplică cu valoarea 1 - operatorul - operator de decrementare - micşorează valoarea operandului cu 1. Pot fi: i) prefixaţi, când sunt aplicaţi sub forma ++ operand sau operand - se foloseşte valoarea operandului la care s-a aplicat operatorul respectiv. ii) postfixaţi, când sunt aplicaţi sub forma operand++ sau operand - se foloseşte valoarea operandului de dinaintea aplicării operatorului. Exemplu a = 5; b = ++ a; b = a++ ; => a primeşte valoarea 6 şi apoi b ia valoarea 6. => variabila b ia valoarea 5 şi apoi lui a i se atribuie valoarea 6.

Operatorul de forţare a tipului (conversie implicită) Exemple - operator unar - este folosit la conversia valorii unui operand spre un alt tip - se aplică sub forma: (tip)(operand) int k; scanf("%d",&k); printf("\n k/k+1 = %.15g",(double)k/(k+1)); printf("\n k/k+1 = %.15g",(double)(k/(k+1))); int n; double f(float x)... f((float)(n));

Operatorul dimensiune (sizeof) - determină dimensiunea în octeţi a unei date sau a unui tip de date - se aplică sub forma: sizeof data sau sizeof(tip) data - nume de variabilă simplă, nume de tablou sau element de tablou, nume de structură sau de element al unei structuri tip - cuvânt cheie corespunzător unui tip de bază sau unui tip de utilizator Exemplu int i,d,x,y,z,v; long double sir[10]; d = sizeof(i); x = sizeof(sir[3]); y = sizeof(sir); z = sizeof(float); v = sizeof (char); printf("d= %d\nx= %d\ny= %d\nz= %d\nv= %d",d,x,y,z,v);

Operatorul adresă (&) - determină adresa de început a zonei de memorie alocată unei date - operator unar - numit şi operator de referenţiere - folosit la citirea valorilor datelor cu funcţia scanf şi de asemenea este folosită cu pointeri - se aplică sub forma: &nume unde nume este numele unei variabile simple, al unui tablou sau al unei structuri Exemplu int n, *pi; printf("introduceti o valoare intreaga: "); scanf("%d",&n); pi=&n; printf("valoarea citita este %d\nlocatie de memorie \nrezervata ei incepe la adresa %X",n,pi); Operatorii paranteză () - sunt de prioritate maximă - au ca efect impunerea ordinii de evaluare a expresiilor - nu pot fi folosiţi cu operatorii de incrementare şi decrementare şi cu operatorul adresă

Operatori condiţionali (? şi :) - permit construirea expresiilor condiţionale, adică a unor expresii a căror valoare depinde de valoarea unei alte expresii - se folosesc împreună în ordinea indicată de formatul expresiei condiţionale Expresia: E?E1:E0 are valoarea şi tipul lui E1 dacă E are valoarea 1 (adevărat), altfel are valoarea şi tipul lui E0 (dacă E = 0 (fals) ). Exemplu max = (a>b)?a:b; min=a<b?a:b; caz=x==y? egale : diferite ; if(a>b) max=a; else max=b;

Operatorul virgulă (,) - leagă două expresii în una singură - are cea mai mică prioritate dintre toţi operatorii limbajului C - se utilizează când într-un anumit punct al unui program este necesar să se realizeze un calcul complex exprimat în mai multe expresii - folosit si pentru separarea listei de argumente ale unei funcţii Expresia: exp1, exp2,..., expn este o expresie a cărui tip şi valoare coincide cu tipul şi valoarea ultimei expresii. Evaluarea expresiilor de genul celei de mai sus se evaluează de la stânga la dreapta. Program exemplu: tipărirea maximului a două valori absolute, folosind operatorii condiţionali şi operatorul virgulă. #include<stdio.h> int main () int a, b, c, d; scanf("%d%d",&a, &b); printf("a=%d\tb=%d\tmax( a, b )=%d",a,b,((c=a<0?-a:a),(d=b<0?-b:b), (c>d?c:d))); //c = a d = b tipăreşte c sau d return 0;

Operatorul * - se foloseşte pentru a accesa conţinutul unei zone de memorie definită prin adresa ei - se numeşte şi operator de dereferenţiere. Exemple de folosire a acestui operator vor fi date la discuţia pointerilor. Operatorii. si -> - utilizaţi pentru a accesa componentele structurilor - sunt de prioritate maximă. Exemple de utilizare a acestor operatori vor fi date la discuţia structurilor.

Operatori pe biţi - folosiţi pentru manipularea biţilor - utili pentru scrierea softului de sistem Limbajul C oferă următorii operatori pe biţi: operatorul ŞI logic pe biţi: & (AND) operatorul SAU logic pe biţi: (OR inclusiv) are valoare 1 când cel puţin unul dintre biţi este 1 operatorul SAU exclusiv: ^ (OR exclusiv) are valoare 1 când cei doi biţi sunt diferiţi şi zero în caz contrar operatorul de deplasare spre stânga: << (left shift) operatorul de deplasare spre dreapta: >> (right shift) operatorul de complementare faţă de 1: ~ O1 O2 O1&O2 O1 O2 O1^O2 ~O1 0 0 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 biţii de rang oarecare "i" ai celor doi operanzi cărora li se aplică operatorul logic pe biţi

Program exemplu: testarea operatorilor logici pe biţi #include <stdio.h> void binar(unsigned int v) long int i,s[100],j,r,c,dim; double val; j=0; do c=v/2; r=v%2; s[j]=r; j++; v=c; while(c>0); val=0; for(dim=j-1;dim>=0;dim--) val=10.0*val+(s[dim]); printf("%016.0lf",val); int main() long int a,b,c,i,o1,o2,rez; printf("program pentru testarea operatorilor logici pe biti:\n"); printf("introduceti o1: "); scanf("%ld",&o1); printf("introduceti o2: ");scanf("%ld",&o2); binar(o1);

printf("\to1= %ld\n",o1); binar(o2); printf("\to2= %ld\n",o2); //Testarea operatorului & rez=o1&o2; binar(rez); printf("\to1&o2= %ld\n",rez); //Testarea operatorului rez=o1 o2; binar(rez); printf("\to1 o2= %ld\n",rez); //Testarea operatorului ^ rez=o1^o2; binar(rez); printf("\to1^o2= %ld\n",rez); //Testarea operatorului << printf("\n"); binar(o1); printf("\to1= %d\n",o1); for(i=1;i<=3;i++) binar(o1<<i); printf("\to1<<%ld= %ld\n",i,o1 << i); //Testarea operatorului <<= printf("\n"); binar(o2); printf("\to2= %ld\n",o2); for(i=1;i<=3;i++) binar(o2<<=i); printf("\to2<<=%ld= %ld\n",i,o2);

//Testarea operatorului >> binar(o1); printf("\to1= %ld\n",o1); for(i=1;i<=3;i++) binar(o1>>i); printf("\to1>>%ld= %ld\n",i,o1 >> i); //Testarea operatorului ~ printf("\n"); binar(o1); printf("\to1= %ld\n",o1); b=~o1; binar(b); printf("\t~o1= %ld\n",b);

Exerciţiu Scrieţi un program care să transforme în binar valori de tip int (stocate pe 16 biţi) folosind o masca pentru biţi. (vezi Mark Burgess, C Programming Tutorial, Faculty of Engineering, Oslo College, http://www.iu.hio.no/~mark/ctutorial/c-tut-4.02.pdf, pag. 240-243) Ce se întâmplă dacă folosiţi ca şi mască de biţi valoarea lui 1 (unu)? Explicati!!! Pentru a înţelege mai uşor programul, urmăriţi figura de mai jos:

CURS 6 Instructiunile limbajului C Instructiuni - părţi de program care prin compilare produc coduri executabile - specifică ordinea şi modul în care vor fi efectuate calculele impuse de modul de prelucrare a datelor de intrare ale programului. structura secvenţială instrucţiuni compuse structura alternativă instrucţiunea if sau instrucţiunea if-else structura repetitivă instrucţiunile for, while sau do-while

structura selectivă instrucţiunea switch instrucţiunile: expresie, return, break, continue şi goto

Instrucţiunea expresie - se obţine adăugând terminatorul de instrucţiune ; după o expresie - poate fi concret o instrucţiune de atribuire sau o instrucţiune de apel de funcţie. Exemple pi=3.1415; getch(); clrscr(); h_max=v0*v0/2/g; y=sqrt(fabs(x-a)); i++; --contor; N=N0*exp(-lambda*t[i]); //instrucţiune de atribuire //apel de funcţie //apel de funcţie //atribuire //apel de funcţie şi atribuire //atribuire //atribuire //atribuire Instrucţiunea compusă - folosită la codificarea structurilor secvenţiale - constă dintr-o succesiune de instrucţiuni cuprinse între acolade Exemple t=a[i]; a[i]=a[i+1]; a[i+1]=t; k++; printf("\n%d:\t%d",k*k);

Instrucţiunile if şi if-else Instrucţiunea if - folosită pentru implementarea structurilor alternative cu decizie simplă Sintaxa if(expresie) instrucţiune; Executie - se evaluează expresie - dacă expresie este adevărată (are valoare diferită de zero) se execută instrucţiune, iar dacă expresie este falsă nu se execută instrucţiune şi se trece la instrucţiunea imediat următoare lui if. Instrucţiunea if-else - folosita pentru implementarea structurilor alternative cu decizie dublă Sintaxa if(expresie) instrucţiune_1; else instrucţiune_2; Executie - se evaluează expresie - dacă expresie este adevărată se execută instrucţiune_1 după care se trece la instrucţiunea imediat următoare lui if-else. Dacă expresie este falsă se execută instrucţiune_2 după care se trece la execuţia instrucţiunii care urmează după ifelse.

Tips Pentru simplificarea expresiilor: if(a!=0)... if(a)... si: if(a==0)... if(!a)... Exemple //rezolvarea ecuaţiei de gradul 1: ax+b=0... if(a) //în loc de if(a!=0) x=-b/a;... // Calculul solutiei unei ecuaţii neliniare //folosind metoda lui Newton... if(df==0) //sau if(!df) df=eps; x=x-f(x)/df;... //ordonarea crescătoare a unui şir de numere //(metoda bulelor)... if(a[i]>a[i+1]) t=a[i]; a[i]=a[i+1]; a[i]=t; ordonat=0;

Rezolvarea ecuaţiilor prin metoda înjumătăţirii intervalului... if(f(a)*f(c)<=0) if(f(c)==0) sol=c; else face pereche cu cel mai apropiat if else b=c; else a=c;... Discutati secventa:... if(n>0) if(i<n) s[i]=2*a[i]; else printf("\n n este negativ!");... Exerciţiu: Scrieţi un program care să calculeze impedanţa unui circuit de curent alternativ. Se vor citi valorile R, L şi C, precum şi tipul circuitului (serie sau paralel). În funcţie de valorile datelor de intrare se va calcula Z.

Instrucţiunea for - utilizată pentru implementarea unei structuri repetitive condiţionată anterior, atunci când se ştie apriori de câte ori se repetă blocul de calcul al acesteia Sintaxa for(exp1;exp2;exp3) Antet instrucţiune; Corp de instructiuni - se execută repetat cât timp este îndeplinită condiţia definită de exp2 exp1 - secvenţa de iniţializare a instrucţiunii for exp2 - defineşte condiţia de continuare a ciclului! Dacă exp2 are valoarea zero (este falsă) de la început, corpul instrucţiune nu se execută niciodată. exp3 - secvenţa de reiniţializare a instrucţiunii for

for(exp1;exp2;exp3) instrucţiune; Execuţie: 1. se execută secvenţa de iniţializare definită de către exp1. 2. se evaluează exp2. Dacă exp2 0 (adevărată) se execută corpul de instrucţiuni al instrucţiunii for. Dacă exp2=0 (falsă) se termină execuţia instrucţiunii for şi se trece la execuţia instrucţiunii imediat următoare lui for. 3. după execuţia corpului de instrucţiuni al instrucţiunii for se execută secvenţa de reiniţializare definită de exp3 şi se reia execuţia de la pasul 2.! exp1, exp2 şi exp3 pot fi vide caracterele ; trebuie să fie prezente şi în acest caz.

Exemple //Tiparirea tuturor literelor mari char c; for(c='a';c<='z';c++) putchar(c); //Tiparirea valorilor de la 0 la 100 din 2 in 2 int i; for(i=0;i<=100;i+=2) printf("%d ",i); //Adunarea elementelor unui sir de numere int n=4,j; float s,sir[4]=3.5,-2,8,14.1; for(s=0,j=0;j<n;j++) s=s+sir[j]; //Calculul lui x^n for(p=1,i=1;i<=fabs(n);i++) p=p*x; if(n<0) p=1/p; //Citirea elementelor unei matrici for(i=0;i<nl;i++) for(j=0;j<nc;j++) printf("a[%d,%d]= ",i,j); scanf("%f",&a[i][j]); //Calculul lui n! for(f=1,i=2;i<=n;i++) f*=i;

//Produsul a doua matrici #define m 2 #define n 3 #define p 3... for(i=0;i<m;i++) for(j=0;j<p;j++) C[i][j]=0; for(k=0;k<n;k++) C[i][j]=C[i][j]+A[i][k]*B[k][j]; for(i=0;i<m;i++) for(j=0;j<p;j++) printf("\nc[%d,%d]= %g",i,j,c[i][j]);...

Instrucţiunea while -folosita pentru implementarea structurilor repetitive condiţionate anterior. Sintaxa while(expresie ) instrucţiune; Antet Corp de instructiuni - se execută repetat cât timp expresie are valoare logica de adevar (diferita de zero) Execuţie: 1. Se evaluează expresie. Dacă expresie este adevărată (are valoare nenulă) se execută corpul instrucţiunii while şi se revine la evaluarea expresiei. 2. Când expresie devine falsă se trece la instrucţiunea imediat următoare instrucţiunii while.! Dacă expresie este falsă de la început, corpul de instrucţiuni al lui while nu se execută niciodată. Pentru a se evita ciclarea infinită a corpului de instrucţiuni al lui while, acesta trebuie să conţină în mod obligatoriu instrucţiuni prin care să se modifice termenii expresiei lui while.

Exemple Tiparirea valorilor de la 0 la 100, din 2 in 2 int i=0; while(i<=100) printf("%d ",i); i+=2; Sau echivalent: int i=0; while((i+=2)<=100) printf("%d ",i); //Afisarea valorilor functiei sinus din grad in grad de la 0 la 360 o, oprirea dupa afisarea a 24 linii pe ecran, cu evitarea opririi dupa afisarea valorii sin(0) int x; double pi=4*atan(1.0); x=-1; while(++x<=360) printf("\nsin(%d)= %.15f",x,sin(x*pi/180)); if(x%24==0&&x) //stop din afisare dupa 24 de linii si evitarea while(!_kbhit()); // opririi dupa afisarea valorii sin(0)

//Citirea dintr-un fisier, a cate 4 valori simultan, pana se ajunge la sfarsitul fisierului FILE *fin; float m,x,y,z; int n=0; fin=fopen("d:\\user\\c\\test.dat","r"); while(!feof(fin)) if(fscanf(fin,"%f%f%f%f",&m,&x,&y,&z)==4) n++; printf("\n%g\t%g\t%g\t%g",m,x,y,z); fclose(fin); printf("\nn= %d",n);

Instrucţiunea do-while - utilizată pentru implementarea structurilor repetitive condiţionate posterior. Sintaxa do instrucţiune; while(expresie ) Execuţie: 1. Se execută instructiune. 2. Se evaluează expresie. Dacă expresie este adevărată ( 0 ) se revine la pasul 1, altfel se trece la instrucţiunea imediat următoare lui do-while.! Corpul de instrucţiuni al lui do-while se execută cel puţin o dată, chiar dacă expresie este falsă de la început. Pentru a se evita ciclarea infinită a corpului de instrucţiuni al lui do-while, acesta trebuie să conţină în mod obligatoriu instrucţiuni prin care să se modifice termenii expresiei.

Exemple //Metoda bisectiei... do c=(inf+sup)/2.0; if((*pf)(c)==0) return c; if((*pf)(inf)*(*pf)(c)<0) sup=c; else inf=c; while(fabs((*pf)(c)) >= eps);

//Metoda Newton... float newton(float (*)(float), float xv, float er) float xn,der,eps=5e-4; //x nou =x vechi -f(x vechi )/f'(x vechi ) xn=xv; do xv=xn; der=(f(xv+eps)-f(xv))/eps; if(der= =0.0) der=eps; xn=xv-f(xv)/der; while(fabs(f(xn))>er); return xn;...

Instrucţiunea switch - folosită pentru codificarea structurii selective (o generalizare a structurii alternative) - echivalentă cu mai multe instrucţiuni if imbricate - are avantajul că duce la creşterea lizibilităţii şi calităţii programului http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm Optionala! Sintaxa switch (expresie) case c1: instrucţiune_1; break; case c2: instrucţiune_2; break;... case cn: instrucţiune_n; break; default: instrucţiune; break; c1, c2,..., cn - etichete case - reprezintă valori constante instrucţiune_1, instrucţiune_2,..., instrucţiune_n şi instrucţiune - instrucţiuni simple sau compuse. break; - instrucţiune care are ca scop întreruperea instrucţiunii switch sau întreruperea unui ciclu. - la întâlnirea acesteia se iese imediat din switch şi execuţia programului continuă cu instrucţiunea imediat

Execuţie: 1.se evaluează expresie; fie v valoarea acesteia. 2.se compară v cu valorile constantelor c1, c2,..., cn. Dacă v este egală cu una dintre aceste constante, de exemplu ci, atunci se execută instrucţiune_i şi apoi se trece la instrucţiunea de după switch. 3. Dacă v nu coincide cu nici una dintre constantele ci se execută instrucţiunea de după default (dacă aceasta există) după care se continuă la instrucţiunea de după switch. Instrucţiunea switch este echivalentă cu o succesiune de mai multe instrucţiuni if imbricate: if(expresie==c1) instrucţiune_1 else if(expresie==c2) instrucţiune_2 else if...... else if(expresie==cn) instrucţiune_n else instrucţiune switch (expresie) case c1: instrucţiune_1; break; case c2: instrucţiune_2; break;... case cn: instrucţiune_n; break; default: instrucţiune; break;

Exemple Meniu pentru alegerea rezolvării unui sistem de ecuaţii, calculul unui determinant sau determinarea inversei unei matrici #include<stdio.h> int main() char optiune; printf("\t\tmeniu:\ns)istem\t\td)eterminant\ti)nversa\n"); optiune=getchar(); switch(optiune) case 'S': printf("ati ales rezolvarea unui sistem de ecuatii"); break; case 'D': printf("ati ales calculul unui determinant"); break; case 'I': printf("ati ales determinarea inversei unei matrici"); break; default: printf("optiune ilegala!");

Simularea unui calculator de operaţii simple #include<stdio.h> #include<stdlib.h> #include<conio.h> int main() char oper; float op1, op2, rez; printf("tastati o expresie de forma: operand1 operatie operand2: \n"); if(scanf("%f%c%f",&op1,&oper,&op2)!=3) printf("\nexpresie eronata!"); exit(1); switch(oper) case '+': rez=op1+op2; break; case '-': rez=op1-op2; break; case '*': rez=op1*op2; break;

case '/': if(op2==0) printf("eroare! Divizor nul."); rez=0; else rez=op1/op2; break; default: printf("operator ilegal!"); rez=0; printf("\n%g %c %g = %g",op1,oper,op2,rez); while(!_kbhit()); return 0;

Exerciţiu: Folosiţi instrucţiunea switch pentru a modela următorul experiment: generaţi 100 de valori aleatoare între 1 şi 5. Tipăriţi un grafic de forma alăturată, în funcţie de apariţiile fiecărei valori generate.

Instrucţiunile break şi continue break - întrerupe execuţia unui ciclu (for, while sau do-while) sau a unei instrucţiuni switch - se foloseşte pentru ieşirea imediată, fără testarea unei anumite condiţii, dintr-un ciclu şi renunţarea la execuţia în continuare a acestuia Sintaxa break; continue - abandonează iteraţia curentă a ciclului şi reia ciclul cu iteraţia următoare - se foloseşte numai în interiorul instrucţiunilor for, while sau dowhile Sintaxa continue;

Exemple Folosirea instrucţiunilor break şi continue #include <stdio.h> #include <conio.h> int main() int k; for( k=0;k<6;k++) if(k==3) break; // se abandoneaza instructiunea for printf("in ciclul for cu *break*, k are acum valoarea %d\n",k); for(k=0;k<6;k++) if(k==3) continue; // se abandoneaza iteratia corespunzatoare lui k=3 printf("in ciclul for cu *continue*, k are acum valoarea %d\n",k); while(!_kbhit()); return 0;

Funcţia exit - folosită pentru evitarea nivelelor mari de imbricare ale instrucţiunilor if sau if-else. - prototipul funcţiei este: void exit (int stare) - se găseşte în <stdlib.h> şi în <process.h> -are rolul de a întrerupe execuţia programului şi închiderea tuturor fişierelor deschise. Stare defineşte starea programului în momentul apelului: valoarea 0 (zero) pentru stare corespunde unei întreruperi normale, fără eroare a programului o valoarea diferită de zero defineşte o întrerupere cu eroare a programului.

Exemple Se citeşte o valoare, se testează dacă ea aparţine intervalului [1,10] şi se calculează pătratul acestei valori #include <stdio.h> #include <stdlib.h> #include <conio.h> int main() int v; printf("introduceti o valoare in intervalul [1,10]: "); if(scanf("%d",&v)!=1) printf("valoare incorecta"); while(!_kbhit()); exit(1); if((v<1) (v>10)) puts("eroare! v este in afara intervalului"); else printf("%d^2= %d",v,v*v); while(!_kbhit()); return 0;

Instrucţiunea goto - transfera controlul execuţiei programului la o instrucţiune etichetată - poate fi utilă doar atunci când se doreşte ieşirea din mai multe instrucţiuni if imbricate Sintaxa goto eticheta; etichetă - şir de caractere urmat de caracterul : şi care precede o anumită instrucţiune

Exemple Găsirea unui element comun a două şiruri #include <stdio.h> #include <stdlib.h> #include <conio.h> int main() int n,i,j,a[10],b[3]=0,5,10; //Cauta in sirul a un element al sirului b. //Daca un astfel de element este gasit, cautarea inceteaza printf("dimensiunea primului sir: "); scanf("%d",&n); printf("introduceti elementele primului sir\n"); for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<3;i++) for(j=0;j<n;j++) if(b[i]==a[j]) goto gasit; printf("\nnu s-a gasit nici un element comun al celor doua siruri"); while(!_kbhit()); exit(0); gasit: printf("\ns-a gasit elementul comun: %d",b[i]); while(!_kbhit()); return 0;

CURS 7 Pointeri - tipuri speciale variabile sau constante care au ca valori adrese ale unor alte variabile sau constante (adrese ale unor locaţii de memorie) - permit calcule cu adrese - specifice limbajelor de asamblare - sunt folosiţi în scopul scrierii unor programe mai eficiente atât din punctul de vedere al timpului de execuţie cât şi din punctul de vedere al utilizării resurselor hard, în mod concret al utilizării memoriei computerelor. - sunt în mod special utili la alocarea dinamică a memoriei şi la apelul prin referinţă.

Pointerii - păstrează adresa începutului locaţiei în care este stocată o anumită valoare. - pachet compus din două părţi: - pointerul însuşi - care are ca valoare adresa primului octet al locaţiei de memorie în care este stocată o variabilă (sau constantă) - tipul valorii stocate în locaţia de memorie la începutul căreia pointează - spune computerului câtă memorie să citească după adresa la care pointează şi cum să o interpreteze

Limbajul C foloseşte pointerii în trei moduri: a) pentru a crea structuri dinamice de date construite din blocuri de memorie b) pentru a opera cu parametrii pasaţi funcţiilor la apelul acestora c) pentru a accesa informaţia stocată în tablouri În cazul unui pointer la o funcţie, tipul pointerului va fi tipul de dată returnat de către funcţie, iar valoarea sa va fi adresa la care începe codul funcţiei respective Pentru lucrul cu pointeri, limbajul C oferă doi operatori: - & - &x înseamnă adresa variabilei x (de fapt adresa primului octet al locaţiei de memorie în care este stocată variabila x) - * - *p1 valoarea stocată în locaţie de memorie la care pointează pointerul p1.

Declararea şi iniţializarea pointerilor Declarare tip *nume_pointer; sau tip* nume_pointer; tip - tip de date de bază sau tip utilizator nume_pointer - identificator folosit pentru pointerul care se declară Exemple float *pf; //pf poate conţine adrese la care se află memorate date de tip float int *pi; //pi poate conţine adrese la care se află memorate date de tip int char* pc; //pc poate conţine adrese la care se află memorate date de tip char struct agenda char nume[20]; char tel[15]; ; struct agenda *psa; //psa este un pointer la date de tip structură agenda.

Iniţializare - precizarea adresei unui obiect definit în memorie. - p - numele unui pointer => *p reprezintă valoarea de la adresa la care "pointează" pointerul p.

CURS 8 Managementul fişierelor în C Fisier - colecţie de date, păstrată pe un dispozitiv periferic (magnetic sau optic) - succesiune de caractere, de cuvinte, linii sau pagini ale unui document de tip text - înregistrări ale unei baze de date - pixelii unei imagini grafice - etc. Operatii - deschidere, închidere, creare, citirea datelor, adăugarea de înregistrări, poziţionarea pe o anumită înregistrare, ştergerea fişierelor Accesare - de la începutul sau de la sfârşitul fişierului - dintr-un loc oarecare din fişier. 1. Pentru prevenirea folosirii necorespunzătoare a unui fişier, sistemul de operare instalat pe calculator trebuie să fie înştiinţat despre scopul în care este deschis fişierul şi despre operaţiile care vor fi efectuate (citire, scriere, adăugare) asupra datelor. 2. La încheierea operaţiunilor care se efectuează asupra datelor dintr-un fişier acesta trebuie închis deoarece în caz contrar, sistemul de operare nu poate actualiza datele referitoare la acel fişier (dimensiune, data ultimei accesări, etc.).

Tipuri de fişiere 1. fişiere text stochează datele ca o secvenţă de caractere alfanumerice conţinutul acestor fişiere este lizibil şi poate fi editat direct cu ajutorul unui editor de texte. sunt organizate pe rânduri, fiecare rând fiind delimitat de caracterul de sfârşit de rând (EOL) sunt citite caracter cu caracter => funcţiile pentru citirea şi scrierea lor vor fi aproape identice cu cele folosite pentru citirea de la tastatură şi respectiv scrierea pe monitor. sunt procesate secvenţial => un fişier text se deschide de obicei numai pentru un anumit tip de operaţie la un moment dat (citire, scriere sau adăugare) 2. fişiere binare pot să conţină orice tip de date, codate într-o formă binară, în secvenţe de bytes pot conţine orice fel de informaţie : text formatat, imagini, sunete, etc. diferă de fişierele text în două puncte esenţiale: fiecare octet de date este transferat pe sau de pe disc neprocesat interpretarea lor este lăsată pe seama programatorului (pot fi citite sau scrise în orice mod dorit de către programator) pot fi procesate secvenţial sau aleator sunt accesate mai rapid decât fişierele text sunt înţelese numai de programe scrise special să lucreze cu astfel de fişere (de ex. bazele de date)

Exemple

Declararea fişierelor FILE *df; FILE - cuvânt cheie care semnifică o structură de date de tip fişier df - descriptor de fişier - pointer spre tipul FILE. Exemple FILE *f1, *fin, *frez, *ftext; Deschiderea fişierelor Funcţia fopen: -> #include <fstream> FILE *fopen(const char *cale, const char *mod); cale - pointer spre un şir de caractere care defineşte calea spre fişierul care se deschide mod - pointer spre un şir de caractere care defineşte modul de prelucrare a fişierului după deschiderea acestuia. cale = reprezintă orice nume valid de fişier, eventual precedat de calea de directoare până la acesta, cuprins între ghilimele. Dacă trebuie specificată calea până la respectivul fişier, atunci directoarele căii vor fi separate prin \\ ca de exemplu: "d:\\input.txt". fopen - returneaza: in caz de succes - un pointer la fisier in caz de eroare pointerul NULL

mod = atributul fişierului - poate avea valorile "r" "w" "a" "rb" "wb" "r+b" - - fişierul se deschide pentru citire - fişierul se deschide pentru scriere - fişierul se deschide pentru adăugare de înregistrări - nu permite repozitionarea in fisier - fişierul se deschide pentru citire binară - fişierul se deschide pentru scriere binară caz în care fişierul se deschide pentru citire şi scriere binară 1. Un fişier inexistent, deschis în modul "w" va fi creat (dacă este posibil) în momentul deschiderii, iar un fişier existent deschis în modul "w" va fi creat din nou, ceea ce înseamnă că vechiul său conţinut se va şterge. 2. Deschiderea în modul "w" va eşua dacă sistemul nu poate deschide fişierul -disc plin, disc protejat la scriere, nu exista drepturi de acces la fisier 3. Deschiderea în modul "r" eşuează daca: fişierul nu există, fişierul este protejat într-un anume fel 4. Unui fişier inexistent deschis în modul "r" i se va asocia pointerul NULL. 5. La deschiderea în modul "a", dacă fişierul există, poziţionarea se face la sfârşitul fişierului, iar dacă nu există atunci el va fi creat. 6. Deschiderea în modul "a" poate eşua în aceleaşi cazuri în care eşuează deschiderea în modul "w".

Exemple FILE *f, *fin; f=fopen("notean1.dat","r"); /* se deschide fisierul notean1.dat, din directorul curent, in modul citire.*/ fin=fopen("c:\\soft\\config.ini","w"); // se deschide fisierul c:\soft\config.ini in modul scriere. Folosirea pointerului NULL poate fi folosit pentru testarea posibilităţii deschiderii unui fişier if((f=fopen("fis_test","r"))==null) printf("eroare la deschiderea fisierului!"); sau : f=fopen("fis_test","r"); if(!f) printf("eroare la deschiderea fisierului!"); Închiderea fişierelor int fclose(file *pf); pf - pointerul spre tipul FILE - valoarea lui a fost determinată de către funcţia fopen la deschiderea fişierului. - returnează valoarea 0 la închidere reuşită şi valoarea -1 în caz de eroare.

Exemplu 1. fclose(fin); 2. // Testarea închiderii reusite a unui fisier // se poate intampla atunci cand pointerul fin nu a fost initializat if(fclose(fin)) //sau: if(fclose(fin)!=0) printf("fisierul nu exista! "); exit(0);

Citirea şi scrierea fişierelor fscanf, fprintf, fgetc, fputc, fgets, fptus, fread, fwrite. fscanf(*pf, "control", &par1, &par2,..., &parn); fprintf(*pf,"control",par1, par2,..., parn); Exemple FILE *fin, *fout; fin=fopen("test.inp","r"); fout=fopen("test.out","w");... fscanf(fin,"%d",&n); fprintf(fout,"n^2= %d",n*n);... După fiecare caracter citit, poziţia în fişier avansează cu o unitate.

Funcţiile fread şi fwrite - folosite pentru citirea/scrierea fişierelor binare. Funcţia fwrite - scrie un bloc de memorie în fişierul specificat Functia fread - citeşte date dintr-un fişier binar şi le pune într-un bloc de memorie. Apelul funcţiei fread: fread( ptr, size, n, f ) ptr - pointer la blocul de memorie în care se vor prelua datele citite din fişier size - lungimea în octeţi a blocului citit n - numărul de itemi citiţi f - pointer la fişierul din care se face citirea Apelul funcţiei fwrite : fwrite( ptr, size, n, f ) ptr - pointerul la blocul de date care va fi scris în fişierul binar Numărul de octeţi scrişi este n*size.

Funcţiile fgetc şi fputc -folosite pentru citirea, respectiv scrierea unui caracter dintr-un/într-un fişier (stream) - returnează caracterul citit sau scris în caz de succes şi EOF în caz de eroare. Prototipuri: fgetc(file *stream); fputc(int c, FILE *stream); EOF - caracter constant care indică sfârşitul de fişier. - citirea lui se testeaza cu funcţia feof(f) feof returnează: - o valoare nenulă dacă a fost detectat caracterul EOF - zero dacă nu a fost citit caracterul EOF. Funcţiile fgets şi fputs - folosite pentru preluarea într-un şir, respectiv scrierea într-un şir a unor caractere dintr-un/întrun fişier (stream). Prototipuri: char *fgets(char *s, int n, FILE *stream); int fputs(const char *s, FILE *stream); Funcţia fgets - preia într-un şir n-1 caractere dintr-un fişier - returnează şirul la care pointează s, respectiv pointerul NULL în caz de eroarea sau la întâlnirea caracterului EOF. Funcţia fputs - scrie un şir de caractere într-un fişier - returnează ultimul caracter scris, respectiv EOF în caz de eroare.

Exemple //Citirea unui rand dintr-un fisier char sir[100]; FILE *f; f=fopen("d:\\test.inp","r"); fgets(sir,100,f); printf("sirul citit este: %s",sir); fclose(f); // Tiparirea la imprimanta (functioneaza pentru o imprimanta // conectata la portul LPT1 FILE = *prt; if((prt=fopen("lpt1","w"))==null) printf("\a\nprinter nedisponibil"); exit(0); else fprintf(prt,"test tiparire la imprimanta!");

Poziţionarea într-un fişier Funcţiile ftell şi fseek ftell - determină poziţia curentă a capului de citire/scriere - are prototipul: long ftell(file *pf) - returnează o valoare care reprezintă deplasamentul în octeţi al poziţiei capului de citire/scriere faţă de începutul fişierului. Fseek - permite poziţionarea aleatoare într-un fişier - returnează 0 în caz de succes (poziţionare corectă a cursorului în fişier) - prototipul funcţiei: int fseek(file *pf, long deplasament, int origine); pf - pointer spre tipul FILE - defineşte fişierul în care se face poziţionarea capului de citire/scriere - valoarea sa este determinată la deschiderea fişierului. Deplasament - defineşte numărul de octeţi peste care se va deplasa capul de citire/scriere al discului - poate fi o valoare întreagă pozitivă sau negativă. Origine - determină locul din care se face deplasarea capului - poate avea valorile: 0 -> deplasare de la inceputul fisierului 1 -> deplasare de la pozitia curenta a capului de citire/scriere a fisierului 2 -> (deplasare de la sfârşitul fişierului)

Ştergerea unui fişier - se foloseşte funcţia unlink - prototip: int unlink(const char *cale); cale - specifică fişierul care va fi şters. Funcţia nu poate şterge fişierele read-only sau fişierele deschise şi returnează valoarea 0 la ştergere reuşită, respectiv -1 în caz de eroare. Program exemplu: crearea unui fişier text cu 5 linii #include <stdio.h> #include<string.h> #include <fstream> int main( ) FILE *fp; char text[25]; int i; fp = fopen("d:\\flinii.txt","w"); strcpy(text,"acesta este randul: "); for (i=1;i<=5;i++) fprintf(fp,"%s%d\n",text,i); fclose(fp); return 0;

Program exemplu: determinarea numărului de caractere dintr-un fişier (se numără şi caracterele de rând nou) #include <stdio.h> #include <stdlib.h> #include <fstream> int main( ) FILE *fp; char c; int n=0; /*Se deschide fisierul de intrare, testandu-se deschiderea corecta a acestuia. Daca deschiderea fisierului nu se poate realiza (fisier inexistent) functia fopen returneaza pointerul NULL*/ if((fp = fopen("d:\\flinii.txt","r"))==null) printf("eroare la deschiderea fisierului!"); exit(1); while(fscanf(fp,"%c",&c)==1) n++; fclose(fp); printf("in fisier sunt %d caractere.",n); return 0; Exerciţiu Modificaţi programul de mai sus astfel încât caracterele de rând nou să nu fie numărate.

Program exemplu: interogarea utilizatorului în cazul suprascrierii unui fişier deschis în modul "w".

#include<stdio.h> #include<conio.h> int main() FILE *fout; char nfout[20]; char opt; int OK; do printf("\nintroduceti numele fisierului de iesire: " ); gets(nfout) ; fout=fopen(nfout,"r") ; if(fout!=null) fclose(fout); printf("\afisierul exista! \nsuprascrieti acest fisier? (D/N): "); opt=getche(); switch(opt) case 'D': OK=1; fout=fopen(nfout,"w"); break; default: OK=0; else fclose(fout); OK=1; fout=fopen(nfout,"w"); while((ok!=1)&&fout); if(opt=='d') fprintf(fout,"suprascriere in fisier!"); else fprintf(fout,"scriere in fisier!"); printf("\nterminat!"); fclose(fout); return 0;

Program exemplu: folosirea funcţiei fgets pentru tipărirea unui fişier pe ecran #include<stdio.h> #include<conio.h> int main() char *c, rand[100],nf[25]; FILE *f; printf("introduceti numele fisierului: "); scanf("%s",nf); f=fopen(nf,"r"); do c=fgets(rand,100,f); //functia fgets returneaza sirul la care pointeaza //pointerul rand. if(c) printf("%s",rand); while(c); fclose(f); while(!_kbhit()); return 0;

Program exemplu: folosirea funcţiilor fwrite şi fread //Testarea functiilor fwrite si fread #include <stdio.h> #include<stdlib.h> #include <string.h> struct bd char n[20],p[20],tel[20]; int v; int s; ; void main() FILE *fin; struct bd ag; char sir[20]; int *pi,*pu; if((fin=fopen("c:\\temp\\bd.dat","wb"))==null) printf("eroare la deschiderea fisierului!"); exit(1); După rularea acestui program se obţine fişierul bd.dat în directorul d:\c. Deschizând fişierul bd.dat cu un utilitar de gestiune a fişierelor, acesta va arăta sub forma: strcpy(ag.n,"popescu"); strcpy(ag.p,"georgel"); strcpy(ag.tel,"0445111222"); ag.v=40; ag.s=1; fwrite(&ag,sizeof(ag),1,fin); fclose(fin); fin=fopen("c:\\temp\\bd.dat","rb"); fseek(fin,0,0); printf("datele din fisier:\n\n"); fread(sir,sizeof(ag.n),1,fin); printf("nume: \t\t%s\n",sir); fread(sir,sizeof(ag.p),1,fin); printf("prenume: \t%s\n",sir); fread(sir,sizeof(ag.tel),1,fin); printf("telefon: \t%s\n",sir); fread(pi,sizeof(ag.v),1,fin); printf("varsta: \t%d\n",*pi); fread(pu,sizeof(ag.s),1,fin); printf("stare civila: \t%d\n",*pu); Pe ecran, va fi tipărit:

Program exemplu: calculul coordonatelor centrului de masă al unui sistem de particule ale căror date se găsesc într-un fişier #include <stdio.h> #include <stdlib.h> #include <conio.h> FILE *fin,*fout; float m,x,y,z,sm,smx,smy,smz,xc,yc,zc; int i; char opt; void scrie_date() fout=fopen("d:\\bc\\centru.rez","w"); fprintf(fout,"nr. particule: %d",i); fprintf(fout,"\nsm= %g \nsmx= %g smy= %g smz= %g ",sm,smx,smy,smz); fprintf(fout,"\nxc= %g\t yc=%g\t zc=%g\n",xc,yc,zc); fclose(fout); int main() sm=smx=smy=smz=0; i=0; if((fin=fopen("d:\\bc\\centru.dat","r"))==null) printf("\nfisierul nu poate fi deschis\a\a\a"); while(!feof(fin)) if(fscanf(fin,"%f%f%f%f",&m,&x,&y,&z)==4) sm+=m; smx+=m*x; smy+=m*y; smz+=m*z; i++;

xc=smx/sm; yc=smy/sm; zc=smz/sm; fclose(fin); if((fout=fopen("d:\\bc\\centru.rez","r"))!=null) printf("\natentie! Fisierul de output exista!"); printf("\ncontinuati? (Y/N)"); opt=getch(); fclose(fout); if((opt=='y') (opt=='y') ) scrie_date(); else printf("\nexecutie terminata!"); exit(1); else scrie_date(); printf("\nterminat!"); return 0; Bibliografie suplimentară http://www.codingunit.com/c-tutorial-binary-file-io

Parametrii liniei de comandă În C este posibilă apelarea programelor şi transferarea parametrilor acestora în linia de comandă. Exemplu: suma 3.8 9.2 Funcţia main trebuie să fie definită sub următoarea formă: int main(int argc, char* argv[])... argc - specifică numărul de argumente, adică numărul parametrilor din linia de comandă cu care a fost apelat programul. argv[] - vector de pointeri la şiruri de caractere care constituie argumentele cu care este apelat programul; fiecare element al vectorului de pointeri pointează la un şir (de fapt la primul caracter al şirului). Lista de pointeri în argv este terminată întotdeauna cu pointerul NULL, astfel încât argv[argc] este NULL. Prin convenţie, argv[0] este numele aplicaţiei (calea completă către programul executabil), iar cel de-al doilea este primul argument furnizat de către utilizator. Dacă argc are valoarea 1 atunci nu există parametri în linia de comandă, după numele programului.

Program exemplu: Tipărirea numelui programului şi a parametrilor săi din linia de comandă #include <stdio.h> int main(int argc, char *argv[]) int i; printf("numele programului este: %s\n",argv[0]); //Numele programului este primul pointer din tabloul de pointeri argv[] printf("programul are %d parametri, si acestia sunt:\n",argc-1); //Numele programului nu este considerat explicit ca parametru for (i=1; i<argc; i++) printf("%s%s",argv[i],(i < argc- 1)? " " : ""); //Se tipareste caracterul spatiu dupa fiecare parametru daca acel //parametru nu este ultimul return 0; Executabilul se lansează în execuţie într-o fereastră DOS (Start -> Run -> cmd) sub forma:

Program exemplu: suma a două numere introduse în linia de comandă #include <stdio.h> #include <process.h> #include <math.h> main(int argc,char *argv[]) double n1,n2,s; int n=argc; if(n<3) printf("\nparametri insuficienti!"); exit(1); else if(n>3) printf("prea multi parametri!"); exit(1); else n1=atof(argv[1]); //atof face conversia de la string la double n2=atof(argv[2]); s=n1+n2; printf("\nsuma numerelor introduse este %lf",s); return 0; Exercitiu Scrieti un program cu parametri in linia de comanda, pentru concatenarea a doua fisiere.

CURS 9 Tipuri de date derivate - tipuri definite de către utilizator - bazate pe tipurile de date de bază - permit prelucrarea globală a unor grupe complexe de date Tipul enumerare - permite folosirea unor nume sugestive pentru valori numerice. Exemple 1. roşu, oranj, galben, verde albastru, indigo şi violet pot fi asociate valorilor numerice 1, 2, 3, 4, 5, 6, 7. enum nume nume_0, nume_1,..., nume_k data_1, data_2,..., data_n; enum culoare Rosu=1,Oranj, Galben, Verde, Albastru, Indigo, Violet cul; cul=galben; printf( %d,cul); 3 enum colors rosu=650, oranj=590, galben=570, verde=510, albastru=475, indigo=445, violet=400 col;

Tipul reuniune - variabilă care poate păstra obiecte de diferite tipuri şi dimensiuni. - permite păstrarea într-o zonă de memorie a unor date de tipuri diferite, lucru care duce la posibilitatea reutilizării unor zone de memorie şi deci la economisirea memoriei Declarare union nume lista de declaraţii; data_1, data_2,..., data_n; Exemplu union a int x,y; double r; char fill; cerc; Pentru date de diferite tipuri union se alocă o zonă de memorie necesară pentru a păstra data care necesită un număr maxim de octeţi. În exemplul de mai sus, pentru orice dată de tip union a se alocă 8 octeţi. Accesul membrilor reuniunii: - prin nume calificate - prin intermediul pointerilor : cerc.x cerc.y cerc.r cerc.fill cerc *p,c1; p=&c1; p->x p->y p->r p->fill Membrii unei structuri sunt stocaţi la aceeaşi adresă, aşadar, în mod evident, un singur membru poate fi stocat la un moment dat. O reuniune poate păstra oricare dintre membrii săi, dar la momente diferite de timp. se recomandă utilizarea cu atenţie a datelor de acest tip

Tipul structură - un set de variabile, nu neapărat de acelaşi tip, grupate împreună sub un singur nume, conform unei ierarhii. - permite ca un grup de variabile aflate într-o anumită legătură să fie tratate ca o unitate şi nu ca entităţi separate. Declararea structurilor: struct nume lista_de_declaratii; data_1, data_2,..., data_n; struct nume lista de declaraţii; ; struct nume data_1, data_2,..., data_n;

Exemple Explicaţi output-ul programului de mai jos: #include <stdio.h> int main() union a int x,y; double r; char fill; cerc, *p; cerc.y=66; printf("y= %d",cerc.y); printf("\nfill: %c",cerc.fill); cerc.y=67; printf("\nx= %d",cerc.x); printf("\nfill: %c",cerc.fill); printf("\nr: %lf",cerc.r); printf("\nr: %d",cerc.r); return 0; Output:

Tipul structură - set de variabile, nu neapărat de acelaşi tip, grupate împreună sub un singur nume, conform unei ierarhii - permit ca un grup de variabile aflate într-o anumită legătură să fie tratate ca o unitate şi nu ca entităţi separate. Tablourile sunt structuri particulare în care toate elementele structurii sunt de acelaşi tip. Declarare: struct nume lista_de_declaratii; data_1, data_2,..., data_n; struct nume lista de declaraţii; ; struct nume data_1, data_2,..., data_n; nume - numele tipului introdus prin această structură data_1, data_2,..., data_n - date de tipul structură nume typedef struct nume lista de declaraţii; ; nume data_1, data_2,..., data_n; membrii structurii

Exemple struct coord int x; int y; poz; Initializarea structurii: struct coord poz=30,30; typedef struct nucleu int nrp; int nrn; ; nucleu C12=6,6,C13; C13.nrp=6; C13.nrn=7; O structură poate avea ca mebru o altă structură. Având declarată structura coord, o structură dreptunghi poate fi declarată sub forma: struct drpt struct coord pss; struct coord pdj; dr; struct data int zi; enum luniian=1, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec luna; int an; ; struct date_personale char nume[30], prenume [30], adresa[50]; struct data data_nasterii; long cod; int varsta; enum stare Necasatorit, Casatorit stare_civ; int nr_copii; ; struct date_personale staff_ubb[2000], staff_ffiz[50], angajat;

Accesul la elementele structurilor - se foloseste operatorul. (operator membru de structură) poz.x=20; staff_ubb[7].data_nasterii.an=1950; strcpy(angajat.data_nasterii.luna,"apr"); Transferarea structurilor catre funcţii - se folosesc pointeri Exemplu Fie o funcţie care prelucrează structura angajat. O astfel de funcţie va fi apelată sub forma: f(&angajat) Antetul funcţiei f va fi: void f(struct date_personale *psdp) În corpul lui f nu se pot utiliza nume calificate de forma: angajat.nume, angajat.data_nasterii.zi, etc. Accesul elementelor structurii se face prin intermediul pointerului, sub forma: (*psdp).nume, (*psdp).data_nasterii.zi Eventual, în loc de construcţia (*psdp). se pot folosi construcţii de forma: psdp->nume, psdp->data_nasterii.zi, etc. Este posibila copierea unei întregi structuri într-o singură instrucţiune: angajat=staff_ubb[2];

Exemple Exemple structuri

Y CURS 10 Regresia liniară - aproximarea unei functii tabelate cu o functie analitica de gradul 1, prin metoda celor mai mici patrate 1310 1300 1290 1280 1270 1260 1250 1240 1230 1220 y = -78.545x + 1313.4 R² = 0.9823 0 0.2 0.4 0.6 0.8 1 1.2 X

Fie o funcţie: f:[a,b], [a,b] pentru care este cunoscut un număr discret de valori y i într-un număr de puncte de reţea x i [a,b]: Y x i f(x i )=y i, i 1,n In general, valorile y i sunt afectate de erori de măsură sau de erori de calcul y i 0.10 1305.00 0.20 1295.00 0.30 1293.00 0.40 1283.00 0.50 1270.00 0.60 1267.00 0.70 1260.00 0.80 1256.00 0.90 1243.00 1.00 1230.00 1310 1300 1290 1280 1270 1260 1250 1240 1230 1220 Cum alegem functia model? 0 0.2 0.4 0.6 0.8 1 1.2 X Ce vrem? Aproximarea acestei funcţii tabelate f cu o funcţie "model": α j - parametri ai funcţiei model De ce? F(x i; α j ) - permite cunoasterea valorii in orice punct x x i - poate fi derivata, integrata sau folosite in alte calcule F trebuie să fie determinată de fenomenul fizic modelat F se va alege dintr-o clasă convenabilă de funcţii care să ofere simplitate şi eficienţă în prelucrări ulterioare

α j => F Cum determinam parametrii funcţiei model? Se defineşte o funcţională care să reflecte gradul în care funcţia F aproximează funcţia tabelată f. Distanţa dintre funcţia tabelată şi funcţia model: Cazuri: Interpolare: graficul functiei F trece prin toate punctele (x i,y i ) Fitare: graficul functiei F nu trece neaparat prin punctele (x i,y i )

Fitare - se minimizează suma abaterilor pătratice ale funcţiei model faţă de funcţia tabelată: n 2 i i j i1 S y F(x ; ) Condiţiile de obţinere a parametrilor α j : S j 0; j 1, k = regresie (ajustare) prin metoda celor mai mici pătrate

Regresia liniară Funcţia model = funcţie de gradul 1: F=ax+b F=F(x i, α j ) j=2 Funcţionala S: n i1 S y (ax b) i i 2 Condiţiile de obţinere a parametrilor α j (a şi b): S a S b 0 0 n 2y i (axi b) ( x i ) 0 i1 n 21 y i (axi b) 0 i1 n n n 2 2xiy i 2axi 2bxi 0 i1 i1 i1 n n n 2 y 2 ax 2 b 0 i i i1 i1 i1 Notăm: n n n n 2 xi yi Sxy xi Sxx xi Sx yi Sy i1 i1 i1 i1 Tinem cont că: n i1 b nb

Sistemul de ecuaţii devine: Sxy asxx bsx 0 Sy asx nb 0 Înmulţind prima ecuaţie cu n şi a doua cu (-S x ) şi adunându-le se obţine: a S S ns x y xy b Sy asx 2 (S x ) nsxx 1 n Semnificatia parametrilor de fit: a - panta dreptei de regresie a=tg(α) α - unghiul făcut de graficul funcţiei F cu axa absciselor b - valoarea la care graficul funcţiei intersectează axa ordonatelor (interceptor) U b =E-rI F=ax+b E=b r= tg() Valorile estimate de dreapta de regresie (y i calc ) sunt interpretate ca medii ale valorilor y asociate cu o anumită valoare x i.

Cum se procedează atunci când funcţia model nu este o funcţie de gradul 1? Exemplu Un set de măsurători de radioactivitate t(ore) Λ(mCi) 2.5 280 3 218 3.5 177 4 140 4.5 100 5 85 5.5 67 6 48 6.5 42 7 30 7.5 20 8 17 1Ci = 3.7 10 10 Bq (t) t 0e

t(ore) Λ(mCi) ln(λ)) 2.5 280 5.63 3 218 5.38 3.5 177 5.18 4 140 4.94 4.5 100 4.61 5 85 4.44 5.5 67 4.20 6 48 3.87 6.5 42 3.74 7 30 3.40 7.5 20 3.00 8 17 2.83 ln( (t)) ln( 0) t ln(λ 0 (t))=y y'=a-bt unde a=ln(λ 0 ) şi b=λ Λ 0 =exp(6.9565)=1049.95 - ln( 0 )

Coeficientul de corelare R 2 - dă calitatea unei drepte de regresie R 2 = 1 => funcţia model explică întreaga variabilitate a lui y R 2 = 0 => nu există nici o relaţie liniară între variabila răspuns şi variabila x (între y şi x) R 2 = 0.5 => aproximativ 50% din variaţia variabilei răspuns poate fi explicată de către variabila independentă

//regresia liniara #include <stdio.h> #include <conio.h> #include <graphics.h> #include<stdlib.h> #include<math.h> int main() FILE *f; int n,i,xpmin,xpmax,ypmin,ypmax,xr,yr; float x,y,xd[20],yd[20],xdmin,xdmax,ydmin,ydmax; float Sx,Sy,Sxx,Sxy,a,b; float ymed, s1,s2,r2; float ax,bx,ay,by; int xp[50],yp[50]; char nf[20],stra[15], strb[15]; printf("numele fisierului de intrare: "); gets(nf); f=fopen(nf,"r"); if(!f) printf("\nfisier inexistent!"); getch(); exit(1); i=0; Sx=Sy=Sxx=Sxy=0; while(!feof(f)) if(fscanf(f,"%f%f",&x,&y)==2) xd[i]=x; yd[i]=y; i++; Sx+=x; Sy+=y; Sxx+=x*x; Sxy+=x*y; n=i; a=(n*sxy-sx*sy)/(n*sxx-sx*sx); b=(sy-a*sx)/n; fclose(f);

f=fopen(nf,"r"); s1=s2=0; ymed=sy/n; while(!feof(f)) R2=1-s1/s2; if(fscanf(f,"%f %f",&x,&y)==2) s1+=(a*x+b-y)*(a*x+b-y); s2+=(ymed-y)*(ymed-y); printf("===================================================\n"); printf("n= %d",n); for(i=0;i<n;i++) printf("\n%10.2f\t%10.2f",xd[i],yd[i]); printf("\n\nparametrii de fit sunt:\na= %7.3f\tb= %7.3f\n",a,b); printf("\ncoeficientul de corelare: R2= %g\n",r2); printf("===================================================\n"); fclose(f); xdmin=xdmax=xd[0]; ydmin=ydmax=yd[0]; for(i=0;i<n;i++) if(xd[i]>xdmax) xdmax=xd[i]; else if(xd[i]<xdmin) xdmin=xd[i]; if(yd[i]>ydmax) ydmax=yd[i]; else if(yd[i]<ydmin) ydmin=yd[i];

//Dimensiunile ferestrei de afisare si coeficientii de scalare xpmin=160;xpmax=440; ypmin=85;ypmax=365; ax=(xpmax-xpmin)/(xdmax-xdmin); bx=xpmin-ax*xdmin; ay=(ypmax-ypmin)/(ydmin-ydmax); by=ypmax-ay*ydmin; for(i=0;i<n;i++) xp[i]=(int)(ax*xd[i]+bx); yp[i]=(int)(ay*yd[i]+by); initwindow(800,500,"regresia liniara",5,5); xpmax=getmaxx(); ypmax=getmaxy(); setcolor(green); xr=4;yr=4; for(i=-1;i<=1;i++) rectangle(150+i,75+i,450-i,375-i); for(i=0;i<n;i++) fillellipse(xp[i], yp[i], xr, yr); delay(500); setcolor(yellow); setlinestyle(0,0,2); //Trasarea dreptei de regresie line(xp[0],(int)(ay*(xd[0]*a+b)+by),xp[n-1],(int)(ay*(xd[n-1]*a+b)+by)); delay(2000); //Tiparirea informatiilor pe grafic settextstyle(4,horiz_dir,1); outtextxy(270,390,"i (ma)"); settextstyle(1,horiz_dir,3);

outtextxy(150,10,"regresia liniara"); settextstyle(6,horiz_dir,1); outtextxy(150,40,"exemplu: potentiometrul compensator"); settextstyle(4,vert_dir,1); outtextxy(120,270,"u (V)"); settextstyle(8,horiz_dir,1); outtextxy(460,200,"functia de fit:"); outtextxy(460,230,"f(x) = "); gcvt(a,5,stra); gcvt(b,7,strb); outtextxy(530,230,stra); outtextxy(610,230,"x +"); outtextxy(650,230,strb); gcvt(r2,5,stra); outtextxy(460,260,"r^2 = "); outtextxy(530,260,stra); outtextxy(460,320,"e = "); outtextxy(500,320,strb); outtextxy(570,320," V"); outtextxy(460,350,"r = "); gcvt(-a,5,stra); outtextxy(500,350,stra); outtextxy(580,350," ohmi"); setcolor(red); rectangle(455,310,650,376); while(!_kbhit()); closegraph(); return 0;

Deviaţia standard (abaterea standard) = distanţa medie dintre media valorilor unui set de date şi datele setului respectiv - măsoară împrăştierea datelor dintr-un set (dispersia faţă de medie) 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 valori, media = 5 20 valori, media = 5 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10

Formula n i1 X i X n 1 2 Numitorul: - n-1 dacă datele X i reprezintă un eşantion - n dacă datele X i reprezintă întreaga populaţie (pentru n-mare, n-1n) Semnificatie

2 1 1 2 _ n i i n i x i x n n S a er 2 _ ns xx S x n S a er 2 1 1 2 1 2 _ n i i n i i n i i x x n x S b er 2 _ x xx xx S ns S S b er 2 1 2 n y b x a S n i i i unde: Eroarea estimarii parametrilor de fit Sunt necesare minim trei puncte pentru aputea folosi regresia liniara!

Exemplu Presupunem că s-au obţinut mai multe valori pentru E şi pentru r, din măsurători repetate. Rezultatul final se raportează ca şi valoarea medie +/- deviaţia standard.

Analiza reziduurilor 350 300 250 200 y = -44.531x + 335.79 R² = 0.8931 y = 9.7762x 2-147.18x + 576.12 R² = 0.9936 y = 1049.9e -0.512x R² = 0.9956 80 60 40 Fit liniar 150 20 100 0 0 2 4 6 8 10 12 50-20 0-50 0 2 4 6 8 10-40 60 50 Fit exponential 80 60 Fit parabolic 40 30 40 20 10 20 0-10 0 2 4 6 8 10 12 0 0 2 4 6 8 10 12-20 -20-30 -40-40

Distribuţia normală (Gaussiană) Funcţia densităţii de probabilitate (densitatea unei variabile aleatoare continue) este o funcţie care descrie probabilitatea relativă pentru ca respectiva variabilă sa aibă o anumită valoare. Probabilitatea ca variabila aleatoare să aibă valori într-un anumit interval este dată de integrala densităţii variabilei respective pe intervalul dat. Funcţia densităţii de probabilitate este nenulă pe întreg domeniul său de definiţie, iar integrala sa pe întreg spaţiul este egală cu unu. Funcţia densităţii de probabilitate pentru distribuţia Gaussiană cu media şi deviaţia standard ( x;, ) 1 exp 2 ( x ) 2 2 2 Distribuţia Gaussiană standard (=0 şi =1) 1 x ( x) exp 2 2 2

CURS 11 Rezolvarea ecuaţiilor transcendente Fie ecuatia: f(x)=0 algebrică - dacă poate fi adusă la o formă polinomială transcendentă dacă nu este algebrică Ecuaţii algebrice: 3x=9; 2x 2-3x+2=0; x5=x(2x-1); Ecuaţii transcendente: sin(x)+cos(x)=0.5; e ln(x)-x =π; Pentru determinarea soluţiilor ecuaţiilor transcendente este nevoie de metode de aproximare. Rădăcină unei ecuatii: Cum se defineste o rădăcină aproximativă?

Pentru determinarea soluţiilor unei ecuaţii de forma f(x)=0 trebuie parcurse două etape: 1. separarea rădăcinilor - partiţionarea intervalului de definiţie al funcţiei în mai multe subintervale determinate de nodurile x min =x 1, x 2,..., x M =x max astfel încât oricare subinterval să conţină cel mult o rădăcină a ecuaţiei 2. calculul rădăcinilor cu o anumită precizie

1. Separarea rădăcinilor Teorema: Dacă o funcţie continuă f(x) are valori de semn opus la capetele unui interval [a,b] (dacă f(a) f(b)<0) atunci în acel interval se găseşte cel puţin o rădăcină a ecuaţiei f(x)=0. Rădăcina este unică în intervalul [a,b] dacă derivata funcţiei (f'(x)) există şi îşi păstrează semnul în acel interval. O singura radacina in intervalul [10,15] Nici o radacina in intervalul [-10,-5] Radacini multiple in intervalul intervalul [0,10] Dacă subintervalele rezultate în urma partiţionării domeniului de definiţie al funcţiei sau a domeniului în care se caută zerourile funcţiei, [x m,x m+1 ], sunt suficient de mici astfel ca fiecare să conţină cel mult o rădăcină, atunci:

2. Calculul rădăcinilor cu o anumită precizie Metode: - metoda bisecţiei (înjumătăţirii intervalului) - metoda lui Newton (metoda tangentei) - metoda secantei - metoda falsei poziţii -metoda aproximaţiilor succesive -...

Metoda bisecţiei - constă în împărţirea repetată a intervalului iniţial [a,b] în jumătăţi ale acestuia şi selectarea intervalului (jumătăţii) în care se află soluţia.

Conditia de oprire a procesului iterativ :

Avantaje si dezavantaje - oferă convergenţă liniară a soluţiei ecuaţiei - convergenţă lentă - garantează convergenţa la soluţia exactă dacă valorile f(a) şi f(b) sunt de semne contrare

Program exemplu: metoda bisecţiei //metoda bisectiei #include<stdio.h> #include<math.h> #include <conio.h> #include <stdlib.h> #define eps 1e-8 int main() double s; float A=3.0, B=4; s=bisect(a,b,f); printf("\nsolutia este s= %lf\a",s); while(!_kbhit()); return 0; double f(double x) return 4.5*cos(x/3)*cos(x/3)-x/4; double bisect(double inf, double sup, double (*pf)(double)) double c; if((*pf)(inf)==0) return inf; if((*pf)(sup)==0) return sup; if((*pf)(inf)*(*pf)(sup)>0) printf("\nnu exista sol sau exista solutii multiple"); while(!_kbhit()); exit(1); do c=(inf+sup)/2.0; if((*pf)(c)==0) return c; if((*pf)(inf)*(*pf)(c)<0) sup=c; else inf=c; while((sup-inf) >= eps); // conditia de oprire return c;

Metoda lui Newton - propusă de către Isaac Newton în anul 1669 - revăzută de către Joseph Raphson în 1690 si Thomas Simpson în 1740 - una dintre cele mai răspândite metode folosite în acest scop - algoritmul bazat pe această metodă poate fi folosit şi la determinarea minimului sau maximului unei funcţii prin determinarea zeroului primei derivate a funcţiei, în metode de optimizare. Fie ecuatia: f(x)=0

Conditia de oprire a procesului iterativ : Calculul soluţiei exacte implică: 1. alegerea unei aproximaţii iniţiale (x 0 ) a soluţiei ecuaţiei f(x)=0 - condiţie necesară şi suficientă: f(x 0 )f"(x 0 )>0. 2. calculul derivatei funcţiei al cărui zero se calculează - calcul numeric (daca nu este posibil analitic) Deoarece în relaţia iterativă de calcul a rădăcinii valoarea f'(x 0 ) apare la numitor, în cazul accidental în care derivata funcţiei în punctul x i este zero, se va alege pentru aceasta valoarea ε (o valoare mică, diferită de zero) folosită la calculul derivatei sale. Dezavantajele metodei lui Newton 1. în unele cazuri este necesară o alegere atentă a valorii de start, x 0 2. necesită evaluarea a două funcţii. 3. la o iteraţie, se poate determina numai una dintre rădăcinile ecuaţiei cu rădăcini multiple (depinde de rădăcina aproximativă de "guess" de la care se porneşte)

Calculul numeric al derivatelor 1. Forward differences method (FDM) 2. Central differences method (CDM)

Pentru valori de tip REAL, stocate pe 4 octeţi, p 10-7, iar pentru valori de tip DOUBLE, stocate pe 8 octeţi, p 10-16. Vezi cursul 2 pasul de reprezentare a numerelor reale simpla precizie: 2-23 = 1.192 x 10-7 dubla precizie: 2-52 = 2.22 x 10-16 Conditii pentru alegerea valorii

//Metoda Newton #include <stdio.h> #include <stdlib.h> #include <math.h> #include <conio.h> double f(double x) return 4.5*cos(x/3)*cos(x/3)-x/4; double newton(double (*) (double), double x0) double p=1.0,eps,x,df; int k; //Calculul preciziei masinii si a valorii eps do p=p/2.0; while(p+1.0!=1.0); eps=pow(p,1/3.0); printf("p= %.20lf\teps= %.20lf",p,eps); //Calculul solutiei x=x0; k=0; do k++; x0=x; //calculul numeric al derivatei prin CDM df=(f(x+eps)-f(x-eps))/2/eps; //evitarea cazului in care df este zero if(df==0) df=eps; //actualizarea solutiei x=x0-f(x)/df; printf("\niteratia: %d: x= %15.12lf",k,x); if(k>20) printf("\nnu converge!"); exit(1); while(x!=x0); printf("\nsolutia ecuatiei este %15.12lf\nNr. de iteratii: %d",x,k); return x; int main () double x0,x; int k; printf("solutia initiala: x0= "); scanf("%lf",&x0); newton(f,x0); while(!_kbhit()); return 0;

CURS 12 Integrarea funcţiilor Metoda trapezelor - functia de integrat este aproximata liniar

//Metoda trapezelor #include <stdio.h> #include <math.h> float f (float x) return x*x-exp(x); float trapez( float (*p)(float), float a, float b, int n) float h,vint; int i; h=(b-a)/(n-1); vint=((*p)(a)+(*p)(b))/2.0; for(i=2;i<=n-1;i++) vint+=(*p)(a+(i-1)*h); vint=h*vint; return vint; int main() int n; float li,ls,v; printf("limita inferioara: "); scanf("%f",&li); printf("limita superioara: "); scanf("%f",&ls); printf("nr. puncte de integrare: "); scanf("%d",&n); v=trapez(f,li,ls,n); printf("valoarea integralei este: %g",v); // Caz test: Functia: x*x-exp(x) cu limitele a=0, b=2 // valoarea exacta este: printf("\ncaz test: %f",11.0/3.0-exp(2.0)); while(!_kbhit()); return 0;

Metoda Simpson - functia de integrat este aproximată cu un polinom de gradul 2 (parabolă) - polinomul aceleaşi valori ca şi f(x) la capetele intervalului de integrare şi în mijlocul acestuia, adică pentru f(a), f(b) şi pentru f(q), unde q=(a+b)/2. Trapez Simpson

Cum se calculeaza integrala functiei f? - se aproximeaza cu integrala polinomului

(1) (2) (3) (2)*4+(3) Dar: valoarea integralei se poate calcula evaluând funcţia f în 3 puncte: 0, h şi 2h. Nu trebuie determinati coeficientii polinomului de interpolare!

1. Pentru un interval oarecare [a,b] se împarte intervalul [a,b] în m intervale şi se aplică formula fiecărui subinterval [x 0,x 2 ], [x 2,x 4 ],... 2. Numărul de intervale m trebuie să fie par pentru a putea aplica formula parabolei definită de trei puncte care determină două intervale. 3. In intervalul [x 0,x 2 ] se va evalua valoarea funcţiei în punctele a, a+h şi a+2h, în intervalul [x 2,x 4 ] se va evalua valoarea funcţiei în punctele a+2h, a+3h şi a+4h, etc.