Program Area Calculatoarelor - Note De Curs

  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Program Area Calculatoarelor - Note De Curs as PDF for free.

More details

  • Words: 16,516
  • Pages: 228
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

Related Documents