Metode evoluate de programare Limbajele c şi C++


Facilităţi noi în limbajul C++



Yüklə 1,64 Mb.
səhifə34/44
tarix07.04.2018
ölçüsü1,64 Mb.
#46828
1   ...   30   31   32   33   34   35   36   37   ...   44

15. Facilităţi noi în limbajul C++




    1. Extinderea limbajului C

Programele scrise în limbajul C pot fi executate şi folosind compilatorul C++ (eventual cu modificări nesemnificative). Deci limbajul C++ conţine toate instrucţiunile limbajului C, dar în plus oferă şi facilităţi noi. Cele mai importante avantaje ale limbajului C++ faţă de C sunt următoarele. S-a introdus noţiunea de clasă prin care se defineşte un tip abstract de date, astfel programatorul are posibilitatea folosirii metodei de programare prin abstractizarea datelor. Clasele pot fi organizate într-o ierarhie de clase, deci este posibilă şi programarea prin metode orientate obiect.

În continuare prezentăm nişte elemente noi ale limbajul C++, iar în secţiunile care urmează vor fi tratate facilităţi noi, mai importante, referitoare la operatori, structuri, reuniuni, tipuri enumerare şi funcţii.

Există un nou tip de comentarii în limbajul C++ de forma: // comentariu

În acest caz, tot ce se află după caracterele // se va ignora de către compilator, până la sfârşitul rândului.

În limbajul C o instrucţiune compusă este de forma:


{

declaraţii

instrucţiuni

}
Deci toate declaraţiile trebuie să fie înainte de prima instrucţiune. În limbajul C++ declaraţiile şi instrucţiunile pot fi în orice ordine în interiorul unei instrucţiuni compuse.

Nu există instrucţiuni de intrare/ieşire în limbajul C, şi nici în C++. În schimb în limbajul C există biblioteci standard de funcţii pentru operaţii de intrare/ieşire. Ele pot fi folosite şi în limbajul C++, dar în afară de aceste biblioteci, mai există şi ierarhii de clase pentru realizarea operaţiilor de intrare/ieşire. Ele vor fi tratate pe larg în capitolul 4, dar pentru a putea utiliza aceste clase, prezentăm aici nişte exemple simple, ilustrative.

Dispozitivului standard de intrare respectiv ieşire s-au ataşat aşa numitele streamuri standard: cin pentru stdin şi cout pentru stdout. Operaţiile de intrare se vor efectua aplicând operatorul >> streamului standar cin, iar cele de ieşire aplicând operatorul << streamului standard cout.

Prezentăm în continuare exemple de operaţii de intrare/ieşire folosind streamurile standard cin şi cout. Pentru fiecare exemplu se va specifica în formă de comentariu echivalentul operaţiei, folosind funcţii din biblioteca standard a limbajului C.

Ierarhia de clase pentru operaţii de intrare/ieşire poate fi utilizată numai dacă se include fişierul iostream.h. În continuare prezentăm exemple pentru operaţii de afişare pe dispozitivul standard de ieşire:


#include

int main() {

...

int x;


...

cout << x; // printf("%d", x);

...

double y;



...

cout << y; // printf("%lg", y);

...

char z;


...

cout << z; // printf("%c", z);

...

char t[] = "exemplu";



...

cout << t; // printf("%s", t);

...

}
Exemple pentru operaţii de citire de la dispozitivul standard de intrare:


#include

int main() {

...

int x;


...

cin >> x; // scanf("%d", &x);

...

double y;



...

cin >> y; // scanf("%lf", &y);

...

char z[20];



...

cin >> z; // scanf("%s", z);

...

}
Fără a intra acum în detalii menţionăm că operatorii << respectiv >> pot fi aplicaţi înlănţuit. Deci de exemplu


int w;

...


cout << "w = " << w + 25 << '\n';
este echivalent cu
int w;

...


printf("w = %d\n", w);
Trecerea la linie nouă se poate efectua şi cu
cout << endl;
Deci în loc de apelarea funcţiei printf de mai sus, s-ar fi putut scrie şi:
cout << "w = " << w + 25 << endl;
Există o diferenţă minoră dintre limbajele C şi C++, referitoare la constantele de tip caracter. Ele sunt memorate pe doi octeţi în limbajul C şi au tipul int. În limbajul C++ însă există două feluri de constante de tip caracter. Memorate pe un octet ele au tipul char, iar pe doi octeţi au tipul int.

