Informatică Pentru Clasa a X A

26
Informatică pentru clasa a X-a Cap. 1 Tehnica programării modularizate 1. Noţiunea de subprogram Prin subprogram se î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 un alt subprogram. Subprogramul este cea mai mică unitate de program care poate fi compilată separat. Exemplu : Se citeşte un vector cu n componente numere întregi. Se cere să se tipărească vectorul sortat. Această problemă poate fi rezolvată si clasic, utilizând funcţia main în care se vor realiza toate prelucrările necesare pentru rezolvarea problemei: - citeşte dimensiunea vectorului n - citeşte elementele vectorului - sortează vectorul utilizând unul din algoritmii cunoscuţi - afişează vectorul sortat De această dată vom încerca să rezolvăm problema utilizând tehnica programării modularizate, adică ”spărgând” problema în subprobleme mai mici care vor fi rezolvate, fiecare, de câte un subprogram. În acest caz, programul ar arăta astfel: - apelează subprogramul care citeşte dimensiunea şi elementele vectorului - apelează subprogramul care sortează vectorul - apelează subprogramul care afişează vectorul Utilizând acestă metodă, vom obţine următoarea structură de program: În structura modulară de mai sus am notat cu v vectorul supus prelucrării, iar cu n dimensiunea lui, adică numărul de elemente. În general, o problemă complexă se rezolvă mai uşor dacă o descompunem în altele mai simple; şansele de a greşi la scrierea unui subprogram sunt mai mici decât acelea de a greşi la scrierea unui program mare. Acesta din urmă rezultă din asamblarea subprogramelor la care se adaugă, eventual, câteva linii scrise în programul principal. Avantajele utilizării subprpogramelor sunt: - reutilizarea 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 putem rezolva mai uşor problema, eventual prin colaborarea unei echipe de programatori - reducerea numărului de erori care pot apărea la scrierea programelor - depistarea cu uşurinţă a erorilor : verificăm subprogramele, apoi modul în care le-am asamblat În limbajul C/C++ subprogramele sunt de tip funcţie, inclusiv funcţia main este un subprogram, primul care se execută la rularea unui program. 1 funcţia main() funcţia citire(v,n) funcţia sortare(v,n) funcţia scriere(v,n)

description

Informatică Pentru Clasa a X A

Transcript of Informatică Pentru Clasa a X A

  • Informatic pentru clasa a X-a

    Cap. 1 Tehnica programrii modularizate

    1. Noiunea de subprogram

    Prin subprogram se nelege un ansamblu alctuit din tipuri de date, variabile i instruciuni scrise n vederea unei anumite prelucrri (calcule, citiri, scrieri) i care poate fi utilizat (rulat) doar dac este apelat de un program sau de un alt subprogram.

    Subprogramul este cea mai mic unitate de program care poate fi compilat separat.Exemplu: Se citete un vector cu n componente numere ntregi. Se cere s se tipreasc vectorul sortat.

    Aceast problem poate fi rezolvat si clasic, utiliznd funcia main n care se vor realiza toate prelucrrile necesare pentru rezolvarea problemei:- citete dimensiunea vectorului n- citete elementele vectorului- sorteaz vectorul utiliznd unul din algoritmii cunoscui- afieaz vectorul sortat

    De aceast dat vom ncerca s rezolvm problema utiliznd tehnica programrii modularizate, adic sprgnd problema n subprobleme mai mici care vor fi rezolvate, fiecare, de cte un subprogram. n acest caz, programul ar arta astfel:- apeleaz subprogramul care citete dimensiunea i elementele vectorului- apeleaz subprogramul care sorteaz vectorul- apeleaz subprogramul care afieaz vectorulUtiliznd acest metod, vom obine urmtoarea structur de program:

    n structura modular de mai sus am notat cu v vectorul supus prelucrrii, iar cu n dimensiunea lui, adic numrul de elemente.

    n general, o problem complex se rezolv mai uor dac o descompunem n altele mai simple; ansele de a grei la scrierea unui subprogram sunt mai mici dect acelea de a grei la scrierea unui program mare. Acesta din urm rezult din asamblarea subprogramelor la care se adaug, eventual, cteva linii scrise n programul principal. Avantajele utilizrii subprpogramelor sunt:- reutilizarea 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 putem

    rezolva mai uor problema, eventual prin colaborarea unei echipe de programatori- reducerea numrului de erori care pot aprea la scrierea programelor- depistarea cu uurin a erorilor : verificm subprogramele, apoi modul n care le-am asamblat

    n limbajul C/C++ subprogramele sunt de tip funcie, inclusiv funcia main este un subprogram, primul care se execut la rularea unui program.

    1

    funcia main()

    funcia citire(v,n) funcia sortare(v,n) funcia scriere(v,n)

  • Informatic pentru clasa a X-a

    2. Structura funciilor i apelul lor

    2.1 Generaliti

    n esen, o funcie are structura:antetinstruciune compus

    a) Anteul conine mai multe informaii importante necesare compilatorului i anume: numele funciei, lista parametrilor formali, tipul rezultatului.Structura antetului este:

    tip nume(lista parametrilor formali)Lista parametrilor formali este de forma:

    parametru1,parametru2,..,parametrunFiecare parametru are forma:

    tip numeObservaie: Exist i posibilitatea ca lista parametrilor formali s fie vid.

    b) Instruciunea compus cuprinde declaraiile variabilelor locale i instruciunile propriu-zise care descriu operaiile realizate de ctre funcie.

    Observaii:- poate fi tip al unei funcii orice tip de dat cu excepia tablourilor- dac inem neaprat, exist posibilitatea ca funcia s ntoarc tablouri, dac acestea sunt

    nglobate n tipuri declarate cu struct, aa cum se va vedea ntr-un paragraf ulterior.Exemple de antete de func ii: - int suma(int a,int b) funcia se numete suma, returneaz un rezultat de tip int i are doi

    parametri formali de tip int, numii a i b- void t(int n,float v[20]) funcia se numete t, este de tip void (nu returneaz rezultat

    prin nume), are doi parametri formali, primul numit n, de tip int, al doilea numit v, de tip float* (pointer la float)

    - char* sir(int n,char a[200]) funcia se numete sir, ntoarce un pointer ctre un ir de caractere i are doi parametri formali, unul de tip int, numit n i altul de tip char* (pointer la ir de caractere) numit a

    - elev mana(int n,char n[200]) funcie de tip elev, unde elev este de tipul structur urmtor:

    struct elev{char nume[20];int varsta;

    };Observaii:- O funcie returneaz rezultatul la ntlnirea instruciunii return, care are forma return

    expresie; Trebuie ca tipul expresiei s coincid cu tipul funciei sau s poat fi convertit implicit ctre acesta. La ntlnirea instruciunii return, dup atribuirea valorii, execuia funciei se ncheie i se revine la funcia care a apelat-o. n absena instruciunii return, execuia funciei se ncheie dup execuia ultimei instruciuni. n acest caz nu se ntoarce nici-o valoare (cazul funciilor de tip void).

    - O funcie poate fi apelat de sine stttor (prin nume i lista parametrilor efectivi), dar poate fi inclus i n cadrul expresiilor, caz n care, la evaluarea expresiei este apelat. Acest ultim form de apel nu este valabil n cazul funciilor de tip void.

    Exemplu:#includeint prod(int x,int y){

    return x*y;}void main(){

    int x=4,y=9;printf(%d,7+prod(x,y));

    }

    2

  • Informatic pentru clasa a X-a

    Apelul funciei s-a realizat din interiorul expresiei 7+prod(x,y)Observaii:- n cadrul expresiei, apelul este un operand; el intr n calcul cu valoarea returnat de funcie- dup apelul funciei se continu evaluarea expresiei- la apel, ordinea de evaluare a parametrilor nu este definit; de exemplu, la apelul test(2-3,2+3) nu

    tim dac nainte se efectueaz scderea sau adunarea

    2.2 Declararea variabilelor

    2.2.1 Noiuni generale

    Pn n prezent am declarat variabile doar n corpul funciilor, inclusiv n cel al funciei main(). Variabilele astfel declarate se numesc locale. Sistemul de operare aloc fiecrui program trei zone distincte n memoria intern a calculatorului, n care se gsesc memorate variabilele programului. Harta simplificat a memoriei interne este prezentat n continuare:

    segment de datesegment de stiv

    heap

    Segmentul de date este folosit pentru stocarea codului programului aflat n execuie i pentru variabilele care sunt folosite de ctre acesta pe toat durata execuiei. Segmentul de stiv este utilizat pentru a realiza transferul parametrilor la apelul subprogramelor i pentru a controla execuia programului n cazul lucrului cu subprograme. Zona heap se numete i zon de accumulare a variabilelor dinamice i se folosete pentru alocarea variabilelor dinamice, create la cererea expres a programatorului, n timpul execuiei unui program.

    De asemenea, n limbajul C, 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 obine programe optimizate. Numrul variabilelor care pot fi memorate n regitrii interni este ns redus.

    n general o variabil se caracterizeaz prin patru atribute i anume:- clasa de memorare- vizibilitatea- durata de via- tipul variabilei, singurul studiat pn n acest moment

    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.

    Vizibilitatea precizeaz liniile textului surs din care variabila respectiv poate fi accesat. Astfel avem:- vizibilitate la nivel de bloc (instruciune compus)- vizibilitate la nivel de fiier, n cazul n care programul ocup doar un singur fiier surs (singurul

    caz tratat momentan)- vizibilitate la nivel de clas, legat de programarea orientat pe obiecte, facilitate specific n C++

    Durata de via reprezint timpul n care variabila respectiv are alocat spaiu n memoria intern (deci exist efectiv). Astfel avem:- durat static, conform creia variabila are alocat spaiu n tot timpul execuiei programului- durat local, conform creia variabila are alocat spaiu n timpul n care se execut nstruciunile

    blocului respectiv (blocul care conine declaraia variabilei)- durat dinamic, caz n care alocarea i dealocarea spaiului necesar variabilei respective se face

    explicit de ctre programator, n timpul execuiei programului, prin folosirea unor operatori i funcii speciale (de exemplu, new, malloc() etc.)

    n limbajul C/C++ variabilele pot fi mprite n trei mari categorii: locale, globale i dinamice.

    2.2.2 Variabile globale

    Aceste variabile se declar n afara corpului oricrei funcii, ca n exemplul urmtor:#includeint a;void t()

    3

  • Informatic pentru clasa a X-a

    {a=3;printf(%d,a);

    }int b;void main(){

    b=4;printf(%d,b);t();

    }Variabilele a i b sunt globale. Ele pot fi utilizate de toate funciile care urmeaz n textul surs

    declaraiei variabilei respective. Deoarece pot fi utilizate, deci implicit i modificate, de toate funciile care succed momentul declaraiei, aceste variabile se numesc globale.

    Observaie: La declarare, variabilele globale sunt iniializate de ctre compilator cu 0.

    Atributele variabilelor globale sunt:- clasa de memorare este segmentul de date- vizibilitatea: sunt vizibile n toate funciile care le succed; n exemplul anterior, a poate fi acccesat

    din corpul oricrei funcii, n timp ce variabila b poate fi accesat numai din funcia main- durata de via este static, adic au spaiu de memorie rezervat n tot timpul execuiei programului

    2.2.3 Variabile locale

    Aceste variabile sunt declarate n corpul funciilor, mai precis, pot fi declarate n orice bloc (instruciune compus) al acestora.

    Observaie: Variabilele declarate n funcia main() sunt tot variabile locale, deci sunt vizibile numai n aceast funcie.

    n exemplul urmtor, variabila a este declarat n corpul funciei t(), iar variabila b este declarat n corpul funciei main():

    void t(){

    int a=3;printf(%d,a+2);

    }void main(){

    int b=4;printf(%d,b--);

    }Atributele variabilelor locale sunt:

    - clasa de memorare este, implicit, segmentul de stiv. Exist posibilitatea ca acestea s fie alocate i n registrele microprocesorului, caz n care declaraia lor trebuie precedat de cuvntul cheie register, ca n exemplul urmtor: register int b=4;

    - vizibilitatea variabilelor locale este la nivelul blocului n care au fost declarate.- durata de via a variabilelor locale este att timp ct dureaz execuia blocului respectiv, adic

    este local

    Observaie: Variabilele locale nu sunt iniializate implicit de ctre compilator cu 0, aceast sarcin revenind programatorului. n cazul n care iniializarea este omis, ele conin o valoare oarecare numit valoare rezidual care poate duce la rezultate eronate.

    Exemplul 1: n funcia urmtoare am declarat dou variabile de tip int, numite b i c. Variabila b este vizibil la nivelul funciei, dar variabila c este vizibil doar la nivelul blocului n care a fost declarat. Ambele sunt variabile locale alocate pe segmentul de stiv.

    void func(){

    int b=7; // vizibila in toata functia{

    4

  • Informatic pentru clasa a X-a

    int c=9; // vizibila numai in acest bloc (instr.compusa)printf(%d %d,b,c);

    }}

    Exemplul 2: n programul urmtor am declarat trei variabile, toate numite a. Una este global, iar dou sunt locale, dar declarate n blocuri diferite.

    #includeint a; // variabila globala,vizibila in orice punct din programvoid func(){

    int a=4; // variabila locala,vizibila in toata functia {

    int a=3; // variabila locala,vizibila numai in acest blocprintf(%d,a); // tipareste a=3a+=2;

    }printf(%d,a); // tipareste a=4a++;

    }void main(){

    a=5; // refera variabila globala afunc();printf(%d,a); // tipareste a=5

    }Observa ie : n cazul n care, ntr-un anumit bloc sunt vizibile (se pot accesa) mai multe variabile cu acelai nume, dar cu domenii de vizibilitate diferite, se acceseaz variabila cu vizibilitatea cea mai mic. Este cazul variabilei a din blocul interior funciei func() pentru care se consider cea mai mic vizibilitate (cea de bloc) i se tiprete valoarea 3.

    Observaie: Durata de via a unei variabile locale poate fi modificat folosind atributul static, astfel nct, dei respectiva variabil nu este recunoscut n afara funciei, ea nu moare adat cu revenire dintr-un apel. Cu alte cuvinte, apeluri succesive vor regsi, fiecare, valoarea lsat de apelul anterior.Exemplu: n urma execuiei programului urmtor, variabila m va avea valoarea 3, deoarece cele dou apeluri succesive ale funciei f() vor returna valorile 1, respectiv 2, variabila local a avnd atributul static.

    #includeint f(){

    static int a=1;return a++;

    }void main(){

    int m;m=f()+f();printf(%d,m);

    }

    2.3 Transmiterea parametrilor

    Parametrii care se gsesc n antetul funciei se numesc parametri formali, iar cei care se gsesc n instruciunea de apel se numesc parametri efectivi.Exemplu: Funcia urmtoare calculeaz suma a dou numere naturale.

    #includeint suma(int a,int b){

    return a+b;}void main()

    5

  • Informatic pentru clasa a X-a

    {int c=4,d=3;printf(%d\n,suma(2,3));printf(%d\n,suma(2+7,3-1*2);printf(%d\n,suma(c,d);printf(%d\n,suma(1.9,3.3);

    }Parametrii formali ai funciei sunt a i b. Funcia este apelat de mai multe ori. Parametrii

    efectivi sunt pe rnd:- 2, 3- 2+7, 3-1*2- c, d- 1.9, 3.3 Dup fiecare apel al funciei se tiprete suma obinut. ntre parametrii formali i cei efectivi trebuie s existe o anumit concordan care este descris prin regulile urmtoare:- Numrul parametrilor formali trebuie s coincid cu numrul parametrilor efectivi. La aceast regul

    exist i excepii. n exemplul dat numrul parametrilor formali este 2, iar cel al parametrilor efectivi tot 2.

    - Tipul parametrilor efectivi trebuie s coincid cu tipul parametrilor formali sau tipul parametrilor efectivi s poat fi convertit implicit ctre tipul parametrilor formali. La apelul suma(2,3); parametrii efectivi sunt constante de tip ntreg i coincid cu tipul parametrilor formali. La apelul suma(2+7,3-1*2); parametrii efectivi sunt expresii de tip ntreg. n acest caz, nainte de apel se evalueaz expresiile respective. La apelul suma(c,d); parametrii formali sunt variabile de tip ntreg date prin valorile lor. La apelul suma(1.9,3.3); parametrii efectivi sunt constante de tip real care se convertesc la tipul int prin trunchiere i suma calculat este 1+3=4.

    Observaie: Nu este obligatoriu ca numele parametrilor formali s coincid cu numele parametrilor efectivi i, n multe situaii nici nu este recomandabil, pentru a evita confuziile.

    n momentul lansrii n execuie a unei funcii (la apel), parametrii efectivi se transmit funciei apelate dup urmtoarele reguli:- Pentru memorarea parametrilor efectivi subprogramele folosesc segmentul de stiv, ntocmai ca

    pentru variabilele locale.- Memorarea parametrilor efectivi transmii se face n ordinea n care acetia figureaz n antet, de

    la stnga spre dreapta.- n cadrul subprogramului, parametrii transmii n momentul apelului i memorai pe stiv sunt

    variabile. Numele lor este cel din lista parametrilor formali. Aceste variabile se comport ca nite variabile locale subprogramului, deci nu sunt vizibile n afara funciei i exist ct timp funcia este n execuie.

    - La revenirea n blocul apelant, coninutul variabilelor memorate pe stiv se pierde, durata de via a variabilelor locale fiind local.

    Exist dou mecanisme de transmitere a parametrilor, transmiterea prin valoare i transmiterea prin referin.

    2.3.1 Transmiterea prin valoare

    Se utilizeaz atunci cnd suntem interesai ca subprogramul s lucreze cu acea valoare, dar s nu poat modifica parametrul efectiv corespunztor din blocul apelator. Se pot transmite prin valoare:

    1. Valorile reinute de variabile. n acest caz parametrii efectivi trebuie s fie numele variabilelor. Exemplu:

    #includevoid test(int n){

    n++;printf(n=%d\n,n); // tipareste n=8

    }void main(){

    int n=7;test(n);printf(n=%d\n,n); // tipareste n=7

    }

    6

  • Informatic pentru clasa a X-a

    Parametrul n este transmis prin valoare. n funcia main() acest parametru este iniializat cu valoarea 7. Cnd apelm funcia test(), se rezerv spaiu pe stiv, spaiu care are numele parametrului formal (n acest caz, tot n) i care este iniializat cu valoarea memorat de variabila n a programului principal. Altfel spus, pe stiv se copie valoarea parametrului efectiv de apel. n funcie, variabila n (care este local acestei funcii) este incrementat i devine 8, valoare care va fi tiprit. La ieirea din funcie, variabila n din stiv se pierde, adic nu mai are spaiu alocat, prin urmare valoarea 8 este pierdut. n main() se tiprete valoarea variabilei n (local acesteia) care are valoarea 7.

    Pentru exemplul anterior, coninutul stivei, n momentul apelului i dup execuia funciei test(), este urmtorul:

    Se observ c, n momentul apelului funciei test(), pe stiv sunt alocate dou variabile cu acelai nume n. Prima variabil este variabila local funciei main() care se salveaz pe stiv n momentul apelului pentru a putea reface contextul funciei main() dup ncheierea apelului. A doua variabil este parametrul formal tip valoare n, vizibil numai n funcia test() i iniializat n momentul apelului cu valoarea 7. Indiferent ce valori primete acest n n corpul funciei test(), dup ncheierea execuiei acestei funcii, spaiul su este dealocat din stiv, adic variabila respectiv este distrus. Din acest motiv, dup execuia funciei test(), coninutul stivei este cel din dreapta. Se reface contextul din care s-a lansat apelul funciei test(), adic se recupereaz din stiv valoarea variabilei locale n=7 i adresa de revenire, adic adresa instruciunii printf.

    2. Expresii. n acest caz, parametrii efectivi sunt expresii, care pot conine i funcii i care mai nti se evalueaz. Exemplu:

    #include#includevoid test(int n){

    printf(n=%d\n,n);}void main(){

    test(5); // se va tipari 5test(7+(int)sqrt(45)); // se va tipari 13

    }n funcie se creaz o variabil numit n, reinut pe stiv, care la primul apel va primi valoarea 5 i la al doilea apel valoarea 13. La ieirea din funcie coninutul acestei variabile se pierde.

    Transmiterea parametrilor prin valoare se utilizeaz cnd nu dorim ca subprogramul apelat s poat modifica parametrii efectivi de apel. Acesta este modul implicit de transmitere a parametrilor n limbajul C. Dac nu ar exista dect transmiterea prin valoare, ar fi imposibil s modificm valoarea anumitor valori care sunt declarate n blocul apelator. Acest lucru este totui posibil dac lucrm cu variabile de tip pointer, care, aa cum tim deja, conin adresele de memorie ale altor variabile din program. Avnd acces la locaia de memorie a unei variabile (prin adresa ei), i putem desigur modifica coninutul. Funcia urmtoare realizeaz interschimbarea valorilor a dou variabile din programul principal. Pentru a putea face acest lucru, funcia primete adresele de memorie ale celor dou variabile, adic doi pointeri.

    #includevoid schimba(int *x,int *y){

    int aux;

    7

    n=7, parametru valoare de apel, local funciei

    testn=7 , var. local funciei

    main()adresa de revenire din

    funcia test

    n momentul apelului

    n=7 , var. local funciei main()

    adresa de revenire din funcia test

    dup execuia funciei test

    adresa(n)

  • Informatic pentru clasa a X-a

    aux=*x;*x=*y;*y=aux;

    }void main(){

    int a=7, b=12;schimba(&a,&b);printf(a=%d\t b=%d,a,b); // tipareste a=12, b=7

    }Se observ c parametrii formali sunt doi pointeri la ntreg care n momentul apelului primesc ca valori adresa variabilei a, respectiv b (obinute prin aplicarea operatorului &). n limbajul C acesta este singurul mod prin care se pot transmite parametrii prin adres, deci modifica de ctre un subprogram apelat.

    Pentru exemplul anterior, evoluia stivei este:

    n cazul transmiterii prin adres, pe stiva procesorului se depun, pe lng adresa de revenire i valorile variabilelor locale funciei main(), necesare pentru a reface contextul din care s-a fcut apelul, i adresele de memorie ale parametrilor efectivi corespunztori. Dei pointerii x i y sunt locali funciei schimb() i sunt dealocai de pe stiv n momentul n care execuia acestei funcii se ncheie, orice modificare a locaiilor de memorie adresate de aceti pointeri se pstreaz i dup ncheierea apelului. Din acest motiv, dup execuia funciei schimb(), coninutul stivei este cel din dreapta. Valorile variabilelor a i b, locale funciei main(), au fost modificate n timpul execuiei funciei schimba() care a avut acces la adresele lor de memorie. La revenirea din funcie, se recupereaz din stiv noile valori ale variabilelor a i b, adresa instruciunii printf i se continu execuia funciei main().

    Observaie: Exist o excepie de aceast regul, i anume, cnd parametrul este un tablou. n C, numele unui tablou este un pointer ctre componentele tabloului. Cnd transmitem prin valoare un tablou, ceea ce primete subprogramul este un pointer ctre elementele acestuia, adic adresa de nceput a tabloului n memorie. Avnd acces la aceast adres, subprogramul poate modifica valorile reinute n tablou. Practic, n cazul tablourilor, transmiterea prin valoare devine transmitere prin adres.

    2.3.2 Transmiterea tablourilor ctre funcii

    Fie urmtorul fragment de program:void main(){

    int a[10];......func(a); // apelul unei functii cu parametrul a.....

    }Dac o funcie primete un tablou unidimensional, atunci parametrul formal al acesteia poate fi declarat n trei moduri: ca pointer, ca tablou dimensionat sau ca tabloul nedimensionat. De exemplu, putem declara funcia func() n urmtoarele moduri:

    void func(int *x) // parametru formal de tip pointer{

    8

    y=&b, parametru formal de tip pointer, local funciei schimba()x=&a, parametru formal de tip pointer, local funciei schimba()b=12, variabil local funciei main()a=7, variabil local funciei main()adresa de revenire din funcia schimba()

    n momentul apelului funciei schimba()

    b=7, variabil local funciei main()

    a=12, variabil local funciei main()

    adresa de revenire din funcia schimba()

    dup execuia funciei schimba()

    adresa(a)

    adresa(b)

  • Informatic pentru clasa a X-a

    }

    sau ca:void func(int x[10]) // tablou dimensionat{

    ..}

    sau ca:void func(int x[]) // tablou nedimensionat{

    }

    Toate cele trei metode de declarare determin rezultate asemntoare, deoarece indic compilatorului c urmeaz s fie primit un pointer la ntreg. Dimensiunea tabloului nu conteaz din punctul de vedere al funciei, deoarece C nu verific depirea limitelor unui tablou. Din punct de vedere funcional, declaraia:

    void func(int x[32]){

    ......}

    este de ademenea funcional, deoarece compilatorul C genereaz un cod care cere funciei func() s primeasc un pointer la ntreg, fr a crea efectiv un tablou cu 32 de elemente.

    Metoda de transmitere este aceeai i cnd un tablou bidimensional este folosit ca argument al unei funcii. n acest caz se transmite efectiv numai pointerul ctre primul element. Cu toate acestea, parametrul care primete un tablou bidimensional trebuie s defineasc mcar dimensiunea din dreapta a tabloului. Aceasta deoarece compilatorul C trebuie s cunoasc lungimea fiecrui rnd pentru a aplica corect indicii fiecrui termen al matricii. De exemplu, o funcie care primete o matrice de 10*10 ntregi va fi declarat astfel:

    void func(int x[][10]){

    ....}

    Se poate preciza i dimensiunea din stnga, dar nu este absolut necesar.

    2.3.3 Transmiterea structurilor ctre funcii

    Cnd membrul unei structuri este transmis unei funcii, ceea ce se transmite funciei este de fapt valoarea acelui membru. Ca atare, se transmite doar o variabil. Fie structura urmtoare:

    struct info{

    char x;int y;float z;char s[10];

    }set;Iat exemple de transmitere ale fiecrui membru ctre o funcie:

    func(set.x); // transmite valoarea caracter a lui xfunc(set.y); // transmite val. intreaga a lui yfunc(set.z); // transmite val. virgula mobila a lui zfunc(set.s); // transmite adresa sirului sfunc(set.s[3]); // transmite val. tip caracter a lui s[3]

    Dac dorim s transmitem adresa unui anumit membru al unei structuri, inserm operatorul & naintea numelui structurii.

    func(&set.x); // transmite adresa caracterului xfunc(&set.y); // transmite adresa intreagului yfunc(&set.z); // transmite adresa variabilei float zfunc(set.s); // transmite adresa sirului sfunc(&set.s[3]); // transmite adresa caracterului s[3]

    Cnd o structur este folosit ca argument al unei funcii, se va efectua transmiterea ntregii structuri, folosind metoda standard a apelului prin valoarea. Aceasta nseamn c structura nu va putea fi modificat. Tipul structurii trebuie s coincid cu tipul parametrului formal care primete structura. Din

    9

  • Informatic pentru clasa a X-a

    acest motiv, declaraia tipului structurii trebuie s aib caracter global, pentru a putea fi folosit de ctre toate funciile din program, ca n exemplul urmtor:

    #includestruct data{

    int a,b;char ch;

    }; // declaratie globala de tipvoid func(data x) // foloseste tipul global{

    printf(%d,x.a);}void main(){

    data arg; // foloseste tipul globalarg.a=157;func(arg);

    } Deoarece limbajul C permite declararea pointerilor ctre structuri, putem modifica un argument de tip structur folosind mecanismul transmiterii prin adres, cu ajutorul pointerilor ca n exemplul urmtor:

    #includestruct ora{

    int ore;int minute;int secunde;

    }; // declaratie globalavoid func(ora *p) // pointer la structura globala{

    .}void main(){

    ora arg;....func(&arg); // transmite adresa structurii

    }Observaie: Poate fi tip al unei funcii orice tip de dat cu excepia tablourilor. Dac inem neaprat, exist posibilitatea ca funcia s ntoarc tablouri, dac acestea sunt nglobate n tipuri declarate cu struct, aa cum se arat n exemplul urmtor:

    #includestruct mat{

    float matrice[6][8];};mat citire(int m,int n){

    mat a;int i,j;for(i=0;i

  • Informatic pentru clasa a X-a

    2.3.4 Transmiterea prin referin

    n limbajul C++ exist un tip special de date care permite ca o variabil s fie identificat prin mai multe nume, tip numit referin. Aparent, programul lucreaz cu mai multe variabile, dar de fapt toi identificatorii respectivi refer aceeai locaie de memorie. Declararea unei variabile de tip referin se face cu sintaxa:

    tip& nume variabil=valoare de iniializare;n programul urmtor, variabila x este o referin pentru variabila y. Ele au aceeai valoare i aceeai adres de memorie, dar poart nume diferite.

    #includevoid main(){

    int x=7;int& y=x; // sau int x=7, &y=a;printf(x=%d si are adresa %p\n,x,&x);printf(y=%d si are adresa %p\n,y,&y);

    }n cazul subprogramelor, parametrii sunt transmii prin referin atunci cnd ne intereseaz ca

    la revenirea din subprogram variabila transmis s rein valoarea stabilit n timpul execuiei subprogramului.

    n cazul transmiterii prin referin parametrii formali trebuie s fie referine la variabile. n acest caz subprogramul reine pe stiv adresa variabilei transmis prin referin i avnd acces la adresa de memorie a parametrului efectiv corespunztor, l poate modifica.Exemplu: Programul urmtor interschimb valorile a dou variabile transmise prin referin.

    #includevoid schimba(int &a, int &b){

    int aux=a; a=b; b=aux;}void main(){

    int x=7, y=5;schimba(x,y);printf(x=%d\ty=%d\n,x,y);

    }Conclu zii : a) n momentul n care ntr-un subprogram este ntlnit instruciunea de apel a unui alt subprogram, controlul execuiei este cedat subprogramului apelat i pe stiv se depun, n ordine:- adresa de revenire din subprogramul apelat- valorile variabilelor locale subprogramului apelator- valorile parametrilor transmii prin valoare- adresele parametrilor transmii prin referinb) Revenirea din subprogramul apelat se face fie la ntlnirea instruciunii return (cazul funciilor care returneaz un rezultat de un anumit tip), fie la ntlnirea acoladei care ncheie instruciunea compus a subprogramului apelat (cazul funciilor de tip void)c) La ncheierea execuiei subprogramului apelat se recupereaz din stiv, n ordine, valorile variabilelor locale subprogramului apelator i adresa de revenire, adic se reface contextul din care s-a fcut apelul.

    2.4 Definirea i declararea unui subprogram

    Dei aparent asemntoare, cele dou noiuni difer. A defini un subprogram, nseamn a-l scrie efectiv (antet i instruciune compus). Este foarte important locul n care se definete un subprogram. A declara un subprogram, nseamn a-l anuna. Un subprogram nedeclarat nu poate fi folosit. Definiia unui subprogram ine loc i de declaraie.Exemplu: Programul urmtor conine dou funcii f1 i f2. Definiiile ambelor funcii se gsesc naintea funciei main() i din acest motiv ele pot fi apelate din main(). Definiia funciei f1 este naintea definiiei

    11

  • Informatic pentru clasa a X-a

    lui f2, deci funcia f1 poate fi apelat din f2, n schimb, din f1 nu poate fi apelat f2 pentru c declaraia acesteia i succede lui f1.

    #includevoid f1(){

    printf(functia f1\n);}void f2(){

    f1();printf(functia f2\n);

    }void main(){

    f1(); f2();

    }Dac dorim ca f1 s poat apela funcia f2 folosim prototipul funciei care este antetul acesteia urmat de punct i virgul. Prototipul are rolul de a declara o funcie i nu conine definiia acesteia.Exemplu:

    #includevoid f1(); // prototip f1void s2(); // prototip f2void main(){

    f1();}void f1() // definitia lui f1{

    f2();printf(functia f1\n);

    }void f2() // definitia lui f2{

    f1();printf(functia f2\n);

    }Observaie: n prototipul unei funcii se poate omite numele parametrilor formali, precizndu-se numai tipul acestora. Spre exemplu, este corect un prototip de forma float func(int, int&); care declar o funcie cu rezultat de tip float si doi parametri, unul valoare de tip int i unul referin la int.

    n C++ este o practic uzual s se scrie mai nti prototipurile tuturor funciilor utilizate n program, fr funcia main(), iar dup funcia main() s fie definite aceste funcii. n acest fel, orice funcie, mai puin main(), poate fi apelat din oricare alta.

    2.5 Funcii cu numr variabil de argumente

    O facilitate important a limbajului C este posibilitatea utilizrii funciilor cu un numr variabil de argumente. Este obligatoriu ca cel puin primul parametru s apar n lista parametrilor formali. Pentru parametrii variabili antetul va conine . Parametrii efectivi sunt depui, unul dup altul, n ordinea declarrii n antet, n stiv. Dac la adresa primului parametru adunm 1, obinem adresa urmtorului parametru i aa mai departe. De regul, parametrii fici conin informaii despre cei variabili (numrul lor, n unele cazuri tipul lor).

    n exemplul urmtor, funcia f are un numr neprecizat de parametri, aspect semnalat prin prezena celor trei puncte dup parametrul fix n n antetul funciei. Accesarea parametrilor actuali n momentul apelului se bazeaz pe faptul c parametrii se memoreaz la adrese consecutive n stiv. Astfel, se pleac de la adresa ultimului parametru fix, n acest exemplu &n. Valoarea &n+1 reprezint adresa urmtorului parametru, adic a primului parametru variabil, &n+2 este adresa celui de-al doilea parametru variabil etc. n felul acesta, valorile care vor aprea la apel dup parametrii fici vor putea fi

    12

  • Informatic pentru clasa a X-a

    accesai printr-un calcul obinuit de adrese i funcia va returna maximul dintre elementele vectorului x, adic 23.

    #includeint f(int n,){

    int *x=&n+1, m=x[0], j;for(j=1;jm? m=x[j]: m=m;return m;

    }void main(){

    printf(%d,f(4,12,11,23,2);}Un alt aspect important referitor la funciile limbajului C este posibilitatea de a iniializa

    parametrii formali ai unei funcii direct n antetul acesteia. n acest situaii, la apelul funciei pot s lipseasc unul sau mai muli parametri actuali, chiar toi parametrii. n cazul n care la apel lipsete un parametru actual, compilatorul va folosi n funcie valoarea cu care a fost iniializat la declarare parametrul formal aferent.Exemplu: Programul urmtor este corect i va afia valorile m=6, n=15, p=34 i q=52.

    #includeint f(int a=1,int b=2,int c=3){

    return a+b+c;}void main(){ int m,n,p,q; m=f(); n=f(10); p=f(12,19); q=f(11,23,18); printf(%5d%5d%5d%5d,m,n,p,q);}

    2.6 Folosirea funciilor ca parametri de apel

    Limbajul C permite transmiterea funciilor ca parametri de apel pentru alte funcii. Numele funciei este dat ca parametru prin intermediul unui pointer ctre funcie. Considerm programul urmtor:

    #include#includefloat ma(int x,int y){

    return (x+y)/2.;}float mg(int x,int y){

    return sqrt(x*y);}void calcul(int x,int y,float (*f)(int,int)){

    printf(%.1f,f(x,y));}void main(){

    int a,b;scanf(%d %d,&a,&b);if(a>=b) calcul(a,b,ma);

    13

  • Informatic pentru clasa a X-a

    else if(a>0 && b>0) calcul(a,b,mg);}n acest exemplu, funcia calcul are un antet mai deosebit. Primii doi parametri sunt doi ntregi x

    i y. Al treilea parametru, float (*f)(int,int) , reprezint un pointer ctre o funcie f. Aceast funcie f are la rndul ei doi parametri de tipul int. Nu este necesar s se precizeze numele acestor parametri, ci doar tipul lor. Instruciunea printf(%.1f,f(x,y)); din corpul funciei f afieaz valoarea ntoars de funcie. n funcia main() se fac apelurile: calcul(a,b,ma);, respectiv calcul(a,b,mg);. La apel, al treilea parametru din antet (pointerul la funcie), este nlocuit cu numele unei funcii, ma, respectiv, mg. Aceste funcii au fost scrise anterior. Spre exemplu, dac se citesc valorile a=7 i b=6, identificatorul f este nlocuit cu ma, se calculeaz media aritmetic a parametrilor x i y i se tiprete valoarea 6.5. Dac se citete a=2 i b=8, identificatorul f se nlocuiete cu mg, se calculeaz media geometric a parametrilor x i y i se tiprete valoarea 4.

    3. Exemple de aplicaii care folosesc subprograme

    Exemplul 1: Se citesc dou numere ntregi m i n. S se tipresc numerele prime aflate n intervalul [m,n].

    Pentru a verifica primalitatea unui numr din intervalul dat vom folosi o funcie care returneaz 1 dac numrul respectiv este prim, i 0 n caz contrar.

    #include#includeint prim(int x){

    int i;for(i=2;i

  • Informatic pentru clasa a X-a

    int i;printf("n="); scanf("%d",&n);for(i=0;ib)

    a-=b;else

    b-=a;return a;

    }Exemplul 3: Se citesc dou numere naturale m i n, m

  • Informatic pentru clasa a X-a

    void main(){

    int m,n,a[10][10],i,j;citire(m,n,a);printf("\n\t Matricea citita este:\n");for(i=0;i

  • Informatic pentru clasa a X-a

    b) o vitez mai mare n execuia programului

    c) posibilitatea de a executa de mai multe ori instruciunile cuprinse ntr-o funcie

    d) un program care conine funcii poate fi urmrit i corectat mai uor

    e) nici unul dintre avantajele de mai sus8. Deducei irul de valori care se afieaz n urma execuiei programului de mai jos:#includeint i,j,k;int test(int x,int y){

    return (x-y);}void calcul(int p,int q){

    int u,v;u=p-i; v=q+j;i=test(u,q);j=test(v,p);

    }void main(){

    i=2; j=3;calcul(i,,j);printf(%3d %3d,i,j);calcul(j,i);printf(%3d %3d\n,i,j);

    }a) 2 3 2 3 b) 3 2 3 2c) 2 3 3 4 d) 3 4 4 3e) 3 4 10 3

    9. Cte erori va produce execia programului urmtor?#include#includeint calcul(int p,int q){

    return(sqrt(p*q)); }void main(){

    printf(%d,calcul(1,2));}

    a) una b) dou c) treid) patru e) nici una

    10. Considerm programul urmtor:#includeint m;void p(int& c){

    int b;b=3*m; c=b+2; m+=3;printf(%6d,m); // (5)printf(%6d %6d\n,b,c);//(6)

    }void main(){

    m=3; p(m); // (1)p(3); // (2)

    printf(%6d,m); // (3)printf(%6d %6d,b,c); // (4)

    }Care dintre urmtoarele afirmaii sunt adevrate?

    a) n cursul execuiei primului apel al funciei p, cel din linia (1), se vor afia, n ordine, valorile 14,9,14 (liniile (5) i (6))

    b) cele dou apeluri ale funciei p, din liniile (1) i (2), sunt corecte i echivalente (produc acelai rezultat n orice situaie)

    c) linia (3) afieaz valoarea 14d) linia (4) afieaz valorile 9 i 14e) la fiecare execuie a funciei p, se

    salveaz pe stiv valoarea lui c

    11. Ce valori va afia programul urmtor?#includeint n,m;void t(int n,int& m){

    n+=2; m--;}void main(){

    n=2; m=5;t(n,m);printf(%d %d,n,m);n=10; m=20;t(n,m);printf(%d %d,n,m);

    }a) 4 4 12 19 b) 4 5 12 20c) 2 4 10 19 d) 2 5 10 20e) 7 2 22 10

    12. Precizai ce se va afia n urma execuiei programului de mai jos:#includeint v[2],i;void test(int x[],int k){

    x[k]=0;}void main(){

    v[0]=1; v[1]=2;for(i=0;i

  • Informatic pentru clasa a X-a

    void main(){

    x=2;printf(%d,test(x,x+3);//(1)printf(%d,x); //(2)

    }int test(int a,int b){

    int x=a+b;for(j=1;ja && j

  • Informatic pentru clasa a X-a

    x=x/2; nr++;}while(x>0);

    }void main(){

    int m,n;scanf(%d,&m);n=0;F(n,m);printf(%d,n);

    }a) 12 b) 13 c) 14 d) 15 e) 16

    19. Precizai care dintre funciile de mai jos returneaz 1 dac numrul x este prim, 0 n caz contrar.

    a) int p(int x){

    int j,ok;for(j=2;j

  • Informatic pentru clasa a X-a

    d) 1 i 43 e) 43 i 1

    23. Considerm urmtorul program:#include#includeint *f(int *a,int *b){

    return (*a>=*b)? a:b;}void main(){ int *x,*y; x=(int*)malloc(sizeof(int));//(1) y=(int*)malloc(sizeof(int));//(2) scanf(%d %d,x,y); //(3) printf(%d,*f(x,y)); //(4) free(x); //(5) free(y); //(6)}n timpul execuiei programului sunt posibile urmtoarele situaii:

    a) funcia nu returneaz corect valoarea dorit, deoarece tipul valorii returnate nu este cel definit n antetul funciei

    b) n locul liniilor (1) i (2), pentru alocarea dinamic a memoriei putem scrie x=y=(int*)malloc(sizeof(int));

    c) n locul liniilor (5) i (6), pentru eliberarea memoriei alocate putem scrie free(x,y);

    d) instruciunea scanf din linia (3) este eronat; corect era scanf(%d,&x, &y);, deoarece numele variabilelor citite trebuie precedat n scanf de operatorul &

    e) programul este n totalitate corect, el afind astfel maximul a dou numere ntregi definite cu ajutorul pointerilor x i y

    24. Deducei ce numere va afia programul urmtor:#includeint& f(int a,int b,int& c){

    c=a+b;return c;

    }void main(){

    int x=2,y=3,z=11;printf(%d,f(x,y,z));printf(%d,z);f(x,y,z)=9;printf(%d,z);

    }a) 5,11,5 b) 5,11,9 c) 5,11,11d) 5,11,9 e) 5,5,9

    25. Ce valoare se va afia n urma execuiei programului urmtor?#include

    int f(int a=5,int b=2){

    return -a+2*b++;}void main(){

    printf(%d,f());}

    a) 7 b) 8 c) 9 d) 10 e) 11

    26. Se consider programul urmtor:#includeint f(int x,int y=5){

    static int m=3;m+=x;return m>=y? m : -1;

    }void main(){

    int a,b,c;a=f(4); b=f(1,7); c=f();

    }Care dintre cele trei apeluri realizate n main sunt corecte?

    a) numai primele dou apeluri sunt corecte iar valorile variabilelor sunt a=7 i b=8

    b) numai primele dou apeluri sunt corecte iar valorile variabilelor sunt a=7 i b=-1

    c) numai al doilea apel este corect i se obine b=8

    d) numai al doilea apel este corect i se obine b=-1

    e) toate cele trei apeluri sunt corecte

    27. Fie funcia F de mai jos:int* F(int* a,int* b,int c){

    int d=(*a+*b+c)/3;return &d;

    }Presupunem c sunt declarate urmtoarele variabile:int *x,*y,z,*m,n;Care dintre secvenele de program de mai jos nu afieaz corect valoarea returnat de ctre funcia F?

    a) scanf(%d %d %d,x,y,&z);printf(\n%d,*F(x,y,z));

    b) *m=*F(x,y,z);printf(%d,*m);

    c) n=*F(x,y,z);printf(%d,n);

    d) printf(%d,*F(2,3,4));28. Fie funcia:void afis1(int v[]){

    int j=0;while(j

  • Informatic pentru clasa a X-a

    }Funciile afis2 i afis3 de mai jos sunt corecte i echivalente cu funcia dat afis1? (adic afieaz acelai ir de valori)void afis2(int v[4]){

    int j=0;do printf(%d ,*(v+j++);while(j

  • Informatic pentru clasa a X-a

    }void main(){

    int a=2,b=5;test(a,b,plus,minus);test(3,0,plus,minus);test(a,b,plus(a),mins(b));test(3,0,plus(3),minus(0));

    }Ce se poate spune despre apelurile funciei test realizate din main?

    a) primele dou apeluri sunt corecte, determinnd afiarea valorilor 2, respectiv 1, iar ultimele dou sunt eronate

    b) primele dou apeluri sunt corecte, determinnd afiarea valorilor 3, respectiv 1, iar ultimele dou sunt eronate

    c) ultimele dou apeluri sunt corecte, determinnd afiarea valorilor 2, respectiv 1, iar primele dou sunt eronate

    d) ultimele dou apeluri sunt corecte, determinnd afiarea valorilor 3, respectiv 1, iar primele dou sunt eronate

    e) toate cele patru apeluri sunt eronate

    34. Ce valoare se va afia n urma execuiei programului urmtor?#includeint f(int n,){

    int *a=&n+1, *b=a+2;return n*(*a+*b);

    }void main(){

    printf(%d,f(3,2,11,5,8));}

    a) 21 b) 39 c) 18 d) 30e) antetul funciei este greit

    35. Ce trebuie pus n locul secvenei XXX astfel nct programul de mai jos s furnizeze minimul unui numr variabil de argumente, precizat la apel prin valoarea lui n?#includedouble f(int n,){

    double min=*(double *)(&n+1);for(int j=1;j

  • Informatic pentru clasa a X-a

    c) n urma execuiei f2(&b), obinem b=3d) n urma execuiei *f2(&b), obinem b=6e) valoarea variabilei locale a din funcia

    f2 nu poate fi modificat prin nici un mecanism n funcia main

    39. Precizai valoarea variabilei n rezultat n urma execuiei programului:#includeint f(char a[2]){

    int j=0;while(a[j++]); return j;

    }void main(){

    int n=f(abcdefgh);}

    a) 0 b) 2 c) 9d) corpul funciei conine o bucl infinite) programul are erori de sintax

    40. Fie programul :#include void fct(int a,int *b){ a+=3; *b+=a;}void main(){

    int c, d; c=4; d=5;

    fct(c,&d);printf(%d%d,c,d);fct(c,&d);printf(%d%d,c,d);

    }Ce se afieaz pe ecranul monitorului n urma execuiei programului ?

    a) 4545 b) 412412c) 712719 d) 412419

    41. Se d funcia :int fct(int n){ int d=2; int g=(int) sqrt(n); int f=1; while (d=A&&a

  • Informatic pentru clasa a X-a

    }a) dac dou elemente din vector sunt

    distincteb) dac oricare dou elemente din vector

    sunt egalec) dac primele dou elemente din vector

    sunt egaled) dac dou elemente consecutive sunt

    egale , fr a considera primul element

    45. Spunei ce realizeaz urmtoarul subprogram :void fct(char s[]){ int i,j,t; for(i=0,j=strlen(s)-1;i0) {a=b;b=r;r=a%b;} return b;} Pentru a=45 si b=27 , valoarea lui f este:

    a) 3 b) 9 c) 72 d) 135

    52. S se precizeze care sunt valorile care vor fi tiprite de programul de mai jos :int i,j;void p(int j){ j++; i=j+1;}void main(void){ i=2; j=4; p(i); printf(%d %d,i,j);}

    a) 1 6 b) 1 4 c) 4 6 d) 4 4

    53. Se consider urmtoarea funcie :float x[10];int f(int n){ int i,k=0; for(i=1;i

  • Informatic pentru clasa a X-a

    else return k;} Dac x=(5, 6, 6, 6, 3, 4, 4, 9) valoarea returnat pentru f este :

    a) 3 b) 2 c) 7 d) 5

    54. Care este implementarea corecta a functiei toupper ?I) int tomare(char c)

    { return(c-a+A);}

    II) int tomare(char c){ if(c>=a&&c=a&&c

  • Informatic pentru clasa a X-a

    int f(int tab[],int n,int a){ int j,s,i; i=0; s=n-1; while(i