Sunteți pe pagina 1din 17

COLEGIUL NATIONAL DE INFORMATICA

LUCRARE PENTRU ATESTAREA COMPETENTELOR PROFESIONALE

LA INFORMATICA

Profesor coordonator: Ene Dumitru

Elev: Anastasoaei Andrei

Clasa a-XII- D -2023-

TEMA PROIECTULUI
Subprograme
Motivatie

Am ales “Subprograme” drept tema pentru lucrarea de atestat pentru ca ele au o deosebita
importanta practica in programarea C++ iar principiul care sta la baza lor are o larga aplicabilitate in
viata de zi cu zi. Subprogramele, numite in C++ functii, fac posibila crearea programelor complicate
intr-un mod efi cient diminuand munca pe care programatorul o depune. Functiile impart o
problema aparent foarte complicata in mai multe probleme mai mici care pot fi cu usurinta
rezolvate. Prin interactiunea mai multor functii simple se rezolva o problema complexa.

Definitie

Subprogramele sunt parti ale unui program defi nite in afara functiei main, identifi cabile prin nume
si aeplabile de cate ori este nevoie. Ele contin tipuri de date, variabile si instructiuni in vederea unei
anumite prelucrari. Pentru a face referire la un subprogram, in C++ se foloseste doar notiunea de
functie, spre deosebire de limbajul Pascal unde subprogramele se impart in functii si proceduri.

Avantaje

Funcţiile :

• sunt esenţiale în construcţia blocurilor

• permit folosirea facilităţilor oferite de programarea structurată

• permit elaborarea unor aplicaţii proprii utilizatorului

• permit obţinerea unor funcţii mai complexe prin combinareaunora mai simple, care scriu, citesc,
testează şi depanează programe

Un program C++ conţine cel putin o funcţie main() care este apelată la lansarea în execuţie a
programului, funcţii predefi nite (de bibliotecă) şifuncţii construite de programator.

Structura:

Un subprogram (funcţie) are o definiţie şi atâtea apeluri câte sunt necesare.


Declarare:

Dacă o funcţie este apelată dintr-o bibliotecă standard sau defi nită de utilizator sub forma de fi şier
obiect sau dacă se afl ă într-un alt fi şier sursă, pentru a verifi ca validitatea apelurilor de către
compilator esteobligatorie folosirea declaraţiei acelei funcţii, declaraţie numită prototip.

Declaraţia are forma :

tip-rez nume(lista);

unde lista poate conţine doar tipul parametrilor şi numărul lor fără a fi neapărat necesară şi specifi
carea numelui lor (care este însărecomandată).Prototipul unei funcţii trebuie pus înaintea primului
apel al său, de obiceichiar la începutul programului.

Definitia unei functii este alcatuita din: tip_returnat nume_funcţie(lista parametrilor formali)

El conține următoarele:

Antetul subprogramului:

În cazul în care tipul rezultatului este diferit de void, corpul funcţiei trebuie să conţină cel puţin o
instrucţiune return. Instrucţiunea return va specifi ca valoarea calculată şi returnată de funcţie care
trebuie să fi e de acelaşi tip ca şi tip_returnat.

Instructiune 1;

Instructiune 2;

Instructiune 3;

Corpul funcţiei este un bloc, care implementează algoritmul de calcul folosit de către funcţie. În
corpul funcţiei apar (în orice ordine) declaraţii pentru variabilele locale şi instrucţiuni.

Apelul unei funcţii care nu returnează o valoare are forma generală:

nume_funcţie (lista parametrilor efectivi);

Parametrii unui subprogram


Parametri formali

apar în antetul subprogramului şi sunt utilizaţi de subprogram pentru descrierea abstractă a unui
proces de calcul.

Parametri actuali

apar în instrucţiunea de apelare a unui subprogram şi sunt folosiţi la execuţia unui proces de calcul
pentru valori concrete.

