Sunteți pe pagina 1din 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 Prelucrarea Afisarea


de intrare datelor rezultatelor

Validarea datelor Calcularea mãrimilor


cerute
Etapa 3
Notăm lungimile celor trei laturi cu a, b, c.

Aria unui triunghi (conform formulei lui Heron)


este:

A= p⋅( p−a)⋅( p−b)⋅( p−c)


unde
a+b+c
p=
2

Celelalte mărimi vor fi calculate cu relaţiile:


2⋅ A
Înălţimea din vârful A ha =
a
Mediana din vârful A

ma =
(
2 ⋅ b2 + c2 − a2)
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 <conio.h>
#include <stdlib.h> // system
#include "triunghi.h"
int main(void)
{
int a, b, c;
int ok;
float aria, ha, ma, ba;
clrscr(); // system("cls");
/*
* Se introduc lungimile celor 3 laturi
*/

Fişierul P1.c – continuare


do {
printf("a = "); scanf("%d", &a);
printf("b = "); scanf("%d", &b);
printf("c = "); scanf("%d", &c);
ok = OK(a,b,c);
if (ok == 0) {
printf("Numerele a=%d, b=%d, c=%d \
nu pot fi lungimile laturilor unui triunghi.\n", a, b, c);
printf("Introduceti inca o data datele de intrare\n");
}
} while (ok == 0);
Fişierul P1.c – continuare
/*
* Se calculeaza valorile cerute
*/
aria = Aria(a, b, c);
ha = inaltime(a, b, c);
ma = mediana(a, b, c);
ba = bisectoare(a, b, c);

Fişierul P1.c – continuare


/*
* Afiseaza rezultatele
*/
printf("Aria calculata a triunghiului este %4.2f\n", aria);
printf("Lungimea inaltimii din varful A este %4.2f\n", ha);
printf("Lungimea medianei din varful A este %4.2f\n", ma);
printf("Lungimea bisectoarei unghiuluil A este %4.2f\n", ba);

if(getch() == 0x00) getch(); // if(!getch()) getch();

return 0;
}
TEMA
•Folosind funcţiile scris (şi nu altele) să se calculeze
lungimile înălţimii, medianei şi bisectoarei care pleacă
din vârfurile B şi C.

• Să se reyolve problema în cazul în care datele de


intrare sunt reprezentate de coordonatele în plan ale
celor vârfurilor triunghiului.

•De ce folosesc construcţia


if(getch()== 0x00) getch()ş
PROGRAMAREA
CALCULATOARELOR

Curs nr. 2-3

Limbajul C – Scurt istoric


Justificarea numelui

Este urmaşul limbajului B creat la AT&T


Bell Laboratories pentru scrierea unui
sistem de operare (UNIX)

Este creat de D.M. Ritchie îin 1972

25/04/07 PC - Curs nr. 2 2


Limbajul C – scurt istoric
Prima carte despre limbaj:

Kernighan B.W. & Ritchie D.M., The C


Programming Language, 1978

Cartea este republicată în 1988.

25/04/07 PC - Curs nr. 2 3

Limbajul C – scurt istoric


1983 – se înfiinţează comisia X3J11 a
Institutului Naţional American de Standarde
(ANSI) pentru definirea unui standard

1989 (1990) – apare standardul de C. Limbajul


C standard mai este cunoscut şi sub
denumirea de C ANSI sau C90

1999 – un nou standard de C cu îmbunătăţiri


faţă de cel din 1990 Æ C99
25/04/07 PC - Curs nr. 2 4
Elemente de bază ale limbajului C

Program
• Ce este?
Sistem care prelucrează informaţii.

• Cum?
Prin interacţiunea unor entităţi (mai
simple sau mai complexe) care lucrează
împreună cu scopul de a îndeplini o
sarcină.
25/04/07 PC - Curs nr. 2 6
Entităţi
• Pot fi formate la rândul lor din alte
entităţi, mai simple.

• Se caracterizează prin:
– atribute
– comportament

25/04/07 PC - Curs nr. 2 7

Entităţi
În programarea structurată şi modulară
– Care conţin informaţii (se mai numesc şi date)
• variabilele
• constantele
– Care prelucrează informaţia:
• subprogramele (funcţiile)
În plus, pentru POO
– Care conţin informaţii şi în acelaşi timp pot
prelucra informaţii (conţin date şi funcţii - metode)
• obiecte

25/04/07 PC - Curs nr. 2 8


Variabile
• Sunt nume pe care le dăm unor locaţii de
memorie

• În program au dublă semnificaţie (în funcţie


de context):
– locaţia de memorie în sine
(i Å 2)
– valoarea care se găseşte în locaţia de memorie
respectivă
(j Å i)

25/04/07 PC - Curs nr. 2 9

Variabile
• Îşi pot modifica valoarea pe parcursul
execuţiei programului

• Pot fi accesate
– din întregul program (cazul variabilelor
globale)
– numai din funcţia sau blocul în care au fost
declarate şi/sau definite (cazul variabilelor
locale)
25/04/07 PC - Curs nr. 2 10
Constante
• Pot fi:
– de tip numeric, de tip caracter sau de tip şir de
caractere
– simbolice (numele şi valoarea sunt stocate în
tabele create de compilator)

• Nu se pot modifica pe parcursul programului

• Nu au asociată o locaţie de memorie


25/04/07 PC - Curs nr. 2 11

Funcţii
• Sunt entităţi care rezolvă o sarcină clar
delimitată din cadrul unui program

• Sunt formate din:


– definirea entităţilor purtătoare de informaţii
necesare
– instrucţiuni (comenzi)

