FUNCTII

Dupa cum se stie, in limbajul C, exista doua moduri de transmitere a parametrilor efectivi unor functii: transmiterea parametrilor prin valoare si transmiterea parametrilor prin intermediul pointerilor. In limbajul C++, pe langa cele doua metode de transmitere a parametrilor din C, exista o a treia metoda numita transmiterea parametrilor prin referinte. Concluzionand, definirea si apelul functiilor in C++ se poate realiza prin:

II. 1. Utilizarea parametrilor de tip valoare in descrierea si apelarea functiilor:

a1) Definirea unei functii cu parametri formali de tip valoare:

tip_functie nume_functie(tipargf1 argf1[,tipargf2 argf2] ,,, [,tipargfn argfn])

{

// declararea constantelor si variabilelor locale

// descrierea algoritmului functiei

[return (expresie);]

}        

unde:

tip_functie reprezinta tipul valorilor returnate de functie, dupa apelarea si executia sa,  si poate fi unul din tipurile valide in C++: void, cand functia nu returneaza nici-o valoare, int, char, float, double si derivatele acestora, cand functia returneaza o valoare de tipul specificat;

nume_functie este un identificator ales de programator, care denumeste functia si prin intermediul caruia se apeleaza functia de catre o alta functie, numita si functie apelanta;

argf1, argf2, … ,argfn sunt identificatori alesi de programator, care reprezinta parametri formali ai functiei de tip valoare, numiti si argumentele functiei si care pot fi date simple: int, char, float, double sau derivatele acestora sau pot fi date compuse: tablouri, structuri, etc. sau definite de programator;

tipargf1, tipargf2, … , tipargfn reprezinta tipul parametrilor formali ai functiei care pot fi tipuri simple, compuse sau definite de utilizatori;

– return (expresie) determina, daca este prezenta in corpul functiei, prin valoarea calculata a expresiei expresie, valoarea  reintoarsa, returnata de functie, structurii apelante de program (functiei main() sau altei functii utilizator)

a2) Apelarea unei functii cu parametri de tip valoare

– apelarea independenta, ca o procedura:

nume_functie(arge1[,arge2] … [,argen]);

– apelarea dependenta, ca o functie intr-o expresie:

– e=… nume_functie(arge1[,arge2] … [,argen]) …;

unde:

nume_functie este numele functiei apelate, anterior descrise;

– arge1, arge2, … ,argen sunt parametri efectivi de apel ai functiei, de acelasi tip cu tipul parametrilor formali omologi, precizati in descrierea functiei si pot fi: literali, constante, variabile, functii sau expresii. Corespondenta dintre parametri formali din descrierea functiei si parametri  efectivi din apelul functiei se face prin tip, ordine si numar;

– e este identificatorul unei variabile rezultat, care va primi o valoare corespunzatoare, dupa evaluarea expresiei in care este apelata functia anterior definita.

Observatii:

– la apelul unei functii cu parametri de tip valoare, functiei apelate, i se transmite o copie a listei parametrilor efectivi. Ca atare, orice mofificare a acestora in corpul functiei apelate, nu afecteaza, la returnarea in functia apelanta, valoarile initiale ale acestora. Cu alte cuvinte, o functie apelata nu modifica valorile initiale ale parametrilor efectivi transmisi prin valoare;

– daca tipul functie este void si daca instructiunea return(expresie) este sau nu prezenta, functia nu returneaza nici o valoare functiei apelante;

– in cazul apelarii dependente a unei functii, in cadrul unei expresii, valoarea returnata de functie trebuie sa fie diferita de void si compatibila cu constructia expresiei

 

II. 2. Utilizarea parametrilor de tip pointer, in descrierea si apelarea functiilor:

a1) Definirea unei functii cu parametri formali de tip pointer, adresa:

tip_functie nume_functie(tipargf1 *argf1[,tipargf2 *argf2] ,,, [,tipargfn *argfn])

{

// declararea constantelor si variabilelor locale

// descrierea algoritmului functiei

[return (expresie);]

}        

unde:

tip_functie reprezinta tipul valorilor returnate de functie, dupa apelarea si executia sa, si poate fi unul din tipurile valide in C++: void, cand functia nu returneaza nici o valoare, int, char, float, double si derivatele acestora, cand functia returneaza o valoare de tipul specificat;

