2.6. Parametrii implici?i

2.6. Parametrii implici?i

?n C++ a ap?rut posibilitatea de a indica valorile implicite pentru parametri ?n descrierea func?iilor. Examin?m urm?torul program, care pentru un set de puncte ?n sistemul de coordonate cartezian bidimensional afi?eaz? informa?ii despre repartizarea punctelor pe cadrane:

#include "iostream.h"
 
void printcadran(double x, double y=0.0, const char *ln="\n")
{
   cout << "Punctul (" << x << "," << y 
        << ") se afla ";
   if(y>0.0)
      if(x>0.0)
         cout << "in cadranul I";
      else
         if(x<0.0)
            cout << "in cadranul II";
         else
            cout << "pe axa OY";
   else
      if(y<0.0)
         if(x<0.0)
            cout << "in cadranul III";
         else
            if(x>0.0)
               cout << "in cadranul IV";
            else
               cout << "pe axa OY";
      else
         if(x!=0.0)
            cout << "pe axa OX";
         else
            cout << "in originea";
 
   cout << ln; // ad?ugarea la mesajul principal 
}
 
void main()
{
   printcadran(1., 1., ". "); // f?r? valori implicite
   printcadran(-1., 1.); // implicit pentru parametrul 3
   printcadran(-1., -1., ". "); // f?r? valori implicite
   printcadran(1., -1.); // implicit pentru parametrul 3
   printcadran(0., 1., ". "); // f?r? valori implicite
   printcadran(1.); // implicit pentru parametrii 2 si 3
   double xt=-1.0,  yt=-1.0;
   printcadran(0., yt, ". "); // f?r? valori implicite
   printcadran(xt); // implicit pentru parametrii 2 si 3
   printcadran(0.); // implicit pentru parametrii 2 si 3
 
   char c; cin >> c;
}


Primul rol ?n acest program ?i revine func?iei printcadran() cu trei parametri. Primii doi reprezint? coordonatele punctului de testare (respectiv x ?i y). Prin al treilea parametru poate fi transmis un ?ir de caractere care se adaug? la mesajul afi?at despre apartenen?a punctului (x, y) unuia din cele patru cadrane sau uneia din cele dou? axe de coordonate.

Func?ia main() apeleaz? consecutiv func?ia printcadran() cu diferite valori pentru coordonate. Codul func?iei printcadran() este destul de transparent, a?a c? atragem aten?ia la descrierea antetului ei, fiindc? el con?ine valorile implicite pentru ultimii doi parametri. Modul obi?nuit de apelare a func?iei printcadran(), de exemplu, este:

printcadran(2.5, 3.1, "\n");

Rezultatul apelului va fi afi?area textului:

Punctul (2.5,3.1) se afla in cadranul I

?i cursorul va fi pozi?ionat la ?nceputul liniei urm?toare. ?ntr-adev?r, primele dou? argumente dau coordonatele punctului care se afl? ?n cadranul I (acestea sunt, respectiv, 2.5 ?i 3.1). Argumentul trei arat? ?irul care trebuie afi?at la coada mesajului principal. ?n cazul nostru "\n" ?nseamn? c? dup? afi?area mesajului principal cursorul va fi deplasat la ?nceputul r?ndului urm?tor, lucru care, consider?m, trebuie s? fie f?cut ?n majoritatea cazurilor dup? afi?area mesajului principal. De aceea, pentru ultimul parametru (pointer la un ?ir de caractere constant) a fost indicat? valoarea implicit? (const char *ln="\n"), adic? adresa ?irului "\n". Ceea ce ?nseamn? c? putem apela func?ia printcadran() d?nd numai dou? argumente, iar pentru argumentul trei va fi luat? valoarea implicit?. Adic? apelul:

printcadran(2.5, 3.1);

este echivalent cu apelul:

printcadran(2.5, 3.1, "\n");

Func?ia printcadran() are valoarea implicit? ?i pentru parametrul doi (double y=0.0). Aceasta ?nseamn? c? apelul:

printcadran(0.5);

este echivalent cu apelul:

printcadran(0.5, 0.0);

?i cu apelul:

printcadran(0.5, 0.0, "\n");

?n func?ia main() sunt date diferite exemple de apelare a func?iei printcadran(). Programul fiind rulat va afi?a urm?torul text:

Punctul (1,1) se afla in cadranul I. Punctul (-1,1) se afla in cadranul II

Punctul (-1,-1) se afla in cadranul III. Punctul (1,-1) se afla in cadranul IV

Punctul (0,1) se afla pe axa OY. Punctul (1,0) se afla pe axa OX

Punctul (0,-1) se afla pe axa OY. Punctul (-1,0) se afla pe axa OX

Punctul (0,0) se afla in originea

Caracterele din textul dat au fost special mic?orate ?n carte, pentru ca textul s? se ?ncadreze ?n limitele paginii, a?a cum el a fost aranjat pe ecran.

La crearea ?i apelarea func?iilor cu parametrii implici?i sunt anumite restric?ii.

?n primul r?nd, dac? vrem s? indic?m valoarea implicit? pentru un parametru care nu este ultimul ?n lista parametrilor, obligatoriu trebuie indicate valorile implicite ?i pentru to?i ceilal?i parametri care urmeaz? dup? el, altfel va fi o eroare. De exemplu, urm?toarele anteturi vor fi gre?ite ?i nu vor fi compilate:

//nu este indicat? valoarea implicit? pentru parametrul ln;

void printcadran(double x, double y=0.0, const char *ln);

//nu este indicat? valoarea implicit? pentru parametrul y;

void printcadran(double x=0.0, double y, const char *ln="\n") ;

//nu sunt indicate valorile implicite pentru parametrii y ?i ln;

void printcadran(double x=0.0, double y, const char *ln);

//nu este indicat? valoarea implicit? pentru parametrul ln;

void printcadran(double x=0.0, double y=0.0, const char *ln);
La apelul func?iilor cu parametri implici?i, dac? vrem s? omitem un argument pentru care este prev?zut? valoarea implicit?, vom fi nevoi?i s? omitem ?i toate celelate argumente care urmeaz? dup? el. A?adar, func?ia printcadran() poate fi apelat? cu valoarea implicit? pentru parametrul y numai dac? ?i pentru parametrul ln va fi utilizat? valoarea implicit?.

Adic?, apelul de tipul printcadran(2.5,," Eroare!") va fi gre?it, deoarece a fost omis argumentul doi ?i este prezent argumentul trei. Corect va fi numai printcadran(2.5), sau printcadran(2.5, 0.0," Corect!") dac? valoarea implicit? pentru parametrul ln ?n acest caz nu ne aranjeaz?.

?n majoritatea cazurilor, pentru indicarea valorilor implicite se folosesc constante. ?ns?, poate fi indicat? ?i o variabil?, sau chiar o expresie, cu condi?ia c? toate variabilele ce se con?in ?n aceast? expresie sunt cunoscute la momentul c?nd se indic? valoarea explicit?. De exemplu, dac? declar?m func?ia printcadran() astfel:

double z=5.2;
char *s;
void printcadran(double x, double y=(z+1.0)*3.0,
                 const char *ln=s)
{}


atunci valoarea implicit? pentru parametrul ln va fi valoarea curent? (la momentul apelului) a pointerului s, iar valoarea implicit? pentru parametrul y va fi rezultatul expresiei (z+1.0)*3.0 calculat? ?n momentul apelului func?iei printcadran().

P?n? acum a fost cercetat? specificarea valorilor implicite pentru argumente care se transmit prin valoare. Este posibil? specificarea valorilor implicite ?i pentru argumentele care se transmit prin referin?e. ?n cazul acesta, valoarea care se indic? ca valoare implicit? nu poate fi o constant?, ci va fi luat? dintr-o variabil? specificat?, care este cunoscut? la momentul descrierii antetului func?iei. ?n programul de mai sus prefacem antetul func?iei printcadran() astfel:

double  z;
void printcadran(double &x=z, double &y=z, const char *ln="\n")
{}
Iar func?ia main() o prefacem astfel:
void main()
{
   double x1=1.0, x2=-1.0, x3=0.0, y1=1.0;
   z=1.0;
   printcadran(x1, y1, ". "); // f?r? valori implicite
   printcadran(x2); // implicit pentru parametrii 2 ?i 3
   z=-1.0;
   printcadran(x2, z, ". "); // f?r? valori implicite
   printcadran(x1); // implicit pentru parametrii 2 ?i 3
   printcadran(x3, y1, ". "); // f?r? valori implicite
   printcadran(x1, x3); // implicit pentru parametrul 3
   printcadran(x3, x2, ". "); // f?r? valori implicite
   z=0.0;
   printcadran(x2); // implicit pentru parametrii 2 ?i 3
   printcadran(); // implicit pentru toate argumentele
 
   char c; cin >> c;
}


Fiind rulat, programul modificat va afi?a exact acela?i text ca ?i programul ini?ial. ?n versiunea modificat? a func?iei printcadran() parametrii x ?i y se transmit prin referin?? ?i pentru ambii a fost specificat? valoarea implicit?. A?a este ?i ?n exemplul respectiv, ?ns? nu este obligatorie nici una, nici alta.

Adic?, modul de transmitere poate fi diferit pentru diferi?i parametri. La specificarea valorilor implicite r?m?ne regula „parametrului din dreapta”, adic? specificarea valorii implicite pentru parametrul x era posibil? fiindc? a fost specificat? valoarea implicit? pentru y, iar specificarea valorii implicite pentru y era posibil? fiindc? a fost specificat? valoarea implicit? pentru ln. ?n acest exemplu valorile implicite pentru parametrii x ?i y vor fi luate din una ?i aceea?i (nu este obligatoriu) variabil? z ?i, ca urmare, la apelul func?iei printcadran() f?r? argumente va fi testat punctul cu coordonatele egale.

La aceast? tem? mai avem de discutat despre locurile unde pot fi specificate valorile implicite pentru parametri. ?n exemplele precedente func?ia printcadran() a fost definit? complet ?nainte de a fi utilizat?. Cercet?m cazul c?nd ?n partea de sus a programului va fi declarat numai prototipul func?iei printcadran(), iar defini?ia func?iei va fi pus? ?n partea de jos a programului, conform schemei:

<#include "iostream.h"
 
void printcadran(double x, double y, const char *ln);
 
void main()
{}
void printcadran(double x, double y, const char *ln)
{}


S? presupunem c? vrem s? specific?m valorile implicite 0.0 pentru x ?i y ?i valoarea "\n" pentru ln. Cel mai potrivit loc pentru aceasta este declararea func?iei printcadran() din partea de sus a programului, adic? s? scriem:

void printcadran(double x=0.0, double y=0.0,const char *ln="\n");

sau chiar f?r? numele parametrilor (numai cu spa?iile ?nainte de caracterul '='):

void printcadran(double =0.0, double =0.0,const char* ="\n");

Se admite specificarea valorilor implicite pentru parametri ?i la definirea func?iei, adic? l?s?m prototipul func?iei f?r? valorile implicite ale parametrilor ?i vom scrie definirea func?iei astfel:

void printcadran(double x=0.0, double y=0.0, const char *ln="\n")
{}


?n a?a caz, utilizarea argumentelor implicite se admite numai ?n func?iile a c?ror definire urmeaz? dup? definirea func?iei printcadran(). ?n ultimul exemplu nu putem scrie ?n func?ia main() apelurile cu argumentele implicite (de tipul printcadran(2.3, -1.0);,  printcadran(2.3);,   printcadran();), fiindc? ?n func?ia main() ?nc? nu este ?tiut c? func?ia printcadran() are argumente implicite. ?ns?, putem proceda astfel:

<#include "iostream.h"
 
void printcadran(double x, double y, const char *ln);
void f();
 
void main()
{
   …
   printcadran(1.0, 1.0, ”\n”); // apelul f?r? argumente implicite   
   …
   f(); // apelul func?iei f() ?n care se apeleaz? func?ia cu
        // argumente implicite}
void printcadran(double x=0.0, double y=0.0, const char *ln="\n")
{}
void f()
{
   printcadran(2.3, -1.0);
   printcadran(2.3);
   printcadran();
}


?n func?ia f() apelurile func?iei printcadran() cu argumente implicite sunt corecte.

?n general, o parte de valori implicite poate fi specificat? la declararea func?iei ?i o parte – la definirea func?iei. ?n orice caz, respect?m urm?toarele reguli:

  • specificarea valorii implicite pentru fiecare parametru poate fi f?cut? numai ?ntr-un singur loc;
  • valoarea implicit? pentru un parametru poate fi specificat? dac? sunt specificate valorile implicite pentru to?i parametrii ce urmeaz? dup? el;
  • argumentele implicite pot fi utilizate ?n locurile unde valorile implicite pentru parametrii respectivi sunt cunoscute;
  • parametrul ce are valoarea implicit? poate fi omis ?n apelul func?iei, dac? sunt omi?i ?i to?i parametrii din partea dreapta a lui.

_________________________
Autorul: dr.conf. S. Pereteatcu

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов