capitolul subprograme

54
Capitolul SUBPROGRAME 1. NOŢIUNEA DE SUBPROGRAM 2. EXEMPLE DE UTILIZARE A FUNCŢIILOR

Upload: helen

Post on 05-Jan-2016

114 views

Category:

Documents


8 download

DESCRIPTION

Capitolul SUBPROGRAME. NO ŢIUNEA DE SUBPROGRAM EXEMPLE DE UTILIZARE A FUNCŢIILOR. NO ŢIUNEA DE SUBPROGRAM. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Capitolul  SUBPROGRAME

Capitolul SUBPROGRAME

1. NOŢIUNEA DE SUBPROGRAM

2. EXEMPLE DE UTILIZARE A FUNCŢIILOR

Page 2: Capitolul  SUBPROGRAME

NOŢIUNEA DE SUBPROGRAM

Prin subprogram vom înţelege un ansamblu alcătuit din tipuri de date, variabile şi instrucţiuni scrise în vederea unei anumite prelucrări (calcule, citiri, scrieri) şi care poate fi utilizat (rulat) doar dacă este apelat de un program sau de alt subprogram.

Page 3: Capitolul  SUBPROGRAME

AVANTAJELE UTILIZĂRII SUBPROGRAMELOR:

realizarea codului – o dată scris, un subprogram poate fi utilizat de mai multe programe;

elaborarea algoritmilor prin descompunerea problemei în altele mai simple. În acest fel, rezolvăm cu mult mai uşor problema;

reducerea numărului de erori care pot apărea la scrierea programelor;

depistarea cu uşurinţă a erorilor – verificăm la început subprogramele, apoi modul în care le-am apelat în cadrul programului.

Page 4: Capitolul  SUBPROGRAME

EXEMPLE DE UTILIZARE A FUNCŢIILOR

Se citeşte n, număr natural. Să se scrie programele care tipăresc valoarea calculată a expresiilor:

;1

...3

1

2

111 n

E

;1

...3

1

2

112

n

nE

Page 5: Capitolul  SUBPROGRAME

Primul program este:

#include <iostream.h>double subp(int n){double s=0; int i;for (i=1;i<=n;i++) s+=(float)1/i;return s;}main(){int n;cout<<“n=”;cin>>n;cout<<subp(n);}

Page 6: Capitolul  SUBPROGRAME

Al doilea program este:

#include <iostream.h>double subp(int n){double s=0; int i;for (i=1;i<=n;i++) s+=(float)1/i;return s;}main(){int n,i;double rez, prod=1;cout<<“n=”;cin>>n;rez=subp(n);for (i=1;i<=n;i++) prod*=rez;cout<<prod;}

Page 7: Capitolul  SUBPROGRAME

Funcţia care calculează prima expresie este:

double subp(int n){double s=0; int i;for (i=1;i<=n;i++) s+=(float)1/i;return s;}

Antetul funcţiei este: double subp(int n)Funcţia se numeşte subp şi are parametrul n are un anumit tip, care precizează natura rezultatului are valori proprii – adică variabile care sunt definite în cadrul ei întoarce un anumit rezultat (în acest caz).

Page 8: Capitolul  SUBPROGRAME

Tipuri de parametri

Parametrii care se găsesc în apelul funcţiei se numesc parametri formali.

Atunci când scriem o funcţie nu cunoaştem valoarea propriu-zisă a parametrilor. Funcţia trebuie să întoarcă rezultatul corect, oricare ar fi valoarea lor. Din acest punct de vedere ei se numesc formali.

Page 9: Capitolul  SUBPROGRAME

Tipuri de parametri

Parametrii care se utilizează la apel se numesc parametri efectivi.

La apel, valorile sunt cunoscute. De aceea se numesc efectivi.

Pentru apelul rez=subp(n); parametrul efectiv este n.

Page 10: Capitolul  SUBPROGRAME

Structura funcţiilor şi apelul lor

O funcţie este alcătuită din: Antet – acesta conţine mai multe informaţii

