Post on 18-Feb-2015
transcript
PROGRAMAREA CALCULATOARELOR
CURS – AN I
TITULAR DISCIPLINĂ:ş. l. dr. ing. ELENA ŞERBAN
www.ace.tuiasi.ro/~eserban
Bibliografie1. 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 algoritmilorModuri de descriere a algoritmilor:
VerbalAlgebric (prin formule)Scheme logicePseudocod
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 intrare2. Validarea datelor de intrare (cele trei valori
pot reprezenta laturile unui triunghi?)3. Calculul elementelor cerute din triunghi4. Afişarea datelor de ieşire
Descompunerea problemei în subprobleme
Citirea datelorde intrare
Validarea datelor Calcularea mãrimilorcerute
Prelucrarea datelor
Afisarearezultatelor
Problema
Notăm lungimile celor trei laturi cu a, b, c.
Aria unui triunghi (conform formulei lui Heron) este:
Etapa 3
( ) ( ) ( )cpbpappA −⋅−⋅−⋅=
unde
2cbap ++
=
Celelalte mărimi vor fi calculate cu relaţiile:
( )cb
apcbpba +
−⋅⋅⋅⋅=2
aAha⋅
=2
( )4
2 222 acbma−+⋅
=
Înălţimea din vârful A
Mediana din vârful A
Bisectoarea unghiului A
Etapa 4 Datele de test
Date de test pentru care ar trebui să se afişezemesaj de eroare:
• a = 1, b = 2, c = 3 • a = 0, b = 2, c= 4 • a = -5, b = 5, c= 3
Etapa 4 Datele de testDate 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 = 14A = 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ŢIEFiş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 datelefloat Aria(int a, int b, int c); // Calculeaza ariafloat semiP(int a, int b, int c); // Calculeaza semiperimetrulfloat mediana(int a, int b, int c); // Calculeaza medianafloat inaltime(int a, int b, int c); // Calculeaza inaltimeafloat 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;
elseok = 1;
return ok;}
Fişierul triunghi.c - continuarefloat 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 - continuarefloat 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 - continuarefloat 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);
/** 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;}
Fişierul P1.c – continuare
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
25/04/07 PC - Curs nr. 2 2
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 3
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 4
Limbajul C – scurt istoric1983 – 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
Elemente de bază ale limbajului C
25/04/07 PC - Curs nr. 2 6
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 7
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 8
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 9
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 10
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 11
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 12
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 13
• 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 14
IdentificatoriSunt 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 latin2. caracterul _ (subliniere sau underscore)3. cifre (de la 0 la 9)
AtenţiePrimul caracter poate fi numai din 1. sau 2.
25/04/07 PC - Curs nr. 2 15
IdentificatoriLa 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 16
Exemple identificatori
Corectalfa beta _STIVA_ __CcitesteDateDeIntrarea_1afiseaza_vector
25/04/07 PC - Curs nr. 2 17
Exemple identificatori
Incorecttop...ten2_si_3a+bmedie aritmetica
25/04/07 PC - Curs nr. 2 18
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 19
Tipuri fundamentaleConţin o singură informaţie (sunt tipuri scalare)
1. întregi:1. de tip caracter definite prin char2. de tip întreg definite prin int
2. reale1. în simplă precizie definite prin float2. în dublă precizie definite prin double
25/04/07 PC - Curs nr. 2 20
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 21
Tipuri fundamentale
• pentru entităţile de tip int– short– long
• pentru entităţile de tip double– long
25/04/07 PC - Curs nr. 2 22
Tipuri fundamentale
long doubledoublefloat
unsigned long intsigned long int
unsigned intsigned int
unsigned short intsigned short intint
unsigned charsigned charchar
25/04/07 PC - Curs nr. 2 23
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.
Tipuri fundamentale
25/04/07 PC - Curs nr. 2 24
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.
Tipuri fundamentale
25/04/07 PC - Curs nr. 2 25
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 26
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 27
Tipuri definite de programator1. 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 elemente1. de acelaşi tip - tablourile2. care pot fi de tipuri diferite - structurile
2. uniuni3. câmpuri de biţi4. pointeri
25/04/07 PC - Curs nr. 2 28
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 29
Tipuri structurate – tablouriForma generală:
tip nume[dim1][dim2]…[dimn];
unde tip tipul elementelor tablouluinume numele tablouluidim1, dim2, …, dimn valorile celor ndimensiuni ale tabloului
25/04/07 PC - Curs nr. 2 30
Tipuri structurate – tablouriExemple:
int A[10]; // Vectordouble 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 31
Tipuri structurate – tablouriAccesul al un element al tabloului:
nume[index1][index2]…[indexn]
undenume este numele tablouluiindex1, index2,…, indexn sunt indiciielementului accesat
25/04/07 PC - Curs nr. 2 32
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 33
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 34
Tipuri structurate – structuriExemple:
struct _PUNCT {double x, y;
};
struct _DATA {int zi;char luna[20];int an;
};
struct _Persoana {char nume[50];int varsta;struct _DATA dataNasterii;double salariu;double impozit;
};
25/04/07 PC - Curs nr. 2 35
Tipuri structurate – structuriFolosire:
struct _PUNCT A, B;
A.x = 3.5;B.y = A.y;
struct _Persoana Alecu;
Alecu.impozit = 0.16 * Alecu.salariu;
Alecu.nume[0]Alecu.dataNasterii.zi
25/04/07 PC - Curs nr. 2 36
Crearea de sinonimeSe face prin folosirea declaraţiei de tip
typedef.
typedef tipExistent tipNou;undetipExistent este un tip de entitate care există în
limbaj sau care a fost definit anteriortipNou este noul nume (sinonimul tipului
existent)
25/04/07 PC - Curs nr. 2 37
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 38
Crearea de sinonimeExemple:
typedef int VECTOR[20];typedef struct _MATRICE {
int n; // Numar liniiint 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 39
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 40
Entităţi de tip funcţie
Date de intrareDate de ieşire
Funcţie
tip_f numeFunctie (tip1 nume1, tip2 nume2, ..., tipn numen)
Antet, interfaţă
25/04/07 PC - Curs nr. 2 41
Declaraţii şi definiţiiSunt 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 42
Declaraţii şi definiţiiPentru 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 43
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 44
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 45
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 46
Exemplefloat 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 47
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 48
Declaraţii şi definiţii de variabile
• Definiţia unei variabileint x; // Nu poate fi într-un fişier header
• Declaraţia unei variabileextern int x; //Poate fi într-un fişier headerSe foloseşte în special pentru variabile
globale pentru a fi vizibile din mai multe fişiere.
25/04/07 PC - Curs nr. 2 51
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 52
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 sufixeleul uL lu Lu
23ul 23Lu
25/04/07 PC - Curs nr. 2 53
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 54
Constante numerice întregi octale
Dacă numărul este precedat se cifra 0 se consideră constantă octală
015027
25/04/07 PC - Curs nr. 2 55
Constante numerice întregi hexazecimale
Dacă numărul este precedat de 0x sau 0X se consideră constantă de tip hexazecimal.
0x150XB30x31
25/04/07 PC - Curs nr. 2 56
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-51.234E+1
25/04/07 PC - Curs nr. 2 57
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 double4.5l 3.24L
25/04/07 PC - Curs nr. 2 58
Constante de tip caracter
Au ca valoare codul ASCII al caracterului respectiv.
Sunt specificate prin:1. caracterul pus între apostrofExemplu:
'A' '0' 'i'
25/04/07 PC - Curs nr. 2 59
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 60
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 61
Constante de tip caracter
Un caz particular sunt secvenţeleESCAPE:
'\n' - LF '\\' - backslash'\r' - CR '\'' - apostrof'\t' - TAB '\"' - ghilimele'\0' - zero '\f' - FF'\b' - BackSpace '\a' - BEL
25/04/07 PC - Curs nr. 2 62
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 caracteruluib. octetul superior conţine extensia de semn
25/04/07 PC - Curs nr. 2 63
Constante de tip caracter
2. Pot apare în expresii aritmetice avândca valoare codul ASCII corespunzător astfel putem scrie:
c-'a'+'A' sau c-'A'+'a'c – '0'
25/04/07 PC - Curs nr. 2 64
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 65
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 66
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 67
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 metode1. folosirea directivei preprocesor define#define N 100#define _TEST_
25/04/07 PC - Curs nr. 2 68
Constante simbolice - const
2. prin folosirea modificatorului constconst int x = 10;
Trebuie făcută iniţializarea.
Avantaj faţă de define se verifică tipul
25/04/07 PC - Curs nr. 2 69
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 70
Constante simbolice – tipul enum
Forma generală:enum [id] {id1 [=cst1], id2[=cst2], …};
undeid este numele setului de constanteid1, id2, … sunt identificatori (constantesimbolice)cst1, cst2, … sunt valorile asociateidentificatorilor (valorile constantelor simbolice)
25/04/07 PC - Curs nr. 2 71
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 72
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 73
Constante simbolice – tipul enumObservaţii:
1. În cazul în care valoarea asociată variabilei enumnu 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 1
PROGRAMAREA CALCULATOARELOR
Curs nr. 4
25/04/07 2
Operaţii de intrare - ieşire
Operaţii de intrare – ieşire cu format
25/04/07 3
Fluxuri de date (stream)
• stdin• stdout• stderr
25/04/07 4
Citirea se face conform schemei
Golirea buffer-ului (a zonei tampon) se face cu:fflush(stdin);
Citirea datelor - scanf
TastaturăBuffer(Zona
tampon)Program
25/04/07 5
Citirea datelor de la tastatură - scanfForma 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 6
Citirea datelor - scanf
Forma generală a formatului este:
%[*][width][F|N][h|l|L]tip_charunde 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 7
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 8
scanfObservaţ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:45scanf("%d:%d:%d", &ora, &min, &sec);23.09.2004scanf("%d.%2d.%4d", &zi, &luna, &an);
25/04/07 9
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 10
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 11
Citirea datelor de la tastatură - scanfFuncţ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 12
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 13
scanf - exemplunr = scanf("%c",&c);
printf("2 nr = %d\n", nr);printf("2 c = %c", c);
getch();return 0;
}
25/04/07 14
scanfOBSERVAŢ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 15
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 16
printf
Exemplu:int zi = 12;int luna = 2; int an=2004;printf("%02d.%02d.%5d", zi, luna, an);
12.02. 2004
25/04/07 17
printfint a=1;printf("%02d", a); // 01printf("%.3d", a); // 001
float a=2.3;printf("%.0f", a); // 2double f = 34.5; // %lflong double g = 74; // %Lflong j = 123; // %ld
25/04/07 18
printfx = ( 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 19
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 20
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 21
Analiza problemeiFie cei doi vectori
X = (xi)i=1,n
şiY = (yi)i=1,n
atunci
∑=
⋅=n
iii yxPS
1iii yxs +=
25/04/07 22
Analiza problemei1. 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 vector4. funcţia de calcul a vectorului sumă5. funcţia de calcul a produsului scalar
25/04/07 23
Proiectul
• P2.C – fişier care conţine funcţia main
• modulul VECTOR– VECTOR.H– VECTOR.C
25/04/07 24
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 vectoruluivoid citireVector2(int a[], int n, char den[]);
25/04/07 25
VECTOR.H – continuare// Functia de afisare vectorvoid afisareVector(int a[], int n, char den[]);// Functia de calcul a produsului scalarlong produsScalar(int a[], int b[], int n);//Functia de calcul a vectorului sumavoid sumaVectori(int a[], int b[], int c[], int n);#endif
25/04/07 26
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 27
P2.Cn = 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 28
P2.Celse
fprintf(stderr,"Vector nul.\n");
if(!getch()) getch();return 0;
}
25/04/07 29
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 30
VECTOR.Cvoid 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 31
VECTOR.Cvoid 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 32
VECTOR.Clong 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 33
VECTOR.Cvoid 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 34
Operaţii de intrare – ieşire
Operaţii de intrare – ieşire pentru caractere şi şiruri de caractere
25/04/07 35
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 36
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 37
Operaţii de intrare – ieşire pentru caractere
Prototipuri în conio.hNu sunt în standard
int getch(void);int getche(void);int putch(int c);
25/04/07 38
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 39
Exemplu:
#include <stdio.h>
int main(void){
int c;int numarLinii = 0;
25/04/07 40
c = getchar();while(c != EOF) {
if (c == '\n')numarLinii = numarLinii + 1;
c = getchar();}
25/04/07 41
printf("S-au introdus %d linii.\n", numarLinii);return 0;
}
25/04/07 42
Operaţii de I/O pentru şiruri şi fişiere
• sscanf, sprintfint sscanf(char s[], format, arg1, arg2, …);int sprintf(char s[], format, arg1, arg2, …);
• fscanf, fprintfint fscanf(FILE *fisier, format, arg1, arg2, …);int fprintf(FILE *fisier, format, arg1, arg2, …);
25/04/07 43
Operaţii de intrare - ieşirechar temp[81];int a;………………………while(fgets(temp,80,stdin) != 0){
nr = sscanf(temp, ",%d", &a);if(nr == 1)
printf("%d ",a);}………………………….
25/04/07 44
Citirea unei matriceint 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 45
Citirea unei matrice
……………ok = citireMatrice(n,m,a);if(ok == 0)
fprintf(stderr, "Eroare la citirea matricei.\n");…………………
25/04/07 3
ExpresieO 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 4
OperatoriCaracteristici:1. aritate număr de operanzi
2. tip domeniul de definiţie al operaţieidesemnate şi la domeniul valorilor acestei operaţiiExemplu:
+ (real, real; real)
3. efect dat de operaţia simbolizată
25/04/07 5
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 6
Operatori
În funcţie de operaţia realizată:aritmeticiincremetare şi decrementarerelaţionalilogicilogici la nivel de bitatribuireaccesul la date şi dimensiune
25/04/07 7
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 8
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 9
Expresii aritmeticeReguli 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 10
Conversii1. implicite
char, enum intse face conversia la tipul prioritar
T + long double long doubleT + double doubleT + float floatT + unsigned long unsigned longlong + unsigned int unsigned longT + long longunsigned int + int int (dacă se poate) sau
unsigned intint
25/04/07 11
Conversii2. 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 12
Operatori de incrementare - decrementareDefiniţii:
Incrementare operaţia de mărire a valorii unei variabile
de tip întreg cu 1.Operator: ++
Decrementareoperaţia de micşorare a valorii unei
variabile de tip întreg cu 1.Operator: --
25/04/07 13
Sunt operatori care calculează o expresie şi modifică în acelaşi timp o variabilă
Exemple:++i //este echivalent cu i = i + 1n-- //este echivalent cu n = n + 1
Operatorii sunt operatori unari şi pot fi:prefixaţi ++ipostfixaţi n--
Operatori de incrementare - decrementare
25/04/07 14
Exemplu:int x, n= 5;
x = ++n;x = 6n = 6
x = n++;x = 5n = 6
Operatori de incrementare - decrementare
25/04/07 15
Exemplu:temp [nc] = c;nc++;
este echivalent cutemp [nc++] = c;
Operatori de incrementare - decrementare
25/04/07 16
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++);
Operatori de incrementare - decrementare
25/04/07 17
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;
Operatori de incrementare - decrementare
25/04/07 18
4) {int i = 1;printf("%d %d\n", i++, i++);
}
Se afişează2 1
5) i = ++i + 1; /* expresie nedefinită */
6) i++ + j++ * k++ /*expresie nedefinită */
Operatori de incrementare - decrementare
25/04/07 19
#include <stdio.h>#include "ex.h"
int main(void){
int a, i = 10;a = next(i);
printf("a =\n\t%d\n", a);
return 0;}
Operatori de incrementare - decrementareint next (int x){
return x++;}
Programul va afişa:a = 10
25/04/07 20
Expresii de relaţieRezultatul 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 21
Expresii de relaţieOperatori:
< <= > >=== !=
Au prioritatea mai mică decât a operatorilor aritmetici.Se evaluează de la stânga la dreapta.
Exemple:i < lim – 1b == a*agetchar() != EOF
25/04/07 22
Expresii logiceSe 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 23
Expresii logiceEvaluarea 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 24
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 25
Expresii logice
Programul afişează:Mesaj 2 si 2 1
25/04/07 26
Expresii logicePrioritatea
&& 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 egale0 < i < 10 // pentru a testa dacă valoarea lui i este între 1 şi 9
25/04/07 27
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);
Program exemplu P3
25/04/07 28
if( (an >= 1600 && an <= 4900) &&(an % 4 == 0 && an % 100 != 0 || an %
400 == 0))copie(bisect ,“este”);
elsecopie(bisect , “nu este”);
printf(“Anul %d %s bisect\n”, an, bisect);if (!getch()) getch();return 0;
}
Program exemplu P3
25/04/07 29
void copie(char d[], const char s[]){
int i;for(i=0; (d[i] = s[i]) != ‘\0’; i=i+1)
;}
Program exemplu P3
25/04/07 30
Operatori şi expresii de atribuireOperatorul de atribuire
=
Exemple:x = 1a = by = a*x*x + b*x + c
Forma generală este:v = expresie
25/04/07 31
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 valoareExemple:
2 2*i a[j] f(a,2);
Operatori şi expresii de atribuire
25/04/07 32
Evaluarea se face de la dreapta la stângaa = b = c = 2
Expresia de atribuire v = expresie
are o valoare care este valoarea atribuită lui v.
Exemple:(c = getchar()) != EOFz = sqrt(a = 3*x)
Operatori şi expresii de atribuire
25/04/07 33
Forma generală prin care modificăm o variabilă prin operaţii asupra propriei valori este:
v = v op expunde
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
Operatori şi expresii de atribuire
25/04/07 34
Î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 += 1a[i] = a[i] / b a[i] /= bk = k * (n+1) k *= n+1a[i+j+2*k] = a[i+j+2*k] + 4 a[i+j+2*k] += 4
Operatori şi expresii de atribuire
25/04/07 35
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.
Operatori şi expresii de atribuire
25/04/07 36
Operatori şi expresii de atribuireIniţializarea se poate face:
pentru variabile scalarela definire
Exemplu: int a=10;
pe parcursul programului……………….
int a;…………………
a = 10;
25/04/07 37
Operatori şi expresii de atribuirepentru tablouri la definire
int a[5] = {3,4,5,6,7};int a[] = {10,20,30,40};
n = sizeof(a)/sizeof(int);
int a[2][3] = {1,2,3,4,5,6};
int a[2][3] = {{1,2,3},{4,5,6}};
654321
654321
25/04/07 38
pentru structuri la definire
Exemplu:typedef struct _PUNCT {
double x, y;} PUNCT;
PUNCT a = {3.2, 4.5};
Operatori şi expresii de atribuire
25/04/07 39
Un caz special de folosire a operatorului de atribuireeste î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);
Operatori şi expresii de atribuire
25/04/07 40
Operatori logici asupra biţilorSe aplică numai variabilelor de tip întreg (int şi char).
Aceşti operatori conduc la expresii care al căror rezultatdepind de reprezentarea internă a întregilor şi au caracteristici care depind de implementarea tipurilor cu semn.
25/04/07 41
Operatori logici asupra biţilorSunt 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 42
Operatori logici asupra biţilorToţ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 43
Operatorul & (ŞI)
Operatori logici asupra biţilor
101
000
10&
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 44
Operatorul & (ŞI)Exemple:
a) n = 6710
c = n & 01008;
MASCĂ
n = 6710= 26 + 21 + 20 = 010000112 = 01038
c = n & 01008 = 01038 & 01008 = 01008
Operatori logici asupra biţilor
25/04/07 45
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
Operatori logici asupra biţilor
25/04/07 46
Operatorul ^ (SAU EXCLUSIV XOR)
Operatori logici asupra biţilor
011
100
10^
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).
0 – lasă biţii nemodificaţi
1 – complementează biţii
25/04/07 47
Operatorul ^ (SAU EXCLUSIV XOR)
Exemplu:Trebuie complementat bitul 4 dintr-un octet.MASCA = 0x10 00010000Pentru
c = 0x5bu 01011011rezultatul expresiei
c^MASCAeste 01001011
Operatori logici asupra biţilor
25/04/07 48
Operatorul | (SAU)
Operatori logici asupra biţilor
111
100
10|
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 49
Operatorul | (SAU)Exemple:
z = x | MASK
a) x = 6610 MASK = 118
z = 6610 | 118 = 1028 | 118 = 1138 = 7510
MASCĂ
00000000 01000010 | (SAU)00000000 0000100100000000 01001011
Operatori logici asupra biţilor
25/04/07 50
Operatorul | (SAU)Exemple:
z = x | MASK
b) x = 6610 MASK = 778
z = 6610 | 778 = 1028 | 778 = 1778 = 12710
c) x = 6610 MASK = 6810
z = 6610 | 6810 = 4216 | 4416 =
= 010000102 | 010001002 = 010001102 = 4616 = 7010
Operatori logici asupra biţilor
25/04/07 51
ObservaţieOperatorii & şi | sunt diferiţi de operatorii logici &&şi ||.
Exemplu:x = 1, y =2 x & y este 0
x && y este 1
Operatori logici asupra biţilor
25/04/07 52
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
n << 3
n >> 3
Operatori logici asupra biţilor
1110100000000000
0001110100000000
0100000000000000
25/04/07 53
Operatorii de deplasare << şi >><<
completează poziţiile libere cu zerourideplasarea 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
Operatori logici asupra biţilor
25/04/07 54
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
Operatori logici asupra biţilor
25/04/07 55
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
Operatori logici asupra biţilor
ziualunaan
10101110010010110458915
25/04/07 56
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
Operatori logici asupra biţilor
25/04/07 57
Fişier P4.cpp
#include <stdio.h>#include "data.h"
int main(void){
WORD zi, luna, an;WORD data;int nr, valid;
Operatori logici asupra biţilor
25/04/07 58
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;
}
Operatori logici asupra biţilor
25/04/07 59
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;
}
Operatori logici asupra biţilor
25/04/07 60
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');
}
Operatori logici asupra biţilor
25/04/07 61
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');
}
Operatori logici asupra biţilor
25/04/07 62
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;
}
Operatori logici asupra biţilor
25/04/07 63
else
if(luna == 4 || luna == 6 || luna == 9 || luna == 11)if(zi > 30)
valid = 0;else
valid = 1;}return valid;
}
Operatori logici asupra biţilor
25/04/07 64
int anBisect(WORD an){
int bisect;if((an>=1600 && an<=4900) &&
(an%4 == 0 && an%100 != 0 || an%400 == 0))bisect = 1;
elsebisect = 0;
return bisect;}
Operatori logici asupra biţilor
25/04/07 65
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 : beste valoarea minimă dintre a şi b.
Expresia şi operatorul condiţional
25/04/07 66
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
Expresia şi operatorul condiţional
=contrar cazin 0
adevarata este 1 expresia daca efxx
25/04/07 67
Scriemf1(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.
Expresia şi operatorul condiţional
25/04/07 68
d) Să se calculeze valoarea funcţiei f(x) pentru un x citit de la tastatură.
................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));
Expresia şi operatorul condiţional
( )
>+=<−+
=0pentru 340pentru 2
0pentru 1073
2
2
xxxxxxx
xf
25/04/07 69
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.
Expresia şi operatorul condiţional
25/04/07 70
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.
Operatori de apel de funcţie ()
25/04/07 71
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.
Operatorul virgulă
25/04/07 72
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.
Operatorul virgulă
25/04/07 73
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ă.
Operatorii de selecţie
25/04/07 74
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.
Operatorii de selecţie
25/04/07 75
Exemplu:struct PUNCT {
double x,y;};
struct DREPTUNGHI {struct PUNCT A; // colt stanga susstruct PUNCT B; // colt dreapta jos
};
struct DREPTUNGHI D1;struct PUNCT p1;
p1.x D1.A.y
Operatorii de selecţie
25/04/07 76
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) 2float tab[10];sizeof(tab) este 40, iar sizeof(tab[1]) este 4.
Operatorul sizeof
25/04/07 77
Î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));
Operatorul sizeof
25/04/07 78
Pentru BorlandC 3.1 (nu ţine cont de alinierea datelor)
Pentru Visual C 6.0 (ţine cont de alinierea datelor)
Operatorul sizeof
ac1floatc
ac1floatc
25/04/07 79
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) sunte1 && e2 şi e1 || e2e0 ? e1 : e2e1, e2
În toate celelalte cazuri standardul C ANSI nu specifică nimic, ca urmare depinde de fiecare implementare.
Ordinea de efectuare a operaţiilor
25/04/07 80
Tabelul de precedenţă a operatorilor
Operatori Sensul de evaluare
( ) [ ] -> .(punct) De la stânga la dreapta
! ~ ++ -- * & (cast)
sizeof -(unar)
(linia operatorilor unari)
De la dreapta la stânga
* / % 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)
+= -= *= /= %= (atribuire relativă)
<<= >>= &= ^= |= (atribuire relativă)
De la dreapta la stânga
, (virgula) De la stânga la dreapta
25.04.2007 3
Maşina virtuală
Operaţii de bază:citireascriereaatribuirea
D.I. MEMORIE D.E.
UNITATE CENTRALĂ
25.04.2007 4
Structura de control a programuluiOrdinea î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 5
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ţaselecţiaiteraţia
25.04.2007 6
Blocuri de instrucţiuniBloc de instrucţiuni =
o succesiune de declaraţii/definiţii de variabile şi instrucţiuni încadrată de caracterele
{şi
}
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ă.
Înaintea unui bloc nu se pune ;.
După un bloc nu se pune ;.
25.04.2007 7
Blocuri de instrucţiuniIndiferent 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 8
Blocuri de instrucţiuniVariabilele 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 9
Blocuri de instrucţiuniExemplu:
if(...) {tip1 x1;……………
}else {
tip2 x2;……………
}
Variabilele x1 şi x2 nu există niciodată simultan.
STIVA
Intrare în bloc Ieşire din bloc
x1
..............
..............
x2
25.04.2007 10
InstrucţiuniRECOMANDĂ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 11
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 12
Instrucţiuni simple - Instrucţiunea expresieAre 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 13
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ţiunede apel de funcţie
Instrucţiuni simple - Instrucţiunea expresie
25.04.2007 14
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) expresiex = a + f(2,3); instrucţiune
Instrucţiuni simple - Instrucţiunea expresie
25.04.2007 15
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 16
Structuri de control - secvenţaEste o structură formată
din una sau mai multe instrucţiuni care se execută secvenţial (în ordinea în care sunt scrise în program).
Se execută conform schemei din figură.
Actiune 1
Actiune 2
Actiune n
Aici schema secontinua cateste nevoie
25.04.2007 17
Structuri de control - secvenţaEste formată dintr-un bloc de instrucţiuni, deci
forma generală este:
{declaratii;instructiuni;
}
25.04.2007 18
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 19
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 20
Structuri de control – selecţia (decizia)S1). Selecţia cu două alternative
Reprezentare prin schema logică:
conditie
Secventa A Secventa B
Adevarat Fals
25.04.2007 21
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 22
Structuri de control – selecţia (decizia)S1). Selecţia cu două alternative
Instrucţiunea C corespunzătoare este if ... else
if(conditie)Secventa_A;
elseSecventa_B;
25.04.2007 23
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 24
Structuri de control – selecţia (decizia)S1). Selecţia cu două alternativeExemple: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 25
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ţiunevoid 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 26
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 27
Structuri de control – selecţia (decizia)S2). Selecţia cu o alternativă (cu o ramură vidă)
Reprezentarea prin schema logică
conditie
Secventa
Adevarat
25.04.2007 28
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 29
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 30
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 31
Structuri de control – selecţia (decizia)S3). Selecţia multiplă - S3.1) Cu instrucţiunea ifReprezentare prin pseudocoddacă <conditie1>
atunci <secventa1>;
altfel dacă <conditie2>
atunci <secventa2>;
...........................................
dacă <conditien>
atunci <secventan>
altfel <secventan+1>;
sf. dacă
25.04.2007 32
conditie 1
conditie 2
conditie 3
Secventa 1
Secventa 2
Seventa 3
Adevarat Fals
Adevarat Fals
Adevarat
conditie n
Secventa n Secventan+1
Adevarat Fals
Fals
Aici schema secontinua cu cate
conditii este nevoie
25.04.2007 33
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;
Structuri de control – selecţia (decizia)
25.04.2007 34
Structuri de control – selecţia (decizia)S3). Selecţia multiplă - S3.1) Cu instrucţiunea if
sau if(conditie1) {
if(conditie2)secventa1;
elseif(conditie3)
secventa2;}else
secventa3;
25.04.2007 35
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");
elseputs("Alt caracter");
25.04.2007 36
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 37
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 38
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 39
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 40
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:
Secventa 1 Secventa 2Secventa
n+1
Expresie ?
Secventa 3 Secventa n
Val2Val1 Val3 Valn Rest
25.04.2007 41
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 42
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 43
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 44
Structuri de control – selecţia (decizia)S3). Selecţia multiplă - S3.2) Cu instrucţiunea switchForma generală:
switch(exp) {case c1:
... cod ...break;
case c2:... cod ...break;
…………………………………....default:
... cod ...}
25.04.2007 45
Structuri de control – selecţia (decizia)S3). Selecţia multiplă - S3.2) Cu instrucţiunea switch
undeexp este o expresie de tip întregc1, 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 cicare egalează valoarea expresiei exp.
25.04.2007 46
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 47
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 48
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 49
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 50
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 51
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 52
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 53
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 54
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 55
Structuri de control repetitive –iteraţia cu test iniţial
conditie
Secventa
AdevaratFals
Schema logică a acestei structuri de control este
25.04.2007 56
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 57
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 58
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 59
Structuri de control repetitive –iteraţia cu test final
Secventa
conditieAdevaratFals
Schema logică a acestei structuri de control este
25.04.2007 60
Structuri de control repetitive –iteraţia cu test final
În pseudocod are forma:
repetă<secvenţă>;
cât timp <condiţie>
25.04.2007 61
Structuri de control repetitive –iteraţia cu test final
Instrucţiunea C corespunzătoare
do {secventa;
} while (expresie);
25.04.2007 62
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 63
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).
KK ++++++=!!3!2
132
nxxxxen
x
( ) 1!1
!
01
1
=⋅=⋅−
=
=
−
−
ukxu
kx
kxu
kxu
k
k
k
k
k
25.04.2007 64
Structuri de control repetitive –iteraţia cu test final
2)
Calculul se repetă până când
nnx Ruuuue +++++= K210
011
110
=+=++++=
−−
−
SuSSuuuuS
kkk
kkk K
ε<<− − kkk uSS 1
25.04.2007 65
Structuri de control repetitive –iteraţia cu test final2)
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 66
Iteraţia cu contor
Secventa
Fals
v i←v a r
p a s+← v a rv a r
v f≤v a rAdevarat
Schema logică a acestei structuri de control este dată în figură.
25.04.2007 67
Structuri de control repetitive –iteraţia cu contor
În pseudocod reprezentarea este
repetă pentru <var> = vi, vf, pas<secvenţă>;
sf. repetă
25.04.2007 68
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 69
Structuri de control repetitive –iteraţia cu contor
Observaţii:1. variabila de buclă poate fi de tip întreg sau real2. 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 70
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 71
Iteraţia cu contor
Ei
Et
Secventa
Em
AdevaratFals
O formă mai generală pentru instrucţiunea de iteraţie cu contor este dată în figura alăturată.
25.04.2007 72
Structuri de control repetitive –iteraţia cu contor
undeei 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 73
Structuri de control repetitive –iteraţia cu contorInstrucţ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 74
Structuri de control repetitive –iteraţia cu contorObservaţ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 75
Exemplu:Calculul valorii unui polinom într-un punct.
Structuri de control repetitive –iteraţia cu contor
( ) nnnn axaxaxaxP ++++= −−
11
10 ...
( ) 01 =− xP
( ) ( ) nnn axxPxP +⋅= −1
25.04.2007 76
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;
}
Structuri de control repetitive –iteraţia cu contor
25.04.2007 77
Alte instrucţiunibreak
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 78
Alte instrucţiunibreak - exemple
1)while((c=getchar()) != '\n') {
if(c == EOF)break;
++lung;}
25.04.2007 79
Alte instrucţiunibreak - 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 80
Alte instrucţiunicontinue
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 81
Alte instrucţiunicontinue - exemple
1)for(i=0; i< MAX; i++){
r = i%7;if(0 == r)
continue;sum += 15780/r;
……………………………………………….}
25.04.2007 82
Alte instrucţiunireturn
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;
undeexpresie trebuie să fie de acelaşi tip cu tipul funcţiei. Valoarea expresiei este valoarea furnizată de funcţie.
25.04.2007 83
Alte instrucţiunigoto
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 aprilie 2007 Programarea Calculatoarelor 1
PROGRAMAREA CALCULATOARELOR
Curs nr. 9-10-11
25 aprilie 2007 Programarea Calculatoarelor 2
POINTERI 1
25 aprilie 2007 Programarea Calculatoarelor 3
PointeriPointeri
Notăm în continuare prin T un tip de dată predefinitsau definit de utilizator.
Definirea unei variabile:T n; 2 semnificaţii
int j, k;k=2;j = 7; // Linia 1k = j; // Linia 2
25 aprilie 2007 Programarea Calculatoarelor 4
PointeriPointeri -- definiţiidefiniţii
Variabile pointeri– definiţie
– definireT *pt;T *pt1, *pt2, pt3;
typedef T* PT; // in headerPT p1, p2, p3;
pt
25 aprilie 2007 Programarea Calculatoarelor 5
PointeriPointeri -- definiţiidefiniţii
Variabile pointeriExemple:
int *pi;double *pr;struct PUNCT *pp;
typedef int *POINTER_LA_INTREG; // in header
POINTER_LA_INTREG p1, p2;
25 aprilie 2007 Programarea Calculatoarelor 6
PointeriPointeri -- definiţiidefiniţii
Variabile pointeri –dimensiunea unui pointer
sizeof(pt) ?
25 aprilie 2007 Programarea Calculatoarelor 7
PointeriPointeri –– adresa unei variabileadresa 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 8
PointeriPointeri –– conţinutul unei adreseconţ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 9
PointerPointeri i –– expresii cu pointeriexpresii cu pointeri
Expresii cu pointeriint *pk, j;double d;
j = *pk + 10d = sqrt((double) *pk)*pk = 0*pk += 1
25 aprilie 2007 Programarea Calculatoarelor 10
PointeriPointeri –– expresii cu pointeriexpresii cu pointeri
*pk++(*pk)++pk = pj
Prioritatea operatorilor * şi &
j = *pk + 1j = *(pk + 1)
25 aprilie 2007 Programarea Calculatoarelor 11
Pointeri Pointeri –– trebuietrebuie cunoscutcunoscut tipultipul
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 12
PointeriPointeri –– pointer genericpointer 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 13
Pointer Pointer –– pointer genericpointer 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 14
Pointeri Pointeri –– exempluexemplu pointer genericpointer 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 15
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorcu cu adresaadresa uneiunei variabilevariabile
a) atribuirea unei adrese de variabilă
int i;int *pi;
pi = &i;
25 aprilie 2007 Programarea Calculatoarelor 16
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilor cu cu valoareavaloarea zerozero
b) atribuirea valorii NULL
int *pi = NULL;
double *pr = 0;
25 aprilie 2007 Programarea Calculatoarelor 17
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilor cu cu valoareavaloarea unuiunui alt pointeralt pointer
c) atribuirea valorii unui alt pointer
int i;int *pi, *pj;
pi = &i;pj = pi;
pj
ipi
25 aprilie 2007 Programarea Calculatoarelor 18
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă 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 19
a) void *malloc(size_t nrOcteti);
Exemplu:char *p;p = (char *)malloc(15);
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
p
25 aprilie 2007 Programarea Calculatoarelor 20
a) void *malloc(size_t nrOcteti);
Exemplu:short int *p1;p1 = (short int *)malloc(5*sizeof(short int));
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
p1
25 aprilie 2007 Programarea Calculatoarelor 21
T *pt;
pt = (T *)malloc(n * sizeof(T));if(pt == 0) {
fprintf(stderr, "Eroare la alocare \n");exit(EXIT_FAILURE);
}
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 22
xmalloc funcţie de alocare a memoriei, cu verificarea alocării şi care păstrează aceeaşi semnătură ca şi malloc.
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 23
void *xmalloc(size_t nrOcteti){
void *ptr;ptr = malloc(nrOcteti);if(ptr == NULL) {
fprintf(stderr, "Eroare alocare memorie\n");exit(EXIT_FAILURE);
}return ptr;
}
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 24
Exemple:
1)int *p;p = (int *)xmalloc(20 * sizeof(int));
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 25
2) struct DATA {int zi, an;char *luna;
};
struct DATA *ps, astazi;ps = (struct DATA *)
xmalloc(sizeof(struct DATA));
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 26
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);
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 27
ps->luna = (char *)xmalloc(15*sizeof(char));
astazi.luna = (char *)xmalloc(15*sizeof(char));
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 28
b) eliberarea memoriei
void free(void *p);
free((T *)pt);pt = NULL;
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 29
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);
}
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 30
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);
}
PointeriPointeri –– iniiniţializareaţializarea pointerilorpointerilorprinprin alocareaalocarea dinamicdinamică a memorieiă a memoriei
25 aprilie 2007 Programarea Calculatoarelor 31
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
Operaţii permise în aritmetica pointerilor
adunarea / scăderea unui întregincrementarea / decrementarea unui pointercomparaţii, testarea egalităţiiscăderea a doi pointeri
25 aprilie 2007 Programarea Calculatoarelor 32
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
adunarea / scăderea unui întreg
short int *pi, *p2;float *pf, *pf2;int n = 3;
După o iniţializare, putem scriep2 = pi + n;pf = pf2 + n;
25 aprilie 2007 Programarea Calculatoarelor 33
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
adunarea / scăderea unui întreg
p2pi↑↑
pfpf2↑↑
25 aprilie 2007 Programarea Calculatoarelor 34
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
incrementarea /decrementarea unui pointer
char *p1, *p2, *p3;p2 = ++p1;p3 = --p1;
p2p1p3↑↑↑
25 aprilie 2007 Programarea Calculatoarelor 35
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
incrementarea / decrementarea unui pointer
float *pf1, *pf2, *pf3;pf1++; pf1--;pf2 = pf1; pf3 = pf1;
pf2pf1pf3↑↑↑
25 aprilie 2007 Programarea Calculatoarelor 36
Pointeri Pointeri –– aritmeticaaritmetica pointerilorpointerilor
compararea a doi pointeri< <=> >=== !=
qp↑↑
25 aprilie 2007 Programarea Calculatoarelor 37
Pointeri – aritmetica pointerilor
scăderea a doi pointeri
short int *p1, *p2;…………………………………p2-p1 numărul de elemente dintre p1 şi p2.
p2p1↑↑
25 aprilie 2007 Programarea Calculatoarelor 38
Un tablou:short int v[5];
Un pointer:short int *p;p = (short int *)xmalloc(5*sizeof(short int));
Pointeri şi tablouri
v↑
p↑
25 aprilie 2007 Programarea Calculatoarelor 39
short int *pv;pv = &v[0];
pv = v;
Pointeri şi tablouri
pvv↑
25 aprilie 2007 Programarea Calculatoarelor 40
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 41
Pointeri şi tablouri
short int z;
z = v[i];z = pv[i];
z = *(v+i);z = *(pv + i);
25 aprilie 2007 Programarea Calculatoarelor 42
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]
pv
↑↑
25 aprilie 2007 Programarea Calculatoarelor 43
Pointeri şi tablouri
De ce primul index al unui tablou este 0 (zero)?
25 aprilie 2007 Programarea Calculatoarelor 44
Pointeri şi tablouri
Diferenţa dintre pointeri şi tablouri
short int v[5];short int *pv;
pv = &v[0];pv++;pv = v + 3;
v++; // NUv = pv + 4; // NU
25 aprilie 2007 Programarea Calculatoarelor 45
Pointeri şi tablouri - exemple1) 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 46
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 47
Pointeri şi tablouri - exemple3) determinarea maximuluiint maxim(int a[], int n){
int max;int *p;int *ai = &a[0];int *af = a+n;max = *a;for(p = a+1; p < af; p++)
if(*p > max)max = *p;
return max;}
afai↑↑
25 aprilie 2007 Programarea Calculatoarelor 48
Pointeri şi tablouri - exemple
char c[] = "Sir de test";int i;for(i=0; c[i] != '\0'; i++)
printf("%s\n", &c[i]);
c[i]c
↑↑\0tsetedriS
25 aprilie 2007 Programarea Calculatoarelor 49
Pointeri şi funcţiiPointerii pot fi (ca orice altă variabilă):
-parametri pentru funcţiiExemplu: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 50
Pointeri şi funcţiivoid F(int a, int b){
int aux;aux = a;a = b;b = aux;
}……………
a=10;b = 20;F(a,b);
……………
a ?a ?
b ?b ?
25 aprilie 2007 Programarea Calculatoarelor 51
Pointeri şi funcţiivoid swap(int *a, int *b){
int aux;aux = *a;*a = *b;*b = aux;
}…………………
a = 10;b = 20;swap(&a, &b);
…………………
a ?a ?
b ?b ?
25 aprilie 2007 Programarea Calculatoarelor 52
Pointeri şi funcţii
Pointerii pot fi (ca orice altă variabilă):
-valori de retur pentru funcţiidouble *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 53
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.HVECTOR.C
25 aprilie 2007 Programarea Calculatoarelor 54
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 55
VECTOR.Cint *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 56
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 57
VECTOR.Csize_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 58
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 59
MAIN.Ca = 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 60
Funcţii care returnează pointeriFuncţ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 61
Funcţii care returnează pointeriint main(void){……………………
double *s;……………………
s = sumaVectori(a, b, n);afisareVector(s, n, "Suma");
……………………free((double *) s);s = 0;
……………………}
25 aprilie 2007 Programarea Calculatoarelor 62
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 63
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 64
Pointeri constanţi şi pointeri la o constantă
*cp1 = 30;cp1++;
/* Nepermis, pointer constant la o constanta */
return 0;}
25 aprilie 2007 Programarea Calculatoarelor 1
PROGRAMAREA CALCULATOARELOR
Curs nr. 12-13-14
25 aprilie 2007 Programarea Calculatoarelor 2
POINTERI 2
25 aprilie 2007 Programarea Calculatoarelor 3
Tablou de pointeri
Un tablou unidimensional (vector) se declară astfel:
T tab[100];
typedef T1* T;
T1* tab[100];
25 aprilie 2007 Programarea Calculatoarelor 4
Tablou de pointeri
tab[99]
tab[1]
tab[0]
tab
21
8765
342111
25 aprilie 2007 Programarea Calculatoarelor 5
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 6
Tablou de pointeri – exemplu
text[2]
text[49]
text[1]
text[0]
text
l \0p umexE
\0ed
\0txet
25 aprilie 2007 Programarea Calculatoarelor 7
Tablouri de pointeri – exempluTEXT.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 8
Tablouri de pointeri – exempluTEXT.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 9
Tablouri de pointeri – exempluMAIN.C
#include <stdio.h>#include "text.h"
int main(void){
char *text[L];int numarLinii = 0;
25 aprilie 2007 Programarea Calculatoarelor 10
Tablouri de pointeri – exempluMAIN.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 11
Tablouri de pointeri – exempluMAIN.C
fprintf(stderr, "Nu s-a introdus text\n");return 0;
}
25 aprilie 2007 Programarea Calculatoarelor 12
Tablouri de pointeri – exempluFunctii_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 13
Tablouri de pointeri – exempluFunctii_Text.c
text[nl] = (char *)xmalloc((strlen(temp)+1)*sizeof(char));
strcpy(text[nl], temp);nl++;
}
return nl;}
25 aprilie 2007 Programarea Calculatoarelor 14
Tablouri de pointeri – exempluFunctii_Text.c
void afisareText(char *text[], int nl){
int i;for(i=0; i<nl; i++)
puts(text[i]);}
25 aprilie 2007 Programarea Calculatoarelor 15
Tablouri de pointeri – exempluFunctii_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 16
Tablouri de pointeri – exempluFunctii_Text.c
void sortareText(char *text[], int nl){
int i;int ok;int k = nl – 1;do {
ok = 1;
25 aprilie 2007 Programarea Calculatoarelor 17
Tablouri de pointeri – exempluFunctii_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 18
Tablouri de pointeri – exempluFunctii_Text.c
void swapL(char **p1, char **p2){
char *aux;aux = *p1;*p1 = *p2;*p2 = aux;
}
25 aprilie 2007 Programarea Calculatoarelor 19
Pointer la un tablou
typedef unsigned char Byte;
typedef int VECTOR[10];
VECTOR v;
VECTOR v1[5];
VECTOR *pv;
25 aprilie 2007 Programarea Calculatoarelor 20
Pointer la un tablou
pv = &v1[0];sau
pv = v1;
Dacă nu folosim typedefint (*pv)[10];int *p1[10];
sizeofsizeof(*(*pvpv) ?) ?
25 aprilie 2007 Programarea Calculatoarelor 21
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 22
T *p;
T (*pv)[10];
pv = (T (*)[10])xmalloc(1 * sizeof(*pv));
Pointer la un tablou – exemplu
p
pv
25 aprilie 2007 Programarea Calculatoarelor 23
Pointer la un tablou – exemplu
pv = (T (*)[10])xmalloc(5 * sizeof(*pv));
(*pv+j)
6555453525155
1234567890*(pv+2)
11232072
1925342015pv321
25 aprilie 2007 Programarea Calculatoarelor 24
Pointeri la un tablou
*pv
CeCe semnificaţie semnificaţie areare??
25 aprilie 2007 Programarea Calculatoarelor 25
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 26
Pointeri la un tablou
T *p3[10];
p3[9]
p3[1]
p3[0]
p3
*(p3[0]+j)21
8765
342111
p3[0]+j
25 aprilie 2007 Programarea Calculatoarelor 27
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 28
Pointeri la un tablou – exemplumain_TP.C
int main(void){
T *p1;T (*p2)[10];T *p3[10];int i;
size_t n = 20;
25 aprilie 2007 Programarea Calculatoarelor 29
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 30
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 31
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 32
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 33
Pointeri la un tablou – exemplup3++;
(*p3)++;
p2++;
p1++;
printf("2 p1 = %p, p2 = %p, *p3 = %p\n", p1, p2, *p3);
25 aprilie 2007 Programarea Calculatoarelor 34
Pointeri la un tablou – exemplufree(--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 35
Matrici alocate dinamic
p[9]
p[1]
p[0]
p
*(p[0]+j)21
8765
342111
p[0]+j
25 aprilie 2007 Programarea Calculatoarelor 36
Matrici alocate dinamicT 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 37
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 38
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 39
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 40
Matrici alocate dinamic
puts("Matricea mat1");afisareMatrice(mat1, n, m);
free((VP) mat1);mat1 = 0;
return 0;}
25 aprilie 2007 Programarea Calculatoarelor 41
Matrici alocate dinamicvoid 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 42
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 43
Matrici alocate dinamic
T (*pv)[10];pv = (T (*)[10])xmalloc(5 * sizeof(*pv));
*(pv+i)+j(*pv+j)
6555453525155
1234567890pv+i
11232072
1925342015pv321
25 aprilie 2007 Programarea Calculatoarelor 44
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 45
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 46
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 47
Matrici alocate dinamicT **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 48
Matrici alocate dinamic
void dealoca2dc(T **a){
free((T *) a[0]);a[0] = 0;free ((T **) a);
}
25 aprilie 2007 Programarea Calculatoarelor 49
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 -22 3 1 -1 0 10 -1 -2 2 3 1
25 aprilie 2007 Programarea Calculatoarelor 50
Matrici alocate dinamic - exemplu
Proiect:1. modul de alocare:
ALOCARE.HALOCARE.C
2. modul de lucru cu matriceMATRICE.HMATRICE.C
25 aprilie 2007 Programarea Calculatoarelor 51
Matrici alocate dinamic - exempluALOCARE.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 52
Matrici alocate dinamic - exempluALOCARE.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 53
Matrici alocate dinamic - exempluALOCARE.Cvoid 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 54
Matrici alocate dinamic - exempluMATRICE.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 55
Matrici alocate dinamic - exempluMATRICE.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 56
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 57
Matrici alocate dinamic - exempluvoid 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 58
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 59
Matrici alocate dinamic - exempludo {
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 60
Matrici alocate dinamic - exemplu
void swapi(int **l1, int **l2){
int *aux;aux = *l1;*l1 = *l2;*l2 = aux;
}
25 aprilie 2007 Programarea Calculatoarelor 61
Matrici alocate dinamic - exempluint 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 62
Matrici alocate dinamic - exemplu
#include "alocare.h"#include "matrice.h"
int main(void){
int **a;int n, m;
25 aprilie 2007 Programarea Calculatoarelor 63
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 64
Matrici alocate dinamic - exemplu
puts("\nDupa sortare");afisareMatrice(a, n, m, "A");
dealoca2d(a,n);a=0;
return 0;}
25 aprilie 2007 Programarea Calculatoarelor 65
Argumentele liniei de comandăLinia de comandă
există şi în Windowsredirectarea intrării şi ieşirii
p1 <in.txtp1 >out.txtp1 <in.txt >out.txt
int main(void)
int main(int argc, char *argv[])
25 aprilie 2007 Programarea Calculatoarelor 66
Argumentele liniei de comandă
int main(int argc, char *argv[]){
int i;for(i=0; i<argc; i++)
puts(argv[i]);
return 0;}