Sunteți pe pagina 1din 19

Subprograme

Un subprogram este o colecție de tipuri de date, variabile, instrucțiuni care îndeplinesc o


anumită sarcină (calcule, citiri, afișări), atunci când este apelat de un program sau de un alt
subprogram.

Pentru a înțelege conceptul de subprogram, să considerăm două probleme:

Problema 1: Se dau două numere naturale n și m. Să se determine suma dintre oglinditul
lui n și oglinditul lui m.

Până acum, pentru a rezolva această problemă, trebuia să determinăm, folosind două secvențe
de program aproape identice, oglinditele celor două numere, iar apoi să facem suma. O
soluție mai simplă este să construim un subprogram care determină oglinditul unui număr
natural oarecare, să-l apelăm de două ori pentru a determina oglinditul lui n și al lui m, apoi
să facem suma rezultatelor.

Problema 2: Se citește un tablou cu n elemente, numere întregi. Să se ordoneze crescător


elementele tabloului și apoi să se afișeze.

Putem rezolva această problemă, în mai multe moduri, folosind cunoștințe pe care le avem
deja. Dacă dorim să o rezolvăm folosind subprograme, vom construi trei subprograme:

 citire – care citește elementele vectorului


 sortare – care ordonează elementele vectorului
 afisare – care afișează elementele vectorului

Astfel, programul care rezolvă problema constă în apelul celor trei subprograme, în odinea
potrivită. Am reușit să descompunem rezolvarea unei probleme complexe în mai multe
subprobleme, mai simple, care pot fi rezolvate de mai multe persoane, dacă este cazul.

Constatăm că utilizarea subprogramelor are câteva avantaje:

 reutilizarea codului – după ce am scris un subprogram îl pute apela de oricâte ori


este nevoie;
 modularizarea programelor – subprogramele ne permit să împărțim problema dată
în mai multe subprobleme, mai simple;
 reducerea numărului de erori care pot să apară în scrierea unui program
 depistarea cu ușurință a erorilor – fiecare subprogram va fi verificat la crearea sa,
apoi verificăm modul în care apelăm subprogramele

Subprogramele pot fi de două tipuri:


 funcții – subprograme care determină un anumit rezultat, o anumită valoare, pornind
de la anumite date de intrare. Spunem că valoarea este returnată de către funcție, iar
aceasta va fi apelată ca operand într-o expresie, valoarea operandului în expresie fiind
de fapt valoarea rezultatului funcției.
 proceduri – subprograme care se folosesc într-o instrucțiune de sine stătătoare, nu
într-o expresie. Ele îndeplinesc o sarcină, au un efect și nu returnează un rezultat. De
exemplu, citirea unor variabile, afișarea unor valori, transformarea unor date, etc.

În limbajul C/C++, există doar subprograme de tip funcție. Pentru proceduri se folosește o
formă particulară a funcțiilor.

Anatomia unei funcții C/C++


Considerăm problema: Se dau două numere naturale n și m. Să se determine suma dintre
oglinditul lui n  și oglinditul lui  m.

Programul următor rezolvă problema de mai sus.

#include <iostream>
using namespace std;

int ogl(int x)
{
int r = 0;
do
{
r = 10 * r + x % 10;
x /= 10;
}
while(x != 0);
return r;
}

int main(){
int n , m;
cin >> n >> m;
cout << ogl(n) + ogl(m);
return 0;
}
Funcția care calculează oglinditul unui număr este int ogl(int x).

 funcția are un antet: int ogl(int x), din care deducem că:


o funcția se numește ogl;
o funcția are un parametru, x, de tip int. Parametrul este important, deoarece prin
el se precizează care este numărul pentru care se determină oglinditul. Vom
vedea mai târziu că o funcție poate avea mai mulți parametri. Parametrii care
apar în antetul funcției se numesc parametri formali;
o parametrii unei funcții se mai numesc și argumente;
o funcția are un anumit tip, aici int, care precizează care este tipul rezultatului;
 funcția are un bloc de instrucțiuni, corpul funcției, delimitat de acolade {}, care
precizează operațiile prin care se obține rezultatul. Mai mult:
o corpul funcției are propriile variabile (aici r). Aceste variabile se
numesc variabile locale;
o în corpul funcției, parametrul se comportă ca o variabilă locală. NU putem
avea o variabilă locală cu același identificator ca parametrul;
o în corpul funcției nu se cunosc valorile parametrilor formali. Funcția trebuie să
determine rezultatul corect indiferent de valoarea lor;
o rezultatul determinat în cadrul funcției este întors în programul apelant prin
instrucțiunea return. Rezultatul este calculat în mod obișnuit în variabila r.
Prin instrucțiunea return r;, valoarea curentă a variabilei r este returnată în
programul apelant;
 în funcția main găsim apelul funcției ogl:
o apelul funcției se face într-o expresie: cout << ogl(n) + ogl(m);. Pentru
operația de adunare, operanzii vor fi rezultatele apelurilor celor două funcții;
o parametrii n, respectiv m, întâlniți în apel, se numesc parametri
efectivi sau parametri actuali. Valorile parametrilor
actuali sunt cunoscute;
o

Considerăm problema: Se citește un tablou cu elemente numere întregi. Să se ordoneze


crescător elementele tabloului și apoi să se afișeze.

O rezolvare C/C++ care folosește funcții este următoarea:


#include <iostream>
using namespace std;

void citire(int & n, int x[])


{
cin >> n;
for(int i = 0 ; i < n ; ++ i)
cin >> x[i];
}

void sortare(int n, int x[])


{
bool sortat = false;
while(! sortat)
{
sortat = true;
for(int i = 0 ; i < n - 1 ; i++)
if(x[i] > x[i+1])
{
int aux = x[i];
x[i] = x[i+1];
x[i+1] = aux;
sortat = false;
}
}
}

void afisare(int n, int x[])


{
for(int i = 0 ; i < n ; ++ i)
cout << x[i] << " ";
}

int main(){
int k, v[1005];
citire(k , v);
sortare(k , v);
afisare(k , v);
return 0;
}
Față de cele de mai sus, putem observa următoarele:

 funcțiile citire, sortare și afisare nu returnează valori și au un tip al rezultatului


special, void. Tipul void este un tip de date care nu conține valori și poate fi folosit
tocmai în asemenea situații. Am putea spune că sunt de tip procedură;
 apelul acestor funcții se face în instrucțiuni de sine stătătoare;
 funcțiile au câte doi parametri, numărul de elemente ale tabloului și tabloul propriu
zis. Pentru parametrul formal de tip tablou nu trebuie să fie precizată dimensiunea
declarată a tabloului;
 numele parametrilor actuali nu trebuie să fie aceiași cu cei ai parametrilor formali.
Trebuie însă să corespundă numărul lor, tipul lor și ordinea;
 parametrul actual de tip tablou nu conține []:
o dacă am fi avut apelul citire(k , v[]); am fi obținut o eroare de sintaxă,
sintagma v[] neavând înțeles;
o dacă am fi avut apelul citire(k , v[k]); am fi obținut de asemenea eroare de
sintaxă, v[k] fiind elementul de indice k din tabloul v, deci o variabilă de
tip int, nu tablou;
 observați prezența caracterului & înaintea parametrului formal n din antetul
funcției citire. Acesta transformă parametrul formal într-un alias al parametrului
actual, iar modificările făcute asupra parametrului formal n au loc de fapt asupra
parametrului actual k din main;

Definirea și declararea unei funcții C/C++


Una dintre regulile limbajului C/C++ este următoarea, și o știm foarte bine pentru
variabile: Orice identificator, pentru a putea fi folosit, trebuie să fie mai întâi declarat.
Această regulă este valabilă și pentru funcții, astfel că identifică următoarele noțiuni, aparent
asemănătoare. Buna lor înțelegere ne va scuti de numeroase erori!!

 definirea unei funcții înseamnă scrierea ei în întregime; este alcătuită din antetul


funcției și din corpul funcției;
 declararea unei funcții înseamnă să-i anunțăm existența; Declararea funcției se face
într-o instrucțiune declarativă și se mai numește și prototip al funcției. Declararea
funcției poate fi înlocuită de definirea ei.

Să considerăm următorul exemplu, fără însemnătate practică:


#include <iostream>

using namespace std;

void F(){
cout << "Salut";
}

int main(){
F();
return 0;
}

Programul este sintactic corect. Partea:

void F(){
cout << "Salut";
}

reprezintă definirea funcției F(), dar tot aici are loc și declararea. Dacă schimbăm ordinea
funcțiilor F() și main() obținem:

#include <iostream>

using namespace std;

int main(){
F();
return 0;
}

void F(){
cout << "Salut";
}

De data aceasta programul nu mai este corect; la compilare obținem următoarea eroare:

ttt.cpp: In function ‘int main()’:


ttt.cpp:6:7: error: ‘F’ was not declared in this scope
F();
^
Compilation failed.
Constatăm că identificatorul F nu este declarat. El poate fi declarat precizând prototipul
funcției înaintea funcției main() (practic, înainte de a o apela), ca mai jos:

#include <iostream>

using namespace std;

void F();

int main(){
F();
return 0;
}

void F(){
cout << "Salut";
}

Observăm că prototipul (declararea) este o instrucțiune C++ obișnuită, care se termină cu ;!!

Declararea variabilelor
După cum știm, în C++ variabilele despre care am învățat până acum trebuie declarate și
odată cu declararea li se alocă în memorie spațiu în conformitate cu tipul lor. Întrebarea este:
“Unde putem declara variabile și prin ce diferă acestea?”.

Sistemul de operare alocă fiecărui program, în memoria RAM, trei zone în care putem
memora variabile:

 zona de date
 zona de stivă
 zona liberă (heap)

O variabilă se caracterizează prin:

1. clasa de memorare
2. vizibilitate
3. durata de viață
4. tipul variabilei

Să nu uităm, de asemenea, identificatorul variabilei! Dar nu toate variabilele au un


identificator, așa cum vom vedea cândva!
Clasa de memorare reprezintă zona de memorie unde poate fi alocat spațiu pentru o
variabilă. Ea poate fi: zona de date, zona de stivă, heap-ul sau un registru al procesorului – o
memorie specială, de mici dimensiuni, foarte rapidă existentă în procesor (CPU).

Vizibilitatea unei variabile precizează zona din codul sursă (liniile programului C++) unde
se poate folosi respectiva variabilă și poate fi:

 la nivel de bloc – variabila este vizibilă numai într-un bloc al programului


 la nivel de fișier – variabila este vizibilă în tot fișierul sursă cu care lucrăm
 la nivel de clasă – specific programării orientate pe obiecte

Durata de viață reprezintă timpul în care variabilei îi este alocat spațiu în memorie și poate
fi:

 durată statică – variabila are alocat spațiu pe tot parcursul execuției programului
 durata locală – variabila are alocat spațiu numai pe parcursul execuției instrucțiunilor
dintr-un bloc
 durata dinamică – variabila se creează (i se alocă spațiu) și se distruge de către
programator, în timpul executării programului

În C++ variabile pot fi: locale, globale și dinamice. Variabile dinamice vor fi prezentate într-
un alt articol, iar cele statice și dinamice în continuare.

Variabile locale
Variabilele locale se declară într-un anumit bloc al programului, în corpul unei funcții. Fie
programul de mai jos:

#include <iostream>
using namespace std;

void F(){
int x;
x = 5;
cout << x << endl;
}

int main(){
int y = 10;
F();
cout << y << endl;
return 0;
}
Variabilele x și y declarate în programul de mai sus sunt locale. Variabila x poate fi utilizată
numai în funcție F(), iar variabila y numai în funcția main(). Mai mult, cele două variabile ar
fi putut avea același nume și nu ar fi fost nicio confuzie.

Variabilele locale respectă următoarele reguli:

 li se alocă memorie în zona de stivă


 sunt vizibile numai în blocul în care au fost declarate
 durata de viață a lor este execuția instrucțiunilor din blocul în care au fost declarate
 sunt inițializate cu valori aleatorii. Mai precis, standardul C++ nu garantează
inițializarea lor cu o anumită valoare. Asta nu înseamnă că nu este posibil ca
variabilele locale să fie inițializate de exemplu cu 0 într-o anumită implementare a
compilatorului, dar nu ne putem baza pe acest lucru. Mai mult, compilatorul utilizat
pe pbInfo nu inițializează variabilele locale cu o anumită valoare

Observație: Parametrii formali ai unei funcții respectă proprietățile unei variabile locale. Nu


vom putea declara în blocul funcției variabile cu același nume ca al parametrilor formali.

Variabile globale
Variabilele globale se declară în afara oricărei funcții. La declarare, ele sunt inițializate cu 0.