• Instrucţiune Æ o comandă simplă, scrisă într-


un limbaj de programare şi care determină o
acţiune
25/04/07 PC - Curs nr. 2 12
• Fiecărei entităţi dintr-un program i se
asociază:
– un tip
– un identificator (nume)
– atribute (număr de elemente, componenţă,
date de intrare)

25/04/07 PC - Curs nr. 2 13

Identificatori
Sunt numele asociate entităţilor cu care lucrează
programul

In limbajul C, un identificator este o combinaţie de:


1. litere (mari sau mici) ale alfabetului latin
2. caracterul _ (subliniere sau underscore)
3. cifre (de la 0 la 9)

Atenţie
Primul caracter poate fi numai din 1. sau 2.

25/04/07 PC - Curs nr. 2 14


Identificatori
La alegerea identificatorilor:
1. Limbajul C este "case sensitive"
MIN ≠ Min ≠ min ≠ MiN

2. Lungimea maximă a unui identificator este de 31


de caractere

3. Trebuie folosiţi identificatori descriptivi


(identificatorul unei entităţi trebuie să sugereze ce
reprezintă sau ce face acea entitate)

25/04/07 PC - Curs nr. 2 15

Exemple identificatori
Corect
alfa beta _STIVA_ __C
citesteDateDeIntrare
a_1
afiseaza_vector

25/04/07 PC - Curs nr. 2 16


Exemple identificatori
Incorect
top...ten
2_si_3
a+b
medie aritmetica

25/04/07 PC - Curs nr. 2 17

Tip
Fiecare identificator dintr-un program are
un tip asociat.
Acest tip determină:
– mulţimea valorilor posibile pentru entitatea
respectivă
– ce operaţii pot fi aplicate entităţii asociate
asociate acelui nume
– cum sunt interpretate aceste operaţii

25/04/07 PC - Curs nr. 2 18


Tipuri fundamentale
Conţin o singură informaţie (sunt tipuri scalare)

1. întregi:
1. de tip caracter definite prin char
2. de tip întreg definite prin int

2. reale
1. în simplă precizie definite prin float
2. în dublă precizie definite prin double

25/04/07 PC - Curs nr. 2 19

Tipuri fundamentale
Fiecare din aceste tipuri poate fi folosit
însoţit de un modificator care se
plasează în faţa cuvântului cheie care
descrie tipul.

• pentru entităţile de tip întreg şi caracter


– signed
– unsigned

25/04/07 PC - Curs nr. 2 20


Tipuri fundamentale
• pentru entităţile de tip int
– short
– long

• pentru entităţile de tip double


– long

25/04/07 PC - Curs nr. 2 21

Tipuri fundamentale
char signed char unsigned char

int signed short int unsigned short int

signed int unsigned int

signed long int unsigned long int

float double long double

25/04/07 PC - Curs nr. 2 22


Tipuri fundamentale
Observaţii:
1. Mărimea exactă (în octeţi) a diferitelor tipuri
fundamentale şi domeniul de valori sunt
specificate în limits. h şi float. h.
2. Nu se fac presupuneri cu privire la
mărimea diferitelor tipuri. Pentru a
determina mărimea (în octeţi) a unui
anumit tip se foloseşte operatorul sizeof.

25/04/07 PC - Curs nr. 2 23

Tipuri fundamentale
Observaţii:
Forma generală a expresiei de determinare a
dimensiunii (în octeţi) a unui anumit tip
este:
sizeof(den_tip)
unde den_tip este denumirea tipului de entitate.

25/04/07 PC - Curs nr. 2 24


Exemplu - sizeof
#include <stdio.h>

int main(void)
{
printf("Tipul short int are %d octeti.\n", sizeof(short int));
printf("Tipul int are %d octeti.\n", sizeof(int));
printf("Tipul long int are %d octeti.\n", sizeof(long int));
printf("Tipul char are %d octeti.\n", sizeof(char));
printf("Tipul float are %d octeti.\n", sizeof(float));
printf("Tipul double are %d octeti.\n", sizeof(double));
printf("Tipul long double are %d octeti.\n", sizeof(long double));

return 0;
}
25/04/07 PC - Curs nr. 2 25

Exemple
char x;
unsigned int a, b;
float x;
long double valoare;
long numarDeTelefon;
unsigned char OCTET;
int numarLinii;
double mediaAritmetica;
25/04/07 PC - Curs nr. 2 26
Tipuri definite de programator
1. Tipuri derivate Æ sunt formate prin
utilizarea unei combinaţii de unul sau mai
multe tipuri fundamentale şi/sau definite de
programator:
1. tipuri structurate (agregate) – conţin mai multe
elemente
1. de acelaşi tip - tablourile
2. care pot fi de tipuri diferite - structurile
2. uniuni
3. câmpuri de biţi
4. pointeri
25/04/07 PC - Curs nr. 2 27

Tipuri definite de programator


2. Tipuri sinonime Æ limbajul permite
crearea unor sinonime pentru a creşte
lizibilitatea programului

25/04/07 PC - Curs nr. 2 28


Tipuri structurate – tablouri
Forma generală:

tip nume[dim1][dim2]…[dimn];

unde
¾tip Æ tipul elementelor tabloului
¾nume Æ numele tabloului
¾dim1, dim2, …, dimn Æ valorile celor n
dimensiuni ale tabloului
25/04/07 PC - Curs nr. 2 29

Tipuri structurate – tablouri


Exemple:
int A[10]; // Vector
double matrice[20][20]; // Matrice
// Prima dimensiune = numărul de linii
// A doua dimensiune = numărul de coloane

long b[10][5][100];

char denumire[30]; // Şir de caractere


25/04/07 PC - Curs nr. 2 30
Tipuri structurate – tablouri
Accesul al un element al tabloului:

nume[index1][index2]…[indexn]

unde
¾ nume este numele tabloului
¾ index1, index2,…, indexn sunt indicii
elementului accesat

25/04/07 PC - Curs nr. 2 31

Tipuri structurate – tablouri


Exemplu:
1. int A[15];
A[5] sau A[0] sau A[14]

2. double B[10][20];
B[0][1] sau B[5][4] sau B[9][19]

25/04/07 PC - Curs nr. 2 32


Tipuri structurate – structuri
Este necesar să creăm un model (prototip)
pentru structură. Acest model va fi plasat în
fişierul header:

struct nume_prototip_structura {
declaraţii de variabile;
};

25/04/07 PC - Curs nr. 2 33

Tipuri structurate – structuri


Exemple:
struct _PUNCT { struct _Persoana {
double x, y; char nume[50];
}; int varsta;
struct _DATA dataNasterii;
struct _DATA { double salariu;
int zi; double impozit;
char luna[20]; };
int an;
};
25/04/07 PC - Curs nr. 2 34
Tipuri structurate – structuri
Folosire:
struct _PUNCT A, B; struct _Persoana Alecu;

A.x = 3.5; Alecu.impozit =


B.y = A.y; 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; // De exemplu V[0]


MATRICE A; // De exemplu A.m sau A.A[0][0]

25/04/07 PC - Curs nr. 2 38


Crearea de sinonime
Observaţii:
1. declaraţia de tip typedef trebuie să apară
în fişerul header înaintea oricărei referiri la
noul tip.

2. se recomandă ca noul tip să fie scris cu


litere mari pentru a-l diferenţia de tipurile
fundamentale.

25/04/07 PC - Curs nr. 2 39

Entităţi de tip funcţie

Date de ieşire
Date de intrare Funcţie

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) // este in fisierul cu functii


{
float rez;
rez = sqrt(a*b);
return rez;
}

25/04/07 PC - Curs nr. 2 46


int main(void)
{
int x, float y;
float z;
…………………………..
x = 3;
y = 2.35;
………………………….
z = FCT(x, y); // se poate si z = FCT(3, 2.35);
………………………….
return 0;
}
25/04/07 PC - Curs nr. 2 47

Declaraţii şi definiţii de variabile


• Definiţia unei variabile
int x; // Nu poate fi într-un fişier header

• Declaraţia unei variabile


extern int x; //Poate fi într-un fişier header
Se foloseşte în special pentru variabile
globale pentru a fi vizibile din mai multe
fişiere.
25/04/07 PC - Curs nr. 2 48
25/04/07 PC - Curs nr. 2 49

CONSTANTE
Constante numerice întregi zecimale
Dacă nu se specifică altfel, compilatorul
consideră că o constantă este un număr
zecimal cu semn:
47 3 1101 -235

Pentru numerele fără semn trebuie să


adăugăm sufixul u
47u 23u
25/04/07 PC - Curs nr. 2 51

Constante numerice întregi zecimale


Pentru constantele în format lung
adăugăm sufixul l sau L
23l 23L

Pentru constantele în format lung fără


semn avem sufixele
ul uL lu Lu
23ul 23Lu
25/04/07 PC - Curs nr. 2 52
Constante numerice întregi zecimale
Compilatorul stabileşte lungimea
reprezentării în funcţie de valoarea
constantei astfel:
23 este în format scurt,
72365 este în format lung

25/04/07 PC - Curs nr. 2 53

Constante numerice întregi octale


Dacă numărul este precedat se cifra 0 se
consideră constantă octală
015
027

25/04/07 PC - Curs nr. 2 54


Constante numerice întregi
hexazecimale
Dacă numărul este precedat de 0x sau 0X
se consideră constantă de tip
hexazecimal.
0x15
0XB3
0x31

25/04/07 PC - Curs nr. 2 55

Constante numerice reale


Sunt numere care pot conţine punctul
zecimal sau caracterele e sau E (cu
semnificaţia de putere a lui 10)
Implicit sunt considerate de tip double.
Exemple:
12.34 1.157e+3 2.5678e-5
1.234E+1

25/04/07 PC - Curs nr. 2 56


Constante numerice reale
Pot avea sufixele f sau F Æ constante de
tip real în simplă precizie (de tip float)
2.3f 1e-4f

Pot avea sufixele l sau L Æ constante de


tip long double
4.5l 3.24L

25/04/07 PC - Curs nr. 2 57

Constante de tip caracter


Au ca valoare codul ASCII al caracterului
respectiv.
Sunt specificate prin:
1. caracterul pus între apostrof
Exemplu:
'A' '0' 'i'

25/04/07 PC - Curs nr. 2 58


Constante de tip caracter
2. Codul ASCII exprimat ca un cod octal
'\ddd' (unde d este o cifră octală)
Exemplu:
'\023' '\117'
'\139'

25/04/07 PC - Curs nr. 2 59

Constante de tip caracter


3. Codul ASCII exprimat ca un cod
hexazecimal '\xhh' (unde h este o cifră
hexazecimaă)
'\xff'
'\xab'

25/04/07 PC - Curs nr. 2 60


Constante de tip caracter
Un caz particular sunt secvenţele
ESCAPE:
'\n' - LF '\\' - backslash
'\r' - CR '\'' - apostrof
'\t' - TAB '\"' - ghilimele
'\0' - zero '\f' - FF
'\b' - BackSpace '\a' - BEL
25/04/07 PC - Curs nr. 2 61

