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 Afisarea rezultatelor Validarea datelor 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 p = a + b 2 + c Celelalte mărimi vor fi calculate cu relaţiile: Înălţimea din vârful A Mediana din vârful A m a Bisectoarea unghiului A h a = A a = 2 ( 2 2 2 b + c ) 4 p b c b a = 2 b + c a 2 ( p a)
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 <conio.h> #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. litere (mari sau mici) ale alfabetului latin 2. caracterul _ (subliniere sau underscore) 3. 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 C citestedatedeintrare a_1 afiseaza_vector 25/04/07 PC - Curs nr. 2 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 int float signed char signed short int signed int signed long int double unsigned char unsigned short int unsigned int unsigned long int long double 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 short int are %d octeti.\n", sizeof(short int)); printf("tipul int are %d octeti.\n", sizeof(int)); printf("tipul long int are %d octeti.\n", sizeof(long int)); printf("tipul char are %d octeti.\n", sizeof(char)); printf("tipul float are %d octeti.\n", sizeof(float)); printf("tipul double are %d octeti.\n", sizeof(double)); printf("tipul 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]; // Şir de caractere 25/04/07 PC - Curs nr. 2 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; ; struct _Persoana { char nume[50]; int varsta; struct _DATA datanasterii; double salariu; double impozit; ; 25/04/07 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; // De exemplu V[0] // De exemplu A.m sau A.A[0][0] 25/04/07 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 49 CONSTANTE
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
Comstantesimbolice-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 25/04/07 1 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("<format>", <adr1>, <adr2>,...); 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 <conio.h> 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("<format>", <arg1>, <arg2>, ); unde <format> 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); // 01 printf("%.3d", a); // 001 float a=2.3; printf("%.0f", a); // 2 double f = 34.5; // %lf long double g = 74; // %Lf long j = 123; // %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<n-1; i=i+1) printf("%3d, ", a[i]); printf("%3d)\n",a[i]); 25/04/07 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 = (x i ) i=1,n şi Y = (y i ) i=1,n atunci s = x + i i y i PS = n i= 1 x i y i 25/04/07 21 Analiza problemei 1. 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. 2. o funcţie de citire a unui vector când se cunoaşte numărul de elemente care trebuie citite 3. o funcţie de afişare a unui vector 4. funcţia de calcul a vectorului sumă 5. funcţia de calcul a produsului scalar 25/04/07 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 <conio.h> #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<n; i=i+1) { printf("%s(%d) = ", den, i); scanf("%d",&a[i]); 25/04/07 30
VECTOR.C void afisarevector(int a[], int n, char den[]) { int i; printf("%s=(", den); for(i=0; i<n-1; i=i+1) { printf("%d, ", a[i]); printf("%d)\n", a[n-1]); 25/04/07 31 VECTOR.C long produsscalar(int x[], int y[], int n) { long ps; int i; ps = 0; for(i=0; i<n; i=i+1) ps = ps + x[i]*y[i]; return ps; 25/04/07 32
VECTOR.C void sumavectori(int a[], int b[], int s[], int n) { int i; for(i=0; i<n; i = i+1) s[i] = a[i] + b[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<n; i=i+1) for(j=0; j<m; j=j+1) { char temp[81]; fgets(temp, 80, stdin); if(sscanf(temp, "%lf", &a[i][j])!= 1) { ok = 0; return ok; return ok; 25/04/07 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 25/04/07 1 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ă: aritmetici incremetare şi decrementare relaţionali logici logici la nivel de bit atribuire accesul 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++) /*CORECT */ a[i] = i; 25/04/07 17 Operatori de incrementare - decrementare 4) { int i = 1; printf("%d %d\n", i++, i++); Se afişează 2 1 5) i = ++i + 1; /* expresie nedefinită */ 6) i++ + j++ * k++ /*expresie nedefinită */ 25/04/07 18
Operatori de incrementare - decrementare #include <stdio.h> #include "ex.h" int main(void) { int a, i = 10; a = next(i); printf("a =\n\t%d\n", a); int next (int x) { return x++; Programul va afişa: a = 10 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 a[i+j+2*k] += 4 25/04/07 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); int a[2][3] = {1,2,3,4,5,6; 1 4 2 5 3 6 int a[2][3] = {{1,2,3,{4,5,6; 1 4 2 5 3 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 = 67 10 c = n & 0100 8 ; MASCĂ n = 67 10 = 2 6 + 2 1 + 2 0 = 01000011 2 = 0103 8 c = n & 0100 8 = 0103 8 & 0100 8 = 0100 8 25/04/07 44
Operatori logici asupra biţilor Operatorul & (ŞI) Exemple: b) c = n & 0177400 8 = n & 11111111 00000000 2 MASCĂ octet superior octet inferior c) c = n & 0377 8 = n & 00000000 11111111 2 octet superior octet inferior 25/04/07 45 Operatori logici asupra biţilor Operatorul ^ (SAU EXCLUSIV XOR) ^ 0 0 0 1 1 0 lasă biţii nemodificaţi 1 complementează biţii 1 1 0 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 bitul 4 dintr-un octet. MASCA = 0x10 00010000 Pentru c = 0x5bu 01011011 rezultatul expresiei c^masca este 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 = 66 10 MASK = 11 8 z = 66 10 11 8 = 102 8 11 8 = 113 8 = 75 10 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 = 77 8 z = 66 10 77 8 = 102 8 77 8 = 177 8 = 127 10 c) x = 66 10 MASK = 68 10 z = 66 10 68 10 = 42 16 44 16 = = 01000010 2 01000100 2 = 01000110 2 = 46 16 = 70 10 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 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 n << 3 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 n >> 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 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 = 42 16 şi x = x & ~077u 8 (fără semn) ~077 8 = ~00000000 00111111 2 = 11111111 11000000 2 x = 00000000 01000010 2 & 11111111 11000000 2 x = 00000000 01000000 2 = 100 8 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 = D275 16 15 an 9 8 luna 5 4 ziua 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 return valid; if(luna == 4 luna == 6 luna == 9 luna == 11) if(zi > 30) valid = 0; else valid = 1; 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<b)? a : b este valoarea minimă dintre a şi b. 25/04/07 65 Expresia şi operatorul condiţional b) for(i=0; i<n; i++) printf("%6d%c", a[i], (i%10 == 9) (i == N-1)? '\n' : ' '); c) f1(a, b+1, c+d, xx, (g+h+i)/2); unde f xx = 0 daca expresia e1este adevarata 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ă. 2 3x + 7x 10 pentru x < 0 f ( x) = 2 pentru x = 0 2 4x + 3x 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ă: expresie 1, expresie 2,..., expresie n Valoarea şi tipul acestei expresii coincid cu valoarea şi tipul ultimei expresii (expresie n ) 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[index 1 ][index 2 ] [index n ] unde numetablou trebuie să fie numele unui tablu cu n dimensiuni, iar index 1,..., index n 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