ELENA ŞERBAN
PROGRAMAREA CALCULATOARELOR Note de curs
http://www.ace.tuiasi.ro/~eserban
PROGRAMAREA CALCULATOARELOR CURS – AN I TITULAR DISCIPLINĂ: ş. l. dr. ing. ELENA ŞERBAN www.ace.tuiasi.ro/~eserban
Bibliografie 1. Kernigham, B. W. şi Ritchie, D. M., Limbajul C, Editura TEORA, Bucureşti. 2. Schildt, H., C – Manual complet, Editura TEORA, Bucureşti. 3. Botez, C., Şerban, E., Maftei, L., Gospodaru, M., Şova, I., Programarea calculatoarelor în limbajul C/C++. Lucrări practice, Editura Gh. Asachi, Iaşi, 2002. 4. Iorga, V., Chiriţă, P., Stratan, C., Opincaru, C., Programare în C/C++. Culegere de probleme. Editura Niculescu, Bucureşti.
Curs nr. 1 • Etapele de rezolvare a unei probleme • Exemplu de program in C
Etapele de rezolvare a unei probleme • Faza 1 - Proiectare – Definirea problemei – Proiectarea soluţiei – Rafinarea soluţiei
Etapele de rezolvare a unei probleme • Faza 2 - Implementare – Dezvoltarea unei strategii de testare – Scrierea programului, testarea şi depanarea lui (punerea la punct a programului) – Completarea documentaţiei programului – Întreţinerea programului
Etapa 1 Definirea problemei • Enunţ clar şi precis al problemei • Specificaţii asupra datelor de intrare şi a datelor de ieşire
Etapa 2 Proiectarea soluţiei Se abordează o proiectare descendentă (top – down) Se definesc modulele care vor compune programul final. Fiecare modul are trei caracteristici de bază: • Funcţia • Logica • interfeţele
Etapa 3 Rafinarea soluţiei Elaborarea şi descrierea algoritmilor Moduri de descriere a algoritmilor: Verbal Algebric (prin formule) Scheme logice Pseudocod
Etapa 4 Dezvoltarea unei strategii de testare Definirea unor combinaţii de date de intrare care să verifice funcţionarea programului în toate cazurile Datele de test trebuie cunoscute înainte de implementarea algoritmilor
Etapa 5 Scrierea programului, testarea şi depanarea lui • Implementarea algoritmilor descrişi în Etapa 3 • Testarea folosind datele de test definite în Etapa 4
Etapa 5 (continuare) • Erorile pot apare: • La codificare (implementare) • La elaborarea algoritmului (în metoda de rezolvare a problemei) • La proiectarea programului • La calcularea rezultatelor de test
Etapa 6 Completarea documentaţiei • Explicaţia tuturor etapelor şi metodelor aplicate • Deciziile de proiectare care au fost luate • Problemele întâlnite în timpul scrierii şi testării programului • Instrucţiuni pentru utilizator
Etapa 7 Întreţinerea programului • Eliminarea noilor erori detectate în programe • Modificarea programului existent • Adăugarea unor noi facilităţi programului • Aducerea la zi a documentaţiei
Să se rezolve următoarea problemă: Cunoscând lungimile laturilor unui triunghi să se calculeze aria triunghiului şi lungimile medianei, bisectoarei şi înălţimii care plecă din vârful A.
Etapa 1 Intrarea: lungimile celor trei laturi. Sunt acestea de tip întreg sau real? De unde se citesc aceste date?
Ieşirea: • aria calculată a triunghiului • lungimea medianei, bisectoarei şi a înălţimii care pleacă din vârful A
Ce fel de date sunt? Toate sunt date de tip real. Unde se vor scrie aceste date?
Etapa 2 Care sunt subproblemele pe care trebuie să le rezolvăm? 1. Citirea datelor de intrare 2. Validarea datelor de intrare (cele trei valori pot reprezenta laturile unui triunghi?) 3. Calculul elementelor cerute din triunghi 4. Afişarea datelor de ieşire
Descompunerea problemei în subprobleme Problema Citirea datelor de intrare
Prelucrarea datelor
Validarea datelor
Afisarea rezultatelor
Calcularea mãrimilor cerute
Etapa 3 Notăm lungimile celor trei laturi cu a, b, c. Aria unui triunghi (conform formulei lui Heron) este:
A= p⋅( p−a)⋅( p−b)⋅( p−c) unde
a+b+c p= 2
Celelalte mărimi vor fi calculate cu relaţiile:
2⋅ A ha = a
Înălţimea din vârful A Mediana din vârful A
(
)
2 ⋅ b2 + c2 − a2 ma = 4
Bisectoarea unghiului A
2 ⋅ p ⋅ b ⋅ c ⋅ ( p − a) ba = b+c
Etapa 4 Datele de test Date de test pentru care ar trebui să se afişeze mesaj de eroare: • a = 1, b = 2, c = 3 • a = 0, b = 2, c= 4 • a = -5, b = 5, c= 3
Etapa 4 Datele de test Date de test pentru care ar trebui să se calculeze valorile cerute: • a = 6, b = 6, c = 6 Æ A = 15,59; ma = ha = ba = 5,20 • a = 3, b = 5, c = 4 Æ A = 6,00; ma = 4,27; ha = 4,00; ba = 4,22 • a = 10, b = 16, c = 14 Æ A = 69,28; ma = 14,18; ha = 13,86; ba = 14,11
Etapa 5 Implementarea programului • Se va folosi limbajul C • Problema se implementează cu ajutorul unui proiect care include toate modulele necesare • Gestionarea modulelor (modul şi timpul când se face apel la ele) este făcută prin funcţia main
Etapa 5 • Un modul este format din: • Fişier header (sau antet) cu extensia h • Fişier cod sursă cu extensia c (pentru fişiere C) sau cpp (pentru fişiere C++)
Crearea proiectelor • BorlandC 3.1 – Project → Open Project (dacă nu apare fereastra Project atunci Window → Project) – Apoi, cu fereastra Project activă Project → Add Item şi se introduce numele fişierul sursă care conţine codul sursă.
ATENŢIE Fişierele header nu vor fi incluse în proiect.
Crearea proiectelor • Visual C 6.0 – File → New → Project – Se alege opţiunea Win32 Console Application → An empty project
Proiectul P1 • Fişierul P1.cpp care conţine funcţia main • Modulul triunghi compus din • triunghi.h – fişierul care conţine prototipurile funcţiior • triunghi.c – fişierul care conţine codul sursă pentru funcţiile care calculează valorile cerute
Fişierul triunghi.h #ifndef _TRIUNGHI_ #define _TRIUNGHI_ int OK(int a, int b, int c); // Valideaza datele float Aria(int a, int b, int c); // Calculeaza aria float semiP(int a, int b, int c); // Calculeaza semiperimetrul float mediana(int a, int b, int c); // Calculeaza mediana float inaltime(int a, int b, int c); // Calculeaza inaltimea float bisectoare(int a, int b, int c); // Calculeaza bisectoarea #endif
Fişierul triunghi.c #include <math.h> #include "triunghi.h" int OK(int a, int b, int c) { int ok; if(a <= 0 || b<= 0 || c<= 0) ok = 0; else if(a+b <= c || a+c <= b || b+c <=a) ok = 0; else ok = 1; return ok; }
Fişierul triunghi.c - continuare float Aria(int a, int b, int c) { float A; float sP; sP = semiP(a,b,c); A = sqrt(sP * (sP-a) * (sP-b) * (sP-c)); return A; } float semiP(int a, int b, int c) { float p; p = (a+b+c)/2.; // p = (float)(a+b+c)/2; return p; }
Fişierul triunghi.c - continuare float inaltime(int a, int b, int c) { float h; float A; A = Aria(a,b,c); h = 2*A/a; return h; } float mediana(int a, int b, int c) { float med; med = sqrt((2*(b*b + c*c) - a*a)/4.); return med; }
Fişierul triunghi.c - continuare float bisectoare(int a, int b, int c) { float bis; float sP; sP = semiP(a,b,c); bis = 2*sqrt(sP * b * c * (sP - a)) / (b + c); return bis; }
Fişierul P1.c #include <stdio.h> #include
#include <stdlib.h> // system #include "triunghi.h" int main(void) { int a, b, c; int ok; float aria, ha, ma, ba; clrscr(); // system("cls"); /* * Se introduc lungimile celor 3 laturi */
Fişierul P1.c – continuare do { printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); printf("c = "); scanf("%d", &c); ok = OK(a,b,c); if (ok == 0) { printf("Numerele a=%d, b=%d, c=%d \ nu pot fi lungimile laturilor unui triunghi.\n", a, b, c); printf("Introduceti inca o data datele de intrare\n"); } } while (ok == 0);
Fişierul P1.c – continuare /* * Se calculeaza valorile cerute */ aria = Aria(a, b, c); ha = inaltime(a, b, c); ma = mediana(a, b, c); ba = bisectoare(a, b, c);
Fişierul P1.c – continuare /* * Afiseaza rezultatele */ printf("Aria calculata a triunghiului este %4.2f\n", aria); printf("Lungimea inaltimii din varful A este %4.2f\n", ha); printf("Lungimea medianei din varful A este %4.2f\n", ma); printf("Lungimea bisectoarei unghiuluil A este %4.2f\n", ba); if(getch() == 0x00) getch(); // if(!getch()) getch(); return 0; }
TEMA •Folosind funcţiile scris (şi nu altele) să se calculeze lungimile înălţimii, medianei şi bisectoarei care pleacă din vârfurile B şi C. • Să se reyolve problema în cazul în care datele de intrare sunt reprezentate de coordonatele în plan ale celor vârfurilor triunghiului. •De ce folosesc construcţia if(getch()== 0x00) getch()ş
PROGRAMAREA CALCULATOARELOR Curs nr. 2-3
Limbajul C – Scurt istoric Justificarea numelui Este urmaşul limbajului B creat la AT&T Bell Laboratories pentru scrierea unui sistem de operare (UNIX) Este creat de D.M. Ritchie îin 1972 25/04/07
PC - Curs nr. 2
2
Limbajul C – scurt istoric Prima carte despre limbaj: Kernighan B.W. & Ritchie D.M., The C Programming Language, 1978 Cartea este republicată în 1988.
25/04/07
PC - Curs nr. 2
3
Limbajul C – scurt istoric 1983 – se înfiinţează comisia X3J11 a Institutului Naţional American de Standarde (ANSI) pentru definirea unui standard 1989 (1990) – apare standardul de C. Limbajul C standard mai este cunoscut şi sub denumirea de C ANSI sau C90 1999 – un nou standard de C cu îmbunătăţiri faţă de cel din 1990 Æ C99 25/04/07
PC - Curs nr. 2
4
Elemente de bază ale limbajului C
Program • Ce este? Sistem care prelucrează informaţii. • Cum? Prin interacţiunea unor entităţi (mai simple sau mai complexe) care lucrează împreună cu scopul de a îndeplini o sarcină. 25/04/07
PC - Curs nr. 2
6
Entităţi • Pot fi formate la rândul lor din alte entităţi, mai simple. • Se caracterizează prin: – atribute – comportament
25/04/07
PC - Curs nr. 2
7
Entităţi În programarea structurată şi modulară – Care conţin informaţii (se mai numesc şi date) • variabilele • constantele
– Care prelucrează informaţia: • subprogramele (funcţiile)
În plus, pentru POO – Care conţin informaţii şi în acelaşi timp pot prelucra informaţii (conţin date şi funcţii - metode) • obiecte 25/04/07
PC - Curs nr. 2
8
Variabile • Sunt nume pe care le dăm unor locaţii de memorie • În program au dublă semnificaţie (în funcţie de context): – locaţia de memorie în sine (i Å 2) – valoarea care se găseşte în locaţia de memorie respectivă (j Å i) 25/04/07
PC - Curs nr. 2
9
Variabile • Îşi pot modifica valoarea pe parcursul execuţiei programului • Pot fi accesate – din întregul program (cazul variabilelor globale) – numai din funcţia sau blocul în care au fost declarate şi/sau definite (cazul variabilelor locale) 25/04/07
PC - Curs nr. 2
10
Constante • Pot fi: – de tip numeric, de tip caracter sau de tip şir de caractere – simbolice (numele şi valoarea sunt stocate în tabele create de compilator)
• Nu se pot modifica pe parcursul programului • Nu au asociată o locaţie de memorie 25/04/07
PC - Curs nr. 2
11
Funcţii • Sunt entităţi care rezolvă o sarcină clar delimitată din cadrul unui program • Sunt formate din: – definirea entităţilor purtătoare de informaţii necesare – instrucţiuni (comenzi)
• Instrucţiune Æ o comandă simplă, scrisă întrun limbaj de programare şi care determină o acţiune 25/04/07 PC - Curs nr. 2
12
• Fiecărei entităţi dintr-un program i se asociază: – un tip – un identificator (nume) – atribute (număr de elemente, componenţă, date de intrare)
25/04/07
PC - Curs nr. 2
13
Identificatori Sunt numele asociate entităţilor cu care lucrează programul In limbajul C, un identificator este o combinaţie de: 1. 2. 3.
litere (mari sau mici) ale alfabetului latin caracterul _ (subliniere sau underscore) cifre (de la 0 la 9)
Atenţie Primul caracter poate fi numai din 1. sau 2. 25/04/07
PC - Curs nr. 2
14
Identificatori La alegerea identificatorilor: 1. Limbajul C este "case sensitive" MIN ≠ Min ≠ min ≠ MiN 2. Lungimea maximă a unui identificator este de 31 de caractere 3. Trebuie folosiţi identificatori descriptivi (identificatorul unei entităţi trebuie să sugereze ce reprezintă sau ce face acea entitate) 25/04/07
PC - Curs nr. 2
15
Exemple identificatori Corect alfa beta _STIVA_ citesteDateDeIntrare a_1 afiseaza_vector
25/04/07
PC - Curs nr. 2
__C
16
Exemple identificatori Incorect top...ten 2_si_3 a+b medie aritmetica
25/04/07
PC - Curs nr. 2
17
Tip Fiecare identificator dintr-un program are un tip asociat. Acest tip determină: – mulţimea valorilor posibile pentru entitatea respectivă – ce operaţii pot fi aplicate entităţii asociate asociate acelui nume – cum sunt interpretate aceste operaţii 25/04/07
PC - Curs nr. 2
18
Tipuri fundamentale Conţin o singură informaţie (sunt tipuri scalare) 1. întregi: 1. de tip caracter definite prin char 2. de tip întreg definite prin int
2. reale 1. în simplă precizie definite prin float 2. în dublă precizie definite prin double 25/04/07
PC - Curs nr. 2
19
Tipuri fundamentale Fiecare din aceste tipuri poate fi folosit însoţit de un modificator care se plasează în faţa cuvântului cheie care descrie tipul. • pentru entităţile de tip întreg şi caracter – signed – unsigned 25/04/07
PC - Curs nr. 2
20
Tipuri fundamentale • pentru entităţile de tip int – short – long
• pentru entităţile de tip double – long
25/04/07
PC - Curs nr. 2
21
Tipuri fundamentale char
signed char
unsigned char
int
signed short int
unsigned short int
signed int
unsigned int
signed long int
unsigned long int
double
long double
float 25/04/07
PC - Curs nr. 2
22
Tipuri fundamentale Observaţii: 1. Mărimea exactă (în octeţi) a diferitelor tipuri fundamentale şi domeniul de valori sunt specificate în limits. h şi float. h. 2. Nu se fac presupuneri cu privire la mărimea diferitelor tipuri. Pentru a determina mărimea (în octeţi) a unui anumit tip se foloseşte operatorul sizeof. 25/04/07
PC - Curs nr. 2
23
Tipuri fundamentale Observaţii: Forma generală a expresiei de determinare a dimensiunii (în octeţi) a unui anumit tip este: sizeof(den_tip) unde den_tip este denumirea tipului de entitate.
25/04/07
PC - Curs nr. 2
24
Exemplu - sizeof #include <stdio.h> int main(void) { printf("Tipul printf("Tipul printf("Tipul printf("Tipul printf("Tipul printf("Tipul printf("Tipul
short int are %d octeti.\n", sizeof(short int)); int are %d octeti.\n", sizeof(int)); long int are %d octeti.\n", sizeof(long int)); char are %d octeti.\n", sizeof(char)); float are %d octeti.\n", sizeof(float)); double are %d octeti.\n", sizeof(double)); long double are %d octeti.\n", sizeof(long double));
return 0; } 25/04/07
PC - Curs nr. 2
25
Exemple char x; unsigned int a, b; float x; long double valoare; long numarDeTelefon; unsigned char OCTET; int numarLinii; double mediaAritmetica; 25/04/07
PC - Curs nr. 2
26
Tipuri definite de programator 1. Tipuri derivate Æ sunt formate prin utilizarea unei combinaţii de unul sau mai multe tipuri fundamentale şi/sau definite de programator: 1. tipuri structurate (agregate) – conţin mai multe elemente 1. de acelaşi tip - tablourile 2. care pot fi de tipuri diferite - structurile
2. uniuni 3. câmpuri de biţi 4. pointeri 25/04/07
PC - Curs nr. 2
27
Tipuri definite de programator 2. Tipuri sinonime Æ limbajul permite crearea unor sinonime pentru a creşte lizibilitatea programului
25/04/07
PC - Curs nr. 2
28
Tipuri structurate – tablouri Forma generală: tip nume[dim1][dim2]…[dimn]; unde ¾tip Æ tipul elementelor tabloului ¾nume Æ numele tabloului ¾dim1, dim2, …, dimn Æ valorile celor n dimensiuni ale tabloului 25/04/07
PC - Curs nr. 2
29
Tipuri structurate – tablouri Exemple: int A[10]; // Vector double matrice[20][20]; // Matrice // Prima dimensiune = numărul de linii // A doua dimensiune = numărul de coloane long b[10][5][100]; char denumire[30]; 25/04/07
PC - Curs nr. 2
// Şir de caractere 30
Tipuri structurate – tablouri Accesul al un element al tabloului: nume[index1][index2]…[indexn] unde ¾ nume este numele tabloului ¾ index1, index2,…, indexn sunt indicii elementului accesat 25/04/07
PC - Curs nr. 2
31
Tipuri structurate – tablouri Exemplu: 1. int A[15]; A[5] sau A[0] sau A[14] 2. double B[10][20]; B[0][1] sau B[5][4] sau B[9][19]
25/04/07
PC - Curs nr. 2
32
Tipuri structurate – structuri Este necesar să creăm un model (prototip) pentru structură. Acest model va fi plasat în fişierul header: struct nume_prototip_structura { declaraţii de variabile; };
25/04/07
PC - Curs nr. 2
33
Tipuri structurate – structuri Exemple: struct _PUNCT { double x, y; }; struct _DATA { int zi; char luna[20]; int an; }; 25/04/07
struct _Persoana { char nume[50]; int varsta; struct _DATA dataNasterii; double salariu; double impozit; };
PC - Curs nr. 2
34
Tipuri structurate – structuri Folosire: struct _PUNCT A, B;
struct _Persoana Alecu;
A.x = 3.5; B.y = A.y;
Alecu.impozit = 0.16 * Alecu.salariu; Alecu.nume[0] Alecu.dataNasterii.zi
25/04/07
PC - Curs nr. 2
35
Crearea de sinonime Se face prin folosirea declaraţiei de tip typedef. typedef tipExistent tipNou; unde tipExistent este un tip de entitate care există în limbaj sau care a fost definit anterior tipNou este noul nume (sinonimul tipului existent) 25/04/07
PC - Curs nr. 2
36
Crearea de sinonime Exemple: typedef unsigned int NATURAL; typedef float REAL; typedef unsigned char BYTE; NATURAL a, b; REAL x; BYTE ok; 25/04/07
PC - Curs nr. 2
37
Crearea de sinonime Exemple: typedef int VECTOR[20]; typedef struct _MATRICE { int n; // Numar linii int m; // Numar coloane; double A[30][30]; // Matricea } MATRICE; VECTOR V; MATRICE A; 25/04/07
// De exemplu V[0] // De exemplu A.m sau A.A[0][0] PC - Curs nr. 2
38
Crearea de sinonime Observaţii: 1. declaraţia de tip typedef trebuie să apară în fişerul header înaintea oricărei referiri la noul tip. 2. se recomandă ca noul tip să fie scris cu litere mari pentru a-l diferenţia de tipurile fundamentale. 25/04/07
PC - Curs nr. 2
39
Entităţi de tip funcţie Date de intrare
Funcţie
Date de ieşire
tip_f numeFunctie (tip1 nume1, tip2 nume2, ..., tipn numen) Antet, interfaţă 25/04/07
PC - Curs nr. 2
40
Declaraţii şi definiţii Sunt modalităţi de "a face cunoştinţă" programului cu entităţile cu care va lucra. O definiţie a unei entităţi presupune rezervarea spaţiului de memorie necesar memorării sale. O declaraţie a unei entităţi nu face decât să indice programului modelul (prototipul) entităţii respective fără a rezerva spaţiu de memorie. 25/04/07
PC - Curs nr. 2
41
Declaraţii şi definiţii Pentru o funcţie sau variabilă pot exista mai multe declaraţii, dar numai o singură definiţie (ODR – One Definition Rule) O definiţie poate fi şi o declaraţie, dar nu şi invers. Într-un fişier header nu pot exista decât definiri de sinonime şi declaraţii pentru date sau funcţii. 25/04/07
PC - Curs nr. 2
42
Declaraţii de funcţii Declaraţia unei funcţii este formată din: 1. antet (interfaţă) 2. caracterul ; la sfârşit tip_f numeF(tip1 nume1, tip2 nume2, ..., tipn numen) ;
Observaţie: Poate apare într-un fişier header. 25/04/07
PC - Curs nr. 2
43
Definţii de funcţii Definiţia unei funcţii este formată din: 1. antet (interfaţă) 2. corpul funcţiei tip_f numeF(tip1 nume1, tip2 nume2, ..., tipn numen) { definiţii de variabile; instrucţiuni; } 25/04/07
PC - Curs nr. 2
44
Definţii de funcţii Observaţii: NU pot apare într-un fişier header. NU pot conţine declaraţiile (prototipurile altor funcţii).
25/04/07
PC - Curs nr. 2
45
Exemple float FCT(int a, float b);
// este in header
float FCT(int a, float b) { float rez; rez = sqrt(a*b); return rez; }
// este in fisierul cu functii
25/04/07
PC - Curs nr. 2
46
int main(void) { int x, float y; float z; ………………………….. x = 3; y = 2.35; …………………………. z = FCT(x, y); // se poate si z = FCT(3, 2.35); …………………………. return 0; } 25/04/07
PC - Curs nr. 2
47
Declaraţii şi definiţii de variabile • Definiţia unei variabile int x;
// Nu poate fi într-un fişier header
• Declaraţia unei variabile extern int x; //Poate fi într-un fişier header Se foloseşte în special pentru variabile globale pentru a fi vizibile din mai multe fişiere. 25/04/07
PC - Curs nr. 2
48
25/04/07
PC - Curs nr. 2
CONSTANTE
49
Constante numerice întregi zecimale Dacă nu se specifică altfel, compilatorul consideră că o constantă este un număr zecimal cu semn: 47 3 1101 -235 Pentru numerele fără semn trebuie să adăugăm sufixul u 47u 23u 25/04/07
PC - Curs nr. 2
51
Constante numerice întregi zecimale Pentru constantele în format lung adăugăm sufixul l sau L 23l 23L Pentru constantele în format lung fără semn avem sufixele ul uL lu Lu 23ul 23Lu 25/04/07
PC - Curs nr. 2
52
Constante numerice întregi zecimale Compilatorul stabileşte lungimea reprezentării în funcţie de valoarea constantei astfel: 23 este în format scurt, 72365 este în format lung
25/04/07
PC - Curs nr. 2
53
Constante numerice întregi octale Dacă numărul este precedat se cifra 0 se consideră constantă octală 015 027
25/04/07
PC - Curs nr. 2
54
Constante numerice întregi hexazecimale Dacă numărul este precedat de 0x sau 0X se consideră constantă de tip hexazecimal. 0x15 0XB3 0x31
25/04/07
PC - Curs nr. 2
55
Constante numerice reale Sunt numere care pot conţine punctul zecimal sau caracterele e sau E (cu semnificaţia de putere a lui 10) Implicit sunt considerate de tip double. Exemple: 12.34 1.157e+3 2.5678e-5 1.234E+1 25/04/07
PC - Curs nr. 2
56
Constante numerice reale Pot avea sufixele f sau F Æ constante de tip real în simplă precizie (de tip float) 2.3f 1e-4f Pot avea sufixele l sau L Æ constante de tip long double 4.5l 3.24L 25/04/07
PC - Curs nr. 2
57
Constante de tip caracter Au ca valoare codul ASCII al caracterului respectiv. Sunt specificate prin: 1. caracterul pus între apostrof Exemplu: 'A' '0' 'i'
25/04/07
PC - Curs nr. 2
58
Constante de tip caracter 2. Codul ASCII exprimat ca un cod octal '\ddd' (unde d este o cifră octală) Exemplu: '\023' '\117' '\139'
25/04/07
PC - Curs nr. 2
59
Constante de tip caracter 3. Codul ASCII exprimat ca un cod hexazecimal '\xhh' (unde h este o cifră hexazecimaă) '\xff' '\xab'
25/04/07
PC - Curs nr. 2
60
Constante de tip caracter Un caz particular sunt secvenţele ESCAPE: '\n' - LF '\\' - backslash '\r' - CR '\'' - apostrof '\t' - TAB '\"' - ghilimele '\0' - zero '\f' - FF '\b' - BackSpace '\a' - BEL 25/04/07
PC - Curs nr. 2
61
Constantele de tip caracter Observaţii: 1. Au rezervaţi 2 octeţi astfel că: sizeof('a') are ca rezultat 2. a. octetul inferior conţine codul ASCII al caracterului b. octetul superior conţine extensia de semn 25/04/07
PC - Curs nr. 2
62
Constante de tip caracter 2. Pot apare în expresii aritmetice având ca valoare codul ASCII corespunzător astfel putem scrie: c-'a'+'A' sau c-'A'+'a' c – '0'
25/04/07
PC - Curs nr. 2
63
Constante de tip şir de caractere Şir de caractere = tablou de caractere. Constante de tip şir de caractere = secvenţă de caractere specificată intre ghilimele (") Exemplu: "exemplu"
25/04/07
PC - Curs nr. 2
64
Constante de tip şir de caractere Orice şir de caractere trebuie să se termine cu caracterul '\0' Acest caracter este pus implicit de compilator sau trebuie pus explicit în cazul în care şirul este construit prin program 25/04/07
PC - Curs nr. 2
65
Constante de tip şir de caractere e x e m p l u \0 Iniţializarea şirurilor de caractere: char fis[] = "a1.txt"; Nu se poate scrie: char fis[20]; fis="a1.txt"; 25/04/07
PC - Curs nr. 2
66
Comstante simbolice - define Sunt identificatori care au asociată o valoare constantă. Asocierea dintre un identificator şi o valoare constantă se poate face prin mai multe metode 1. folosirea directivei preprocesor define #define N 100 #define _TEST_ 25/04/07
PC - Curs nr. 2
67
Constante simbolice - const 2. prin folosirea modificatorului const const int x = 10; Trebuie făcută iniţializarea. Avantaj faţă de define Æ se verifică tipul
25/04/07
PC - Curs nr. 2
68
Constante simbolice – nume de tablou 3. Numele tablourilor pot fi privite ca fiind constante simbolice pentru că numele unui tablou este asociat cu adresa primului element (care este o constantă). A se vedea legătura dintre pointeri şi tablouri.
25/04/07
PC - Curs nr. 2
69
Constante simbolice – tipul enum Forma generală: enum [id] {id1 [=cst1], id2[=cst2], …}; unde id este numele setului de constante id1, id2, … sunt identificatori (constante simbolice) cst1, cst2, … sunt valorile asociate identificatorilor (valorile constantelor simbolice) 25/04/07
PC - Curs nr. 2
70
Constante simbolice – tipul enum Exemple: enum BOOLEAN {FALSE, TRUE}; typedef enum {FALSE, TRUE} BOOLEAN; BOOLEAN ok; enum CULORI {ALB=1, ROSU, VERDE=5, GALBEN};
25/04/07
PC - Curs nr. 2
71
Constante simbolice - tipul enum …………….. enum zile {luni=1, marti, miercuri, joi, vineri, sambata, duminica}; …………….. int main(void) { enum zile astazi = luni; if((astazi == sambata) || (astazi == duminica)) printf("Week end\n"); else printf("Du-te la scoala\n"); return 0; } 25/04/07
PC - Curs nr. 2
72
Constante simbolice – tipul enum Observaţii: 1. În cazul în care valoarea asociată variabilei enum nu face parte din mulţimea de valori definită ca nume de constantă simbolică, apare un mesaj de avertizare (Warning). 2. Facilitează operarea cu variabile care pot lua un număr redus de valori întregi, prin asocierea unui nume fiecărei valori. 3. Se face verificarea tipului valorii asociate 25/04/07
PC - Curs nr. 2
73
PROGRAMAREA CALCULATOARELOR Curs nr. 4
1
25/04/07
Operaţii de intrare - ieşire Operaţii de intrare – ieşire cu format
25/04/07
2
Fluxuri de date (stream) • stdin • stdout • stderr
25/04/07
3
Citirea datelor - scanf Citirea se face conform schemei
Tastatură
Buffer (Zona tampon)
Program
Golirea buffer-ului (a zonei tampon) se face cu: fflush(stdin); 25/04/07
4
Citirea datelor de la tastatură - scanf Forma generală: int scanf("", , , ...); unde format – şir de caractere care indică modul de memorare a datelor citite adr1, adr2, ... – adresele unde se vor stoca valorile citite (sunt numele variabilelor precedate de &) 25/04/07
5
Citirea datelor - scanf Forma generală a formatului este:
%[*][width][F|N][h|l|L]tip_char unde width – lungimea maximă a şirului citit de la tastatură Exemple: %4d - citeşte un întreg de maxim 4 cifre %f - citeşte un real %lf - citeşte un real de tip double 25/04/07
6
scanf %c
- citeşte un caracter
%s - citeşte un şir de caractere care nu conţine caractere albe (se foloseşte denumirea tabloului, fără adresă) char den[30]; scanf("%s", den);
25/04/07
7
scanf Observaţie: În format nu trebuie să apară decât formatele şi eventualele caractere obligatorii din şirul de intrare).
Exemplu: Se citeşte un moment din zi sub forma: 12:23:45 scanf("%d:%d:%d", &ora, &min, &sec); 23.09.2004 scanf("%d.%2d.%4d", &zi, &luna, &an); 25/04/07
8
scanf În formatul de citire pot apare şi şiruri de forma: %[…] caută doar caracterele specificate %[^…] caută toate caracterele cu excepţia celor specificate
Exemplu: char den[30]; scanf("%[abcd]", den); scanf("%[^abcd]", den); scanf("%[0-9]", den); scanf("%20[ a-z]", den);
// %[A-Z], %[0-9a-z], %[^A-FT-Z]
25/04/07
9
scanf Citirea se opreşte la: –* – atingerea lăţimii – următorul caracter din şir care nu se potriveşte cu formatul – următorul caracter din şir care nu există în mulţimea de căutare
25/04/07
10
Citirea datelor de la tastatură - scanf Funcţia returnează numărul de câmpuri corect citite. La întâlnirea sfârşitului de fişier (CTRL/Z) returnează valoarea –1 (EOF). Æ Validare primară a datelor …………………… while(scanf("%d%d%d", &x, &y, &z) != 3) fflush(stdin); printf("Valorile citite sunt: %d %d si %d\n", x, y, z); ……………………………. 25/04/07
11
scanf - exemplu #include <stdio.h> #include int main(void) { int nr; int a=10, b=20, c=30; clrscr(); nr = scanf("%d%d",&a,&b); printf("1 nr = %d\n",nr); printf("1 a = %d, b = %d\n",a,b); 25/04/07
12
scanf - exemplu nr = scanf("%c",&c); printf("2 nr = %d\n", nr); printf("2 c = %c", c); getch(); return 0; }
25/04/07
13
scanf OBSERVAŢII: Pentru formatul %d, scanf ignoră spaţiile albe din faţa datei şi pune înapoi în buffer spaţiile albe care au determinat terminarea unei date(' ', '\t', '\n', '\r') Nu se amestecă formatele %c şi %s cu formatele %d şi %f sau scanf(…) cu getchar(). 25/04/07
14
Afişarea cu format - printf Forma generală: int printf("", <arg1>, <arg2>, …); unde este de forma: %[flags][width][.prec][F|N|h|l|L]tip_char
25/04/07
15
printf Exemplu: int zi = 12; int luna = 2; int an=2004; printf("%02d.%02d.%5d", zi, luna, an); Æ 12.02. 2004 25/04/07
16
printf int a=1; printf("%02d", a); printf("%.3d", a);
//Æ 01 // Æ 001
float a=2.3; printf("%.0f", a); double f = 34.5; long double g = 74; long j = 123;
// // // //
Æ Æ Æ Æ
2 %lf %Lf %ld
25/04/07
17
printf x = ( 24, 31, 29) void afisareVector(int a[], int n, char den[]) { int i; printf("%s=(", den); for(i=0; i
18
printf int err; char fis[50]; printf("\"Eroare \'%2d\' la citirea fisierului %s\"", err, fis); Mesajul: "Eroare '59' la citirea fisierului a1.txt" 25/04/07
19
Exemplu – P2 Să se scrie un program care calculează produsul scalar a doi vectori cu componente numere întregi, precum şi vectorul sumă. Primul vector se citeşte de la tastatură până la întâlnirea combinaţiei de taste CTRL/Z (CTRL/D în Linux), iar al doilea vector are exact atâtea elemente cât şi primul. 25/04/07
20
Analiza problemei Fie cei doi vectori X = (xi)i=1,n şi Y = (yi)i=1,n atunci
si = xi + yi
n
PS = ∑ xi ⋅ yi i =1
25/04/07
21
Analiza problemei 1.
2. 3. 4. 5.
25/04/07
o funcţie de citire a unui şir de numere pânâ la intâlnirea caracterului CTRL/Z. Funcţia returnează numărul elementelor citite. o funcţie de citire a unui vector când se cunoaşte numărul de elemente care trebuie citite o funcţie de afişare a unui vector funcţia de calcul a vectorului sumă funcţia de calcul a produsului scalar
22
Proiectul • P2.C – fişier care conţine funcţia main • modulul VECTOR – VECTOR.H – VECTOR.C
25/04/07
23
VECTOR.H /* * VECTOR.H */ #ifndef _VECTOR_ #define _VECTOR_ // Functia de citire a unui sir de numere pana la CTRL/Z // (CTRL/D) int citireVector1(int a[], char den[], int DimMax); // Functia de citire a unui vector când se cunoaste // dimensiunea vectorului void citireVector2(int a[], int n, char den[]); 25/04/07
24
VECTOR.H – continuare // Functia de afisare vector void afisareVector(int a[], int n, char den[]); // Functia de calcul a produsului scalar long produsScalar(int a[], int b[], int n); //Functia de calcul a vectorului suma void sumaVectori(int a[], int b[], int c[], int n); #endif
25/04/07
25
P2.C /* * P2.C */ #include <stdio.h> #include #include "vector.h" int main(void) { int x[20], y[20], suma[20]; int n; int ps; 25/04/07
26
P2.C n = citireVector1(x,"x",20); if(n > 0) { citireVector2(x,n,"y"); ps = produsScalar(x, y, n); sumaVectori(a, b, suma, n); printf("Pentru vectorii \n"); afisareVector(x, n, "x"); printf("si\n"); afisareVector(y, n, "y"); printf("vectorul suma este\n"); afisareVector(suma, n, "S"); printf("iar produsul scalar este %d.\n",ps); } 25/04/07
27
P2.C else fprintf(stderr,"Vector nul.\n"); if(!getch()) getch(); return 0; }
25/04/07
28
VECTOR.C #include <stdio.h> int citireVector1(int a[], char den[], int DimMax) { int n = 0; printf("%s(%d) = ", den, n); while((n < DimMax) && (scanf("%d", &a[n]) == 1)) { n = n+1; printf("%s(%d) = ", den, n); } return n; } 25/04/07
29
VECTOR.C void citireVector2(int a[], int n, char den[]) { int i; for(i=0; i
25/04/07
30
VECTOR.C void afisareVector(int a[], int n, char den[]) { int i; printf("%s=(", den); for(i=0; i
25/04/07
31
VECTOR.C long produsScalar(int x[], int y[], int n) { long ps; int i; ps = 0; for(i=0; i
25/04/07
32
VECTOR.C void sumaVectori(int a[], int b[], int s[], int n) { int i; for(i=0; i
25/04/07
33
Operaţii de intrare – ieşire Operaţii de intrare – ieşire pentru caractere şi şiruri de caractere 25/04/07
34
Operaţii de intrare – ieşire pentru caractere Prototipuri în stdio.h int getc(FILE *stream); int putc(int c, FILE *stream); int getchar(void); int putchar(int c); 25/04/07
35
Operaţii de intrare – ieşire pentru şiruri de caractere Prototipuri în stdio.h char *gets(char *s); char *fgets(char *s, int n, FILE *stream); int puts(char *s); int fputs(char *s, FILE *stream); 25/04/07
36
Operaţii de intrare – ieşire pentru caractere Prototipuri în conio.h Nu sunt în standard int getch(void); int getche(void); int putch(int c);
25/04/07
37
Exemplu: Se introduce un text de la tastatură caracter cu caracter până la întâlnirea CTRL-Z. Să se afişeze numărul de linii introduse.
25/04/07
38
Exemplu: #include <stdio.h> int main(void) { int c; int numarLinii = 0;
25/04/07
39
c = getchar(); while(c != EOF) { if (c == '\n') numarLinii = numarLinii + 1; c = getchar(); }
25/04/07
40
printf("S-au introdus %d linii.\n", numarLinii); return 0; }
25/04/07
41
Operaţii de I/O pentru şiruri şi fişiere • sscanf, sprintf int sscanf(char s[], format, arg1, arg2, …); int sprintf(char s[], format, arg1, arg2, …);
• fscanf, fprintf int fscanf(FILE *fisier, format, arg1, arg2, …); int fprintf(FILE *fisier, format, arg1, arg2, …);
25/04/07
42
Operaţii de intrare - ieşire char temp[81]; int a; ……………………… while(fgets(temp,80,stdin) != 0) { nr = sscanf(temp, ",%d", &a); if(nr == 1) printf("%d ",a); } …………………………. 25/04/07
43
Citirea unei matrice int citireMatrice(int n, int m, double a[][20]) { int ok=1; int i,j; for(i=0; i
44
Citirea unei matrice …………… ok = citireMatrice(n,m,a); if(ok == 0) fprintf(stderr, "Eroare la citirea matricei.\n"); …………………
25/04/07
45
PROGRAMAREA CALCULATOARELOR Curs nr. 5-6
1
25/04/07
Expresii şi operatori
25/04/07
2
Expresie O secvenţă de operatori şi operanzi care specifică modul de calculare a unei valori. O expresie are un tip care coincide cu tipul valorii rezultatului. Expresia: ¾ operanzi care sunt entităţile care participă ¾ operatori care descriu operaţiile care se execută 25/04/07
3
Operatori Caracteristici: 1. aritate Æ număr de operanzi 2. tip Æ domeniul de definiţie al operaţiei desemnate şi la domeniul valorilor acestei operaţii Exemplu: + Æ (real, real; real) 3. efect Æ dat de operaţia simbolizată 25/04/07
4
Operatori Din punctul de vedere al numărului de operanzi: • unari (sunt pre sau postfixaţi) • binari (sunt infixaţi) • ternari (infixaţi)
25/04/07
5
Operatori În funcţie de operaţia realizată: 9aritmetici 9incremetare şi decrementare 9relaţionali 9logici 9logici la nivel de bit 9atribuire 9accesul la date şi dimensiune 25/04/07
6
Expresii aritmetice Operanzi: constante, variabile, funcţii, elemente de tablou, subexpresii, membrii unei structuri Operatori: 1. unari (prefixaţi): 2. binari (infixaţi):
+, *, /, % +, -
25/04/07
7
Expresii aritmetice Observaţii: 1. dacă cei doi operanzi sunt de acelaşi tip, atunci tipul rezultatului coincide cu tipul celor doi operanzi 4/3 Æ ? 4./3. Æ? 2. dacă rezultatul este în afara domeniului de definiţie, atunci rezultatul este eronat short int a, b, c; a = 31564; b = 5130; c = a+b; printf("c = %d", c); //c = -28842 25/04/07
8
Expresii aritmetice Reguli de evaluare 1. Dacă apar funcţii, se consideră ca operanzi rezultatele furnizate de acele funcţii 2. Priorităţi: + - Æ unari */% + - Æ binari 3. Când apar operanzi de diverse tipuri, sunt convertiţi implicit în tipul cel mai prioritar. 25/04/07
9
Conversii 1. implicite char, enum Æ int se face conversia la tipul prioritar T + long double Æ long double T + double Æ double T + float Æ float T + unsigned long Æ unsigned long long + unsigned int Æ unsigned long T + long Æ long unsigned int + int Æ int (dacă se poate) sau unsigned int Æ int 25/04/07
10
Conversii 2. explicite Folosirea operatorului de conversie (operatorul cast). Forma generală: (tip)operand Exemplu: short int a = 31564, b = 5130; long int c; c = (long)a + b; printf("c = %ld",c); // c = 36694 25/04/07
11
Operatori de incrementare - decrementare Definiţii: Incrementare operaţia de mărire a valorii unei variabile de tip întreg cu 1. Operator: ++ Decrementare operaţia de micşorare a valorii unei variabile de tip întreg cu 1. Operator: -25/04/07
12
Operatori de incrementare - decrementare Sunt operatori care calculează o expresie şi modifică în acelaşi timp o variabilă Exemple: ++i //este echivalent cu i = i + 1 n-//este echivalent cu n = n + 1
Operatorii sunt operatori unari şi pot fi: prefixaţi postfixaţi
++i n--
25/04/07
13
Operatori de incrementare - decrementare Exemplu: int x, n= 5; x = ++n; x=6 n=6 x = n++; x=5 n=6 25/04/07
14
Operatori de incrementare - decrementare Exemplu: temp [nc] = c; nc++; este echivalent cu temp [nc++] = c;
25/04/07
15
Operatori de incrementare - decrementare La folosirea lor trebuie evitate ambiguităţile care apar când se foloseşte mai mult de o operaţie de incremetare – decrementare într-o instrucţiune. Exemplu: 1) x = fn1(i++) + fn2(i++) Corect: x = fn1(i++); x = x + fn2(i++);
25/04/07
16
Operatori de incrementare - decrementare 2) a[i++] = b[i++];
/* GREŞIT */
3) int i, a[10]; i = 0; while(i < 10) a[i] = i++;
/* GREŞIT */
for(i=0; i<10; i++) a[i] = i;
/*CORECT */
25/04/07
17
Operatori de incrementare - decrementare 4) { int i = 1; printf("%d %d\n", i++, i++); } Se afişează 21 5) i = ++i + 1;
/* expresie nedefinită */
6) i++ + j++ * k++ 25/04/07
/*expresie nedefinită */ 18
Operatori de incrementare - decrementare #include <stdio.h> #include "ex.h" int main(void) { int a, i = 10; a = next(i);
int next (int x) { return x++; } Programul va afişa: a= 10
printf("a =\n\t%d\n", a); return 0; } 25/04/07
19
Expresii de relaţie Rezultatul expresiei poate fi: ADEVĂRAT (asociat cu o valoare diferită de 0, în general 1) FALS (asociat cu valoarea 0) Rezultatul unei expresii relaţionale sau logice cu valoarea de adevăr ADEVĂRAT este 1. La evaluarea expresiilor, orice expresie care are un rezultat ≠ 0 se consideră a fi adevărată.
25/04/07
20
Expresii de relaţie Operatori: < ==
<= !=
>
>=
Au prioritatea mai mică decât a operatorilor aritmetici. Se evaluează de la stânga la dreapta. Exemple: i < lim – 1 b == a*a getchar() != EOF 25/04/07
21
Expresii logice Se compun din operanzi şi operatori logici. Operatorii logici: || SAU logic && ŞI logic ! NU logic Exemple: (a==7) || (a==1) (a>= 0) && (a<= 9) !(a<0) 25/04/07
22
Expresii logice Evaluarea expresiei se face de la stânga la dreapta. Evaluarea se termină când se ajunge la un punct în care se cunoaşte cu certitudine rezultatul. Restul expresiei nu se mai evaluează. Exemplu: Dacă a = -2 atunci evaluarea expresiei (a>0) && (a<20) se opreşte după evaluarea primei paranteze. 25/04/07
23
Expresii logice #include <stdio.h> int main(void) { int a=1, b=1; if((++a > 5) && (++b > 5)) printf("Mesaj 1 si %d %d\n", a, b); else printf("Mesaj 2 si %d %d\n", a, b); return 0; } 25/04/07
24
Expresii logice Programul afişează: Mesaj 2 si 2 1
25/04/07
25
Expresii logice Prioritatea && are prioritate mai mare ca || şi mai mică decât a operatorilor aritmetici şi relaţionali. Aceşti operatori sunt folosiţi pentru construirea expresiilor logico-relaţionale. Sunt corecte următoarele expresii? a == b == c // pentru a testa dacă cele trei numere a, b si c sunt egale 0 < i < 10 // pentru a testa dacă valoarea lui i este între 1 şi 9 25/04/07
26
Program exemplu P3 Se citeşte un număr întreg reprezentând un an. Se afişează dacă anul respectiv este bisect sau nu. Programul arată astfel: ……………………. int main(void) { int an; char bisect[8]; clrscr(); printf(“Anul analizat :“); scanf(“%d”, &an);
25/04/07
27
Program exemplu P3 if( (an >= 1600 && an <= 4900) && (an % 4 == 0 && an % 100 != 0 || an % 400 == 0)) copie(bisect ,“este”); else copie(bisect , “nu este”); printf(“Anul %d %s bisect\n”, an, bisect); if (!getch()) getch(); return 0; }
25/04/07
28
Program exemplu P3 void copie(char d[], const char s[]) { int i; for(i=0; (d[i] = s[i]) != ‘\0’; i=i+1) ; }
25/04/07
29
Operatori şi expresii de atribuire Operatorul de atribuire
= Exemple: x=1 a=b y = a*x*x + b*x + c Forma generală este: v = expresie 25/04/07
30
Operatori şi expresii de atribuire Valorile stânga au semnificaţia de locaţie de memorie Exemple: a[i] a[i+2] a v1 Observaţie: nu pot fi tablouri, constante sau funcţii Valorile dreapta au semnificaţia de valoare Exemple: 2 2*i a[j] f(a,2); 25/04/07
31
Operatori şi expresii de atribuire Evaluarea se face de la dreapta la stânga a=b=c=2 Expresia de atribuire v = expresie are o valoare care este valoarea atribuită lui v. Exemple: (c = getchar()) != EOF z = sqrt(a = 3*x) 25/04/07
32
Operatori şi expresii de atribuire Forma generală prin care modificăm o variabilă prin operaţii asupra propriei valori este: v = v op exp unde v este o variabilă (de oricare tip), op este un operator binar aritmetic sau de lucru pe biţi *, +, (, -, % <<, >>, &. |, ^ exp este o valoare sau o expresie al cărui rezultat modifică valoarea variabilei v Exemplu: i = i + 1; a[i+j+2*k] = a[i+j+2*k] + 4 25/04/07
33
Operatori şi expresii de atribuire În acest caz folosim operatorii de atribuire relativă care sunt de forma: op = astfel că: v op= exp ⇔ v = v op exp Exemplu: i=i+1 i += 1 a[i] = a[i] / b a[i] /= b k = k * (n+1) k *= n+1 a[i+j+2*k] = a[i+j+2*k] + 4 25/04/07
a[i+j+2*k] += 4 34
Operatori şi expresii de atribuire Operatorul de atribuire este folosit şi pentru iniţializarea variabilelor. Observaţie: variabilele declarate (definite) într-o funcţie au valori nedefinite dacă nu sunt iniţializate. 25/04/07
35
Operatori şi expresii de atribuire Iniţializarea se poate face: ¾ pentru variabile scalare la definire Exemplu: int a=10; pe parcursul programului ………………. int a; ………………… a = 10; 25/04/07
36
Operatori şi expresii de atribuire ¾ pentru tablouri Æ la definire int a[5] = {3,4,5,6,7}; int a[] = {10,20,30,40}; n = sizeof(a)/sizeof(int); 1 2 3 int a[2][3] = {1,2,3,4,5,6}; Æ 4 5 6 1 2 3 int a[2][3] = {{1,2,3},{4,5,6}}; Æ 4 5 6 25/04/07
37
Operatori şi expresii de atribuire ¾ pentru structuri Æ la definire Exemplu: typedef struct _PUNCT { double x, y; } PUNCT; PUNCT a = {3.2, 4.5};
25/04/07
38
Operatori şi expresii de atribuire Un caz special de folosire a operatorului de atribuire este în cazul structurilor. typedef struct _PUNCT { double x, y; } PUNCT; PUNCT a = {1.2, 4.15}; PUNCT b; b = a; printf("%4.2lf %4.2lf", b.x, b.y); 25/04/07
39
Operatori logici asupra biţilor Se aplică numai variabilelor de tip întreg (int şi char). Aceşti operatori conduc la expresii care al căror rezultat depind de reprezentarea internă a întregilor şi au caracteristici care depind de implementarea tipurilor cu semn.
25/04/07
40
Operatori logici asupra biţilor Sunt operatori: unari (cu prioritatea egală cu a celorlalţi operatori unari) ~ - complement faţă de 1, negare binari << >> & ^ |
deplasare stânga la nivel de bit deplasare dreapta la nivel de bit ŞI pe biţi SAU EXCLUSIV (XOR) pe biţi SAU pe biţi
25/04/07
41
Operatori logici asupra biţilor Toţi operatorii se evaluează de la stânga la dreapta. Prioritatea operatorilor pe biţi: ¾ operatorii de deplasare (<< şi >>) imediat după operatorii aritmetici aditivi şi înaintea operatorilor relaţionali. ¾ operatorii &, ^, | (în această ordine) după operatorii de testarea egalităţii şi înaintea operatorului Şi logic (&&).
25/04/07
42
Operatori logici asupra biţilor Operatorul & (ŞI)
&
0
1
0
0
0
1
0
1
Este folosit pentru a pune pe 0 (a reseta) anumiţi biţi dintr-unul din operanzi sau pentru a extrage anumiţi biţi care ne interesează dintr-unul din operanzi în conformitate cu valoarea celui de al doilea operand numit MASCĂ. 25/04/07
43
Operatori logici asupra biţilor Operatorul & (ŞI) Exemple: a) n = 6710 c = n & 01008; MASCĂ
n = 6710= 26 + 21 + 20 = 010000112 = 01038 c = n & 01008 = 01038 & 01008 = 01008
25/04/07
44
Operatori logici asupra biţilor Operatorul & (ŞI) Exemple: b) c = n & 0177400 8 = n & 11111111 00000000 MASCĂ
c)
2
octet superior octet inferior
c = n & 03778 = n & 00000000 11111111 octet superior
2
octet inferior
25/04/07
45
Operatori logici asupra biţilor Operatorul ^ (SAU EXCLUSIV XOR)
^
0
1
0
0
1
1
1
0
0 – lasă biţii nemodificaţi 1 – complementează biţii
Este folosit pentru a complementa numai anumiţi biţi dintr-un cuvânt (în conformitate cu o configuraţie existentă în mască - cel de-al doilea operand). 25/04/07
46
Operatori logici asupra biţilor Operatorul ^ (SAU EXCLUSIV XOR) Exemplu: Trebuie complementat MASCA = 0x10 Pentru c = 0x5bu rezultatul expresiei c^MASCA este
bitul 4 dintr-un octet. 00010000 01011011
01001011
25/04/07
47
Operatori logici asupra biţilor Operatorul | (SAU)
|
0
1
0
0
1
1
1
1
Este folosit pentru a pune, în unul din operanzi, pe 1 (a seta) toţi biţii care au valoarea 1 în celălalt operand (numit şi MASCĂ). 25/04/07
48
Operatori logici asupra biţilor Operatorul | (SAU) Exemple: z = x | MASK a) x = 6610
MASK = 118
z = 6610 | 118 = 1028 | 118 = 1138 = 7510 MASCĂ
00000000 01000010 | (SAU) 00000000 00001001 00000000 01001011 25/04/07
49
Operatori logici asupra biţilor Operatorul | (SAU) Exemple: z = x | MASK b) x = 66 10
MASK = 778
z = 6610 | 778 = 1028 | 778 = 1778 = 12710 c)
x = 6610
MASK = 6810
z = 6610 | 6810 = 4216 | 4416 = = 010000102 | 010001002 = 010001102 = 4616 = 7010 25/04/07
50
Operatori logici asupra biţilor Observaţie Operatorii & şi | sunt diferiţi de operatorii logici && şi ||. Exemplu: x = 1, y =2 Æ x & y este 0 Æ x && y este 1
25/04/07
51
Operatori logici asupra biţilor Operatorii de deplasare << şi >> Deplasează spre stânga (<<) sau spre dreapta (>>) primul operand cu numărul de biţi indicat de al doilea operand. Exemplu: n = 23
Æ
0000000000010111
n << 3
Æ
0000000010111000
n >> 3
Æ 0000000000000010
25/04/07
52
Operatori logici asupra biţilor Operatorii de deplasare << şi >> << completează poziţiile libere cu zerouri deplasarea cu o poziţie este echivalentă cu o înmulţire cu 2 >> completarea poziţiilor libere se face în funcţie de implementare (la BorlandC 3.1 se completează cu o extensie a semnului) deplasarea cu o poziţie este echivalentă cu o împărţire la 2 25/04/07
53
Operatori logici asupra biţilor Operatorul unar ~ Are ca rezultat complementul faţă de 1 al operandului x = 4216 şi x = x & ~077u8 (fără semn) ~0778 = ~00000000 001111112 = 11111111 110000002 ⇒ x = 00000000 010000102 & 11111111 110000002 x = 00000000 010000002 = 1008
25/04/07
54
Operatori logici asupra biţilor Exemplu: Să se scrie un program care foloseşte operatorii de lucru pe bit pentru a realiza "împachetarea" unei date calendaristice. 21/03/2005 Æ 11010010 01110101 = D27516 an 15
luna 9
8
ziua 5
4
0
1 1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 25/04/07
55
Operatori logici asupra biţilor Fişier DATA. H #ifndef _DATA_ #define _DATA_ typedef unsigned short int WORD; int validData(WORD zi, WORD luna, WORD an); WORD impachetare(WORD zi, WORD luna, WORD an); void afisareBinara(WORD data); void afisareBinara1(WORD data); int anBisect(WORD an); #endif 25/04/07
56
Operatori logici asupra biţilor Fişier P4.cpp #include <stdio.h> #include "data.h" int main(void) { WORD zi, luna, an; WORD data; int nr, valid;
25/04/07
57
Operatori logici asupra biţilor do { fflush(stdin); printf("Introduceti o data calendaristica" "(zz/ll/aaaa): "); nr = scanf("%u/%u/%u", &zi, &luna, &an); if(nr == 3) valid = validData(zi, luna, an); else valid = 0; } while(!valid); data = impachetare(zi, luna, an); afisareBinara(data); return 0; } 25/04/07
58
Operatori logici asupra biţilor Fişier DATA.CPP #include <stdio.h> #include "data.h" WORD impachetare(WORD zi, WORD luna, WORD an) { WORD data = 0u; an = an - 1900; an <<= 9; luna <<= 5; data = data | zi | luna | an; return data; } 25/04/07
59
Operatori logici asupra biţilor void afisareBinara(WORD data) { WORD nr = sizeof(WORD) * 8; WORD c; while(nr--) { c = (data >> nr) & 1; c = c + '0'; putchar(c); if(nr%8 == 0) putchar(' '); } putchar('\n'); } 25/04/07
60
Operatori logici asupra biţilor void afisareBinara1(WORD data) { WORD nr = sizeof(WORD) << 3; WORD MASK = ~((~0u)>>1); WORD c; while(nr--) { c = (data & MASK) >> nr; putchar(c + '0'); if(!(nr & 07)) putchar(' '); MASK >>= (WORD) 1; } putchar('\n'); }
25/04/07
61
Operatori logici asupra biţilor int validData(WORD zi, WORD luna, WORD an) { int valid; if(zi < 1 || zi > 31 || luna < 1 || luna > 12) valid = 0; else { if(luna == 2) if(anBisect(an) == 0) { if(zi > 28) valid = 0; } else { if(zi > 29) valid = 0; } 25/04/07
62
Operatori logici asupra biţilor else if(luna == 4 || luna == 6 || luna == 9 || luna == 11) if(zi > 30) valid = 0; else valid = 1; } return valid; }
25/04/07
63
Operatori logici asupra biţilor int anBisect(WORD an) { int bisect; if((an>=1600 && an<=4900) && (an%4 == 0 && an%100 != 0 || an%400 == 0)) bisect = 1; else bisect = 0; return bisect; }
25/04/07
64
Expresia şi operatorul condiţional Expresia condiţională este formată cu ajutorul operatorului condiţional care este un operator ternar. Forma generală: expresieL ? expresieDa : expresieNu Exemplu: a) Rezultatul expresiei (a
65
Expresia şi operatorul condiţional b) for(i=0; i
f daca expresia e1 este adevarata xx = 0 in caz contrar
25/04/07
66
Expresia şi operatorul condiţional Scriem f1(a, b+1, c+d, e1? f : 0, (g+h+i)/2); Prioritatea acestui operator se situează între cea a operatorului SAU logic (||) şi cea a operatorului de atribuire.
25/04/07
67
Expresia şi operatorul condiţional d) Să se calculeze valoarea funcţiei f(x) pentru un x citit de la tastatură.
3 x 2 + 7 x − 10 pentru x < 0 pentru x = 0 f ( x ) = 2 4 x 2 + 3 x pentru x > 0 ................ double x; ................ scanf("%lf", &x); printf("\n\n Pentru x = %lf f(x) = %lf\n\n", x, (x<0) ? 3*x*x+7*x-10 : ((x==0) ? 2 : 4*x*x+3*x)); 25/04/07
68
Expresia şi operatorul condiţional Observaţii: 1) Expresia condiţională poate apare oriunde poate apare o expresie sau o variabilă. 2) Dacă expresiile expresieDa şi expresieNu sunt de tipuri diferite, tipul rezultatului este determinat de regulile de conversie.
25/04/07
69
Operatori de apel de funcţie () Realizează aplicarea unei funcţii unei liste de valori. Forma generală a apelului este: numeFunctie(e1, e2, ..., en) unde e1, e2, ..., en sunt argumentele efective (reale) ale apelului - numai denumiri de variabile, iar numeFunctie este numele funcţiei apelate Tipul acestei expresii coincide cu tipul valorii returnate de funcţie. Expresia funcţie nu poate fi o valoarea stânga. 25/04/07
70
Operatorul virgulă Leagă două expresii într-una singură. Forma generală: expresie1, expresie2, ..., expresien Valoarea şi tipul acestei expresii coincid cu valoarea şi tipul ultimei expresii (expresien) Are prioritatea cea mai mică. Evaluarea se face de la stânga la dreapta. 25/04/07
71
Operatorul virgulă Exemplu: printf("%5d\n", ((c = (a<0) ? –a : a), ((d = (b<0) ? –b : b), ((c > d) ? c : d))); Calculează şi afişează maximul valorilor absolute ale numerelor întregi a şi b.
25/04/07
72
Operatorii de selecţie 1) Operatori de indexare [] Realizează accesul la un element al unui tablou. Forma generală este: numeTablou[index1][index2]…[indexn] unde numeTablou trebuie să fie numele unui tablu cu n dimensiuni, iar index1, ..., indexn trebuie să fie de tip întreg. Au prioritate maximă. 25/04/07
73
Operatorii de selecţie 2) Operatorul .(punct) Asigură accesul la membrii unei structuri. Are prioritate maximă, alături de operatorii paranteză. Este un operator binar, valoarea din stânga reprezintă o variabilă de tip structură, iar valoarea din dreapta este un membru al structurii respective.
25/04/07
74
Operatorii de selecţie Exemplu: struct PUNCT { double x,y; }; struct DREPTUNGHI { struct PUNCT A; struct PUNCT B;
// colt stanga sus // colt dreapta jos
}; struct DREPTUNGHI D1; struct PUNCT p1; p1.x
D1.A.y
25/04/07
75
Operatorul sizeof Furnizează mărimea în octeţi a entităţii specificate. Forma generală: sizeof data sau sizeof(data) sizeof tip sau sizeof(tip) unde data poate fi un nume de variabilă, de tablou, de structură, element de tablou sau membru al unei structuri, iar tip este un cuvânt ce indică un tip de entitate. sizeof(short int) Æ 2 float tab[10]; sizeof(tab) este 40, iar sizeof(tab[1]) este 4. 25/04/07
76
Operatorul sizeof În cazul structurilor, valoarea returnată de sizeof nu coincide întotdeauna cu suma dimensiunilor membrilor structurii datorită alinierii sau nealinierii datelor. Exemplu: struct TEST { char c; float b; char c1; int a; } t; printf("Marimea structurii de test este de %d octeti. \n", sizeof(t)); 25/04/07
77
Operatorul sizeof Pentru BorlandC 3.1 (nu ţine cont de alinierea datelor) c
float
c1 a
Pentru Visual C 6.0 (ţine cont de alinierea datelor) c
25/04/07
float
c1
a
78
Ordinea de efectuare a operaţiilor Se referă la operatorii cu aceeaşi prioritate (precedenţă). Sensul de evaluare precizează semnificaţia unei expresii şi nu ordinea cronologicş de evaluare a subexpresiilor. Singurele expresii pentru care ordinea (cronologică) este specificată (în standardul C ANSI) sunt 9 e1 && e2 şi e1 || e2 9 e0 ? e1 : e2 9 e1, e2 În toate celelalte cazuri standardul C ANSI nu specifică nimic, ca urmare depinde de fiecare implementare. 25/04/07
79
Tabelul de precedenţă a operatorilor Operatori
() !
[]
~
->
++
Sensul de evaluare
.(punct)
--
*
sizeof
&
De la stânga la dreapta (cast)
De la dreapta la stânga
-(unar)
(linia operatorilor unari) *
/
+
-
%
De la stânga la dreapta
(binari)
De la stânga la dreapta De la stânga la dreapta
<<
>>
(Deplasare pe bit stânga, dreapta)
<
<=
>=
==
>
!= &
De la stânga la dreapta
(XOR pe biţi)
De la stânga la dreapta
(SAU pe biţi)
De la stânga la dreapta
(ŞI logic)
De la stânga la dreapta
(SAU logic)
De la stânga la dreapta
(operator condiţional)
De la dreapta la stânga
| && || =
(atribuire)
+=
-=
*=
/=
%=
(atribuire relativă)
<<=
>>=
&=
^=
|=
(atribuire relativă)
, (virgula)
25/04/07
De la stânga la dreapta De la stânga la dreapta
(ŞI pe biţi)
^
?:
(Operatori relaţionali)
(Testarea egalităţii)
De la dreapta la stânga
De la stânga la dreapta
80
PROGRAMAREA CALCULATOARELOR Curs nr. 7-8
25.04.2007
INSTRUCŢIUNILE LIMBAJULUI C
1
Maşina virtuală D.I.
MEMORIE
D.E.
UNITATE CENTRALĂ
Operaţii de bază: citirea scrierea atribuirea 25.04.2007
3
Structura de control a programului Ordinea în care se execută instrucţiunile unui program defineşte structura de control a programului respectiv. Instrucţiunile simple se execută secvenţial, una după alta. Apar cazuri când este necesară o altă ordine de execuţie a instrucţiunilor. 25.04.2007
4
Structura de control a programului Modificarea ordinii de execuţie a instrucţiunilor se face, în programarea structurată, prin utilizarea structurilor de control. Structurile de control sunt: ¾ secvenţa ¾ selecţia ¾ iteraţia
25.04.2007
5
Blocuri de instrucţiuni Bloc de instrucţiuni = o succesiune de declaraţii/definiţii de variabile şi instrucţiuni încadrată de caracterele { Înaintea unui bloc nu se pune ;. şi După un bloc nu se pune ;. } Din punctul de vedere al sintaxei, un bloc se comportă ca o instrucţiune unică şi poate figura în orice punct în care este permisă o instrucţiune simplă. 25.04.2007
6
Blocuri de instrucţiuni Indiferent de poziţia sa în program, un bloc poate conţine propriile sale declaraţii (definiţii) de variabile. În afara cazului când variabila este declarată de tip extern, o variabilă definită în interiorul unui bloc este locală blocului respectiv (nu este recunoscută în afara blocului respectiv). Această variabilă locală maschează, fără a distruge, toate entităţile cu acelaşi nume recunoscute în afara blocului. 25.04.2007
7
Blocuri de instrucţiuni Variabilele declarate/definite într-un bloc (dacă nu sunt statice) sunt create şi iniţializate la activarea blocului şi distruse în momentul ieşirii din bloc, având rezervată memorie în stivă. Folosirea variabilelor locale blocului permite optimizarea spaţiului de memorie.
25.04.2007
8
Blocuri de instrucţiuni Exemplu: if(...) { tip1 x1; …………… } else { tip2 x2; …………… }
STIVA
.............. x2 x1 .............. Intrare în bloc
Ieşire din bloc
Variabilele x1 şi x2 nu există niciodată simultan. 25.04.2007
9
Instrucţiuni RECOMANDĂRI Deşi intr-un program C pot exista oricâte instrucţiuni pe o linie, se recomandă, pentru uşurinţa depanării programelor scrierea unei singure instrucţiuni pe o linie. De asemenea, se va folosi scrierea indentată pentru evidenţierea blocurilor de instrucţiuni. 25.04.2007
10
Instrucţiuni simple - Instrucţiunea vidă Se reduce la caracterul ;. Se utilizează în secvenţe care cer existenţa unei instrucţiuni, dar nu trebuie să se execute nimic. Exemplu: for(i=0; s[i] != '\0'; i=i+1) ;
25.04.2007
11
Instrucţiuni simple - Instrucţiunea expresie Are forma generală expresie; fiind formată dintr-o expresie urmată de caracterul ;. Observaţie: Caracterul ; este caracter terminator de instrucţiune care se pune numai după instrucţiunile simple, nu şi după cele compuse (blocuri de instrucţiuni) 25.04.2007
12
Instrucţiuni simple - Instrucţiunea expresie Instrucţiunea expresie are sens numai dacă expresia folosită este:
1. expresie de atribuire (inclusiv incrementarea – decrementarea) Æ instrucţiune de atribuire 2. expresia de apel de funcţie Æ instrucţiune de apel de funcţie 25.04.2007
13
Instrucţiuni simple - Instrucţiunea expresie Exemple: 1. i++ x=a+b y += 2 2.
i++; x = a + b; y += 2;
printf("Hello\n"); suma(a,b,n,s); x = a + f(2,3) Æ expresie x = a + f(2,3); Æ instrucţiune
25.04.2007
14
Instrucţiuni compuse şi structuri de control Structurile de control sunt implementate, în limbajul C, prin instrucţiuni compuse formate din instrucţiuni simple şi alte instrucţiuni compuse. Instrucţiunile compuse sunt: – secvenţa – selecţia – iteraţia 25.04.2007
15
Structuri de control - secvenţa Este o structură formată din una sau mai multe instrucţiuni care se execută secvenţial (în ordinea în care sunt scrise în program). Se execută conform schemei din figură. 25.04.2007
Actiune 1
Actiune 2
Aici sche ma se continua cat este nevoie
Actiune n
16
Structuri de control - secvenţa Este formată dintr-un bloc de instrucţiuni, deci forma generală este: { declaratii; instructiuni; }
25.04.2007
17
Structuri de control – selecţia (decizia) Este o structură care conţine mai multe părţi din care se execută numai una, o singură dată, în funcţie de rezultatul unui test logic.
25.04.2007
18
Structuri de control – selecţia (decizia) Există mai multe tipuri de selecţie: S1). selecţia cu două alternative (structura de control fundamentală) S2). selecţia cu o alternativă vidă (structură de control derivată) S3). selecţia multiplă (structură de control derivată) 25.04.2007
19
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Reprezentare prin schema logică:
25.04.2007
Adevarat
Secventa A
conditie
Fals
Secventa B
20
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Reprezentare prin pseudocod: dacă atunci <secvenţă_A>; altfel <secvenţă_B>; sf. dacă 25.04.2007
21
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Instrucţiunea C corespunzătoare este if ... else if(conditie) Secventa_A; else Secventa_B; 25.04.2007
22
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Exemple: 1)
float x, y, z; if(x > y) z = x; else z = y;
25.04.2007
23
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Exemple: 2)
25.04.2007
int c; int init; if(c == 'D') { printf("Da \n"); printf("Ai ales sa continui !!!\n"); init = 0; } else { printf("Iesire din program !!!\n"); init = 1; } 24
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative Exemple: 3) Funcţie de transformare a unui şir din litere mari în litere mici şi invers în funcţie de o opţiune void transf(char sir [], int opt) { int i; if(opt == 1) // se face transformarea in litere mari { for(i=0; sir[i] != '\0'; i++) if(sir[i] >= 'a' && sir[i] <= 'z') sir [i] = sir[i] – 'a' + 'A'; } 25.04.2007
25
Structuri de control – selecţia (decizia) S1). Selecţia cu două alternative else // se face transformarea in litere mici { for(i=0; sir[i] != '\0'; i++) if(sir[i] >= 'A' && sir[i] <= 'Z') sir [i] = sir[i] – 'A' + 'a'; } }
25.04.2007
26
Structuri de control – selecţia (decizia) S2). Selecţia cu o alternativă (cu o ramură vidă) Reprezentarea prin schema logică
Adevarat
conditie
Secventa
25.04.2007
27
Structuri de control – selecţia (decizia) S2). Selecţia cu o alternativă (cu o ramură vidă) Reprezentarea prin pseudocod dacă atunci <secvenţă>; sf. dacă
25.04.2007
28
Structuri de control – selecţia (decizia) S2). Selecţia cu o alternativă (cu o ramură vidă) Instrucţiunea C corespunzătoare este if if(conditie) secventa;
25.04.2007
29
Structuri de control – selecţia (decizia) S2). Selecţia cu o alternativă (cu o ramură vidă) Exemple: 1)
int x, y, z; if(z != 0) y = x/z;
2)
int x, z; if(x) z = 20;
25.04.2007
30
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if Reprezentare prin pseudocod dacă atunci <secventa1>; altfel dacă atunci <secventa2>; ........................................... dacă atunci <secventan> altfel <secventan+1>; sf. dacă 25.04.2007
31
Adevarat
Secventa 1
conditie 1
Adevarat
Secventa 2
Fals
conditie 2
Adevarat
Fals
conditie 3
Aici schema se continua cu cate conditii este nevoie
Seventa 3
Adevarat
Secventa n
25.04.2007
Fals
conditie n
Fals
Secventa n+1
32
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if În limbajul C avem
25.04.2007
if(conditie1) secventa1; else if(conditie2) secventa2; else if(conditie3) secventa3; …………………………………………………………. else if(conditien) secventan; else secventan+1;
33
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if sau
25.04.2007
if(conditie1) { if(conditie2) secventa1; else if(conditie3) secventa2; } else secventa3; 34
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if Exemple: a).
int c; if((c >= 'a') && (c <= 'z')) puts("litera mica"); else if((c >= 'A') && (c <= 'Z')) puts("LITERA MARE"); else if(c == ' ' || c == '\t' || c == '\n') puts("Caracter alb"); else if((c >= '0') && (c <= '9')) puts("Cifra"); else puts("Alt caracter");
25.04.2007
35
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if Exemple: b). if((c >= 'a') && (c <= 'z')) { puts("litera mica"); ++lit_mica; } else if((c >= 'A') && (c <= 'Z')) { puts("LITERA MARE"); ++lit_mare; } else { puts(Alt caracter"); ++alte; } 25.04.2007
36
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if Exemple: b). int esteEchilateral(int a, int b, int c); int esteIsoscel(int a, int b, int c); int esteDreptunghic(int a, int b, int c); int esteTriunghi(int a, int b, int c);
25.04.2007
37
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if if(esteTriunghi(a,b,c)) //if1 { printf("Este triunghi "); if(esteEchilateral(a,b,c)) { printf("echilateral.\n"); } else if(esteIsoscel(a,b,c)) { printf("isoscel.\n"); } 25.04.2007
//if2
//else if2 si if3
38
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.1) Cu instrucţiunea if else if(esteDreptunghic(a,b,c)) { printf("dreptunghic.\n"); } else printf("oarecare.\n"); } else puts("Nu este triunghi");
// else if3 si if4
// else if4
// else if1
25.04.2007
39
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch În cazul unei scheme logice de următorul tip:
Expresie ?
Val1
Secventa 1
25.04.2007
Val2
Secventa 2
Val3
Secventa 3
Valn
Secventa n
Rest
Secventa n+1
40
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch if(x == val1) /* o secvenţă de cod – secventa1*/ else if(x == val2) /* altă secvenţă de cod – secventa2*/ else if(x == val3) /* o a treia secvenţă de cod – secventa3*/ else if(x == val4) /* o a patra secvenţă de cod – secventa4*/ else /* secvenţa de cod implicită - secventa5 */ 25.04.2007
41
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch switch(x) { case val1: secventa1; break; case val2: secventa2; break; case val3: secventa3; break;
25.04.2007
42
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch case val4: secventa4; break; default: }
secventa5;
25.04.2007
43
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch Forma generală: switch(exp) { case c1: ... cod ... break; case c2: ... cod ... break; ………………………………….... default: ... cod ... } 25.04.2007
44
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch unde exp este o expresie de tip întreg c1, c2, ... sunt constante de tip întreg. Observaţie: Instrucţiunea break poate lipsi şi atunci codul se execută în secvenţă, începând cu cazul constantei ci care egalează valoarea expresiei exp.
25.04.2007
45
Structuri de control – selecţia (decizia) S3). Selecţia multiplă Exemplu: 1) Se citesc două numere întregi de la tastatură şi un operator. Să se calculeze rezultatul. ..................................... int a, b; int op; int r; scanf("%d%d", &a, &b); op = getchar();
25.04.2007
46
Structuri de control – selecţia (decizia) S3). Selecţia multiplă /* * Cu if */ if(op == '+') r = a+b; else if(op == '-') r = a-b; else if(op == '*') r = a*b; else if(op == '/') { 25.04.2007
47
Structuri de control – selecţia (decizia) S3). Selecţia multiplă if(b != 0) r = a/b; else { puts("Eroare\n"); r = 0; } } else { puts("Operator necunoscut\n"); r = 0; } 25.04.2007
48
Structuri de control – selecţia (decizia) S3). Selecţia multiplă /* * Cu switch */ switch(op) { case '+': case '-': case '*':
r = a+b; break; r = a-b; break; r = a*b; break;
25.04.2007
49
Structuri de control – selecţia (decizia) S3). Selecţia multiplă case '/': if(b != 0) r = a/b; else { puts("Eroare\n"); r = 0; } break; default: puts("Operator necunoscut\n"); r = 0; }
25.04.2007
50
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch Exemplu 2. int ch; while((ch = getchar()) !=EOF) switch(ch) { case '0': case '2': case '4': case '6': case '8': ++cifre_pare; 25.04.2007
51
Structuri de control – selecţia (decizia) S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch
}
case '1': case '3': case '5': case '7': case '9': ++cifre; default: ++alte;
cifre_impare = cifre – cifre_pare; non_cifre = alte – cifre; ………………………………………
25.04.2007
52
Structuri de control repetitive - iteraţia Este o structură compusă care conţine o parte iterată care se execută de zero, una sau mai multe ori în funcţie de rezultatul unui test logic. Partea iterată poate fi o instrucţiune simplă, o secvenţă, o selecţie sau o altă iteraţie. 25.04.2007
53
Structuri de control repetitive - iteraţia Sunt trei structuri de control repetitive: ¾ iteraţie cu test iniţial (structura de control fundamentală) ¾ iteraţie cu test final (structură de control derivată) ¾ iteraţia cu contor (structură de control derivată) 25.04.2007
54
Structuri de control repetitive – iteraţia cu test iniţial Schema logică a acestei structuri de control este
Fals
conditie
Adevarat
Secventa
25.04.2007
55
Structuri de control repetitive – iteraţia cu test iniţial Reprezentarea în pseudocod: repetă cât timp <secvenţă>; sf. repetă
25.04.2007
56
Structuri de control repetitive – iteraţia cu test iniţial Instrucţiunea C while(conditie) secvenţă; Observaţie: Secvenţa trebuie să modifice una din variabilele ce apar in expresia conditie 25.04.2007
57
Structuri de control repetitive – iteraţia cu test iniţial Exemplu: 1).
ch = getchar(); while(ch != EOF) { ++nl; ch = getchar(); }
2).
int x, y, z; while(scanf("%d%d%d", &x, &y, &z) != 3) fflush(stdin);
25.04.2007
58
Structuri de control repetitive – iteraţia cu test final Schema logică a acestei structuri de control este Secventa
Fals
conditie
25.04.2007
Adevarat
59
Structuri de control repetitive – iteraţia cu test final În pseudocod are forma: repetă <secvenţă>; cât timp
25.04.2007
60
Structuri de control repetitive – iteraţia cu test final Instrucţiunea C corespunzătoare do { secventa; } while (expresie);
25.04.2007
61
Structuri de control repetitive – iteraţia cu test final Exemplu: 1) reluarea programului cu mai multe seturi de date. do { ………………………… printf("Reluati? (d/n) "); ch = getchar(); } while (tolower(ch) == 'd');
25.04.2007
62
Structuri de control repetitive – iteraţia cu test final 2) Calculul valorii exponenţialei (recurenţă când nu se cunoaşte numărul de paşi).
x 2 x3 xn + +K+ +K e =1+ x + n! 2! 3! xk uk = k! x k −1 x x ⋅ = u k −1 ⋅ uk = u0 = 1 (k − 1)! k k x
25.04.2007
63
Structuri de control repetitive – iteraţia cu test final 2)
e x = u0 + u1 + u 2 + K + u n + Rn S k = u0 + u1 + K + u k −1 + u k S k = S k −1 + u k
S −1 = 0
Calculul se repetă până când S k − S k −1 < u k < ε
25.04.2007
64
Structuri de control repetitive – iteraţia cu test final 2) double expProprie(double x, double eps) { double S = 1, u = 1; int k = 0; do { k = k + 1; u = x/k * u; S = S + u; } while(fabs(u) > eps); return S; } 25.04.2007
65
Iteraţia cu contor Schema logică a acestei structuri de control este dată în figură.
Fals
va r ← vi
var ≤ vf
Adevarat
Secventa
var ← var+ pas
25.04.2007
66
Structuri de control repetitive – iteraţia cu contor În pseudocod reprezentarea este repetă pentru = vi, vf, pas <secvenţă>; sf. repetă
25.04.2007
67
Structuri de control repetitive – iteraţia cu contor În C avem instrucţiunea for de forma: for(var = vi; var <= vf; var = var+pas) secventa; Acestei instrucţiuni i se asociază una sau mai multe variabile, numite variabile de buclă care controlează numărul de execuţii ale părţii iterate. În acest caz Æ var 25.04.2007
68
Structuri de control repetitive – iteraţia cu contor Observaţii: 1. variabila de buclă poate fi de tip întreg sau real 2. pas poate avea o valoare pozitivă sau negativă 3. expresia var <= vf poate fi înlocuită cu orice expresie care după un număr finit de paşi permite ieşirea din buclă 4. Această instrucţiune este echivalentă cu o instrucţiune repetitivă cu test anterior. 25.04.2007
69
Structuri de control repetitive – iteraţia cu contor Exemplu: int i, j; for(i=0; i
25.04.2007
70
Iteraţia cu contor O formă mai generală pentru instrucţiunea de iteraţie cu contor este dată în figura alăturată.
Ei
Fals
Et
Adevarat
Secventa
Em
25.04.2007
71
Structuri de control repetitive – iteraţia cu contor unde ei este expresia de iniţializare a variabilei (variabilelor) de buclă et este o expresie relaţională sau logică sau o expresie echivalentă care testează îndeplinirea unei condiţii pentru una sau mai multe variabile din buclă. În momentul în care expresia ia valoarea FALS se iese din buclă. em este o expresie care actualizează (modifică) valoarea variabilei (variabilelor) care se testează prin et. În general, aceasta este o expresie de incrementare, dar nu este singura expresie care poate apare aici. 25.04.2007
72
Structuri de control repetitive – iteraţia cu contor Instrucţiunea corespunzătoare în C este for(ei; et; em) <secventa>; care este echivalentă cu o iteraţie cu test anterior: ei; while(et) { <secventa>; em; } 25.04.2007
73
Structuri de control repetitive – iteraţia cu contor Observaţii: 1). Se foloseşte pentru prelucrarea tablourilor şi a pointerilor 2). Se foloseşte, de asemenea, pentru implemetarea relaţiilor de recurenţă (când se cunoaşte numărul de paşi) 3). Oricare din cele trei expresii poate lipsi. for(;;) i=0; for(; s[i] != '\0'; i=i+1) 25.04.2007
74
Structuri de control repetitive – iteraţia cu contor Exemplu: Calculul valorii unui polinom într-un punct.
P(x ) = a0 x n + a1 x n −1 + ... + an −1 x + an
P−1 (x ) = 0 Pn (x ) = Pn −1 (x ) ⋅ x + an 25.04.2007
75
Structuri de control repetitive – iteraţia cu contor double valoarePolinom(double a[], int n, double x) { int i; double P; P = 0.; for(i=0; i<=n; i=i+1) P = P * x + a[i]; return P; }
25.04.2007
76
Alte instrucţiuni break Permite ieşirea dintr-o buclă înainte de terminarea normală (dată de condiţia de test). Cu instrucţiunea break se iese din bucla cea mai interioară. Se foloseşte în asociaţie cu instrucţiunile repetitive sau instrucţiunea switch.
25.04.2007
77
Alte instrucţiuni break - exemple 1) while((c=getchar()) != '\n') { if(c == EOF) break; ++lung; }
25.04.2007
78
Alte instrucţiuni break - exemple 2)
for(i=0; i<MAX; ++i) { lung = 0; while((c = getchar()) != '\n') { if(c == EOF) break; ++lung; } printf("Lungimea liniei %d este %d\n", i, lung); }
25.04.2007
79
Alte instrucţiuni continue Determină terminarea unei iteraţii, prin saltul peste restul instrucţiunilor din buclă. Transferul programului se realizează la evaluarea expresiei de test (pentru while şi do ... while) şi la expresia de modificare a variabilelor de buclă în for.
25.04.2007
80
Alte instrucţiuni continue - exemple 1) for(i=0; i< MAX; i++) { r = i%7; if(0 == r) continue; sum += 15780/r; ………………………………………………. }
25.04.2007
81
Alte instrucţiuni return Determină oprirea execuţiei funcţiei în care se găseşte şi revine la funcţia care a făcut apelul (funcţia apelantă). Forma generală: return expresie; unde expresie trebuie să fie de acelaşi tip cu tipul funcţiei. Valoarea expresiei este valoarea furnizată de funcţie. 25.04.2007
82
Alte instrucţiuni goto Instrucţiune de salt necondiţionat. Forma generală: goto eticheta; unde eticheta este un identificator asociat unei instrucţiuni executabile din programul C. Identificatorul trebuie urmat de caracterul ':' NU SE FOLOSEŞTE ÎN PROGRAMAREA STRUCTURATĂ. 25.04.2007
83
PROGRAMAREA CALCULATOARELOR Curs nr. 9-10-11
25 aprilie 2007
Programarea Calculatoarelor
1
POINTERI 1
25 aprilie 2007
Programarea Calculatoarelor
2
Pointeri Notăm în continuare prin T un tip de dată predefinit sau definit de utilizator. Definirea unei variabile: T n; Æ 2 semnificaţii int j, k; k=2; j = 7; k = j; 25 aprilie 2007
// Linia 1 // Linia 2 Programarea Calculatoarelor
3
Pointeri - definiţii Variabile pointeri – definiţie – definire T *pt; T *pt1, *pt2, pt3; typedef T* PT; PT p1, p2, p3;
25 aprilie 2007
pt
// in header
Programarea Calculatoarelor
4
Pointeri - definiţii Variabile pointeri Exemple: int *pi; double *pr; struct PUNCT *pp; typedef int *POINTER_LA_INTREG; // in header POINTER_LA_INTREG p1, p2; 25 aprilie 2007
Programarea Calculatoarelor
5
Pointeri - definiţii Variabile pointeri –dimensiunea unui pointer sizeof(pt) Æ ?
25 aprilie 2007
Programarea Calculatoarelor
6
Pointeri – adresa unei variabile Adresa unei variabile. Operator de referenţiere &. T k; T *pt; pt = &k;// extrage valoarea stânga pentru k
INTERZIS: &(k+1) sau &5 25 aprilie 2007
Programarea Calculatoarelor
7
Pointeri – conţinutul unei adrese Conţinutul unei adrese. Operator de dereferenţiere *. T k = 3; T i; T *pt = &k; i = *pt; *pt = 5;
// Conţine valoarea de la adresa pt
printf("%d\n", *pt); // Dacă T este sinonim pentru // int 25 aprilie 2007
Programarea Calculatoarelor
8
Pointeri – expresii cu pointeri Expresii cu pointeri int *pk, j; double d; j = *pk + 10 d = sqrt((double) *pk) *pk = 0 *pk += 1 25 aprilie 2007
Programarea Calculatoarelor
9
Pointeri – expresii cu pointeri *pk++ (*pk)++ pk = pj Prioritatea operatorilor * şi & j = *pk + 1 j = *(pk + 1) 25 aprilie 2007
Programarea Calculatoarelor
10
Pointeri – trebuie cunoscut tipul De ce este necesară cunoaşterea tipului? int k; int *pi = &k; *pi = 2; double r; double *pr = &r; *pr = 3.14159; 25 aprilie 2007
Programarea Calculatoarelor
11
Pointeri – pointer generic Pointer generic (pointer incomplet) void *p; Acest tip de pointer nu poate fi dereferenţiat, nu poate indica către nici o valoare şi nu pot fi utilizaţi în operaţii din aritmetica pointerilor. Pentru a fi utilizat el trebuie convertit (explicit) la un tip complet de pointer. 25 aprilie 2007
Programarea Calculatoarelor
12
Pointer – pointer generic Este folosit pentru a utiliza în aceeaşi expresie diferite tipuri de pointeri. Exemplu: int i; char c; void *data;
25 aprilie 2007
Programarea Calculatoarelor
13
Pointeri – exemplu pointer generic i = 6; c = 'a'; data = &i; printf("Data indica un intreg %d\n", *(int *)data); data = &c; printf("Data indica un caracter %c\n", *(char *)data); 25 aprilie 2007
Programarea Calculatoarelor
14
Pointeri – iniţializarea pointerilor cu adresa unei variabile a) atribuirea unei adrese de variabilă int i; int *pi; pi = &i;
25 aprilie 2007
Programarea Calculatoarelor
15
Pointeri – iniţializarea pointerilor cu valoarea zero b) atribuirea valorii NULL int *pi = NULL; double *pr = 0;
25 aprilie 2007
Programarea Calculatoarelor
16
Pointeri – iniţializarea pointerilor cu valoarea unui alt pointer c) atribuirea valorii unui alt pointer int i; int *pi, *pj;
pi pj
pi = &i; pj = pi; 25 aprilie 2007
i
Programarea Calculatoarelor
17
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei d) alocarea dinamică a memoriei Prototipuri în stdlib.h size_t este definit în stdio.h şi este sinonim pentru unsigned int. typedef unsigned int size_t; 25 aprilie 2007
Programarea Calculatoarelor
18
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei a) void *malloc(size_t nrOcteti); Exemplu: char *p; p = (char *)malloc(15);
p 25 aprilie 2007
Programarea Calculatoarelor
19
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei a) void *malloc(size_t nrOcteti); Exemplu: short int *p1; p1 = (short int *)malloc(5*sizeof(short int));
p1 25 aprilie 2007
Programarea Calculatoarelor
20
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei T *pt; pt = (T *)malloc(n * sizeof(T)); if(pt == 0) { fprintf(stderr, "Eroare la alocare \n"); exit(EXIT_FAILURE); }
25 aprilie 2007
Programarea Calculatoarelor
21
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei xmalloc Æ funcţie de alocare a memoriei, cu verificarea alocării şi care păstrează aceeaşi semnătură ca şi malloc.
25 aprilie 2007
Programarea Calculatoarelor
22
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei void *xmalloc(size_t nrOcteti) { void *ptr; ptr = malloc(nrOcteti); if(ptr == NULL) { fprintf(stderr, "Eroare alocare memorie\n"); exit(EXIT_FAILURE); } return ptr; } 25 aprilie 2007
Programarea Calculatoarelor
23
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei Exemple: 1) int *p; p = (int *)xmalloc(20 * sizeof(int));
25 aprilie 2007
Programarea Calculatoarelor
24
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei 2) struct DATA { int zi, an; char *luna; }; struct DATA *ps, astazi; ps = (struct DATA *) xmalloc(sizeof(struct DATA));
25 aprilie 2007
Programarea Calculatoarelor
25
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei Operatorul de selecţie -> ps -> an = 2005; astazi.an = 2005; ps -> zi = 25; astazi.zi = 5; printf("Anul este %d si ziua %d.\n", ps->an, ps->zi); 25 aprilie 2007
Programarea Calculatoarelor
26
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei ps->luna = (char *) xmalloc(15*sizeof(char)); astazi.luna = (char *) xmalloc(15*sizeof(char));
25 aprilie 2007
Programarea Calculatoarelor
27
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei b) eliberarea memoriei void free(void *p); free((T *)pt); pt = NULL;
25 aprilie 2007
Programarea Calculatoarelor
28
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei c) void *calloc(size_t nrElemente, size_t dimElement); Exemplu: double *p1; p1 = (double *)calloc(10, sizeof(double)); if(p1 == NULL) { fprintf(stderr, "Eroare la alocare\n"); exit(EXIT_FAILURE); } 25 aprilie 2007
Programarea Calculatoarelor
29
Pointeri – iniţializarea pointerilor prin alocarea dinamică a memoriei d) void *realloc(void *block, size_t n); Exemplu: double *p1; p1 = (double *)realloc(p0, nE*sizeof(double)); if(p1 == NULL) { fprintf(stderr, "Eroare la alocare\n"); exit(EXIT_FAILURE); } 25 aprilie 2007
Programarea Calculatoarelor
30
Pointeri – aritmetica pointerilor Operaţii permise în aritmetica pointerilor adunarea / scăderea unui întreg incrementarea / decrementarea unui pointer comparaţii, testarea egalităţii scăderea a doi pointeri
25 aprilie 2007
Programarea Calculatoarelor
31
Pointeri – aritmetica pointerilor adunarea / scăderea unui întreg short int *pi, *p2; float *pf, *pf2; int n = 3; După o iniţializare, putem scrie p2 = pi + n; pf = pf2 + n; 25 aprilie 2007
Programarea Calculatoarelor
32
Pointeri – aritmetica pointerilor adunarea / scăderea unui întreg
↑
↑
pi
p2
↑
↑
pf2
pf Programarea Calculatoarelor
25 aprilie 2007
33
Pointeri – aritmetica pointerilor incrementarea /decrementarea unui pointer char *p1, *p2, *p3; p2 = ++p1; p3 = --p1;
↑
↑
↑
p3 p1 p2 25 aprilie 2007
Programarea Calculatoarelor
34
Pointeri – aritmetica pointerilor incrementarea / decrementarea unui pointer float *pf1, *pf2, *pf3; pf1++; pf2 = pf1;
pf1--; pf3 = pf1;
↑
↑
↑
pf3
pf1
pf2
Programarea Calculatoarelor
25 aprilie 2007
35
Pointeri – aritmetica pointerilor compararea a doi pointeri < > ==
25 aprilie 2007
<= >= !=
↑
↑
p
q
Programarea Calculatoarelor
36
Pointeri – aritmetica pointerilor scăderea a doi pointeri short int *p1, *p2; ………………………………… p2-p1 Æ numărul de elemente dintre p1 şi p2.
↑
↑
p1
p2 Programarea Calculatoarelor
25 aprilie 2007
37
Pointeri şi tablouri Un tablou: short int v[5]; ↑ v Un pointer: short int *p; p = (short int *)xmalloc(5*sizeof(short int)); ↑ p 25 aprilie 2007
Programarea Calculatoarelor
38
Pointeri şi tablouri short int *pv; pv = &v[0];
↑ v
pv
pv = v;
25 aprilie 2007
Programarea Calculatoarelor
39
Pointeri şi tablouri short int x = *pv; short int x = pv[0]; short int y = *(pv+1); short int y = pv[1];
25 aprilie 2007
Programarea Calculatoarelor
40
Pointeri şi tablouri short int z; z = v[i]; z = pv[i]; z = *(v+i); z = *(pv + i);
Programarea Calculatoarelor
25 aprilie 2007
41
Pointeri şi tablouri Putem avea nu numai pointeri la primul element al tabloului, dar şi pointeri la un element oarecare. short int v[5]; short int *p; p = &v[3]; p[1] ↔ v[4]
25 aprilie 2007
↑
↑
v
p Programarea Calculatoarelor
42
Pointeri şi tablouri
De ce primul index al unui tablou este 0 (zero)?
25 aprilie 2007
Programarea Calculatoarelor
43
Pointeri şi tablouri Diferenţa dintre pointeri şi tablouri short int v[5]; short int *pv; pv = &v[0]; pv++; pv = v + 3; v++; v = pv + 4; 25 aprilie 2007
// NU // NU Programarea Calculatoarelor
44
Pointeri şi tablouri - exemple 1) copierea unui şir în alt şir char src[] ="Sir de test"; char dest[30]; char *dp = &dest[0]; char *sp = &src[0]; while(*sp != '\0') { *dp = *sp; dp++; sp++; } *dp = '\0'; 25 aprilie 2007
Programarea Calculatoarelor
45
Pointeri şi tablouri - exemple 2) copierea unui vector de întregi în altul int v1[10], v2[10]; int *ip1, *ip2 = &v2[0]; int *ep = &v1[10]; for(ip1=&v1[0]; ip1 < ep; ip1++) *ip2++ = *ip1;
25 aprilie 2007
Programarea Calculatoarelor
46
Pointeri şi tablouri - exemple 3) determinarea maximului int maxim(int a[], int n) { int max; ↑ int *p; ai int *ai = &a[0]; int *af = a+n; max = *a; for(p = a+1; p < af; p++) if(*p > max) max = *p; return max; } Programarea Calculatoarelor
25 aprilie 2007
↑ af
47
Pointeri şi tablouri - exemple char c[] = "Sir de test"; int i; for(i=0; c[i] != '\0'; i++) printf("%s\n", &c[i]); S i ↑ c
25 aprilie 2007
r
d e ↑
t e s t \0
c[i]
Programarea Calculatoarelor
48
Pointeri şi funcţii Pointerii pot fi (ca orice altă variabilă): -parametri pentru funcţii Exemplu: void f1(int *a, int n); Se simulează astfel transferul prin referinţă. int a[20]; f1(a,n); f1(&a[2], n1); f1((a+2), n1)
25 aprilie 2007
Programarea Calculatoarelor
49
Pointeri şi funcţii void F(int a, int b) { int aux; aux = a; a = b; b = aux; } …………… a? a=10; b = 20; b? F(a,b); …………… 25 aprilie 2007
Programarea Calculatoarelor
50
Pointeri şi funcţii void swap(int *a, int *b) { int aux; aux = *a; *a = *b; *b = aux; } ………………… a = 10; a? b = 20; b? swap(&a, &b); ………………… 25 aprilie 2007
Programarea Calculatoarelor
51
Pointeri şi funcţii Pointerii pot fi (ca orice altă variabilă): -valori de retur pentru funcţii double *f2(int *a, char *b, float *c); Exemplu: double *pf; pf = f2(x,y,z); x, y, z – variabile pointer declarate corespunzător
25 aprilie 2007
Programarea Calculatoarelor
52
Pointeri – exemple Să se scrie un program de calculare a valorii maxime dintr-un şir de caractere folosind operaţii cu pointeri. Modul VECTOR: VECTOR.H VECTOR.C
25 aprilie 2007
Programarea Calculatoarelor
53
VECTOR.H #ifndef _VECTOR_ #define _VECTOR_ void *xmalloc(size_t n); int *citireVector(size_t n, char *s); void afisareVector(int *a, size_t n); size_t maximVector(int *a, size_t n); #endif 25 aprilie 2007
Programarea Calculatoarelor
54
VECTOR.C int *citireVector(size_t n, char *s) { int *a; size_t i; a = xmalloc(n*sizeof(int)); for(i=0; i
Programarea Calculatoarelor
55
VECTOR.C void afisareVector(int *a, size_t n, char *s) { size_t i; printf("%s(=", s); for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
56
VECTOR.C size_t maximVector(int *a, size_t n) { size_t index = 0; int *b = a; int max = *b; for(;(b-a) < n; b++) { if(max < *b) { index = b-a; max = *b; } } return index; } 25 aprilie 2007
Programarea Calculatoarelor
57
MAIN.C #include <stdio.h> #include "vector.h" int main(void) { int *a; size_t n; size_t indexMax; printf("Numarul de elemente din vector: "); scanf("%u", &n); 25 aprilie 2007
Programarea Calculatoarelor
58
MAIN.C a = citireVector(n, "A"); afisareVector(a, n, "A"); indexMax = maximVector(a,n); printf("Valoarea maxima este %d " "si se gaseste in elementul cu indexul %u.\n", *(a+indexMax), indexMax); free((int *)a); a = 0; return 0; } 25 aprilie 2007
Programarea Calculatoarelor
59
Funcţii care returnează pointeri Funcţie care calculează suma a doi vectori de numere reale double *sumaVectori(double *a, double *b, size_t n) { double *suma; size_t i; suma = (double *)xmalloc(n * sizeof(double)); for(i=0; i
Programarea Calculatoarelor
60
Funcţii care returnează pointeri int main(void) { …………………… double *s; …………………… s = sumaVectori(a, b, n); afisareVector(s, n, "Suma"); …………………… free((double *) s); s = 0; …………………… } 25 aprilie 2007
Programarea Calculatoarelor
61
Pointeri constanţi şi pointeri la o constantă int main(void) { int x, y; // Pointer la o constanta const int *pic; // Pointer constant int *const cp = &x; // Pointer constant la o constanta const int *const cp1 = &y; 25 aprilie 2007
Programarea Calculatoarelor
62
Pointeri constanţi şi pointeri la o constantă x = 3; y = 10; pic = &x; *pic = 5; /* Nepermis, pointer la o constanta */ cp++; /* Nepermis, pointer constant */ *cp = 20; 25 aprilie 2007
Programarea Calculatoarelor
63
Pointeri constanţi şi pointeri la o constantă *cp1 = 30; cp1++; /* Nepermis, pointer constant la o constanta */ return 0; }
25 aprilie 2007
Programarea Calculatoarelor
64
PROGRAMAREA CALCULATOARELOR Curs nr. 12-13-14
25 aprilie 2007
Programarea Calculatoarelor
1
POINTERI 2
25 aprilie 2007
Programarea Calculatoarelor
2
Tablou de pointeri Un tablou unidimensional (vector) se declară astfel: T tab[100]; typedef T1* T; T1* tab[100]; 25 aprilie 2007
Programarea Calculatoarelor
3
Tablou de pointeri tab tab[0] tab[1]
tab[99]
25 aprilie 2007
1
2
5
6
7
11
21
34
8
Programarea Calculatoarelor
4
Tablou de pointeri – exemplu Problema Se citeşte de la tastatură un text de maxim 50 de linii. Textul citit se depune în zone de memorie alocate dinamic, după care textul se sortează în ordinea lungimii liniilor şi se afişează.
25 aprilie 2007
Programarea Calculatoarelor
5
Tablou de pointeri – exemplu text text[0] text[1] text[2]
E
x
e m p
d
e \0
t
e
x
l
u \0
t \0
text[49] 25 aprilie 2007
Programarea Calculatoarelor
6
Tablouri de pointeri – exemplu TEXT.H #ifndef _TEXT_ #define _TEXT_ #define L 50 void *xmalloc(size_t size); int citireText(char *text[], int Lmax); void afisareText(char *text[], int nl);
25 aprilie 2007
Programarea Calculatoarelor
7
Tablouri de pointeri – exemplu TEXT.H void sortareText(char *text[], int nl); void swapL(char **l1, char **l2); void eliberareMemorie(char *text[], int nl); #endif
25 aprilie 2007
Programarea Calculatoarelor
8
Tablouri de pointeri – exemplu MAIN.C #include <stdio.h> #include "text.h" int main(void) { char *text[L]; int numarLinii = 0;
25 aprilie 2007
Programarea Calculatoarelor
9
Tablouri de pointeri – exemplu MAIN.C numarLinii = citireText(text, L) if(numarLinii > 0) { afisareText(text, numarLinii); puts("Textul sortat este"); sortareText(text, numarLinii); afisareText(text, numarLinii); eliberareMemorie(text, numarLinii); } else 25 aprilie 2007
Programarea Calculatoarelor
10
Tablouri de pointeri – exemplu MAIN.C fprintf(stderr, "Nu s-a introdus text\n"); return 0; }
25 aprilie 2007
Programarea Calculatoarelor
11
Tablouri de pointeri – exemplu Functii_Text.c int citireText(char *text[], int Lmax) { int nl = 0; char temp[82]; int lung; while(nl < Lmax && fgets(temp, 81, stdin)) { lung = strlen(temp); temp[lung-1] = '\0'; 25 aprilie 2007
Programarea Calculatoarelor
12
Tablouri de pointeri – exemplu Functii_Text.c text[nl] = (char *) xmalloc((strlen(temp)+1)*sizeof(char)); strcpy(text[nl], temp); nl++; } return nl; }
25 aprilie 2007
Programarea Calculatoarelor
13
Tablouri de pointeri – exemplu Functii_Text.c void afisareText(char *text[], int nl) { int i; for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
14
Tablouri de pointeri – exemplu Functii_Text.c void eliberareMemorie(char *text[], int nl) { int i; for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
15
Tablouri de pointeri – exemplu Functii_Text.c void sortareText(char *text[], int nl) { int i; int ok; int k = nl – 1; do { ok = 1;
25 aprilie 2007
Programarea Calculatoarelor
16
Tablouri de pointeri – exemplu Functii_Text.c for(i=0; i strlen(text[i+1])) { swapL(&text[i], &text[i+1]); ok = 0; } k = k-1; } while((ok == 0) && (k>0)); } 25 aprilie 2007
Programarea Calculatoarelor
17
Tablouri de pointeri – exemplu Functii_Text.c void swapL(char **p1, char **p2) { char *aux; aux = *p1; *p1 = *p2; *p2 = aux; }
25 aprilie 2007
Programarea Calculatoarelor
18
Pointer la un tablou typedef unsigned char Byte; typedef int VECTOR[10]; VECTOR v; VECTOR v1[5]; VECTOR *pv; Programarea Calculatoarelor
25 aprilie 2007
19
Pointer la un tablou pv = &v1[0]; sau pv = v1; sizeof(*pv) ? Dacă nu folosim typedef int (*pv)[10]; int *p1[10]; 25 aprilie 2007
Programarea Calculatoarelor
20
Pointer la un tablou T (*pv)[10]; pv = (T (*)[10])xmalloc(1 * sizeof(*pv)); pv = (T (*)[10])xmalloc(N * sizeof(*pv));
25 aprilie 2007
Programarea Calculatoarelor
21
Pointer la un tablou – exemplu T *p; p T (*pv)[10];
pv pv = (T (*)[10])xmalloc(1 * sizeof(*pv)); 25 aprilie 2007
Programarea Calculatoarelor
22
Pointer la un tablou – exemplu pv = (T (*)[10])xmalloc(5 * sizeof(*pv));
(*pv+j)
pv
1 2 3 15 20 34 25 19 72 20 23 11
*(pv+2)
0
9
8
7
6
5
4
3
2
1
5 15 25 35 45 55 65 25 aprilie 2007
Programarea Calculatoarelor
23
Pointeri la un tablou *pv Ce semnificaţie are?
25 aprilie 2007
Programarea Calculatoarelor
24
Pointeri la un tablou *p1 (din legătura dintre pointeri şi tablouri) ⇔ p1[0] *pv+j Æ ? *(*pv+j) ⇔ *(pv[0]+j) ⇔ pv[0][j] *(*(pv+i)+j)
⇔ ⇔
*(pv[i] + j) pv[i][j]
Programarea Calculatoarelor
25 aprilie 2007
25
Pointeri la un tablou T *p3[10]; p3[0]+j
p3 p3[0] p3[1]
p3[9] 25 aprilie 2007
1
2
*(p3[0]+j)
5
6
7
11
21
34
Programarea Calculatoarelor
8
26
Pointeri la un tablou – exemplu TP.H #ifndef _TP_ #define _TP_ typedef int T; void *xmalloc(size_t n); #endif 25 aprilie 2007
Programarea Calculatoarelor
27
Pointeri la un tablou – exemplu main_TP.C int main(void) { T *p1; T (*p2)[10]; T *p3[10]; int i; size_t n = 20;
25 aprilie 2007
Programarea Calculatoarelor
28
Pointeri la un tablou – exemplu p1 = (T *)xmalloc(n * sizeof(T)); p2 = (T (*)[10])xmalloc(2*sizeof(*p2)); for(i=0; i<10; i++) { p3[i] = (T *)xmalloc(n * sizeof(T)); } 25 aprilie 2007
Programarea Calculatoarelor
29
Pointeri la un tablou – exemplu /* * * */
%p – format pentru afişarea valorii unui pointer
printf("1\n p1 = %p, p2 = %p, *p3 = %p, " "p3 = %p\n", p1, p2, *p3, p3); 25 aprilie 2007
Programarea Calculatoarelor
30
Pointeri la un tablou – exemplu for(i=0; i<10; i++) *(p1+i) = i; for(i=0; i<10; i++) { *(*p2+i) = i; *(*(p3+i)+0) = i; } 25 aprilie 2007
Programarea Calculatoarelor
31
Pointeri la un tablou – exemplu for (i=0; i<10; i++) { printf("p1 %p = %d \t",p1+i,*(p1+i)); printf("p2 %p = %d \n",*p2+i,*(*p2+i)); printf("*(p3+%d) %p = %d \n", *(p3+i)+0, *(*(p3+i)+0)); }
25 aprilie 2007
Programarea Calculatoarelor
32
Pointeri la un tablou – exemplu p3++; (*p3)++; p2++; p1++; printf("2 p1 = %p, p2 = %p, *p3 = %p\n", p1, p2, *p3);
25 aprilie 2007
Programarea Calculatoarelor
33
Pointeri la un tablou – exemplu free(--p1); p1 = 0; free(--p2); p2 = 0; free(--(*p3)); *p3 = 0; for(i=1; i<10; i++) { free(p3[i]); p3[i] = 0; } return 0; } 25 aprilie 2007
Programarea Calculatoarelor
34
Matrici alocate dinamic p[0]+j
p p[0] p[1]
p[9]
25 aprilie 2007
1
2
*(p[0]+j)
5
6
7
11
21
34
8
Programarea Calculatoarelor
35
Matrici alocate dinamic T p[10][20]; typedef T LINIE[20]; LINIE p1[10];
typedef T (*PT)[20]; int N = 10; PT p1; p1 = (T (*)[20])xmalloc(N * sizeof(*p1));
25 aprilie 2007
Programarea Calculatoarelor
36
Matrici alocate dinamic #ifndef _M1_ #define _M1_ typedef int T; typedef T LINIE[20]; typedef T (*VP)[20]; void afisareMatrice(T (*a)[20], int n, int m); void *xmalloc(size_t n); #endif 25 aprilie 2007
Programarea Calculatoarelor
37
Matrici alocate dinamic int main(void) { int n=2, m = 3; int i, j; LINIE mat[10]; /* T mat[10][20];
*/
VP mat1; mat1=(VP)xmalloc(10 * sizeof(*mat1));
25 aprilie 2007
Programarea Calculatoarelor
38
Matrici alocate dinamic for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
39
Matrici alocate dinamic puts("Matricea mat1"); afisareMatrice(mat1, n, m); free((VP) mat1); mat1 = 0; return 0; }
25 aprilie 2007
Programarea Calculatoarelor
40
Matrici alocate dinamic void afisareMatrice(VP a, int n, int m) /* void afisareMatrice(T a[][20], int n, int m) */ { int i, j; for(i=0; i
Programarea Calculatoarelor
41
Matrici alocate dinamic De ce trebuie să transmitem a doua dimesiune pentru o matrice? mat[i][j] Æ ? *(*(mat+i) + j))
25 aprilie 2007
Programarea Calculatoarelor
42
Matrici alocate dinamic T (*pv)[10]; pv = (T (*)[10])xmalloc(5 * sizeof(*pv)); (*pv+j)
*(pv+i)+j 1 2 3 15 20 34 25 19
pv
72 20 23 11 pv+i
0
9
8
7
6
5
4
3
2
1
5 15 25 35 45 55 65 25 aprilie 2007
Programarea Calculatoarelor
43
Matrici alocate dinamic typedef T LINIE[20]; LINIE p1[10]; /* T p1[10][20] */ typedef T* PLINIE; PLINIE mat[5]; PLINIE *mat; T** mat;
25 aprilie 2007
Programarea Calculatoarelor
44
Matrici alocate dinamic T **aloca2d(size_t LINII, size_t COLOANE) { T **a; size_t i; a = (T **)xmalloc(LINII * sizeof(T *)); for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
45
Matrici alocate dinamic void dealoca2d(T **a, size_t LINII) { size_t i; for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
46
Matrici alocate dinamic T **aloca2dc(size_t LINII, size_t COLOANE) { T **a; size_t i; a = (T **)xmalloc(LINII * sizeof(T *)); a[0] = (T *)xmalloc(LINII * COLOANE * sizeof(T)); for(i=1; i
Programarea Calculatoarelor
47
Matrici alocate dinamic void dealoca2dc(T **a) { free((T *) a[0]); a[0] = 0; free ((T **) a); }
25 aprilie 2007
Programarea Calculatoarelor
48
Matrici alocate dinamic - exemplu Să se scrie un program care folosind matrice alocate dinamic, ordonează liniile unei matrice de numere întregi în ordinea crescătoare a elementului maxim de pe fiecare linie. Exemplu: -1 0 1 2 3 1 0 -1 -2 25 aprilie 2007
Æ
0 -1 -2 -1 0 1 2 3 1
Programarea Calculatoarelor
49
Matrici alocate dinamic - exemplu Proiect: 1. modul de alocare: ALOCARE.H ALOCARE.C 2. modul de lucru cu matrice MATRICE.H MATRICE.C
25 aprilie 2007
Programarea Calculatoarelor
50
Matrici alocate dinamic - exemplu ALOCARE.H #ifndef _ALOCARE_ #define _ALOCARE_ int **aloca2d(int n, int m); void dealoca2d(int **a, int n); void *xmalloc(size_t n); #endif
25 aprilie 2007
Programarea Calculatoarelor
51
Matrici alocate dinamic - exemplu ALOCARE.C #include "alocare.h" int **aloca2d(int n, int m) { int **a; int i; a = (int **)xmalloc(n * sizeof(int *)); for(i=0; i
Programarea Calculatoarelor
52
Matrici alocate dinamic - exemplu ALOCARE.C void dealoca2d(int **a, int n) { int i; for(i=0; i
Programarea Calculatoarelor
53
Matrici alocate dinamic - exemplu MATRICE.H #ifndef _MATRICE_ #define _MATRICE_ int **citireMatrice(int n, int m, char *den); void afisareMatrice(int **a, int n, int m, char *den); void sortareMatrice(int **a, int n, int m); void swapi(int **l1, int **l2); int maxim(int *a, int m); #endif 25 aprilie 2007
Programarea Calculatoarelor
54
Matrici alocate dinamic - exemplu MATRICE.C #include "alocare.h" #include "matrice.h" int **citireMatrice(int n, int m, char *den) { int **a; int i, j; a = aloca2d(n,m);
25 aprilie 2007
Programarea Calculatoarelor
55
Matrici alocate dinamic - exemplu for(i=0; i
25 aprilie 2007
Programarea Calculatoarelor
56
Matrici alocate dinamic - exemplu void afisareMatrice(int **a, int n, int m, char *den) { int i, j; printf("Matricea %s este\n", den); for(i=0; i
Programarea Calculatoarelor
57
Matrici alocate dinamic - exemplu void sortareMatrice(int **a, int n, int m) { int i; int ok; int k = n-1;
25 aprilie 2007
Programarea Calculatoarelor
58
Matrici alocate dinamic - exemplu do { ok = 1; for(i=0; i maxim(a[i+1], m)) { swapi(&a[i], &a[i+1]); ok = 0; } k = k - 1; } while((ok == 0) && (k>0)); } 25 aprilie 2007
Programarea Calculatoarelor
59
Matrici alocate dinamic - exemplu void swapi(int **l1, int **l2) { int *aux; aux = *l1; *l1 = *l2; *l2 = aux; }
25 aprilie 2007
Programarea Calculatoarelor
60
Matrici alocate dinamic - exemplu int maxim(int *a, int m) { int max; int i; max = *a; for(i=1; i<m; i++) if(*(a+i) > max) max = *(a+i); return max; }
25 aprilie 2007
Programarea Calculatoarelor
61
Matrici alocate dinamic - exemplu #include "alocare.h" #include "matrice.h" int main(void) { int **a; int n, m;
25 aprilie 2007
Programarea Calculatoarelor
62
Matrici alocate dinamic - exemplu do { printf("Nunarul de linii din matrice: "); scanf("%d", &n); printf("Numarul de coloane din matrice: "); scanf("%d", &m); } while(n<=0 || m<=0); a = citireMatrice(n, m, "A"); afisareMatrice(a, n, m, "A"); sortareMatrice(a, n, m);
25 aprilie 2007
Programarea Calculatoarelor
63
Matrici alocate dinamic - exemplu puts("\nDupa sortare"); afisareMatrice(a, n, m, "A"); dealoca2d(a,n); a=0; return 0; }
25 aprilie 2007
Programarea Calculatoarelor
64
Argumentele liniei de comandă Linia de comandă Æ există şi în Windows Æ redirectarea intrării şi ieşirii p1 out.txt p1 out.txt int main(void) int main(int argc, char *argv[]) 25 aprilie 2007
Programarea Calculatoarelor
65
Argumentele liniei de comandă int main(int argc, char *argv[]) { int i; for(i=0; i<argc; i++) puts(argv[i]); return 0; }
25 aprilie 2007
Programarea Calculatoarelor
66
Argumentele liniei de comandă Expandarea argumentelor WILDARGS.OBJ din …\LIB
Aceeaşi problemă cu dimensiunile matricei citite din linia de comandă
25 aprilie 2007
Programarea Calculatoarelor
67