importante necesare compilatorului: numele funcţiei, lista parametrilor formali, tipul rezultatului.

Page 11: Capitolul  SUBPROGRAME

Structura funcţiilor şi apelul lor

Stuctura antetului este:tip nume(lista parametrilor formali)

Lista parametrilor formali este de forma:

parametru1,parametru2,…parametrun

Există posibilitatea ca lista parametrilor formali să fie vidă.

Fiecare parametru are forma:tip nume

Page 12: Capitolul  SUBPROGRAME

Structura funcţiilor şi apelul lor

O instrucţiune compusă – aceasta cuprinde declaraţiile variabilelor locale ţi instrucţiunile propriu-zise.

O funcţie returnează rezultatul la întâlnirea instrucţiunii return, care este de forma:

return expresie;Trebuie ca tipul expresiei să coincidă cu tipul

funcţiei.

Page 13: Capitolul  SUBPROGRAME

Structura funcţiilor şi apelul lor

La întâlnirea instrucţiunii return, după atribuirea valorii, execuţia funcţiei se încheie şi se revine la funcţia care a apelat-o. În absenţa instrucţiunii return, execuţia funcţiei se încheie după execuţia ultimei instrucţiuni. În acest caz nu se întoarce nici o valoare.

Page 14: Capitolul  SUBPROGRAME

Structura funcţiilor şi apelul lor

O funcţie poate fi apelată de sine stătător (prin nume şi lista parametrilor efectivi), dar poate fi inclusă şi în cadrul expresiilor , caz în care, la evaluarea expresiei este apelată. Această formă de apel nu este valabilă în cazul funcţiilor de tip void.

Page 15: Capitolul  SUBPROGRAME

Declararea variabilelor

Sistemul de operare alocă fiecărui program trei zone distincte în memoria internă în care se găsesc memorate variabilele programului.

segment de date

segment de stivă

Heap

Page 16: Capitolul  SUBPROGRAME

Declararea variabilelor

segment de date

segment de stivă

Heap

Page 17: Capitolul  SUBPROGRAME

Declararea variabilelor

segment de date

segment de stivă

Heap

Page 18: Capitolul  SUBPROGRAME

Declararea variabilelor

Există posibilitatea ca variabilele să fie memorate într-un anumit registru al microprocesorului. În acest caz timpul de acces la astfel de variabile este foarte mic, deci se pot obţine programe optimizate

O variabilă se caracterizează prin 4 atribute:

1. Clasa de memorare;

2. Vizibilitate

3. Durata de viaţă

4. Tipul variabilei

Page 19: Capitolul  SUBPROGRAME

1. Clasa de memorare

Precizează locul unde este memorată variabila respectivă. O variabilă poate fi memorată în segmentul de date, în cel de stivă, în heap sau într-un registru al microprocesorului

Page 20: Capitolul  SUBPROGRAME

2. Vizibilitate

Precizează liniile textului sursă din care variabila respectivă poate fi accesată. Astfel avem:

Vizibilitate la nivel de bloc(instrucţiune compusă); Vizibilitate la nivel de fişier – în cazul în care

programul ocupă un singur fişier sursă; Vizibilitate la nivel de clasă – este în legătură cu

programarea pe obiecte.

Page 21: Capitolul  SUBPROGRAME

3. Durata de viaţă

Reprezintă timpul în care variabila respectivă are alocat spaţiul în memoria internă. Astfel avem:

Durata statică – variabila are alocat spaţiu în tot timpul execuţiei programului

Durata locală – variabila are alocat spaţiu în timpul în care se execută instrucţiunile blocului respectiv

Durată dinamică – alocarea şi dezalocarea spaţiului necesar variabilei respective se face de către programator prin operatori sau funcţii speciale.

Page 22: Capitolul  SUBPROGRAME

Variabilele globale

Se declară în afara corpului oricărei funcţii.

Variabilele a şi b sunt globale. În astfel de cazuri, variabilele respective pot fi utilizate de toate funcţiile care urmează în textul sursă declaraţiei variabilei respective. Din acest motiv, astfel de variabile se numesc globale.

La declarare, variabilele globale sunt iniţializate cu 0.

# include <iostream.h>int a;void t(){a=3;cout<<a;}int b;main(){b=4;cout<<a<<endl;t();}

Page 23: Capitolul  SUBPROGRAME

Atributele variabilelor globale sunt:

1. Clasa de memorare – segmentul de date.

2. Durata de viaţă a variabilelor globale este statică. Ele au spaţiu rezervat în tot timpul execuţiei programului.

Page 24: Capitolul  SUBPROGRAME

Atributele variabilelor globale sunt:

3. Vizibilitatea – În cazul în care declaraţiile acestora sunt înaintea tuturor funcţiilor, acestea sunt vizibile la nivelul întregului program(fişier). Dacă anumite funcţii se află plasate înaintea declaraţiilor acestor variabile, atunci ele sunt vizibile doar pentru funcţiile care sunt plasate după aceste declaraţii

Page 25: Capitolul  SUBPROGRAME

Variabilele locale

Sunt declarate în corpul funcţiilor.

Variabilele declarate în corpul funcţiei main() sunt tot locale

void t()

{int a=3;}

main()

{int b=4;}

Variabilele a şi b sunt locale

Page 26: Capitolul  SUBPROGRAME

Atributele variabilelor locale

1. Clasa de memorare a variabilelor locale este, implicit, segmentul de stivă. Există posibilitatea ca acestea să fie alocate în registrele microprocesorului, caz în care declaraţia lor trebuie precedată de cuvîntul cheie register.

register int b=4;

Page 27: Capitolul  SUBPROGRAME

Atributele variabilelor locale

Variabilele locale nu sunt iniţializate implicit cu 0. Dacă nu sunt iniţializate explicit de programator, ele reţin o valoare oarecare, numită valoare reziduală.

Page 28: Capitolul  SUBPROGRAME

Atributele variabilelor locale

2. Vizibilitatea variabilelor locale este la nivelul blocului la care au fost declarate

#include <iostream.h>int a;void t(){ int a=4; {int a=3; cout<<a<<endl; } cout<<a<<endl;}main(){a=5; t();cout<<a;}

Page 29: Capitolul  SUBPROGRAME

Atributele variabilelor locale

În cazul în care, într-un anumit bloc sunt vizibile mai multe variabile, toate cu acelaşi nume, dar au domenii de vizibilitate diferite, se accesează variabila cu vizibilitatea cea mai mică .

#include <iostream.h>int a;void t(){ int a=4; {int a=3; cout<<a<<endl; } cout<<a<<endl;}main(){a=5; t();cout<<a;}

Page 30: Capitolul  SUBPROGRAME

Atributele variabilelor locale

Dacă declarăm o variabilă locală în ciclul for ea este vizibilă doar în blocul for.

3. Durata de viaţă a variabilelor locale este atâta timp cât durează execuţia blocului respectiv.

int n=4, s=0;

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

cout<<s;

Page 31: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Care sunt parametrii formali şi cei efectivi din programul alăturat ?

#include<iostream.h>

int suma(int a, int b)

{ return a+b;}

main()

{

int c=4, d=3;

cout<<suma(2,3)<<endl;

cout<<suma(2+7,3-1*2)<<endl;

cout<<suma(c,d)<<endl;

cout<<suma(1.9,3.3)<<endl;

}

Page 32: Capitolul  SUBPROGRAME

Reguli în transmiterea parametrilor

Numărul parametrilor formali trebuie să coincidă cu numărul parametrilor efectivi.

#include<iostream.h>

int suma(int a, int b)

{ return a+b;}

main()

{

int c=4, d=3;

cout<<suma(2,3)<<endl;

cout<<suma(2+7,3-1*2)<<endl;

cout<<suma(c,d)<<endl;

cout<<suma(1.9,3.3)<<endl;

}

