variabile referint˘ a c++ ˘si clase de echivalent˘ avancea/flp/suport_curs/slides...apare ^ n...

21
Variabile Referint ¸˘ a C++ ¸ si Clase de Echivalent ¸˘ a Fundamentele Limbajelor de Programare VANCEA Alexandru Departamentul de Informatic˘ a Universitatea Babe¸ s-Bolyai Cluj-Napoca, 2018

Upload: hoangthuan

Post on 25-May-2019

226 views

Category:

Documents


0 download

TRANSCRIPT

Variabile Referinta C++ si Clase de EchivalentaFundamentele Limbajelor de Programare

VANCEA Alexandru

Departamentul de InformaticaUniversitatea Babes-Bolyai

Cluj-Napoca, 2018

TipDeData& nume variabila

Acestea nu sunt variabile pointer. Sunt variabile care exprimalucrul la nivel de adresa si se folosesc ıntr-unul dintre urmatoarele 3moduri:

I pentru a defini alieriint i;int& j = i; // j - nume alternativ pentru iint k = 9;j = k; // de fapt i = 9 !

I pentru a transmite parametrii unui subprogram prinreferintavoid f(double & a) { ... a += 9.27; ... }...double d = 12.75;f(d);

I pentru a returnare L-valori (lvalues)int v[20];...int& g(int i) { ... return v[i]; ... }...g(3) = 7; // v[3] = 7;

int& F1(int* talou, int& intreg) {...int& altintreg = tablou[intreg]; // aliere !intreg = altintreg / 3; // apel prin ref !...return tablou[altintreg]; // returnare lvalue

}...int i = 1;int a[] = 14, 6, 15, 3, 21, 31, 16;...F1(a, i) = 40; // a[6] = 40 !

int const& j = i; // are semnificatia ca j NU poate fi lvaluej = 17; // nu este permisSe foloseste pentru alieri ın regim de readonly. Este util ıntransmiterea prin referinta a unei structuri mari

int& j = 25; // pana la C++ 2.0 - se creeaza o variabila anonima(dummy variabile) aliata cu locatia constantei.Din C++ 2.1 - syntax error!Reference initialized with in needs lvalue of type int!

Declaratie Expresie de tip Tipul

int i int ıntreg

int* pi int* pointer la ıntreg

int *p[3] int *[3] tablou de 3 pointeri la ıntreg

int (*p)[3] int (*[3]) pointer la untablou de 3 ıntregi

int *f() int *() functie fara argumentece ıntoarce pointer la ıntreg

int (*pf)(double) int(*)(double) pointer la functiecu argument double ce

ıntoarce pointer la ıntreg

// transforma numele de variabila ıntr-un nume de tip de date.typedef declaratie de variabila;

char* (**f[10]) (int);// f este pointer la un tablou de 10 pointeri la functii// ce au argument int si returneaza un pointer la chartypedef char* f2(int);typedef f2* A[10];A* f;

D.p.d.v. sintactic exista 3 acceptiuni ale echivalentei tipurilor.

I echivalenta structurala (C)

I echivalenta de nume (C++ ımpreuna cu toate limbajele custructura de bloc)

I echivalenta de declarare

Doua tipuri sunt echivalente structual daca si numai dacacomponentele lor sunt aceleasi din toate punctele de vedere

struct A int x, y;struct B int x, y;Sunt compatibile ın C, si NU sunt compatibile ın C++

Echivalentadeclarativa ⇒ Echivalentanume ⇒ Echivalentastructurala

Echivalenta de declarare are loc numai daca variabilele ale carortipuri sunt considerate echivalente, apar sub aceeasi declarare detip

type T = array[5..20] of real;var x, y : array[5..20] of real;var z : array[5..20] of real;var w : T;var a : array[1..10, 1..10] of integer;var b : array[1..100] of integer;var w1: T;

Ed En Es

x y DA DA DA

x z NU [1] DA

a b NU NU NU

w w1 NU DA DA

z w [2]

[1] Echivalenta de nume ın cazul tipurilor de date anonime seimplementeaza ın doua moduri:

I se compara string-urile reprezentand tipurile de date, iar dacaare loc identitatea, atunci echivalenta de nume are loc

I compilatorul atribuie diferite valori fiecarui tip de data anonim/ fiecarei declaratii de tip

[2] de obicei sunt considerate compatibile