Constantele de tip caracter


Observaţii:
1. Au rezervaţi 2 octeţi astfel că:
sizeof('a')
are ca rezultat 2.
a. octetul inferior conţine codul ASCII al
caracterului
b. octetul superior conţine extensia de
semn
25/04/07 PC - Curs nr. 2 62
Constante de tip caracter
2. Pot apare în expresii aritmetice având
ca valoare codul ASCII corespunzător
astfel putem scrie:
c-'a'+'A' sau c-'A'+'a'
c – '0'

25/04/07 PC - Curs nr. 2 63

Constante de tip şir de caractere


Şir de caractere = tablou de caractere.
Constante de tip şir de caractere =
secvenţă de caractere specificată intre
ghilimele (")
Exemplu:
"exemplu"

25/04/07 PC - Curs nr. 2 64


Constante de tip şir de caractere
Orice şir de caractere trebuie să se
termine cu caracterul '\0'

Acest caracter este pus implicit de


compilator sau trebuie pus explicit în
cazul în care şirul este construit prin
program

25/04/07 PC - Curs nr. 2 65

Constante de tip şir de caractere

e x e m p l u \0

Iniţializarea şirurilor de caractere:


char fis[] = "a1.txt";
Nu se poate scrie:
char fis[20];
fis="a1.txt";

25/04/07 PC - Curs nr. 2 66


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

25/04/07 1

Operaţii de intrare - ieşire

Operaţii de intrare – ieşire cu


format

25/04/07 2
Fluxuri de date (stream)
• stdin
• stdout
• stderr

25/04/07 3

Citirea datelor - scanf


Citirea se face conform schemei

Buffer
Tastatură (Zona Program
tampon)

Golirea buffer-ului (a zonei tampon) se face cu:


fflush(stdin);
25/04/07 4
Citirea datelor de la tastatură - scanf
Forma generală:
int scanf("<format>", <adr1>, <adr2>, ...);
unde
format – şir de caractere care indică modul
de memorare a datelor citite

adr1, adr2, ... – adresele unde se vor stoca


valorile citite (sunt numele variabilelor
precedate de &)

25/04/07 5

Citirea datelor - scanf


Forma generală a formatului este:
%[*][width][F|N][h|l|L]tip_char
unde width – lungimea maximă a şirului citit de
la tastatură
Exemple:
%4d - citeşte un întreg de maxim 4 cifre
%f - citeşte un real
%lf - citeşte un real de tip double
25/04/07 6
scanf
%c - citeşte un caracter
%s - citeşte un şir de caractere care nu
conţine caractere albe (se foloseşte
denumirea tabloului, fără adresă)

char den[30];
scanf("%s", den);

25/04/07 7

scanf
Observaţie:
În format nu trebuie să apară decât formatele şi
eventualele caractere obligatorii din şirul de intrare).
Exemplu:
Se citeşte un moment din zi sub forma:
12:23:45
scanf("%d:%d:%d", &ora, &min, &sec);
23.09.2004
scanf("%d.%2d.%4d", &zi, &luna, &an);

25/04/07 8
scanf
În formatul de citire pot apare şi şiruri de forma:
%[…] caută doar caracterele specificate
%[^…] caută toate caracterele cu excepţia celor
specificate
Exemplu:
char den[30];
scanf("%[abcd]", den);
scanf("%[^abcd]", den);
scanf("%[0-9]", den); // %[A-Z], %[0-9a-z], %[^A-FT-Z]
scanf("%20[ a-z]", den);

25/04/07 9

scanf
Citirea se opreşte la:
–*
– atingerea lăţimii
– următorul caracter din şir care nu se
potriveşte cu formatul
– următorul caracter din şir care nu există în
mulţimea de căutare

25/04/07 10
Citirea datelor de la tastatură - scanf
Funcţia returnează numărul de câmpuri corect
citite. La întâlnirea sfârşitului de fişier (CTRL/Z)
returnează valoarea –1 (EOF).

Æ Validare primară a datelor


……………………
while(scanf("%d%d%d", &x, &y, &z) != 3)
fflush(stdin);
printf("Valorile citite sunt: %d %d si %d\n", x, y, z);
…………………………….
25/04/07 11

scanf - exemplu
#include <stdio.h>
#include <conio.h>

int main(void)
{
int nr;
int a=10, b=20, c=30;

clrscr();
nr = scanf("%d%d",&a,&b);
printf("1 nr = %d\n",nr);
printf("1 a = %d, b = %d\n",a,b);
25/04/07 12
scanf - exemplu
nr = scanf("%c",&c);
printf("2 nr = %d\n", nr);
printf("2 c = %c", c);

getch();
return 0;
}

25/04/07 13

scanf
OBSERVAŢII:

Pentru formatul %d, scanf ignoră spaţiile albe


din faţa datei şi pune înapoi în buffer spaţiile
albe care au determinat terminarea unei
date(' ', '\t', '\n', '\r')

Nu se amestecă formatele %c şi %s cu
formatele %d şi %f sau scanf(…) cu
getchar().

25/04/07 14
Afişarea cu format - printf
Forma generală:
int printf("<format>", <arg1>, <arg2>, …);
unde
<format> este de forma:
%[flags][width][.prec][F|N|h|l|L]tip_char

25/04/07 15

printf
Exemplu:
int zi = 12;
int luna = 2;
int an=2004;
printf("%02d.%02d.%5d", zi, luna, an);

Æ 12.02. 2004
25/04/07 16
printf
int a=1;
printf("%02d", a); //Æ 01
printf("%.3d", a); // Æ 001