nume_functie este un identificator ales de programator care denumeste functia si prin intermediul caruia se apeleaza functia, de catre o alta functie, numita si functie apelanta;

argf1, argf2, … , argfn sunt identificatori alesi de programator care reprezinta parametri formali ai functiei de tip pointeri, catre date simple de tip: int, char, float, double sau derivatele acestora sau pointeri catre date compuse: tablouri, structuri, etc sau definite de programator. Prezenta caracterului * in fata parametrilor le confera acestora caracterul de parametri de tip pointer;

tipargf1, tipargf2, … , tipargfn reprezinta tipul pointerilor formali ai functiei, de fapt tipul variabilelor adresate de pointerii formali, care pot fi tipuri simple, compuse sau definite de utilizatori;

– return (expresie) determina, daca este prezenta in corpul functiei, prin valoarea calculata a expresiei expresie, valoarea  reintoarsa, returnata de functie structurii apelante de program (functiei main() sau altei functii utilizator)

a2) Apelarea unei functii cu parametri de tip pointer, adresa

– apelarea independenta, ca o procedura:

nume_functie(&arge1[,&arge2] … [,&argen]);

– apelarea dependenta, ca o functie intr-o expresie:

– e=……… nume_functie(&arge1[,&arge2] … [,&argen]) …….;

unde:

nume_functie este numele functiei apelate, anterior descrise;

&arge1, &arge2, … ,&argen sunt adresele parametrilor efectivi de apel ai functiei, de acelasi tip cu tipul parametrilor pointer formali omologi precizati in descrierea functiei, si pot fi : adrese de constante, de variabile, etc.. Corespondenta dintre parametri formali din descrierea functiei si parametri  efectivi din apelul functie se face prin tip, ordine si numar;

– e este identificatorul unei variabile rezultat, care va primi o valoare corespunzatoare, dupa evaluarea expresiei in care este apelata functia anterior definita.

II. 3. Utilizarea parametrilor de tip referinta in descrierea si apelarea functiilor:

a1) Definirea unei functii cu parametri formali de tip referinta:

tip_functie nume_functie(tipargf1& argf1[,tipargf2& argf2] ,,, [,tipargfn& argfn])

{

// declararea constantelor si variabilelor locale

// descrierea algoritmului functiei

[return (expresie);]

}        

unde:

tip_functie reprezinta tipul valorilor returnate de functie, dupa apelarea si executia sa,  si poate fi unul din tipurile valide in C++: void, cand functia nu returneaza nici-o valoare, int, char, float, double si derivatele acestora, cand functia returneaza o valoare de tipul specificat;

nume_functie este un identificator ales de programator care denumeste functia si prin intermediul caruia se apeleaza functia de catre o alta functie, numita si functie apelanta;

argf1, argf2, … , argfn sunt identificatori alesi de programator care reprezinta parametri formali ai functiei de tip referinta, si care pot fi: int, char, float, double sau derivatele acestora sau pot fi referinte catre date compuse: tablouri, structuri, etc sau definite de programator;

– tipargf1&, tipargf2&, … , tipargfn& reprezinta tipul parametrilor formali de tip referinta ai functiei. De fapt prezenta caracterului &, plasat imediat dupa tipul parametrilor formali confera parametrilor, in fata carora este plasat, caracterul de referinta;

– return (expresie) determina, daca este prezenta in corpul functiei, prin valoarea calculata a expresiei expresie, valoarea  functiei reintoarsa, returnata, structurii apelante de program (functiei main() sau altei functii utilizator)

a2) Apelarea unei functii cu parametri de tip referinta

– apelarea independenta, ca o procedura:

nume_functie(arge1[,arge2] … [,argen]);

– apelarea dependenta, ca o functie intr-o expresie:

– e=……… nume_functie(arge1[,arge2] … [,argen]) …….;

unde:

nume_functie este numele functiei apelate, anterior descrise

arge1, arge2, … ,argen sunt referintele parametrilor efectivi de apel ai functiei, de acelasi tip cu tipul parametrilor referinta formali precizati in descrierea functiei, si pot fi : referinte de constante, de variabile, etc.. Corespondenta dintre parametri formali din descrierea functiei si parametri  efectivi din apelul functie se face prin tip, ordine si numar;