extern f(struct A*)struct A { int x, y; };struct B { int x, y; };void g(struct A* pa, struct B* pb){

f(pa); // ok in C si C++f(pb); // ok in C (Es), syntax error C++ (En)pa = pb; // ok in C (Es), syntax error C++ (En)pa = (struct A*) pb; // ok in C si C++

}

In ce situatii apare necesitatea verificarii compatibilitatii de tip?Care sunt situatiile ın care compilatoarele verifica existenta acestorcompatibilitati?

I compatibilitate la atribuire

I compatibilitate la transmiterea de parametrii

I compatibilitate la calculul de expresii

Raspunsul este dat de definitia limbajului si eventual de anumiteconditionari date de implementarea compilatorului

Accidental booleansif ( a = b ) { ... };if ( 0 ¡ a ¡ 5 ) { ... };

Nivel de Inglobare Statica

Apare ın Algol, Pascal, Modula, Ada, Delphi, dar in C NU.Limbajele cu structura de bloc accepta ıntotdeauna nivele deınglobare statica mai mari decat 1 (adica definirea de subrutinelocale ın interiorul unor functii/proceduri), ın schimb standardullimbajului C nu accepta, aici toate functiile definite fiind la nivelul1 (adica nu putem defini functii ın interiorul altor functii).Implementarea compilatorului gcc accepta implementarea de nivelede ınglobare de nivele mai mari decat 1, asta fiind o exceptie acompilatorului.

Problema Dangling Reference

Utilizarea pointerilor ın limbajele de programare pot provoca douaerori de tip logic.Plecand de la o legatura pointer - entitate, putem identificaurmatoarele doua situatii:

I ıncetarea duratei de viata a pointerului (dealocareapointerului)Presupunand ca entitatea pointata este alocata ın heap si esteo variabila dinamica, suntem ın situatia ın care acea entitatereprezinta o valoare reziduala si inaccesibila, avand necesitateaexistentei / activarii unui instrument de tip garbage collector.

I ıncercarea de a accesa o entitate ınainte de initializare apointerului ce o refera sau ıncercarea de a accesa o locatiedupa ce aceasta a fost eliberata sunt situatii de tip danglingreference

program unu;var x: ˆinteger; { pointer la integer }procedure P;

var y: ˆinteger;begin

y := 7;x := @y; { adresa lui y }

end;begin;

P;writeln(xˆ); { dereferentiere }

end;

program doi;var x: ˆinteger; { pointer la integer }procedure P;

var y: ˆinteger;begin

new(y);yˆ := 7;x := y; { syntax error: ”type mismatch” (Pascal

implementeaza En; ˆinteger este tip anonim (ˆinteger esteexpresie de tip, nu este nume de tip) }

end;begin;

P;writeln(xˆ);

end;

program doi;type pint = ˆinteger;var x: pint;procedure P;

var y: pint;begin

new(y);yˆ := 7;x := y;

end;begin;

P;writeln(xˆ);

end;

program trei;var x: ˆinteger; { pointer la integer }procedure P;

var y: ˆinteger;begin

new(y);yˆ := 7;x := @yˆ;dispose(y);

end;begin;

P;writeln(xˆ);

end;

Utilizarea Constantelor de Tip String ın C si C++

char v[25];int f(char* s);int f(char s[]);int f(char s[25]);f(v);

sizeof(’a’) =

I 1 ın C++

I 2 ın BorlandC

I 4 ın GCC

sizeof(”a”) = 2; // [’a’, ’\0’]”abcd”[2] = ’c’Valoarea asociata unei constante asociate unui sir de caractere esteadresa sa de ınceput

a)char* s;...gets(s);...// eroare logica// (nu s-a alocat// spatiu pentru// string-ul punctat// de s)

b)char* s;...s = ”abcd”;...s = malloc(...);...// OK

c)char s[10];...gets(s);// eroare logica// pentru string-uri// mai lungi// decat 10...s = malloc(...);// syntax error

d)char s[10];...s = ”abcd”;// syntax error

e)char s[] = ”abcd”;// syntactic sugar

In cazurile a) si b),s este variabilade tip pointer

In cazurile c) si d),s este o constantade tip pointer

1)char* f(...){ ... char s[15]; ... return s; }// solutie: static char s[15];

2)char* f(...){ char* s; gets(s); ... return s; }// solutie: s = malloc(...);