float a=2.3;
printf("%.0f", a); // Æ 2
double f = 34.5; // Æ %lf
long double g = 74; // Æ %Lf
long j = 123; // Æ %ld
25/04/07 17

printf
x = ( 24, 31, 29)

void afisareVector(int a[], int n, char den[])


{
int i;
printf("%s=(", den);
for(i=0; i<n-1; i=i+1)
printf("%3d, ", a[i]);
printf("%3d)\n",a[i]);
}

25/04/07 18
printf
int err;
char fis[50];

printf("\"Eroare \'%2d\' la citirea fisierului


%s\"", err, fis);

Mesajul:
"Eroare '59' la citirea fisierului a1.txt"
25/04/07 19

Exemplu – P2
Să se scrie un program care calculează
produsul scalar a doi vectori cu
componente numere întregi, precum şi
vectorul sumă.
Primul vector se citeşte de la tastatură
până la întâlnirea combinaţiei de taste
CTRL/Z (CTRL/D în Linux), iar al doilea
vector are exact atâtea elemente cât şi
primul.

25/04/07 20
Analiza problemei
Fie cei doi vectori
X = (xi)i=1,n
şi
Y = (yi)i=1,n
atunci
n
si = xi + yi PS = ∑ xi ⋅ yi
i =1

25/04/07 21

Analiza problemei
1. o funcţie de citire a unui şir de numere pânâ la
intâlnirea caracterului CTRL/Z. Funcţia returnează
numărul elementelor citite.
2. o funcţie de citire a unui vector când se cunoaşte
numărul de elemente care trebuie citite
3. o funcţie de afişare a unui vector
4. funcţia de calcul a vectorului sumă
5. funcţia de calcul a produsului scalar

25/04/07 22
Proiectul
• P2.C – fişier care conţine funcţia main

• modulul VECTOR
– VECTOR.H
– VECTOR.C

25/04/07 23

VECTOR.H
/*
* VECTOR.H
*/
#ifndef _VECTOR_
#define _VECTOR_
// Functia de citire a unui sir de numere pana la CTRL/Z
// (CTRL/D)
int citireVector1(int a[], char den[], int DimMax);
// Functia de citire a unui vector când se cunoaste
// dimensiunea vectorului
void citireVector2(int a[], int n, char den[]);

25/04/07 24
VECTOR.H – continuare
// Functia de afisare vector
void afisareVector(int a[], int n, char den[]);
// Functia de calcul a produsului scalar
long produsScalar(int a[], int b[], int n);
//Functia de calcul a vectorului suma
void sumaVectori(int a[], int b[], int c[], int n);
#endif

25/04/07 25

P2.C
/*
* P2.C
*/
#include <stdio.h>
#include <conio.h>
#include "vector.h"

int main(void)
{
int x[20], y[20], suma[20];
int n;
int ps;

25/04/07 26
P2.C
n = citireVector1(x,"x",20);
if(n > 0) {
citireVector2(x,n,"y");
ps = produsScalar(x, y, n);
sumaVectori(a, b, suma, n);
printf("Pentru vectorii \n");
afisareVector(x, n, "x");
printf("si\n");
afisareVector(y, n, "y");
printf("vectorul suma este\n");
afisareVector(suma, n, "S");
printf("iar produsul scalar este %d.\n",ps);
}
25/04/07 27

P2.C
else
fprintf(stderr,"Vector nul.\n");

if(!getch()) getch();
return 0;
}

25/04/07 28
VECTOR.C
#include <stdio.h>
int citireVector1(int a[], char den[], int DimMax)
{
int n = 0;
printf("%s(%d) = ", den, n);
while((n < DimMax) && (scanf("%d", &a[n]) == 1))
{
n = n+1;
printf("%s(%d) = ", den, n);
}
return n;
}

25/04/07 29

VECTOR.C
void citireVector2(int a[], int n, char den[])
{
int i;
for(i=0; i<n; i=i+1)
{
printf("%s(%d) = ", den, i);
scanf("%d",&a[i]);
}
}

25/04/07 30
VECTOR.C
void afisareVector(int a[], int n, char den[])
{
int i;
printf("%s=(", den);
for(i=0; i<n-1; i=i+1)
{
printf("%d, ", a[i]);
}
printf("%d)\n", a[n-1]);
}

25/04/07 31

VECTOR.C
long produsScalar(int x[], int y[], int n)
{
long ps;
int i;
ps = 0;
for(i=0; i<n; i=i+1)
ps = ps + x[i]*y[i];
return ps;
}

25/04/07 32
VECTOR.C
void sumaVectori(int a[], int b[], int s[], int n)
{
int i;
for(i=0; i<n; i = i+1)
s[i] = a[i] + b[i];
}

25/04/07 33

Operaţii de intrare – ieşire

Operaţii de intrare – ieşire


pentru caractere şi
şiruri de caractere

25/04/07 34
Operaţii de intrare – ieşire pentru
caractere
Prototipuri în stdio.h

int getc(FILE *stream);


int putc(int c, FILE *stream);

int getchar(void);
int putchar(int c);
25/04/07 35

Operaţii de intrare – ieşire pentru


şiruri de caractere
Prototipuri în stdio.h

char *gets(char *s);


char *fgets(char *s, int n, FILE *stream);

int puts(char *s);


int fputs(char *s, FILE *stream);
25/04/07 36
Operaţii de intrare – ieşire pentru
caractere
Prototipuri în conio.h
Nu sunt în standard

int getch(void);
int getche(void);
int putch(int c);

25/04/07 37

Exemplu:
Se introduce un text de la tastatură
caracter cu caracter până la întâlnirea
CTRL-Z.
Să se afişeze numărul de linii introduse.

25/04/07 38
Exemplu:
#include <stdio.h>

int main(void)
{
int c;
int numarLinii = 0;

25/04/07 39

c = getchar();
while(c != EOF) {
if (c == '\n')
numarLinii = numarLinii + 1;
c = getchar();
}

25/04/07 40
printf("S-au introdus %d linii.\n",
numarLinii);
return 0;
}

25/04/07 41

Operaţii de I/O pentru şiruri şi fişiere


• sscanf, sprintf
int sscanf(char s[], format, arg1, arg2, …);
int sprintf(char s[], format, arg1, arg2, …);

• fscanf, fprintf
int fscanf(FILE *fisier, format, arg1, arg2, …);
int fprintf(FILE *fisier, format, arg1, arg2, …);

25/04/07 42
Operaţii de intrare - ieşire
char temp[81];
int a;
………………………
while(fgets(temp,80,stdin) != 0)
{
nr = sscanf(temp, ",%d", &a);
if(nr == 1)
printf("%d ",a);
}
………………………….

25/04/07 43

Citirea unei matrice


int citireMatrice(int n, int m, double a[][20])
{
int ok=1;
int i,j;
for(i=0; i<n; i=i+1)
for(j=0; j<m; j=j+1) {
char temp[81];
fgets(temp, 80, stdin);
if(sscanf(temp, "%lf", &a[i][j]) != 1) {
ok = 0;
return ok;
}
}
return ok;
}
25/04/07 44
Citirea unei matrice
……………
ok = citireMatrice(n,m,a);
if(ok == 0)
fprintf(stderr, "Eroare la citirea matricei.\n");
…………………

25/04/07 45
PROGRAMAREA
CALCULATOARELOR

Curs nr. 5-6

25/04/07 1

Expresii şi operatori

25/04/07 2
Expresie
O secvenţă de operatori şi operanzi care
specifică modul de calculare a unei valori.

O expresie are un tip care coincide cu tipul


valorii rezultatului.

Expresia:
¾ operanzi care sunt entităţile care participă
¾ operatori care descriu operaţiile care se execută

25/04/07 3

Operatori
Caracteristici:
1. aritate Æ număr de operanzi

2. tip Æ domeniul de definiţie al operaţiei


desemnate şi la domeniul valorilor acestei
operaţii
Exemplu:
+ Æ (real, real; real)

3. efect Æ dat de operaţia simbolizată


25/04/07 4
Operatori
Din punctul de vedere al numărului de
operanzi:

• unari (sunt pre sau postfixaţi)


• binari (sunt infixaţi)
• ternari (infixaţi)

25/04/07 5

Operatori
În funcţie de operaţia realizată:
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 ++i
‰ postfixaţi n--
25/04/07 13

Operatori de incrementare - decrementare


Exemplu:
int x, n= 5;

x = ++n;
x=6
n=6

x = n++;
x=5
n=6
25/04/07 14
Operatori de incrementare - decrementare
Exemplu:
temp [nc] = c;
nc++;

este echivalent cu
temp [nc++] = c;

25/04/07 15

Operatori de incrementare - decrementare


La folosirea lor trebuie evitate ambiguităţile care apar
când se foloseşte mai mult de o operaţie de
incremetare – decrementare într-o instrucţiune.

Exemplu:
1) x = fn1(i++) + fn2(i++)

Corect:
x = fn1(i++);
x = x + fn2(i++);

25/04/07 16
Operatori de incrementare - decrementare
2) a[i++] = b[i++]; /* GREŞIT */

3) int i, a[10];
i = 0;
while(i < 10)
a[i] = i++; /* GREŞIT */

for(i=0; i<10; i++) /*CORECT */


a[i] = i;

25/04/07 17

Operatori de incrementare - decrementare


4) {
int i = 1;
printf("%d %d\n", i++, i++);
}

Se afişează
21

5) i = ++i + 1; /* expresie nedefinită */

6) i++ + j++ * k++ /*expresie nedefinită */

25/04/07 18
Operatori de incrementare - decrementare
#include <stdio.h> int next (int x)
#include "ex.h" {
return x++;
int main(void) }
{
int a, i = 10; Programul va afişa:
a = next(i); 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 a[i+j+2*k] += 4
25/04/07 34
Operatori şi expresii de atribuire

Operatorul de atribuire este folosit şi


pentru iniţializarea variabilelor.

Observaţie:
variabilele declarate (definite) într-o
funcţie au valori nedefinite dacă nu sunt
iniţializate.

25/04/07 35

Operatori şi expresii de atribuire


Iniţializarea se poate face:
¾ pentru variabile scalare
‰ la definire
Exemplu:
int a=10;

‰pe parcursul programului


……………….
int a;
…………………
a = 10;
25/04/07 36
Operatori şi expresii de atribuire
¾ pentru tablouri Æ la definire

int a[5] = {3,4,5,6,7};


int a[] = {10,20,30,40};
n = sizeof(a)/sizeof(int);

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 2
MASCĂ octet superior octet inferior

c) c = n & 03778 = n & 00000000 11111111 2

octet superior octet inferior

25/04/07 45

Operatori logici asupra biţilor


Operatorul ^ (SAU EXCLUSIV XOR)

^ 0 1
0 – lasă biţii nemodificaţi
0 0 1 1 – complementează biţii
1 1 0

Este folosit pentru a complementa numai anumiţi biţi


dintr-un cuvânt (în conformitate cu o configuraţie
existentă în mască - cel de-al doilea operand).

25/04/07 46
Operatori logici asupra biţilor
Operatorul ^ (SAU EXCLUSIV XOR)

Exemplu:
Trebuie complementat bitul 4 dintr-un octet.
MASCA = 0x10 00010000
Pentru
c = 0x5bu 01011011
rezultatul expresiei
c^MASCA
este 01001011

25/04/07 47

Operatori logici asupra biţilor


Operatorul | (SAU)
| 0 1
0 0 1
1 1 1

Este folosit pentru a pune, în unul din operanzi, pe 1 (a


seta) toţi biţii care au valoarea 1 în celălalt operand
(numit şi MASCĂ).

25/04/07 48
Operatori logici asupra biţilor
Operatorul | (SAU)
Exemple:
z = x | MASK
a) x = 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 luna ziua
15 9 8 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<b) ? a : b
este valoarea minimă dintre a şi b.

25/04/07 65

Expresia şi operatorul condiţional


b) for(i=0; i<N; i++)
printf("%6d%c", a[i],
(i%10 == 9) || (i == N-1) ? '\n' : ' ');

c) f1(a, b+1, c+d, xx, (g+h+i)/2);


unde

 f 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

f ( x ) = 2 pentru x = 0
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; // colt stanga sus
struct PUNCT B; // 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 float c1 a

25/04/07 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) De la stânga la dreapta
! ~ ++ -- * & (cast) De la dreapta la stânga
sizeof -(unar)
(linia operatorilor unari)
* / % De la stânga la dreapta
+ - (binari) De la stânga la dreapta
<< >> (Deplasare pe bit stânga, dreapta) De la stânga la dreapta
< <= >= > (Operatori relaţionali) De la stânga la dreapta
== != (Testarea egalităţii) De la stânga la dreapta
& (ŞI pe biţi) 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) De la dreapta la stânga
+= -= *= /= %= (atribuire relativă)
<<= >>= &= ^= |= (atribuire relativă)
, (virgula) De la stânga la dreapta
25/04/07 80
PROGRAMAREA CALCULATOARELOR

Curs nr. 7-8

25.04.2007 1

INSTRUCŢIUNILE LIMBAJULUI C
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:
STIVA
if(...) {
tip1 x1;
…………… ..............
} x2
x1
else {
..............
tip2 x2;
…………… 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++ i++;
x=a+b x = a + b;
y += 2 y += 2;

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 Actiune 1

instrucţiuni care se
execută secvenţial (în
ordinea în care sunt Actiune 2

scrise în program). Aici sche ma se


continua cat
este nevoie

Se execută conform
schemei din figură. Actiune n

25.04.2007 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 Adevarat
conditie
Fals

schema
logică: Secventa A Secventa B

25.04.2007 20
Structuri de control – selecţia (decizia)
S1). Selecţia cu două alternative

Reprezentare prin pseudocod:

dacă <condiţie>
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) 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;
}

25.04.2007 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 Adevarat
conditie
schema
logică
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ă <condiţie>
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ă <conditie1>
atunci <secventa1>;
altfel dacă <conditie2>
atunci <secventa2>;
...........................................
dacă <conditien>
atunci <secventan>
altfel <secventan+1>;
sf. dacă

25.04.2007 31

Adevarat Fals
conditie 1

Secventa 1 Adevarat Fals


conditie 2

Adevarat Fals
Secventa 2 conditie 3
Aici schema se
continua cu cate
conditii este nevoie
Seventa 3

Adevarat Fals
conditie n

Secventa
Secventa n
n+1

25.04.2007 32
Structuri de control – selecţia (decizia)
S3). Selecţia multiplă - S3.1) Cu instrucţiunea if
În limbajul C avem
if(conditie1)
secventa1;
else if(conditie2)
secventa2;
else if(conditie3)
secventa3;
………………………………………………………….
else if(conditien)
secventan;
else
secventan+1;
25.04.2007 33

Structuri de control – selecţia (decizia)


S3). Selecţia multiplă - S3.1) Cu instrucţiunea if

sau if(conditie1)
{
if(conditie2)
secventa1;
else
if(conditie3)
secventa2;
}
else
secventa3;

25.04.2007 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)) //if2
{
printf("echilateral.\n");
}
else if(esteIsoscel(a,b,c)) //else if2 si if3
{
printf("isoscel.\n");
}

25.04.2007 38
Structuri de control – selecţia (decizia)
S3). Selecţia multiplă - S3.1) Cu instrucţiunea if

else if(esteDreptunghic(a,b,c)) // else if3 si if4


{
printf("dreptunghic.\n");
}
else // else if4
printf("oarecare.\n");
}
else // else if1
puts("Nu este triunghi");

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 Val2 Val3 Valn Rest

Secventa
Secventa 1 Secventa 2 Secventa 3 Secventa n
n+1

25.04.2007 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 '+': r = a+b;
break;
case '-': r = a-b;
break;
case '*': 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 Adevarat
conditie

Secventa

25.04.2007 55

Structuri de control repetitive –


iteraţia cu test iniţial
Reprezentarea în pseudocod:

repetă cât timp <condiţie>


<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 Adevarat
conditie

25.04.2007 59

Structuri de control repetitive –


iteraţia cu test final
În pseudocod are forma:

repetă
<secvenţă>;
cât timp <condiţie>

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
e =1+ x +
x
+ +K+ +K
2! 3! n!
xk
uk =
k!
x k −1 x x
uk = ⋅ = u k −1 ⋅ u0 = 1
(k − 1)! k k

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ă va r ← vi

în figură.

Fals Adevarat
var ≤ vf