Parametrii formali nu sunt variabile. O variabilă este caracterizată de nume, tip, şi adresă. Legarea
unui parametru formal la o adresă se realizează în timpul execuţiei instrucţiunii de apelare a
subprogramului.
Lista parametrilor formali

-listă de declaraţii de variabile separate prin virgulă. Această listă poate să fie şi vidă.

Corpul functiei

Modul de definitie:

Predefinite – ele exista in biblioteca mediului de dezvoltare al programelor C++

Exemple:

Apelul unei funcții operand se realizează in expresii (atribuire, instrucțiuni de control (if, while, for) )
sau ca parametrii ai unei alte funcții.

Tipul unei funcţii operand poate fi :

-numeric (intreg sau real)

- character

- pointer

-înregistrare(struct)

NU poate fi tablou (vectori, matrici, string-uri)

nume_subprogram (listă de parametric actuali), de exemplu sch(a,b);

Variabile
Sistemul de operare alocă fi ecărui program trei zone distincte în memoria internă în care se găsesc
memorate variabilele programului:

o Segment de date

o Segment de stivă

o Heap.

Există şi posibilitatea ca variabilele să fi e memorate într-un anumit registru al microprocesorului, caz


în care accesul la acestea este foarte rapid.

Funcţia main.

În C, numele de funcţie main determină prima instrucţiune pe care o va executa programul. Acesta
este unica diferenţă dintre main şi celelalte funcţii.
Funcții operand: subprogram care returnează un rezultat chiar prin numele lui, dar eventual poate
returna și alte rezultate prin intermediul parametrilor de ieșire; 2.

Funcții procedurale: subprogram care are una, mai multe sau nici o valoare, valorile se returnează
prin intermediul parametrilor; apelul unei funcții procedurale se realizează printr-o instrucțiune
procedurala cu sintaxa: 1.

Variabile locale

La fel cum se declară variabilele în cadrul funcţiei main, la fel se pot declara varibile în cadrul
celorlalte funcţii. Aceste variabile se numesc locale şi sunt accesibile doar de funcţia care le-a
declarat.

La fel în cadrul unei funcţii se pot apela şi alte funcţii, ca şi în main, dacă acestea au fost defi nite
înaintea eventualului apel sau dacă este prezent un prototip de funcţie înaintea funcţiei apelante şi o
defi niţie de funcţie în cadrul programului respectiv sau în fi şierele incluse în programului respectiv.

Variabile globale

Sunt declarate în afara oricărei funcţii şi pot sunt vizibile (pot fi utilizate) în tot programul (în
rogramul principal şi în subprograme) din momentul declarării lor.

Mai jos, sunt cateva exemple care ilustreaza modul de folosire a variabilelor locale si globale.

# include <iostream.h>

int N;

void f1()