Page 33: Capitolul  SUBPROGRAME

Reguli în transmiterea parametrilor

Tipul parametrilor formali trebuie să coincidă cu tipul parametrilor efectivi sau tipul parametrilor efectivi să poată fi convertit implicit către tipul parametrilor formali la fel ca în cazul atribuirii.

#include<iostream.h>

int suma(int a, int b)

{ return a+b;}

main()

{

int c=4, d=3;

cout<<suma(2,3)<<endl;

cout<<suma(2+7,3-1*2)<<endl;

cout<<suma(c,d)<<endl;

cout<<suma(1.9,3.3)<<endl;

}

Page 34: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Numele parametrilor formali trebuie să coincidă cu numele parametrilor efectivi?

#include<iostream.h>

int suma(int a, int b)

{ return a+b;}

main()

{

int c=4, d=3;

cout<<suma(2,3)<<endl;

cout<<suma(2+7,3-1*2)<<endl;

cout<<suma(c,d)<<endl;

cout<<suma(1.9,3.3)<<endl;

}

Page 35: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Pentru memorarea parametrilor subprogramele folosesc segmentul de stivă.

Cine mai sunt memorate în segmentul de stivă?

Memorarea parametrilor transmişi se face în ordinea în care aceştia figurează în antet: de la stânga la dreapta.

Page 36: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Î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.

Page 37: Capitolul  SUBPROGRAME

Transmiterea parametrilor

stiva #include<iostream.h>

int suma(int a, int b)

{ return a+b;}

main()

{

int c=4, d=3;

cout<<suma(2,3)<<endl;

cout<<suma(2+7,3-1*2)<<endl;

cout<<suma(c,d)<<endl;

cout<<suma(1.9,3.3)<<endl;

}

2 3

a b

Page 38: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Se poate face

prin valoare

prin referinţă (adresă)

Page 39: Capitolul  SUBPROGRAME

Transmiterea parametrilor prin valoare

Se utilizează atunci când suntem interesaţi ca subprogramul să lucreze cu acea valoare, dar, în prelucrare, nu ne interesează ca parametrul efectiv (cel din blocul apelant) să reţină valoarea modificată în subprogram.

Page 40: Capitolul  SUBPROGRAME

Se pot transmite prin valoare

1. Valorile reţinute de variabile

Ce conţine stiva în timpul rulării programului?

#include<iostream.h>

void test(int n)

{ n+=1; cout<<n<<endl;}

main()

{

int n=1;

test(n);

cout<<n<<endl;

}

Page 41: Capitolul  SUBPROGRAME

Se pot transmite prin valoare

2. Expresii

Ce conţine stiva în acest caz?

#include<iostream.h>

void test(int n)

{cout<<n<<endl;}

main()

{

test(3);

test(3+4*5);

}

Page 42: Capitolul  SUBPROGRAME

Transmiterea parametrilor

Transmiterea prin valoare a tablourilor permite ca funcţiile să întoarcă noile valori ale acestora (care au fost atribuite în funcţii)

#include<iostream.h>

void vector (int x[10])

{ for (int i=0; i<10;i++) x[i]=1;}

main()

{

int a[10];

vector(a);

for(int i=0; i<10;i++) cout<<a[i]<<“ “;

}

Page 43: Capitolul  SUBPROGRAME

Transmiterea parametrilor prin referinţă

Se alege atunci când ne interesează ca la revenirea din subprogram variabila transmisă să reţină valoarea stabilită în timpul execuţiei programului.

Parametrii efectivi trebuie să fie referinţe la variabile

Subprogramul reţine în stivă adresa variabilei.

Page 44: Capitolul  SUBPROGRAME

Transmiterea parametrilor prin referinţă

La compilare, orice referinţă la variabila respectivă, este “tradusă” ca adresare indirectă.

#include<iostream.h>

void intersc (int &a, int &b)

{ int aux=a; a=b; b=aux;}

main()

