Documente Academic
Documente Profesional
Documente Cultură
- ierarhia de tip.
Ierarhia structurala este o ierarhie în care se poate afirma despre un obiect ca este o parte
a altui obiect, mai complex. Exemple de astfel de descompuneri se pot da oricâte, din orice
domeniu.
De exemplu, un calculator poate fi studiat prin descompunerea lui în subansamble
componente: placa de baza, placa video, monitor, etc; la rândul ei, placa de baza este compusa
din placheta de circuit imprimat, procesor, memorie, etc. Aceasta este o ierarhie de tipul “este o
parte din…”.
Pe de alta parte, fiecare obiect poate fi încadrat într-o categorie (clasa, tip) mai larga,
care contine mai multe obiecte care au proprietati comune. De exemplu, procesorul este de o
componenta electronica; monitorul este un dispozitiv de afisare, etc. Aceasta ierarhie se refera la
apartenenta obiectelor la o anumita clasa (sau tip - “este de tipul…”).
Este esential sa privim sistemele complexe din ambele perspective, studiindu-le atât din
perspectiva ierarhiei structurale, deci a obiectelor care le compun, cât si a ierarhiei de tip, deci a
claselor carora le apartin. La rândul lor, clasele din care fac parte obiectele pot fi organizate sau
studiate ca elemente componente ale unei ierarhii, prin care o clasa este considerata ca primitiva
(parinte) a unei alte clase.
Cele doua tipuri de ierarhii, ierarhia de clase si ierarhia de obiecte nu sunt independente,
si, împreuna, pot sa reprezinte un sistem complex.
La fel ca oricare sistem complex, software-ul poate fi controlat prin descompunerea lui.
Rolul descompunerii unui sistem în general (si al programelor în special) este de a permite
întelegerea si manevrarea acestuia: sistemul este descompus în parti din ce în ce mai mici,
fiecare dintre ele putând fi rafinata si dezvoltata independent.
Principiul “divide-et-impera”, care se aplica în multe situatii, este util si în programare.
- descompunerea algoritmica si
Abstractizarea datelor
Încapsularea
Încapsularea este un mecanism care leagă împreună cod şi date şi le păstrează pe ambele în
siguranţă faţă de intervenţii din afară şi de utilizări greşite. Mai mult, încapsularea este cea care
permite crearea unui obiect. Spus simplu, un obiect este o entitate logică ce încapsulează atât date
cât şi cod care manevrează aceste date. Într-un obiect o parte din cod şi/sau date pot fi particulare
acelui obiect şi inaccesibile în afara sa. În acest fel, un obiect dispune de un nivel semnificativ de
protecţie care împiedică modificarea accidentală sau utilizarea incorectă a părţilor
proprii obiectului de către secţiuni ale programului cu care nu are legătură.
În cele din urmă, un obiect este o variabilă de un tip definit de utilizator. Când se defineşte
un obiect, implicit se crează un nou tip de date.
Polimorfism
Moştenirea este procesul prin care un obiect poate să preia prototipul altui obiect. Acest lucru
este important deoarece se admite conceptul de clasificare. Majoritatea cunoştinţelor despre lumea
înconjurătoare sunt accesibile deoarece sunt clasificate ierarhic. De exemplu, un câine ciobănesc
face parte din clasa câine, care la rândul său face parte din clasa mamifere care se află în marea
clasă animale. Fără utilizarea claselor, fiecare obiect ar trebui definit explicitându-se toate
caracteristicile sale. Însă, prin folosirea clasificărilor, un obiect are nevoie doar de definirea acelor
calităţi care îl fac unic în clasa sa. Mecanismul moştenirii face posibil ca un obiect să fie un
exemplar specific al unui caz mai general.
Fig.1. Clase
Setul de caractere
Orice limbaj de programare are la bază un anumit alfabet. În majoritatea cazurilor setul de caractere
este format din:
\b Backspace, \t Tab orizontal, \v Tab vertical, \n Linie nouă, \f Pagina nouă – formfeed
\r Început de rând, \” Ghilimele, \’ Apostrof, \\ Backslash, \? Semnul întrebării, \a Alarmă
• EBCDIC (Extended Binary Coded Decimal Interchenge Code), un cod pe 8 biți, introdus
de IBM;
• ASCII (American Standard Code for Information Interchange), introdus de ANSI
(American National Standard Institute), este un cod pe 7 biți și permite codificarea a 128
de caractere (95 de caractere afișabile și 33 de caractere neafișabile, numite caractere de
control). Ulterior, setul ASCII a fost extins la o codificare pe 8 biți, fiind disponibile astfel
256 de caractere.
Primele 128 sunt din setul ASCII standard, iar următoarele 128 sunt coduri de caractere afișabile
pentru caracterele unor alfabete naționale europene (francez, spaniol, român etc.), o parte din
literele alfabetului grecesc, unele simboluri matematice, caractere speciale pentru desenat tabele
etc.
1. cuvinte cheie – acestea au un înțeles explicit într-un context precizat (de ex., în unele
limbaje de programare cuvintele ce desemnează instrucțiuni pot fi folosite și ca nume de
variabile, neexistând restricții; asemenea situații nu sunt însă indicate deoarece pot ascunde
erori în logica programului și îl fac mai greu de înțeles);
2. cuvinte rezervate – acestea nu pot fi folosite decât în scopul pentru care au fost definite
(de ex., în limbajul C++). Avantajele utilizării acestei categorii de cuvinte sunt
următoarele:
Notatia BNF
Notatia BNF (Backus-Naur Form) a fost utilizata prima data la descrierea sintaxei limbajului
ALGOL (în cadrul raportului ALGOL60 aparut în 1963) si este numita dupa doi dintre autorii
acestui raport. În cadrul BNF sunt folosite metasimboluri, simboluri terminale si simboluri
neterminale.
Metasimboluri sunt simbolurile <, >, ½ si ::= si ele fac parte din mecanismul de descriere a
limbajului. Simbolul ½ semnifica o alternativa, simbolul ::= inseamna „se definește astfel”.
Simbolurile terminale sunt cuvinte care apar acolo unde se specifica în productii (de ex., for, while,
do, +, ; etc.).
Simbolurile neterminale sunt încadrate în < si > si sunt definite prin productii ale limbajului (de
ex., <variabila>, <identificator>, <instructiune if> etc.).
<identificator>::=<litera>|<identificator><cifra>|<identificator><literă>|
unde
<litera>::=a|b|...|z|A|B|...|Z|_
<cifra>::=0|1|2|...|9
Simbolul _ este considerat <litera> în acest context.
Conform acestei reguli, identificatorul are 3 definiții alternative: un identificator este fie o <litera>,
fie un <identificator> urmat de o <cifra> sau o <litera> (definitie recursiva). Semnificatia acestei
definitii este urmatoarea: un identificator poate sa contina o singura litera, sau o litera urmata de
oricâte litere si/sau cifre. Conform acestei definitii, sunt corecte sintactic urmatorii identificatori:
a, t1, sec12a1.
Descrierea sintaxei instructiunii conditionale if-else din limbajul C++ în notatie BNF este:
Semantica unei instrucțiuni reprezintă înțelesul pe care îl are acea instrucțiune, adică ce va executa
calculatorul când o întâlnește.
Astfel, pentru instrucțiunea if-else de mai sus, se evalua condiția <conditie>, iar dacă aceasta este
adevărată (în momentul evaluării), atunci se va executa o singură dată
instrucțiunea <instructiune1>, respectiv, dacă este falsă, se va executa o singură dată
instrucțiunea <instructiune2>.
/*
* primul program in C++
*/
#include <iostream>
int main ()
{
std::cout << "Primul test 1, 2, 3. ";
std::cout << "functioneaza.. \n";
return 0;
}
SAU
/*
* primul program in C++
*/
#include <iostream>
using namespace std;
int main ()
{
cout << "Primul test 1, 2, 3. ";
cout << "functioneaza.. \n";
char c;
cout << "Pentru a iesi, apasati orice tasta!!\n";
cin >> c;
return 0;
}
Rezultatul va fi:
Primul test 1, 2, 3. functioneaza..
} //aici se încheie programul
Directive preprocesare
Sintaxa:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include “biblioteca_mea.h”
#include “t1.h”
Sintaxa:
#define simbol
Exemple:
În cadrul programului, datele pot fi declarate ca fiind constante sau variabile. O constantă
este o dată a cărei valoare nu se poate modifica pe parcursul execuţiei programului, deci rămâne
constantă.
O variabilă este o dată a cărei valoare se poate modifica pe parcursul execuţiei programului,
deci ea poate varia, dar acest lucru nu este obligatoriu. Astfel, se poate declara o dată ca fiind
variabilă în cadrul unui program, apoi ea să primească o anumită valoare, iar această valoare să
rămână asociată respectivei variabile până la terminarea programului.
Evident, atunci când se va declara o dată constantă, se va preciza şi valoarea ei, iar când se va
declara o dată variabilă, se subînţelege că ulterior, pentru a putea fi folosită, această variabilă va
primi o anumită valoare.
Majoritatea limbajelor de programare asignează o valoare iniţială variabilelor, o dată cu
declararea lor. Astfel, şirurile de caractere sunt iniţializate la şirul vid, iar numerele sunt
considerate cu valoarea zero.
Fireşte, atât constantele cât şi variabilele au o anumită structură, mai simplă sau mai complicată,
şi o anumită natură, dată de mulţimea valorilor posibile pentru o dată. Cu ele se pot face anumite
operaţii, în funcţie de natura şi structura lor. Astfel, vom spune că o dată are un anumit tip.
Expresii
Pe baza regulilor de mai sus putem construi expresii foarte complexe, pornind de la
constante şi variabile. Astfel, să considerăm entitatea (3+A)*(5/(-B+C)) şi să verificăm dacă ea
este expresie sau nu. Să presupunem că A, B şi C sunt variabile numerice întregi. Cum 3 este
constantă, conform regulii 1, ea este şi expresie. A, fiind variabilă este, conform regulii 2 expresie.
Acum, conform regulii 4, 3+A este expresie, iar (3+A) este tot expresie, conform regulii 3. După
simbolul înmulţirii (reprezentat adesea prin *), avem: 5 este expresie, fiind constantă, B, C, apoi -
B şi -B+C sunt expresii. În fine, conform regulii 3, (-B+C) este tot expresie, apoi şi (5/(-B+C))
este expresie, în conformitate cu regula 4, şi, tot după această regulă, şi (3+A)*(5/(-B+C)) este
expresie.
Datele sunt caracterizate de
• Tip
• Nume
• Valoare
• Domeniu de vizibilitate
• Timp de viaţă
• Operatori
• Apeluri de funcții
Variabile în C++
Declararea variabilelor
tip variabila;
Variabile globale: declararea lor se face la începutul programului, în afara oricărei funcţii.
Exemplificare
char c;
signed char sc;
int a, b;
a = b = 5;
int i;
int suma = 0;
long j;
• Tip = int
• Nume = x
• Valoare = 4
• Domeniu de vizibilitate: funcția patrat
• Timp de viaţă = pe durata unui apel al funcției
variabila = expresie;
SAU
Exemplu
În atribuirea
În atribuiri apar alte două probleme, despre care vom vorbi mai târziu:
• Compatibilitate
• Conversii
Tipuri de variabile
Tipuri de date
Prin tip de date vom înţelege o mulţime de valori, împreună cu operaţiile ce se pot executa cu ele.
Fiecărei variabile, la declarare, i se va asocia un anumit tip. Tipul unei constante poate fi determinat
implicit din valoarea constantei, sau poate fi precizat explicit ca în cazul variabilelor. Astfel, dacă
constanta K are valoarea numerică 7, putem trage concluzia că ea este de tip întreg, sau de tip real,
nu şi logic sau şir de caractere.
Totuşi, există şi limbaje în care se fac anumite convenţii, de pildă că orice număr diferit de zero
este considerat ca fiind cu valoarea de adevăr adevărat, iar numărul zero are valoarea de adevăr
fals.
Unele limbaje de programare permit declararea unor variabile fără a se preciza tipul lor,
considerându-se astfel ca având un anumit tip general. Astfel, atunci când va fi folosită, variabila
respectivă va fi considerată ca având cel mai adecvat tip cu putinţă, în situaţia concretă respectivă.
De pildă, dacă este declarată o variabilă X, iar la un moment dat i se atribuie valoarea 3,. atunci ea
poate fi considerată ca având un tip numeric. Dacă ulterior, variabila X va primi valoarea „abc”,
adică un şir de caractere, se poate considera că X este de tip şir de caractere.
Pe baza constantelor şi variabilelor se formează expresii. Bineînţeles, în formarea expresiilor se
vor folosi acei operatori, precum şi acele funcţii, permise de tipurile valorilor asupra cărora se
operează. Expresiile mici pot conduce la elaborarea de expresii mai mari, din ce în ce mai
complexe
Domeniul tipului (colecţia de obiecte) – mulțime de valori pentru care s-a adoptat un anumit mod
de reprezentare în memorie
Tipuri întregi
Constante întregi
• Octale: au prefixul 0 (zero), de exemplu: 032 = 26 și 077 = 63
• Hexazecimale: au prefixul 0x sau 0X, de exemplu: 0x32 = 50 și 0x3F = 63
• Întregi „long”: au sufixul l sau L, de exemplu: 2147483647L și 0xaf9Fl = 44959
• Întregi „unsigned” au sufixul u sau U, de exemplu: 345u și 0xffffu = 65535
• Caractere între apostrof: ‘A’, ‘+’, ‘n’
• Caractere în zecimal: 65, 42
• Caractere în octal: ’\101’, ‘\52’
• Caractere în hexazecimal: ‘\x41’, ‘\x2A’
• Caractere speciale – secvențe escape
Operații și funcții
Funcţii:
Operatori
Operatorii ++ și —
float
double
long double
• Numere reale în „extra” dublă precizie
• sizeof(long double) = 12
Constante reale
Expresii logice
expresie_relationala ::= expr < expr | expr > expr | expr <= expr | expr >= expr | expr == expr |
expr != expr expresie_logica ::= ! expr | expr || expr | expr && expr
Negația logică
! 0 = 1, ! orice_nr_diferit_de_0 = 0
Tipul void
• Conversia în tip void a unei expresii semnifică faptul că valoarea sa este ignorată
• Utilizat pentru tipul pointer; nu se face controlul tipului la un pointer de tip void
• Utilizat pentru funcţii fără valoare returnată sau pentru funcţii fără parametri
• Este un tip incomplet ce nu poate fi completat
• Conversia în tip void a unei expresii semnifică faptul că valoarea sa este ignorată
• Utilizat pentru tipul pointer; nu se face controlul tipului la un pointer de tip void
• Utilizat pentru funcţii fără valoare returnată sau pentru funcţii fără parametri
• Este un tip incomplet ce nu poate fi completat
litera_mare u, v=‘a’;
varsta v1, v2;
vector x; string s;
matrice a;
complex z;
sau funcții
Operatorul condiţional ? :
Sintaxa
Semantica
• Se evaluează exp1
• Dacă exp1 are valoare true (nenulă), atunci valoarea expresiei este valoarea lui exp2;
exp3 nu se evaluează
• Dacă exp1 are valoare false (nulă), atunci valoarea expresiei este valoarea lui exp3; exp2
nu se evaluează
Operatorul ?: este drept asociativ
Exemple
x >= 0 ? x : y
x>y?x:y
x>y?x>z?x:z:y>z?y:z
joc=(raspuns==’1’)?JocSimplu();JocDublu();
#include <iostream>
using namespace std;
void main(){
int a=1, b=2, c=3;
int x, y, z;
x = a?b:c?a:b;
y = (a?b:c)?a:b; /* asociere stanga */
z = a?b:(c?a:b); /* asociere dreapta */
cout<< "x=" << x << "\ny=" << y << "/nz="<< z;
}
/* x=2 y=1 z=2 */
Operatorul virgulă ,
Sintaxa
Semantica
Exemplu
a = 1, b = 2;
i = 1, j = 2, ++k + 1;
k != 1, ++x * 2.0 + 1;
for(suma = 0, i = 1; i <= n; suma += i, ++i);
Operatorul sizeof()
sizeof() este un operator unar ce permite determinarea numărului de octeţi pe care se reprezintă
un obiect (un tip sau o expresie).
Exemple:
sizeof(int), sizeof(double);
sizeof(b*b-4*a*c), sizeof(i);
sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)
sizeof(signed)=sizeof(unsigned) = sizeof(int)
sizeof(float)<=sizeof(double)<=sizeof(long double)
Utilizare
#include <iostream>
using namespace std;
void main(){
int x = 1; double y = 9; long z = 0;
cout << "Operatorul sizeof()\n\n\n";
cout << "sizeof(char) = " << sizeof(char) << endl;
cout << "sizeof(int) = " << sizeof(int) << endl;
cout << "sizeof(short) = " << sizeof(short) << endl;
cout << "sizeof(long) = " << sizeof(long) << endl;
cout << "sizeof(float) = " <<sizeof(float) << endl;
cout << "sizeof(double) = " << sizeof(double) << endl;
cout << "sizeof(long double) = " << sizeof(long double) << endl;
cout << "sizeof(x +y + z) = " << sizeof(x+y+z) << endl;
}
În absenţa unui unsigned , obiectele se convertesc la tipul cel mai “înalt” în ordinea
(descrescătoare):
#include <iostream>
using namespace std;
int main(void){
char c1 = -126, c2; /* c1 = 10000010 */
unsigned char c3, c4 = 255; /* c4 = 111111111 */
short s1, s2 = -32767; /* s2=10000000 00000001 */
short s3 = -1, s4; /* s3 = 11111111 11111111 */
s1 = c1;
cout << "c1=" << (int)c1 << " s1=" << s1 << endl;
c2 = s2;
cout << "c2=" << (int)c2 << " s2=" << s2 << endl;
c3 = s3;
cout << "c3=" << (int)c3 << " s3=" << s3 << endl;
s4 = c4;
cout << "c4=" << (int)c4 << " s4=" << s4 << endl;
return 0;
}
(numetip) expresie
Exemple:
(long)(‘A’ + 1.0)
(int)(b*b-4*a*c)
(double)(x+y)/z
(float)x*y/z
x / (float)2
Exemplu cast
#include <iostream>
using namespace std;
int main(void){
int i, j; double x, y, z, t;
i = 5/2; x = 5/2;
y = (double)(5/2); j = (double)5/2;
z = (double)5/2; t = 5./2;
cout << i << ", " << x << ", ";
cout << y << ", " << j << ", ";
cout << z << ", " << t << ", " << endl;
return 0;
}
/* 2, 2, 2, 2, 2.5, 2.5 */
<limits.h>
<float.h>
<stdlib.h>
Forma generală
cin >> var; /* citeşte var de la cin */
• Se pot transfera tipurile aritmetice, șiruri de caractere, pointeri de orice tip în afară de
char
Instrucțiuni
Instrucţiunea expresie
Sintaxa:
Semantica:
• Se evaluează expresia.
• Dacă este o expresie de forma unei instrucțiuni de atribuire, variabila=expresie, atunci
variabila primește valoarea expresiei din dreapta, vechea valoare a expresiei pierzându-
se.
• Dacă este o expresie de forma variabila op = expresie, aceasta este echivalentă cu
variabila=variabila op expresie, unde op este un operator din mulțimea {+, -, *, /, % }
• Dacă este o expresie de forma variabila++ sau ++variabila, aceasta este echivalentă cu
variabila=variabila+1.
• Dacă este o expresie de forma variabila– sau –variabila, aceasta este echivalentă cu
variabila=variabila-1.
Exemple:
a = b;
a + b + c;
;
cout << a;
sizeof(int);
Sintaxa:
Semantica:
Exemple:
{
int a=3, b=10, c=7;
a += b += c;
cout << a << ", " << b << ", " << c; // ?, ?, ?
}
if (x > y){
int temp;
temp = x; x = y; y = temp;
cout << x << y;
}
{
int a, b, c;
{
b = 2; c = 3; a = b += c;
}
cout << "a= " << a <<endl;
} // ?
Sintaxa:
• Expresii aritmetice
• Comparatori: ==, !=, <, <=, >, >=
• Conectori logici: &&, ||, !
Semantica:
Regula:
if ( conditie-1 ) {
instructiuni-1;
}
else if ( conditie-2 ) {
instructiuni-2;
...
}
else if ( conditie-n ) {
instructiuni-n;
}
else {
instructiuni-pt-restul-posibilitatilor;
}
Exemplu:
int main(void){
float operand1, operand2, rezultat;
char operator;
cout << "Expresia:(numar operator numar – FARA SPATII)\n";
cin >> operand1 >> operator >> operand2;
if(operator == '+')
rezultat = operand1+operand2;
else if(operator == '-')
rezultat = operand1-operand2;
else if(operator == '*')
rezultat = operand1*operand2;
else if(operator == '/')
rezultat = operand1/operand2;
else{
cout << "Eroare in scrierea expresiei!";
return 1;
}
cout << "Rezultatul este: " << rezultat << "\n";
return 0;
}
Instrucţiunea switch
Sintaxa:
switch (expresie)
{
case constanta1:
grup de instructiuni 1;
[break;] (break este opțional)
case constanta2:
grup de instructiuni 2;
[break;]
.
.
.
[default:
grup implicit de instructiuni] (default este opțional)
}
Semantica:
• Se evaluează expresia.
• Dacă ea are valoarea constanta1, atunci se execută grupul de instrucțiuni 1, eventual
grupul de instrucțiuni2 etc., până la întâlnirea primului break.
• Dacă ea are valoarea constanta2, atunci se execută grupul de instrucțiuni2 etc., până la
întâlnirea primului break.
• …
• În cazul în care expresia nu este egală cu niciuna din variantele constanta1, constanta2
etc, iar grupul implicit de instrucțiuni este prezent, se execută acesta
Instrucțiunea While
Sintaxa:
Semantica:
Instrucțiunea do-while
Sintaxa:
Semantica:
• Se execută instructiune.
• Se evaluează conditie: dacă valoarea sa este nenulă controlul este transferat înapoi, la
începutul instrucţiunii do..while; dacă valoarea este nulă se execută
instructiunea_urmatoare.
Instrucţiunea for
Sintaxa:
Una, doua sau toate trei dintre expresii pot lipsi, dar cei doi separatori (;) sunt obligatorii.
Semantica
• Dacă instructiune nu conţine continue şi expr-cond este prezentă, atunci for este echivalent cu:
expr-init;
while(expr-cond){
instructiune;
expr-in/decrementare;
}
instructiunea_urmatoare
• break;
o se referă la bucla sau instrucţiunea switch cea mai apropiată.
o produce ieşirea din buclă sau din switch şi trece controlul la instrucţiunea
următoare
• continue;
o se referă la bucla (for, while, do..while) cea mai apropiată.
o întrerupe execuţia iteraţiei curente şi trece controlul la iteraţia următoare.
• goto;
o Permite saltul la o anumită secțiune din program, identificată prin punctul de
începere.
• return expr; sau return;
Instrucţiuni de iteraţie – recomandare
int main(){
int contor = 0;
double suma = 0.0, x;
for(x = 0.0; x != 9.9; x += 0.1){
suma += x;
++contor;
}
cout << "suma = " << suma << ", contor= " << contor << "\n";
return 0;
}