Secventa

var ← var+ pas

25.04.2007 66
Structuri de control repetitive –
iteraţia cu contor
În pseudocod reprezentarea este

repetă pentru <var> = 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<n; i=i+1) {
c[i] = 0;
for(j=0; j<m; j=j+3)
c[i] += a[i][j];
}

25.04.2007 70
Iteraţia cu contor

O formă mai generală


pentru instrucţiunea de Ei

iteraţie cu contor este


dată în figura alăturată.
Fals Adevarat
Et

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; // Linia 1
k = j; // Linia 2

25 aprilie 2007 Programarea Calculatoarelor 3

Pointeri - definiţii
Variabile pointeri
– definiţie

– definire
T *pt; pt
T *pt1, *pt2, pt3;

typedef T* PT; // in header


PT p1, p2, p3;

25 aprilie 2007 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; // Conţine valoarea de la adresa pt
*pt = 5;

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;
pi i
int *pi, *pj;

pj
pi = &i;
pj = pi;

25 aprilie 2007 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);

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

25 aprilie 2007 Programarea Calculatoarelor 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++; pf1--;
pf2 = pf1; pf3 = pf1;

↑ ↑ ↑
pf3 pf1 pf2

25 aprilie 2007 Programarea Calculatoarelor 35

Pointeri – aritmetica pointerilor


‰compararea a doi pointeri
< <=
> >=
== !=

↑ ↑
p q

25 aprilie 2007 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

25 aprilie 2007 Programarea Calculatoarelor 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);

25 aprilie 2007 Programarea Calculatoarelor 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]

↑ ↑
v p

25 aprilie 2007 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++; // NU
v = pv + 4; // NU

25 aprilie 2007 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; ↑ ↑
int *ai = &a[0]; ai af
int *af = a+n;
max = *a;
for(p = a+1; p < af; p++)
if(*p > max)
max = *p;
return max;
}

25 aprilie 2007 Programarea Calculatoarelor 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 r d e t e s t \0
↑ ↑
c c[i]

25 aprilie 2007 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=10; a?
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<n; i++)
{
printf("%s(%d) = ", s, i);
scanf("%d", a+i);
// scanf("%d", &(*(a+i)));
}
return a;
}

25 aprilie 2007 Programarea Calculatoarelor 55

VECTOR.C
void afisareVector(int *a, size_t n, char *s)
{
size_t i;
printf("%s(=", s);
for(i=0; i<n-1; i++)
printf("%3d, ", *(a+i));
printf("%3d)\n", *(a+(n-1)));
}

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<n; i++)
*(suma+i) = *(a+i) + *(b+i);
return suma;
}

25 aprilie 2007 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] 1 2
tab[1]
5 6 7 8

tab[99] 11 21 34

25 aprilie 2007 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] E x e m p l u \0
text[1]
d e \0
text[2]
t e x 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<nl; i++)
puts(text[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<nl; i++) {
free((char *)text[i]);
text[i] = 0;
}
}

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<k; i++)
if(strlen(text[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;

25 aprilie 2007 Programarea Calculatoarelor 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;

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)

1 2 3
pv 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]

25 aprilie 2007 Programarea Calculatoarelor 25

Pointeri la un tablou
T *p3[10];
p3 p3[0]+j

p3[0] 1 2 *(p3[0]+j)
p3[1]
5 6 7 8

p3[9] 11 21 34

25 aprilie 2007 Programarea Calculatoarelor 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 p[0]+j

p[0] 1 2 *(p[0]+j)
p[1]
5 6 7 8

p[9] 11 21 34

25 aprilie 2007 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<n; i++)
for(j=0; j<m; j++)
{
mat[i][j] = i+j;
*(*(mat1+i)+j) = 2*i;
}

puts("Matricea mat");
afisareMatrice(mat, n, m);

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<n; i++)
{
for(j=0; j<m; j++)
printf("%d ", *(*(a+i)+j));
puts("");
}
}

25 aprilie 2007 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
pv 15 20 34 25 19
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<LINII; i++)
a[i] = (T *)xmalloc(COLOANE * sizeof(T));
return a;
}

25 aprilie 2007 Programarea Calculatoarelor 45

Matrici alocate dinamic

void dealoca2d(T **a, size_t LINII)


{
size_t i;
for(i=0; i<LINII; i++) {
free((T *) a[i]);
a[i] = 0;
}
free ((T **) a);
}

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<LINII; i++)
a[i] = a[0] + i * COLOANE;
/* a[i] = a[i-1] + COLOANE; */
return a;
}

25 aprilie 2007 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 0 -1 -2
2 3 1 Æ -1 0 1
0 -1 -2 2 3 1

25 aprilie 2007 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<n; i++)
a[i] = (int *)xmalloc(m * sizeof(int));
return a;
}

25 aprilie 2007 Programarea Calculatoarelor 52


Matrici alocate dinamic - exemplu
ALOCARE.C
void dealoca2d(int **a, int n)
{
int i;
for(i=0; i<n; i++)
{
free(a[i]);
a[i] = 0;
}
free(a);
}

25 aprilie 2007 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<n; i++)


for(j=0; j<m; j++)
{
printf("%s(%d,%d) = ", den, i, j);
scanf("%d", (*(a+i)+j));
}
return a;
}

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<n; i++)
{
for(j=0; j<m; j++)
printf("%4d ", *(*(a+i)+j));
printf("\n");
}
}

25 aprilie 2007 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<k; i++)
if(maxim(a[i],m) > 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 <in.txt
p1 >out.txt
p1 <in.txt >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

S-ar putea să vă placă și