– e este identificatorul unei variabile rezultat, care va primi o valoare corespunzatoare, dupa evaluarea expresiei in care este apelata functia anterior definita.

II. 4. Utilizarea combinata a parametrilor de tip valoare, pointer si referinta in descrierea si apelarea functiilor

a1) Definirea unei functii cu parametri combinti

Mai inainte, au fost prezentate trei modalitati distincte de transmitere a parametrilor unei functii apelate. In practica o functie poate fi definita cu toate cele trei tipuri de transmitere a parametrilor: prin valoare, prin pointeri (adrese) si prin referinte:

tip_functie nume_functie(tipargfv1 argfv1… [,tipargfvn argfvn],

tipargfp1 *argfp1… [,tipargfpn *argfpm],

                                            tipargfr1& argfr1… [,tipargfrk& argfrk])

{

// declararea constantelor si variabilelor locale

// descrierea algoritmului functiei

[return (expresie);]

}        

unde:

–          argfv1, …, argfvn sunt parametri formali de tip valoare;

–          tipargfv1 , tipargfvn sunt tipurile parametrilor formali de tip valoare;

–          argfp1, …, argfpm sunt parametri formali de tip pointer, adresa;

–          tipargfp1 , tipargfpm sunt tipurile parametrilor formali de tip pointer;

–          argfr1, …, argfrm sunt parametri formali de tip referinta;

–          tipargfr1 , tipargfrk sunt tipurile parametrilor formali de tip referinta.

a2) Apelarea unei functii cu parametri combinti

Apelarea generala a unei asemenea functii se face astfel:

– apelarea independenta:

–          nume_functie(argev1 … [,argevn],

                             &argep1 … [,&argepm] ,

                 arger1 … [,&argerm]);

– apelarea dependenta, ca o functie intr-o expresie:

–          – e= … nume_functie(argev1 … [,argevn],

 &argep1 … [,&argepm] ,

 arger1 … [,&argerm])…;

unde:

–          argev1 … [,argevn] sunt parameri efectivi de tip valoare;

–          &argep1 … [,&argepm] adresele parameri efectivi de tip pointer;

–          arger1 … [,&argerm]) sunt parametri efectivi de tip referinta.

– e este identificatorul unei variabile rezultat, care va primi o valoare corespunzatoare, dupa evaluarea expresiei in care este apelata functia anterior definite

Probleme rezolvate:

1) Sa se construiasca o functie generica (template) care sa poata determina valoarea maxima a elementelor unui array numeric, oricare ar fi tipul standard al elementelor acestuia. Sa se scrie functia main() care sa apeleze functia construita, pentru 2 array-uri, de tipuri diferite. Elmentele array-urilor vor fi citite de la tastatura in tehnica OOP.

#include<iostream>

using namespace std;

 

template<class T>

void citire(T a[], int* n, char c)

{

  cout<<„Citim sirul „<<c<<endl;

  cout<<„\tdati dimensiunea: „;

  cin>>*n;

  cout<<„\tintroduceti elementele:\n”;

  for(int i=0;i<*n;i++)

  {

    cout<<„\t\telementul [„<<i+1<<„]= „;

    cin>>a[i];

  }

}

 

template<class T>

void afisare(T a[], int n, char c)

{

  cout<<„Sirul „<<c<<” este: „;

  for(int i=0;i<n;i++)

    cout<<a[i]<<‘ ‘;

  cout<<endl;

}

 

template<class T>

T maxim(T a[], int n)

{

  T max;

  max=a[0];

  for(int i=1;i<n;i++)

    if(a[i]>max)

      max=a[i];

  return max;

}

 

void main()

{

 int a[20];

 double b[20];

 int m,n;

 

 citire(a,&m,’A’);

 citire(b,&n,’B’);

 

 afisare(a,m,’A’);

 afisare(b,n,’B’);

 

 cout<<„\nMaximul sirului A este: „<<maxim(a,m);

 cout<<„\nMaximul sirului B este: „<<maxim(b,n);

 

 int var;

 cin>>var;

}

 

2) Sa se construiasca o functie generica (template) care sa poata determina suma elementelor unui array numeric, oricare ar fi tipul standard al elementelor acestuia. Sa se scrie functia main() care sa apeleze functia construita, pentru 2 array-uri, de tipuri diferite. Elmentele array-urilor vor fi citite de la tastatura in tehnica OOP.

#include<iostream>

using namespace std;

 

 

template<class T>

void citire(T a[], int* n, char c)

{

  cout<<„Citim sirul „<<c<<endl;

  cout<<„\tdati dimensiunea: „;

  cin>>*n;

  cout<<„\tintroduceti elementele:\n”;

  for(int i=0;i<*n;i++)

  {

    cout<<„\t\telementul [„<<i+1<<„]= „;

    cin>>a[i];

  }

}

 

template<class T>

void afisare(T a[], int n, char c)

{

  cout<<„Sirul „<<c<<” este: „;

  for(int i=0;i<n;i++)

    cout<<a[i]<<‘ ‘;

  cout<<endl;

}

 

template<class T>

T suma(T a[], int n)

{

  T sum;

  sum=0;

  for(int i=0;i<n;i++)

  {

    sum=a[i]+sum;

  }

  return sum;

}

 

void main()

{

 int a[20];

 double b[20];

 int m,n;

 

 citire(a,&m,’A’);

 citire(b,&n,’B’);

 

 afisare(a,m,’A’);

 afisare(b,n,’B’);

 

 cout<<„\nSuma sirului A este: „<<suma(a,m);

 cout<<„\nSuma sirului B este: „<<suma(b,n);

 

 int var;

 cin>>var;

}

 

3) Sa se construiasca o functie generica ce inverseaza între ele valorile celor doua variabile cu care este apelata.

//Exemplu de functie sablon

 

#include<iostream>

using namespace std;

 

template <class X>

void schimba(X &a, X &b)

{

X temp;

temp=a;

a=b;

b=temp;

}

void main()

{

int i=0, j=10;

float x=10.3, y=4.8;

char a=’A’, b=’B’;

 

cout<<„Valorile intregi originale :”<<i<<‘ ‘<<j<<endl;

schimba(i,j); //inverseaza intregii

cout<<„Valorile intregi inversate :”<<i<<‘ ‘<<j<<endl<<endl;

cout<<„Valorile reale originale :”<<x<<‘ ‘<<y<<endl;

schimba(x,y); //inverseaza float

cout<<„Valorile reale inversate :”<<x<<‘ ‘<<y<<endl<<endl;

cout<<„Valorile caracter originale :”<<a<<‘ ‘<<b<<endl;

schimba(a,b); //inverseaza intregii

cout<<„Valorile caracter inversate :”<<a<<‘ ‘<<b<<endl<<endl;

 

 int var;

 cin>>var;

}

 

4) Sa se construiasca un program care creeaza o functie generica cu doua tipuri generice.

#include<iostream>

using namespace std;

 

template <class tip1, class tip2>

 

void f (tip1 x, tip2 y)

//merge si pe doua linii cu conditia ca intre aceste doua linii

 sa fie trecuta vreo instructiune

{

            cout<<x<<‘ ‘<<y<<endl;

}

 

void main()

{

            f(10, „hi”);

            f(0.3, 12L);

 

            int var;

            cin>>var;

}

 

5) Sa se construiasca o functie generica ce inverseaza între ele valorile celor doua variabile cu care este apelata, folosind supraîncarcarea explicita a unei functii generice.

#include<iostream>

using namespace std;

 

//Exemplu de functie sablon

 

template <class X> void schimba(X &a, X &b)

{

            X temp;

            temp=a;

            a=b;

            b=temp;

}

 

void schimba(int &a, int &b)

{

            int temp;

            temp=a;

            a=b;

            b=temp+1;

            cout<<„Functie suprascrisa.”<<endl;

}

 

void main()