#include <iostream>
using namespace std;

int x;

void F(){
cout << x << endl;
x = 10;
}

int y;

int main(){
cout << x << " " << y << endl;
x = 5; y = 15;
F();
cout << x << " " << y << endl;
return 0;
}
În programul de mai sus variabilele x și y sunt globale. Variabila x poate fi utilizată atât în
funcția main() cât și in F(), iar variabila y numai în main().

Variabilele globale respectă următoarele reguli:

 li se alocă memorie în zona de date


 sunt vizibile în toate funcțiile care urmează în codul sursă declarării lor
 durata de viață a lor este execuția întregului program
 sunt inițializate cu valoarea 0.

Observație: Într-un program putem avea și variabile globale și variabile locale, ba chiar


variabile globale și locale cu același nume. Următorul program exemplifică această situație.
Rulați-l și analizați valorile afișate pentru a deduce modul în care sunt ele vizibile!

#include <iostream>
using namespace std;

int x;

void F(){
cout << x << endl; //5, variabila globala
int x = 10;
cout << x << endl; //10, variabila locala in F()
{
int x = 20;
cout << x << endl; //20, variabila locala în F(), blocul interior
}
cout << x << endl; //10, variabila locala in F()
}

int y;

int main(){
cout << x << endl; //0, variabila globală
x = 5;
cout << x << endl; //5, variabila globala
F();
cout << x << endl; //5, variabila globala
int x = 100;
cout << x << endl; //100, variabila locala in main()
return 0;
}

Observație: Dacă într-un program avem variabile cu același nume, dar cu domenii de


vizibilitate diferite, are prioritate variabila cu domeniul de vizibilitate cel mai mic. În
particular, dacă ave o variabilă globală și una locală cu același nume are prioritate variabila
locală.

Observație: Dacă declarăm o variabilă în expresia de inițializare a unei instrucțiuni for, ea va


fi vizibilă numai în expresiile de control ale instrucțiunii for și în blocul subordonat acesteia.
De exemplu:

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


cout << i << " " ;

Transmiterea parametrilor
Să ne amintim că parametri din antetul unei funcții se numesc parametri formali, iar cei din
apelul funcției se numesc parametri efectivi.

Corespondența dintre parametri formali și cei efectivi


Fie următorul program, în care funcția cmmdc returnează cel mai mare divizor comun al
parametrilor:

#include <iostream>
using namespace std;

int cmmdc(int a , int b){


while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
return a;
}
int main(){
int x = 24, y = 18;
cout << cmmdc(x , y) << endl; // 6
cout << cmmdc(x, y + 2) << endl; // 4
cout << cmmdc(x , 36) << endl; // 12
cout << cmmdc(26 , 39) << endl; // 13
cout << cmmdc(8.5 , 12.56) << endl; // 4
return 0;
}

Să observăm că între parametri formali și cei actuali trebuie să existe o anumită


corespondență, astfel:

1. numărul parametrilor formali și cel al parametrilor actuali trebuie să fie același (există
și o excepție care depășește cadrul acestui articol)
2. tipul parametrilor formali trebuie să fie același cu cel al parametrilor actuali, sau să se
poată face o conversie implicită:
o cmmdc(x , y) – parametri actuali sunt variabile de tip int
o cmmdc(x, y + 2) – un parametru actual este variabilă de tip int, celălalt este o
expresie al cărei rezultat este de tip int
o cmmdc(26 , 39) – parametri actuali sunt constante de tip int
o cmmdc(8.5 , 12.56) – parametri actuali sunt constante de tip double. Înainte de
apel valorile parametrilor actuali vor fi convertite la tipul int, apelul fiind
similar cu cmmdc(8 , 12).
3. numele parametrilor formali nu trebuie să fie aceiași cu numele parametrilor actuali
corespunzători

Parametrii formali ai unei funcții se comportă la fel ca niște variabile locale:

 li se alocă memorie pe stivă, ca variabilelor locale.


 devin variabile locale pentru funcție, iar numele acestor variabile este identic cu
numele parametrilor din antetul funcției
 la revenirea din apelul funcției, conținutul parametrilor, la fel ca al variabilelor locale,
se pierde

Mecanismele de transmitere a parametrilor în C++


Există două modalități de transmitere a parametrilor:

 transmiterea prin valoare


 transmiterea prin referință

Transmiterea prin valoare


În cazul transmiterii parametrilor prin valoare, parametrii formali ai unei funcții sunt copii ale
valorilor parametrilor actuali. Acest lucru înseamnă că:

 parametri actuali pot fi expresii ale căror valori corespund ca tip cu parametri formali
(sau pot fi convertite implicit la tipul parametrilor formali).
 pe stivă se memorează valoare expresiei (sau variabilei) date ca parametru actual.
 la ieșirea din apelul funcției modificările realizate în funcție asupra parametrilor
formali nu au efect asupra parametrilor actuali. Parametrii actuali sunt nemodificați!
 acesta este modul implicit de transmitere a parametrilor.

Exemplu:

#include <iostream>
using namespace std;

int cmmdc(int a , int b){


cout << "La inceputul functiei cmmdc, a = " << a << " si b = " << b << endl;
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
cout << "La finalul functiei cmmdc, a = " << a << " si b = " << b << endl;
return a;
}

int main(){
int x = 24, y = 18;
cout << cmmdc(x , y) << endl;
cout << "După apelul functiei cmmdc, x = " << x << " si y = " << y << endl;
return 0;
}

Constatăm că deși în funcția cmmdc parametrii formali a și b se modifică, în main(), după


apelul funcției cmmdc(), parametrii actuali x și y au valorile anterioare.

Transmiterea prin referință


Este mecanismul specific C++ prin care putem modifica într-o funcție variabile din afara
funcției. În cazul transmiterii parametrilor prin referință, parametrii formali ai unei funcții
sunt referințe ale parametrilor actuali. Acest lucru înseamnă că:

 parametri actuali pot fi doar variabile, sau expresii ale căror rezultate sunt similare
variabilelor: elemente de tablou, câmp al unei structuri, pointer dereferențiat, etc.
 pe stivă se memorează adresa variabilei date ca parametru actual.
 toate modificările realizate în apelul funcției asupra parametrilor formali se fac de fapt
asupra parametrilor actuali. Parametrii actuali sunt modificați la ieșirea din apel!
 pentru a preciza că un parametru este transmis prin referință va fi precedat de
caracterul & în antetul funcției.

Trebuie amintit că în limbajul C nu este posibilă transmiterea parametrilor prin


referință. Dacă dorim să modificăm într-o funcție o variabilă din afara ei trebuie să folosim
pointeri.

Exemplu:

#include <iostream>
using namespace std;

void dublare(int & n)


{
n = 2 * n;
}

int main(){
int x = 24;
cout << "x = " << x << endl;
dublare(x);
cout << "x = " << x << endl;
return 0;
}

Constatăm că, la ieșirea din apel, valoarea variabilei x este modificată. Mai mult, un apel de
forma dublare(10); reprezintă o eroare de sintaxă, deoarece parametrul actual trebuie să fie
variabilă.
Transmiterea ca parametri a tablourilor
Tablourile au un comportament special în ceea ce privește transferul parametrilor. Mai precis:

Tablourile se transmit prin valoare, dar orice modificare a valorilor elementelor tabloului dat
ca parametru formal va afecta elementul corespunzător al tabloului dat ca parametru actual.

Exemplu:

#include <iostream>
using namespace std;

void dublare(int & x)


{
x = 2 * x;
}

void transf(int n, int x[])


{
for(int i = 0 ; i < n ; i ++)
dublare(x[i]);
}

void afisare(int n, int x[])


{
for(int i = 0 ; i < n ; i ++)
cout << x[i] << " ";
cout << endl;
}

int main(){
int n = 5, v[5];
for(int i = 0 ; i < n ; i ++)
v[i] = i;
afisare(n , v); // tabloul memorează {0, 1, 2, 3, 4}
transf(n, v);
afisare(n , v); // tabloul memorează {0, 2, 4, 6, 8}
return 0;
}

Analizând programul anterior, constatăm că:


 am transmis prin referință funcției dublare() un element al tabloului.
 funcția transf() are doi parametri transmiși prin valoare (inclusiv tabloul).
 la ieșirea din apelul funcției transf() elementele tabloului sunt modificate, deși tabloul
a fost transmis prin valoare.

Pentru a preciza că un parametru formal este tablou unidimensional avem următoarele


posibilități (luăm ca exemplu funcția afișare de mai sus):

void afisare(int n, int x[]); // nu se precizează dimensiunea reală a tabloului


void afisare(int n, int x[10]); // se precizează dimensiunea reală a tabloului
void afisare(int n, int *x); // parametrul este un pointer la tipul elementelor tabloului

Toate variantele de mai sus sunt echivalente.

Pentru un tablou multidimensional, regula este că prima dimensiune a parametrului nu trebuie


să fie în concordanță cu cea a parametrului actual. Toate celelalte dimensiuni ale parametrului
formal trebuie să fie identice cu dimensiunile corespunzătoare ale parametrului actual. De
exemplu, pentru o matrice următoarele secvențe sunt corecte:

void F(int n, int m, int A[][25]); //prototipul funcției


...
int n , m , A[25][25]; //declarații de variabile
F(n,m,A); //apelul funcției

sau

void F(int n, int m, int A[25][25]); //prototipul funcției


...
int n , m , A[25][25]; //declarații de variabile
F(n,m,A); //apelul funcției

Următoare secvență este însă greșită, deoarece a doua dimensiune a parametrului actual
(numărul de coloane) nu corespunde cu cea a parametrului formal:

void F(int n, int m, int A[][25]); //prototipul funcției


...
int n , m , A[20][20]; //declarații de variabile
F(n,m,A); //apelul funcției

Parametri de intrare, de ieșire și de intrare/ieșire


Așa cum am văzut deja, parametri sunt folosiți pentru a transfera date între subprograme.
Astfel prin intermediul parametrilor o funcție poate să primească date pe care să le prelucreze
sau poate să întoarcă rezultate în funcția care a făcut apelul.

Din acest punct de vedere, parametrii unei funcții pot fi:

 parametri de intrare – prin intermediul lor funcția primește date pe care să le


prelucreze. De obicei sunt parametri transmiși prin referință. Valoarea cu care intră în
funcție este importantă, valoarea pe care o au la finalul apelului nu este importantă.
 parametri de ieșire – prin intermediul lor funcția întoarce în programul apelant
rezultate. De obicei sunt parametri transmiși prin referință, cu excepția tablourilor.
Valoare pe care o au la intrarea în funcție nu este importantă; este importantă însă
valoarea pe care o au la finalul apelului, deoarece reprezintă probabil rezultatul.
 parametri de intrare-ieșire – prin intermediul lor funcția primește date de intrare, le
prelucrează și tot prin intermediul lor întoarce în programul apelant rezultatul. De
obicei sunt parametri transmiși prin referință, cu excepția tablourilor. Pentru acești
parametri este importantă atât valoarea cu care intră în apel, cât și valoarea de la
ieșirea din apel.

Pentru exemplificare să vedem câteva variante pentru o funcție care determină oglinditul unui
număr natural, precum și modul de apelare:

Parametri de intrare – funcția are un singur parametru, de intrare, transmis prin valoare,
prin care primește un număr pentru care determină oglinditul. Rezultatul va fi returnat de
către funcție, iar apelul se va face într-o expresie.

int ogl(int n)
{
int r = 0;
while(n)
r = 10 * r + n % 10, n /= 10;
return r;
}
int main(){
int a;
cin >> a;
cout << ogl(a);
return 0;
}

Parametri de ieșire – funcția are doi parametri:


 un parametru de intrare, transmis prin valoare, prin care primește un număr pentru
care determină oglinditul
 un parametru de ieșire, transmis prin referință, prin care întoarce rezultatul

Funcția se apelează într-o instrucțiune de sine stătătoare.

void ogl(int n, int & r)


{
r = 0;
while(n)
r = 10 * r + n % 10, n /= 10;
}
int main(){
int a, x;
cin >> a;
ogl(a, x);
cout << x;
return 0;
}

Parametri de intrare ieșire – funcția are un singur parametru, transmis prin referință, prin
care primește un număr natural. Funcția determină oglinditul acestuia și îl întoarce prin
intermediul aceluiași parametru. Funcția se apelează într-o instrucțiune de sine stătătoare.

void ogl(int & n)


{
int r = 0;
while(n)
r = 10 * r + n % 10, n /= 10;
n = r;
}
int main(){
int a;
cin >> a;
ogl(a);
cout << a;
return 0;
}

S-ar putea să vă placă și