{int x=5;

N=10;

cout << endl<<N;

cout << endl << x;

void main ()

{N=4;

cout << N;

f1();

N este variabilă globală.

Poate fi accesată în cadrul oricărei funcţii.

x este variabilă locală, vizibilă doar în cadrul funcţiei f1().

Se va afişa: 4 10 5
#include <iostream.h>

int N;

void f1()

{int x=5;

cout << endl << x;

P=2 //eroare

int P=9;

void main ()

{f1();

cout << x;

P=7;//corect

Compilatorul generează eroare deoarece funcţia main încearcă să acceseze variabila x care este
vizibilă doar în funcţia f1().

Compilatorul generează eroare deoarece P este accesată în f1() înainte de a fi declarată.

# include

<iostream.h>

int N;

void f1(int p)

int x=p;

cout << x;

void main ()

f1(3);}

Se afişează 3

N este variabilă globală.

Poate fi accesată în cadrul oricărei funcţii.

x este variabilă locală.


Poate fi accesată doar în cadrul funcţiei f1()

p este parametru formal.

Poate fi accesat doar în f1().

Transmiterea parametrilor

Parametrii actuali trebuie să corespundă celor formali, ca număr şi tip de date. Tipul parametrilor
actuali trebuie fi e să coincide cu tipul parametrilor formali, fi e să poată fi convertit implicit la tipul
parametrilor formali.

Pentru memorarea parametrilor, subprogramele folosesc segmentul de stivă, la fel ca pentru


variabilele locale.

Memorarea se face în ordinea în care parametrii apar în antet.

În cadrul subprogramului, parametrii transmişi şi memoraţi în stivă sunt variabile. Numele lor este
cel din lista parametrilor formali.

Variabilele obţinute în urma memorării parametrilor transmişi sunt variabile locale.

La revenirea în blocul apelant, conţinutul variabilelor memorate în stivă se pierde.

Modul de transfer al parametrilor

Transfer prin valoare

Parametrului i se atribuie o valoare, o expresie sau conţinutul unei variabile. Se folosește, de obicei,
numai pentru parametrii de intrare.Dacă se utilizează, totuși, acest mod pentru transmiterea
rezultatelor, se pot folosi variabile de tip pointer.

Varianta 1

(transfer prin valoare a parametrilor de intrare)

# include <iostream.h>

int a,b;

void

sch (int x, int y)

{int z;

z=x; x=y; y=z;

int main()

{cin>>a>>b;

//a=10, b=20

sch(a,b);

cout<<a<<` `<<b;//a=10, b=20


return 0;

Varianta 2

(transfer prin valoare a parametrilor de ieșire, folosind pointeri)

# include <iostream.h>

int a,b;

void

sch (int *x, int *y)

{int z;

z=*x; *x=*y; *y=z;

int main()

{cin>>a>>b;//a=10, b=20

sch(&a,&b);//atenție la parametri

cout<<a<<` `<<b; //a=20, b=10

return 0;

Transfer prin referinţă

Subprogramul primeşte o adresă de memorie la care este stocată variabila primită ca parametru. Se
foloseşte pentru parametrii de ieşire, sau intrare/ieşire. In lista parametrilor formali, sunt precedaţi
de operatorul adresă de memorie (caracterul &).

Parametrii efectivi corespunzători parametrilor formali transmişi prin referinţă TREBUIE să fi e doar
variabile, adică nu pot fi constante, expresii, apeluri ale altor funcţii;
Varianta 3

(transfer prin referinţă a parametrilor de ieşire)

# include <iostream.h>

int a,b;

void sch (int &x, int &y)

{int z;

z=x; x=y; y=z;

int main()

cin>>a>>b; //a=10, b=20

sch(a,b);

// nu se poate apela sch(20, 30), parametrii actuali //TREBUIE să fi e variabile

cout<<a<<` `<<b; //a=20, b=10

return 0;

Supradefinirea funcţiilor

C ++ permite definirea mai multor funcţii cu acelaşinumedar cu liste de parametrii (semnături)


diferite ca tip sau ca număr al parametrilor.Supradefinirea funcţiilor care au parametrii cu valori
implicite poate genera duplicarea semnăturii funcţiilor respective, ambiguitate pe care compilatorul
o semnlează ca eroare.

Această facilitate permite obţinerea unui rezultat chiar dacă tipurile parametrilor diferă. Ea
contribuie la simplifi carea programării pentru că permite folosirea unui singur nume de funcţie când
programul trebuie să îndeplinească o anumită sarcină.

Tipuri speciale de parametri

Parametrul tablou

Funcţiile care transmit ca parametru un tablou necesită declararea acelui parametru ca pointer la
tipul de bază al tabloului.

Prototipul funcţiei are sintaxa:

tip_baza nume_tablou;

tip_rez nume_fct (tip_baza*, alte_tipuri);

Definirea unei funcţii cu parametru tablou are sintaxa:

tip_rez nume_fct (tip_baza*tab, alti_parametri)


tip_rez nume_fct (tip_baza tab[], alti parametri)

Exemplu. Funcţia calculează suma elementelor lui vector. Parametrul int* este tipul de bază al
parametrului vector.

#include < iostream.h>

void main ()

int suma (int *, int);

int vector[] = {4,2,1,5,3,6};

int dim = sizeof (vector) / sizeof (int);

cout << “Suma elementelor vectorului este:” << suma (vector,dim)<<endl;

int suma (int*p, int n)

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

s + = p[i];

return s;

Parametrul şir de caractere

Şirurile de caractere în C + + sunt considerate tablouri de caractere. Dacă un şir de caractere este
parametrul unei funcţii, pentru el sunt valabile aceleaşi reguli ca la parametrul tablou.

Transmiterea structurilor unei funcţii

Exemplu:

struct persoana

char nume[20];

int varsta;

};

void Citeste (persoana &x)

cout << "Numele:";

gets(x.nume);

cout << "Varsta:";


cin >>x.varsta;

void Afi seaza (persoana x)

cout << "NUMELE: " << x.nume;

cout << endl;

cout << "VARSTA: " << x.varsta;

void main ()

clrscr();

persoana P;

Citeste (P);

Afi seaza(P);

Modificarea membrilor structurii necesita apelul prin referinţă pe cand pentru a afi şa o structură
este sufi cient apelul prin valoare

Funcţii recursive

Dacă o funcţie se autoapelează direct sau indirect se numeşte recursivă. Astfel apelul unei funcţii
recursive poate apărea şi în defi niţia sa. O funcţie recursivă nu are sintaxă specială. Ea implică
existenţa unei stive care la fi ecare apel al funcţiei recursive se încarcă cu valorile parametrilor,
variabilelor locale şi rezultatului. La fi ecare revenire,această stivă este descarcată. Recursivitatea se
aplică în special la prelucrarea structurilor de date de tiprecursiv cum ar fi liste, arbori, etc.

Exemplu.

Calculul nerecursiv şi recursiv al factorialului unui număr natural.

Calcul nerecursiv

#include < iostream.h>

int factorial (int n)

int rez=1;

for (int i=1; i<=n; i++)rez*=i;return rez;

void main ()
{

int num;

cout << “Introduceti un numar natural:”;

cin >>num;

cout << endl << “ Rezultat:”<< num <<”!=”<<factorial (num) << endl;

Calcul recursiv

#include < iostream.h>

int fact (int n)

if (n==0)

return 1;

else

return n*fact(n-1);

void main ()

int num;

cout << “Introduceti un numar natural:”;

cin >>num;

cout << endl << “ Rezultat:”<< num <<”!=”<<fact (num) << endl;

Aplicatii

Problema nr. 1.

Să se determine cel mai mare divizor comun

(c.m.m.d.c.)

a doua numere întregi citite de la tastatura.

Cmmdc se va calcula folosind relatia:

cmmdc(a,b)=cmmdc(a-b, b), a>b=cmmdc(a, b-a), b>a

=a, daca a=b,

#include<iostream>
using namespace std;int cmmdc(int a,int b)

if(a==b) return a;

else if(a>b) return cmmdc(a-b,b);

else return cmmdc(a,b-a);

int main(){

int x,y;

cout<<"x=";cin>>x;

cout<<"y=";cin>>y;

cout<<"cmmdc este: "<<cmmdc(x,y);

Problema nr 2.

Sa se afi seze toate numerele din intervalul [1000,99999] care au proprietatea ca

atat ele cat si rasturnatul lor sunt prime

#include<iostream>

using namespace std;#include<math.h>

long n,c,d,k;

int prim(long n)

{if(n==0 || n==1) return 0;

for(int i=2;i<=sqrt(n);i++)

if(n%i==0) return 0;

return 1;

long rasturnat(long n)

{d=0;

while(n!=0)

{c=n%10;

d=d*10+c;

n=n/10;
}return d;

int main(){for(long int x=1001;x<=99999;x++)

if(prim(x) && prim(rasturnat(x))) cout<<x<<endl;

Problema nr. 3.

Scrieţi defi niţia completă a subprogramului

numar

, cu trei parametri, care primeşte prin intermediul parametrului n un număr natural format din cel
mult 9 cifre, iar prin intermediul parametrilor c1 şi c2 câte o cifră nenulă. Subprogramul caută fi
ecare apariţie a cifrei c1 în n, şi dacă aceasta apare, o înlocuieşte cu c2. Subprogramul furnizează tot
prin n numărul astfel obţinut. Dacă cifra c1 nu apare în n, atunci valoarea lui n rămâne nemodifi cată.

#include<iostream>

using namespace std;void numar( long & n,int c1,int c2)

int p=0,p1=1,c;

long nr=n;

while(nr)

p=p+1;

if(nr%10==c1)

p1=1;

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

p1=p1*10;

cout<<p1<<endl;

c=n%p1;

cout<<"c="<<c;

cout<<endl;

p1=p1*10;

n=n/p1;

n=n*10+c2;
p1=p1/10;

n=n*p1+c;

cout<<n<<endl;

nr=nr/10;

int main(){

long n;

int c1,c2;

cin>>n>>c1>>c2;numar(n,c1,c2);

cout<<n;

Problema nr. 4.

Ordonarea şi interclasarea a doi vectori

#include <iostream>

#include <conio.h>

using namespace std;

int a[10],b[10],na,nb,nc,c[20];

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

cout<<"Numarul de elemente: "; cin>>n;

cout<<"Introduceti elementele: ";

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

void afi sare(int x[], int n){

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

void ordonare(int x[], int n){

int i,ok,aux;

do{ok=1;

for (i=0;i<n-1;i++)

if (x[i]>x[i+1]){
ok=0;

aux=x[i];

x[i]=x[i+1];

x[i+1]=aux;

}}while(!ok);}

void inter(int v[]){

int i,j,ok=1;

for (i=0;i<na;i++) v[i]=a[i];

nc=na;

for (i=0;i<nb;i++){

ok=1;

for (j=0;j<na;j++)

if (a[j]==b[i]){

ok=0;

break;

}if (ok){

v[nc]=b[i];

nc++;

}}}

int main(){

clrscr();

cout<<"Primul vector: \n";

citire(a,na);

cout<<"Al doilea vector \n";

citire(b,nb);

ordonare(a,na);

ordonare(b,nb);

cout<<"Primul vector ordonat \n";

afi sare(a,na);

cout<<endl;

cout<<"Al doilea vector ordonat \n";


afi sare(b,nb);

cout<<endl;

cout<<"Interclasarea vectorilor \n";

inter(c);

afi sare(c,nc);

getch();

Problema nr. 5.

Scrieti un program C/C++ care citeste de la tastatura un numar natural nenul n (1≤n≤100),
construieste in memorie si apoi afi seaza pe ecran un tablou unidimensional a, avand n elemente.
Tabloul a se completeaza cu numerele naturale de la 1 la n, astfel : se memoreaza valoarea 1 pe
pozitia 1, valoarea 2 pe pozitia n, 3 pe pozitia 2, 4 pe pozitia n-1, 5 pe pozitia 3, etc.

Elementele tabloului se afi seaza cu cate un spatiu intre ele.

#include<iostream>

#include<math.h>

using namespace std;

int n,i,a[100];

void citire()

cin>>n;

for(i=1;i<=ceil((fl oat)n/2);i++)

a[i]=2*i-1;

for(i=n;i>ceil((fl oat)n/2);i--)

a[i]=2*(n-i)+2;

int main()

citire();

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

cout<<a[i]<<" ";

}
CONCLUZII

Subprogramele au o serie de avantaje care fac programarea mai usoara si mai efi cienta. Impartirea
unei probleme mari in mai multe probleme mici este un principiu aplicabil in viata de zi cu zi, fapt
care m-a determinat sa aleg aceasta tema pentru sustinerea lucrarii de atestat la informatica.

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