{

Int x=2, y=3;

intersc(x,y);

cout<<x<<“ “<<y;

}

Page 45: Capitolul  SUBPROGRAME

Definirea unui subprogram

A defini un subprogram înseamnă a-l scrie efectiv.

A declara un subprogram înseamnă a-l anunţa.

Page 46: Capitolul  SUBPROGRAME

Definirea unui subprogram

Unde pot fi apelate funcţiile s1 şi s2 ?

#include<iostream.h>

void s1 ()

{ cout<<“Eu sunt functia s1”<<endl;}

void s2 ()

{

s1();

cout<<“Eu sunt functia s2”<<endl;}

}

main()

{

s1();

s2();

}

Page 47: Capitolul  SUBPROGRAME

Definirea unui subprogram

Prototipul are rolul de a declara o funcţie

#include<iostream.h>

void s2();

void s1 ()

{s2();

cout<<“Eu sunt functia s1”<<endl;}

void s2 ()

{

cout<<“Eu sunt functia s2”<<endl;}

}

main()

{

s1();

}

Page 48: Capitolul  SUBPROGRAME

Definirea unui subprogram

Putem scrie mai întâi prototipurile tuturor funcţiilor utilizate de program (fără main()) şi să le definim după funcţia main()

#include<iostream.h>

void s1 ();

void s2 ();

main()

{

s1();

}

void s1 ()

{s2 ();

cout<<“Eu sunt functia s1”<<endl;}

void s2 ()

{

s1();

cout<<“Eu sunt functia s2”<<endl;}

}

Page 49: Capitolul  SUBPROGRAME

Funcţii cu un număr variabil de parametri

Limbajul C++ ne permite să lucrăm cu funcţii care au un număr variabil de parametri.

Este obligatoriu ca cel puţin primul parametru să apară în lista parametrilor formali.

Pentru parametrii variabili antetul va conţine “…”

Page 50: Capitolul  SUBPROGRAME

Funcţii cu un număr variabil de parametri

Parametrii efectivi sunt depuşi, unul după altul, în ordinea în care i-am trecut în antet, în stivă. Dacă la adresa primului parametru adunăm 1, obţinem adresa parametrului următor. Parametri ficşi conţin informaţii despre cei variabili(numărul lor, în unele cazuri).

Page 51: Capitolul  SUBPROGRAME

Funcţii cu un număr variabil de parametri

Funcţia suma calculează suma parametrilor variabili care apar în antet. Parametrul fix precizează numărul de parametrii variabili.

#include<iostream.h>

int suma(int n,…)

{ int suma=0;

for(int i=1; i<=n; i++) suma+=*(&n+i);

return suma;

}

main()

{ cout<<suma(3,1,7,9)<<endl;

cout<<suma(5,1,2,0,9,7);

}

Page 52: Capitolul  SUBPROGRAME

Supraîncărcarea funcţiilor

Există posibilitatea ca mai multe funcţii să poarte acelaşi nume.

Ele trebuie să fie diferite fie ca număr de parametrii, fie ca tip. În acest caz, parametrii efectivi trebuie să nu poată fi convertiţi implicit către cei formali.

Page 53: Capitolul  SUBPROGRAME

Supraîncărcarea funcţiilor

#include<iostream.h>

void functia(int n)

{cout<<“ eu sunt functia cu un parametru de tip int”<<endl;

}

void functia(int n, int m)

{cout<<“ eu sunt functia cu doi parametri de tip int”<<endl;

}

void functia(int n)

{cout<<“ eu sunt functia cu un parametru de tip int*”<<endl;

}

main()

{ functia(2); functia(3,5);

int n; functia(&n)

}

Page 54: Capitolul  SUBPROGRAME

Supraîncărcarea funcţiilor

Compilatorul nu poate face distincţie între funcţiile de mai jos:

void functia(int n)

{cout<<“ eu sunt functia cu un parametru de tip int”<<endl;

}

void functia(float n)

{cout<<“ eu sunt functia care are un parametru de tip float”<<endl;

}