Să considerăm următorul exemplu. Fişierul caracter.cpp:


După executarea programului se obţine:


Observăm că într-adevăr caracterul 'AB' este de tip int şi în octetul mai semnificativ este memorat codul ASCII al caracterului 'B', iar în cel mai puţin semnificativ codul ASCII al caracterului 'A'.

În limbajul C utilizarea operatorului de conversie explicită se face sub forma:
(tip) expresie
În limbajul C++ operatorul de conversie explicită se poate aplica şi în modul următor:
tip(expresie)
Să considerăm următorul exemplu. Fişierul conv1.cpp:


După executarea programului obţinem:




Rezultă că într-adevăr s-a realizat conversia variabilei x de la tipul double la tipul int, şi conversia variabilei p de la tipul void* la tipul double*. Menţionăm că în acest caz, introducerea tipului p_double a fost obligatorie. Dacă s-ar fi folosit conversia explicită (double*) p, atunci nu ar fi fost necesar definirea tipului p_double.

În limbajul C++ putem defini şi conversii utilizator ataşate unor tipuri definite de programator. Conversiile utilizator se vor trata în secţiunea 16.8.


15.2. Operatori




15.2.1. Operatorul de rezoluţie

Dacă o dată globală se redefineşte într-o funcţie, atunci referirea la data globală se poate face cu ajutorul operatorului de rezoluţie. Numele datei globale trebuie precedată de caracterele ::, deci de operatorul de rezoluţie.

Prezentăm în continuare un exemplu. Fişierul rezol.cpp:


După execuţie se obţine:




Deci se observă că referirea la variabila globală x de tip int s-a făcut cu ajutorul operatorului de rezoluţie (::x ). Menţionăm că operatorul de rezoluţie se va folosi şi în cazul în care se face referire la datele respectiv funcţiile membru ale unei clase.



15.2.2. Folosirea operatorului adresă pentru definirea tipului referinţă

În limbajul C operatorul & se foloseşte pentru a determina adresa unei variabile. În limbajul C++ acest operator mai este folosit şi pentru definirea tipului referinţă. Am văzut că în cazul pointerilor construcţia


reprezintă un tip pointer. La fel şi în cazul de faţă prin


se va înţelege un tip referinţă. Cu ajutorul tipului referinţă putem defini nume alternative pentru date deja cunoscute. Aceste nume alternative pot fi utilizate în continuare în locul datelor respective. Deasemenea acest tip de date se va folosi şi pentru realizarea apelului prin referinţă în limbajul C++.

Dacă se foloseşte ca şi parametru formal într-o funcţie, atunci tipul referinţă va fi de forma:

tip & parametru_formal


iar declararea unei variabile de tip referinţă se va face sub forma
tip & nume = dată;
Exemplu. Fişierul refer1.cpp.


Prin execuţie se obţine:




Observăm că aceeaşi zonă de memorie este accesată în trei feluri. Primul element al vectorului x este x[0], y este referinţă la acest element, deci un nume sinonim pentru x[0], iar z este un pointer către vectorul x, astfel *z reprezentând acceaşi zonă de memorie ca şi x[0]. Rezultă că valoarea oricărei dintre aceste trei elemente s-ar schimba, valorile celorlalte se schimbă în mod automat.

Există posibilitatea definirii unei referinţe şi la o funcţie. Acest lucru este prezentat în exemplul următor. Fişierul refer2.cpp:


În exemplul de mai sus s-a declarat o referinţă la funcţia standard de bibliotecă sin, deci numele sinus poate fi folosit în locul funcţiei sin pentru a calcula sinusul unui număr real.

Tipul referinţă este cel mai des folosit pentru realizarea apelului prin referinţă, ceea ce se tratează în paragraful următor.


15.2.3. Apelul prin referinţă

În limbajul C apelul este prin valoare. Acest lucru înseamnă că parametrii actuali şi cei formali sunt memorate în diferite locaţii de memorie. La apelarea funcţiei parametrii actuali îşi transmit valoarea lor parametrilor formali corespunzătoare. De aceea modificarea parametrilor formali nu are nici un efect asupra parametrilor actuali. Următorul exemplu scris în limbajul C ilustrează acest lucru. Fişierul valoare1.cpp:




Constatăm că într-adevăr parametrul actual y nu se modifică, şi programul afişează valoarea 10.

Totuşi şi în limbajul C se poate realiza modificarea parametrilor actuali, cu ajutorul pointerilor. Acest lucru este prezentat în următorul exemplu.

Fişierul valoare2.cpp:




În exemplul de mai sus s-a realizat modificarea valorii parametrului actual y, dar şi în acest caz s-a folosit de fapt apel prin valoare. S-a transmis valoarea adresei lui y pointerului x. Deci prin intermediul pointerilor apelul prin valoare s-a transformat în apel prin referinţă. Menţionăm că numele unui vector de elemente este un pointer către primul element al vectorului. În consecinţă, dacă un parametru actual este un vector, atunci valorile elementelor acestui vector pot fi modificate în interiorul funcţiei.

Această modalitate de realizare a apelului prin referinţă, prin intermediul pointerilor, de multe ori îngreunează munca programatorului, de aceea în limbajul C++ s-a introdus şi apelul prin referinţă propriu zis.

Apelul prin referinţă se realizează cu ajutorul tipului referinţă. În cazul folosirii tipului referinţă parametrul formal este un nume alternativ pentru parametrul actual, deci ele reprezintă aceeaşi zonă de memorie şi ca atare orice modificare a parametrului formal conduce la modificarea parametrului actual corespunzător. Iată cum se modifică exemplul de mai sus folosind apelul prin referinţă. Fişierul refer3.cpp:





Putem constata că apelul prin referinţă este mult mai simplu de utilizat, decât realizarea ei prin intermediul pointerilor.



15.2.4. Operatori pentru alocare şi dezalocare dinamică a memoriei

Pentru alocare şi dezalocare de memorie în limbajul C pot fi folosite funcţiile malloc şi free. În limbajul C++ există şi operatori pentru realizarea acestui lucru.

Alocarea memoriei se poate face folosind operatorul new, în unul din următoarele trei moduri:


  1. new tip

  2. new tip(expresie_1)

  3. new tip[expresie_1]

În toate cele trei cazuri construcţiile de mai sus formează o expresie pe care o vom nota cu expresie_2. Valoarea expresiei expresie_2 este egală cu adresa de început a zonei de memorie alocate, şi este zero în cazul unei erori.

În cazul a) se alocă zonă de memorie pentru o variabilă de tipul exprimat prin tip. În cazul b) zona de memorie alocată se iniţializează cu valoarea expresiei expresie_1, iar în cazul c) se alocă memorie un număr de expresie_1 de zone de memorie de tipul menţionat. Deci în cazul a) şi b) se vor aloca un număr de sizeof(tip) octeţi, iar în cazul c) expresie_1 * sizeof(tip) octeţi.

În tabelul 1 prezentăm trei exemple de secvenţe de programe echivalente, în care se foloseşte operatorul new în diferite moduri.

Eliberarea zonei de memorie alocate cu operatorul new se va face cu ajutorul operatorului delete. Să considerăm pointerul q pentru care s-a alocat memorie folosind operatorul delete.

Dacă alocarea zonei de memorie s-a făcut cu una din variantele a) sau b) atunci dezalocarea se va face în forma:


delete q;
iar dacă alocarea s-a făcut prin varianta c) atunci eliberarea zonei de memorie se va face cu
delete [expresie_1] q;
unde expresie_1 este expresia care s-a folosit la alocare. De obicei ea poate să lipsească.


  1. Nr. crt.C++C sau C++double* d;

d = new double;double *d;

  1. d = (double *) malloc(sizeof(double));int* i;

i = new int(20);

int* i;


i = new int;

  1. *i = 20;double* p;

p = new double[10];d = (double *) malloc(10 * sizeof(double));

Tabelul 1: folosirea operatorului new


Yüklə 1,64 Mb.

Dostları ilə paylaş:
1   ...   30   31   32   33   34   35   36   37   ...   44




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin