Limbajul C Florin Moraru

download Limbajul C Florin Moraru

of 202

description

C standard

Transcript of Limbajul C Florin Moraru

Florian Moraru

PROGRAMAREA CALCULATOARELOR n limbajul C

2008

PROGRAMAREA CALCULATOARELOR IN LIMBAJUL C 1. Introducere n programare. Limbajul C Algoritmi si programe . . . . . . . . . . . . . . . . . . . . . . . Dezvoltarea de programe . . . . . . . . . . . . . . . . . . . . . Limbajul de programare C . . . . . . . . . . . . . . . . . . . . Elementele componente ale unui program . . . . . . . . Conventii lexicale ale limbajului C . . . . . . . . . . . . . Structura programelor C . . . . . . . . . . . . . . . . . . . . . Directive preprocesor . . . . . . . . . . . . . . . . . . . . . . . 2. Date si prelucrri Variabile si constante . . . . . . . . . . . . . . . . . . . . . . . Tipuri de date n limbajul C . . . . . . . . . . . . . . . . . . Constante n limbajul C . . . . . . . . . . . . . . . . . . . . . Operatori si expresii aritmetice n C . . . . . . . . . . . Erori de reprezentare a numerelor . . . . . . . . . . . . . Prelucrri la nivel de bit . . . . . . . . . . . . . . . . . . . . . Ordinea de evaluare a expresiilor . . . . . . . . . . . . . . Instructiuni expresie n C . . . . . . . . . . . . . . . . . . . . 3. Operatii de intrare-iesire n C Functii standard de intrare-iesire . . . . . . . . . . . . . . Functii de citire-scriere cu format . . . . . . . . . . . . . Specificatori de format n scanf si printf . . . . . . . . 4. Prelucrri conditionate Bloc de instructiuni . . . . . . . . . . . . . . . . . . . . . . . . Instructiunea "if" . . . . . . . . . . . . . . . . . . . . . . . . . . Operatori de relatie si logici . . . . . . . . . . . . . . . . . . Expresii conditionale . . . . . . . . . . . . . . . . . . . . . . . Instructiunea "switch" . . . . . . . . . . . . . . . . . . . . . . Macroinstructiunea assert . . . . . . . . . . . . . . . . . . 5. Prelucrri repetitive n C Instructiunea "while" . . . . . . . . . . . . . . . . . . . . . . . Instructiunea "for" . . . . . . . . . . . . . . . . . . . . . . . . . Instructiunea "do" . . . . . . . . . . . . . . . . . . . . . . . . . .

Instructiunile "break" si "continue" . . . . . . . . . . . . Vectori n limbajul C . . . . . . . . . . . . . . . . . . . . . . . Matrice n limbajul C . . . . . . . . . . . . . . . . . . . . . .

6. Programare modular n C Importanta functiilor n programare . . . . . . . . . . . . Utilizarea functiilor in C . . . . . . . . . . . . . . . . . . . . Definirea de functii in C . . . . . . . . . . . . . . . . . . . . Instructiunea return . . . . . . . . . . . . . . . . . . . . . . Transmiterea de date intre functii . . . . . . . . . . . . . Functii recursive . . . . . . . . . . . . . . . . . . . . . . . . . . Biblioteci de functii . . . . . . . . . . . . . . . . . . . . . . . . 7. Programare structurat n C Structuri de control . . . . . . . . . . . . . . . . . . . . . . . . Programare structurat n C . . . . . . . . . . . . . . . . . . Solutii alternative . . . . . . . . . . . . . . . . . . . . . . . . . Eficienta programelor . . . . . . . . . . . . . . . . . . . . . . 8. Tipuri structur n C Definirea de tipuri si variabile structur . . . . . . . Utilizarea tipurilor structur . . . . . . . . . . . . . . . . Functii cu argumente si rezultat structur . . . . . . Definirea unor noi tipuri de date . . . . . . . . . . . . . Structuri cu continut variabil . . . . . . . . . . . . . . . . Structuri predefinite . . . . . . . . . . . . . . . . . . . . . . . 9. Tipuri pointer n C Variabile pointer . . . . . . . . . . . . . . . . . . . . . . . . . . Operatii cu pointeri la date . . . . . . . . . . . . . . . . . . Vectori si pointeri . . . . . . . . . . . . . . . . . . . . . . . . . Pointeri n functii . . . . . . . . . . . . . . . . . . . . . . . . . . Pointeri la functii . . . . . . . . . . . . . . . . . . . . . . . . . . Colectii de date generice . . . . . . . .. . . . . . . . . . Utilizarea de tipuri neprecizate . . . . . . . . . . . . . Utilizarea de pointeri la void . . . . . . . . . . . . . 10. Alocarea dinamica a memoriei n C

Clase de memorare n C . . . . . . . . . . . . . . . . . . . . Functii de alocare si eliberare a memoriei . . . . . . Vectori alocati dinamic . . . . . . . . . . . . . . . . . . . . . Matrice alocate dinamic . . . . . . . . . . . . . . . . . . . . Vectori de pointeri la date alocate dinamic . . . . . Structuri legate prin pointeri . . . . . . . . . . . . . . . .

11. Operatii cu siruri de caractere n C Memorarea sirurilor de caractere n C . . . . . . . . . . Erori uzuale la operatii cu siruri de caractere . . . . Functii standard pentru operatii cu siruri . . . . . . . Definirea de noi functii pe siruri de caractere . . . . Extragerea de cuvinte dintr-un text . . . . . . . . . . . . Cutarea si nlocuirea de siruri . . . . . . . . . . . . . . . 12. Fisiere de date n C Tipuri de fisiere . . . . . . . . . . . . . . . . . . . . . . . . . . Functii pentru deschidere si nchidere fisiere . . . Functii de citire-scriere n fisiere text . . . . . . . . . Functii de citire-scriere cu format . . . . . . . . . . . . Functii de acces secvential la fisiere binare . . . . Functii pentru acces direct la date . . . . . . . . . . . . 13. Tehnici de programare n C Stil de programare . . . . . . . . . . . . . . . . . . . . . . . . Conventii de scriere a programelor . . . . . . . . . . . Constructii idiomatice . . . . . . . . . . . . . . . . . . . . . Portabilitatea programelor . . . . . . . . . . . . . . . . . . Erori uzuale n programe C . . . . . . . . . . . . . . . . . Definirea si utilizarea de functii . . . . . . . . . . . . . 14. Tehnici de programare specifice programelor mari Particularitti ale programelor mari . . . . . . . . . . Compilri separate si fisiere proiect . . . . . . . . . . Fisiere antet . . . . . . . . . . . . . . . . . . . . . . . . . . . . Directive preprocesor utile n programele mari . Proiectul initial . . . . . . . . . . . . . . . . . . . . . . . . . Extinderea programului . . . . . . . . . . . . . . . . . . . Imbunttirea programului . . . . . . . . . . . . . . . . .

Concluzii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15. Diferente ntre limbajele C si C++ Diferente de sintax . . . . . . . . . . . . . . . . . . . . . . Diferente la functii . . . . . . . . . . . . . . . . . . . . . . . Operatori pentru alocare dinamic . . . . . . . . . . . Tipuri referint . . . . . . . . . . . . . . . . . . . . . . . . . . Fluxuri de intrare-iesire . . . . . . . . . . . . . . . . . . . Tipuri clas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Supradefinirea operatorilor . . . . . . . . . . . . . . . .

1. Introducere n programare. Limbajul C. Algoritmi si programe Un algoritm este o metod de rezolvare a unei probleme printr-o succesiune de operatii simple, cum ar fi operatii aritmetice, comparatii, s.a.. Numrul de operatii este de obicei foarte mare, dar finit. Spre deosebire de aplicarea unor formule de calcul, un algoritm contine operatii executate conditionat, numai pentru anumite date, si operatii repetate de un numr de ori, n functie de datele problemei. Un program este o descriere precis si concis a unui algoritm ntr-un limbaj de programare. Algoritmii mai simpli pot fi exprimati direct ntr-un limbaj de programare, dar pentru un algoritm mai complex se practic descrierea algoritmului fie sub form grafic (organigrame sau scheme logice), fie folosind un pseudocod, ca un text intermediar ntre limbajul natural si un limbaj de programare. Un pseudocod are reguli mai putine si descrie numai operatiile de prelucrare (nu si variabilele folosite). Nu exist un pseudocod standardizat sau unanim acceptat. Descrierea unor prelucrri n pseudocod se poate face la diferite niveluri de detaliere. Exemplu de pseudocod pentru algoritmul lui Euclid care determin cel mai mare divizor comun a doi ntregi, prin mprtiri repetate:repet cat timp restul mprtirii lui a prin b este nenul a primeste valoarea lui b b primeste valoarea restului mprtirii a prin b cmmdc este ultimul mprtitor b care a produs rest 0

Tipic pentru un algoritm este faptul c anumite operatii se execut conditionat (n functie de valorile datelor initiale), iar alte operatii se execut n mod repetat (iar numrul de repetri poate depinde de datele initiale). Altfel spus, anumite operatii dintr-un program pot s nu fie executate de loc sau s fie executate de un numr de ori, functie de datele initiale. La descrierea anterioar pentru algoritmul lui Euclid trebuie s adugm citirea datelor initiale (numerele ntregi a si b) si afisarea rezultatului (cmmdc). Variant de descriere a algoritmului lui Euclid n pseudocod:citeste a si b r = rest mprtire a prin b repeta ct timp r > 0 a=b b=r r=rest impartire a prin b scrie b

Prin deplasarea spre dreapta a celor trei linii s-a artat c acele operatii fac obiectul repetrii (nu ns si operatia de scriere).

Urmeaz un program C care implementeaz algoritmul lui Euclid descris anterior si care contine n plus declaratii pentru variabilele folosite:int main () { int a=15, b=9, r ; r= a%b; while ( r > 0) { a=b; b=r; r=a%b; } printf ("%d \n",b); } // declaratii cu initializarea variabilelor // restul impartirii lui a prin b // repeta cat timp rest nenul // noul deimpartit va fi a // noul impartitor va fi r // noul rest // afiseaza ultimul impartitor

Exemplu de algoritm pentru afisarea numerelor perfecte mai mici ca un numr n dat, descris ntr-un pseudocod:repet pentru fiecare ntreg m ntre 2 si n calcul sum s a divizorilor lui m dac m = s atunci scrie m

sau, la un nivel de detaliere mai aproape de un program n C:repet pentru fiecare ntreg m ntre 2 si n s=0 repeta pentru fiecare ntreg d ntre 1 si m daca d este divizor al lui m atunci aduna d la s dac m = s atunci scrie m

Prin alinierea spre dreapta s-a pus n evident structura de blocuri, adic ce operatii fac obiectul unei comenzi de repetare (repet) sau de selectie (dac). Aceast conventie nu este suficient de precis si poate fi nlocuit cu caractere delimitator pentru operatiile dintr-un bloc ce face obiectul unei repetri sau unei conditionri. Exemplu:repet pentru fiecare ntreg m ntre 2 si n { s=0 repeta pentru fiecare ntreg d ntre 1 si m { daca d este divizor al lui m atunci aduna d la s } dac m = s atunci scrie m }

Un program are un caracter general si de aceea are nevoie de date initiale (diferite de la o utilizare la alta a programului), date care particularizeaz programul pentru o situatie concret. De exemplu, un program pentru afisarea numerelor perfecte mai mici ca un numr dat n are ca date initiale numrul n si ca rezultate numerele perfecte ntre 2 si n. Exemplu:#include void main () { int n,m,s,d ; printf("n="); scanf("%d",&n); for (m=2; m b \n"); else printf(" x < a\n");

Operatorul unar de negare logic este '!'. Exemplu:if (!d) return; // preferabil: if ( d==0) return;

Negarea unei sume logice este un produs logic si reciproc. Exemple:a >=0 && b >=0 x < a || x > b // echiv. cu !(a a+c || c > a+b ) printf (" a,b,c nu pot forma un triunghi \n");

Intr-o expresie logic evaluarea operanzilor (expresii de relatie) se face de la stnga la dreapta; din acest motiv ordinea operanzilor ntr-o expresie logic poate fi uneori important si poate conduce la erori de programare. Exemplu:int main () { int k, b=9, a[]={1,2,3,4}; k=0; while ( b != a[k] && k 0); // verifica daca n 0 si b>0

Prin simplitatea de utilizare assert ncurajeaz efectuarea ct mai multor verificri asupra corectitudinii datelor initiale citite sau primite ca argumente de functii si asupra unor rezultate intermediare. Macroinstructiunea assert se foloseste pentru erori irecuperabile si mai ales n etapa de punere la punct a programelor, deoarece pentru versiunea final se prefer afisarea unor mesaje mai explicite pentru utilizatorii programului, eventual n alt limb dect engleza, nsotite de semnale sonore sau de imagini (pentru programe cu interfat grafic). Exemplu:#include #include #define MAX 1000 int main () { int n; printf (n = ); scanf (%d,&n); if ( n > MAX) { printf ( Eroare: n > %d \n,MAX);

return ; } ... }

De asemenea, assert se poate folosi pentru erori foarte putin probabile dar posibile totusi. Exemplu:double arie (double a, double b, double c) { // arie triunghi cu laturile a,b,c double p; assert (a > 0 && b > 0 && c > 0); // verificare argumente functie p =(a+b+c)/2; return sqrt (p*(p-a)*(p-b)*(p-c)); }

Anumite erori la operatii de citire de la consol sunt recuperabile, n sensul c se poate cere operatorului repetarea introducerii, si nu se va folosi assert. Eliminarea tuturor apelurilor assert dintr-un program se poate face prin secventa de directive:#define NDEBUG // inainte de include #include

4. Prelucrri repetitive n C Instructiunea "while" Instructiunea while exprim structura de ciclu cu conditie initial si cu numr necunoscut de pasi si are forma urmtoare: while (e) i unde e este o expresie, iar i este o instructiune (instructiune expresie, bloc sau instructiune de control). Efectul este acela de executare repetat a instructiunii continute n instructiunea while ct timp expresia din paranteze are o valoare nenul (este adevarat). Este posibil ca numrul de repetri s fie zero dac expresia are valoarea zero de la nceput. Exemplu:// cmmdc prin incercari succesive de posibili divizori d= min (a,b); // divizor maxim posibil while (a % d || b % d ) // repeta cat timp nici a nici b nu se divid prin d d=d -1; // incearca alt numar mai mic

In exemplul anterior, dac a=8 si b=4 atunci rezultatul este d=4 si nu se execut niciodat instructiunea din ciclu (d=d-1). Ca si n cazul altor instructiuni de control, este posibil s se repete un bloc de instructiuni sau o alt instructiune de control. Exemplu:// determinare cmmdc prin algoritmul lui Euclid while (a%b > 0) { r = a % b; // restul impartirii a prin b a =b; b = r; } // la iesirea din ciclu b este cmmdc

Este posibil ca n expresia din instructiunea while s se efectueze atribuiri sau apeluri de functii nainte de a compara rezultatul operatiei efectuate. Exemplu:// algoritmul lui Euclid while (r=a%b) { a=b; b=r; } // b este cmmdc

Instructiunea "for"

Instructiunea for din C permite exprimarea compact a ciclurilor cu conditie initial sau a ciclurilor cu numr cunoscut de pasi si are forma:for (e1; e2; e3) i

Efectul acestei instructiuni este echivalent cu al secventei urmtoare:e1; // operatii de initializare while (e2){ // cat timp exp2 !=0 repeta i; // instructiunea repetata e3; // o instructiune expresie }

Oricare din cele 3 expresii pot fi expresii vide, dar nu pot lipsi separatorii de expresii (caracterul ';'). Dac lipseste "e2" atunci se consider c e2 are valoarea 1, deci ciclul se va repeta neconditionat. Exemplu de ciclu infinit (sau din care se va iesi cu break sau return):// repetare fara sfarsit for ( ; ; ) instructiune // sau while(1) instructiune

Cel mai frecvent instructiunea for se foloseste pentru programarea ciclurilor cu numr cunoscut de pasi (cu contor). Exemple:// stergere ecran prin defilare repetata de 24 ori for (k=1;k0;k--) putchar('\n');

Exemplul urmtor arat cum se poate folosi for n loc de while:// determinare cmmdc pornind de la definitie for (d=min(a,b); a%d || b%d; d--) ; // repeta nimic // determinare cmmdc pornind de la definitie d=min(a,b); // sau o instr. "if" for (; a%d || b%d;) d--;

Cele trei expresii din instructiunea for sunt separate prin ';' deoarece o expresie poate contine operatorul virgul (','). Este posibil ca prima sau ultima expresie s reuneasc mai multe expresii separate prin virgule. Exemplu:

// calcul factorial de n for (nf=1, k=1 ; k0);

Motivatia instructiunii do este aceea c expresia verificat contine valori calculate (citite) n operatiile din ciclu, deci (aparent) expresia trebuie plasat dup instructiunile din ciclu si nu naintea lor (ca n cazul instructiunii while). Cu pretul repetrii unor instructiuni, un ciclu do poate fi rescris ca ciclu while// echivalent cu: do i while(e); i; // prima executie a intructiunii i while (e) // daca e nevoie mai repeta i; // instructiunea i

Exemplu de citire repetat cu validare:printf (n=); scanf (%d,&n); // prima citire while ( n > 1000) { // daca n0; d--) if (a%d==0 && b%d==0) break; printf ("%d \n",d); // d este cmmdc(a,b) // verifica daca un numar dat n este prim

for (k=2; k