{

            int i=0, j=10;

            float x=10.3, y=4.8;

            char a=’A’, b=’B’;

            cout<<„Valorile intregi originale :”<<i<<‘ ‘<<j<<endl; schimba(i,j); //inverseaza intregii

            cout<<„Valorile intregi inversate :”<<i<<‘ ‘<<j<<endl<<endl;

            cout<<„Valorile reale originale :”<<x<<‘ ‘<<y<<endl; schimba(x,y); //inverseaza float

            cout<<„Valorile reale inversate :”<<x<<‘ ‘<<y<<endl<<endl;

            cout<<„Valorile caracter originale :”<<a<<‘ ‘<<b<<endl; schimba(a,b); //inverseaza intregii

            cout<<„Valorile caracter inversate :”<<a<<‘ ‘<<b<<endl<<endl;

 

            int var;

            cin>>var;

}

 

6) Sa se realizeze o clasa generica pentru lucrul cu stiva statica.

#include<iostream>

using namespace std;

 

 

template <class X>

class Stiva_Vector

{

            X *memorie;

            int dimensiune;

            int vf;

            public:

            Stiva_Vector(int);

            ~Stiva_Vector(){delete memorie;}

            virtual int push(X);

            virtual int pop(X&);

            virtual int varf(X&);

            virtual int goala()

            {

                        vf=-1;

                        return vf;

            }

            virtual int plina()

            {

                        vf=dimensiune-1;

                        return vf;

            }

};

template <class X> Stiva_Vector<X>::Stiva_Vector(int dim)

{

            dimensiune=dim;

            memorie=new X[dimensiune];

            vf=-1;

}

template <class X> int Stiva_Vector<X>::push(X v)

{

            if(vf<dimensiune-1)

            {

                        memorie[++vf]=v;

                        return 1;

            }

            else return 0;

}

template <class X> int Stiva_Vector<X>::pop(X& v)

{

            if(vf!=-1)

            {

                        v=memorie[vf–];

                        return 1;

            }

            else return 0;

}

template <class X> int Stiva_Vector<X>::varf(X& t)

{

            if(vf!=-1)

            {

                        t=memorie[vf];

                        return 1;

            }

            else return 0;

}

void main()

{

            int c;

            Stiva_Vector<int>*a=new Stiva_Vector<int>(255);

            cout<<„Introduceti un numar (-1 face oprirea): „;

            cin>>c;

            while(c!=-1)

            {

                        a->push(c);

                        cout<<„Introduceti un numar (-1 face oprirea): „;

                        cin>>c;

            }

            cout<<endl;

            while(a->pop(c))

            {

                        cout<<c<<” „;

            }

            cout<<endl;

            delete a;

 

            int var;

            cin>>var;

}

 

Probleme propuse:

 

1)Sa se verifice daca un cuvant este palindrom.

2)Sa se transforme un sir din litere mici in litere mari.

3)Sa se transforme un sir din litere mari in litere mici.

4)Sa se determine frecventa de aparitie a unui caracter intr-un text.

5)Sa se genereze toate prefixele / sufixele unui cuvant.

6)Se citeste un text dintr-un fisier si un caracter c. Sa se determine de cate ori se gaseste caracterul in text (nu se face distinctie intre literele mari si literele mici).

7)Se citeste un text de la tastatura astfel incat cuvintele sa fie separate printr-un singur spatiu si imediat dupa ultimul cuvant se scrie punct. Textul va fi scris pe un singur rand.

8)Sa se determine cate cuvinte contine textul. De ex : „Ana are mere.” Contine 3 cuvinte.

9)Sa se determine daca textul are cuvinte distincte (se ignora diferenta de cheie).

10)Sa se determine daca textul contine cifre.

11)Sa se determine de cate ori se gaseste un cuvant intr-un text.

12)Codificati un text astfel incat litera a sa devina c, b sa devina e s.a.m.d.

Sa se sorteze alfabetic un sir de cuvinte (eventual, fara a distinge literele mici de cele mari).

Codificarea pasareasca a unui cuvant (dupa fiecare vocala, se pune litera p urmata de acea vocala). Ex : informatica à ipinfopormapatipicapa

Se citesc n cuvinte. Sa se afiseseze grupurile de cuvinte care rimeaza (au ultimele 2 caractere identice).

Sa se desparta un text in cuvinte si sa se afiseze cuvintele separate. Sa se afiseze cuvantul de lungime maxima.

Sa se verifice daca doua cuvinte sunt sau nu anagrame.