Functii

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

Descărcați ca doc, pdf sau txt
Descărcați ca doc, pdf sau txt
Sunteți pe pagina 1din 7

Pointeri la funcii. Suprancrcarea funciilor.

Funcii cu numr variabil de parametrii


Motto : Micu btrn Cu brul de ln Pe cmpi alergnd, Din ochi lcrmnd, De mine-ntrebnd: - L-ai vzut cumva pe Zdrean Cel cu ochii de faian ? - Da-mprate !

1. Pointeri (cam pe) la funcii


Dac acest studiu s-ar dori exhaustiv, ar trebui s precizm c la nceput a fost haosul Cu riscul de a prea superficiali, vom sri ns peste unele etape ce nu fac obiectul prezentei lucrri, pentru a surprinde gestul omului de cromagnon care, vizibil afectat de urmrile transformrii energiei cinetice in energie potenial de deformare la interaciunea dintre propria regiune lombar i instrumentul complementar al vecinului de grot (bta), i ndreapt mna spre zona precedentului contact, acuznd astfel sursa senzaiei de disconfort. Aa a luat natere conceptul de pointer. Mai trziu ajungem n anul 1853 cnd se mplineau deja cinci ani de la Revoluia din 1848 Fcnd o parantez, putem preciza c n informatic (n limbajele de programare de nivel mediu i nalt) pointerii, ca noiune, au fost introdui din necesitatea de a controla poziia efectiv n memorie att a datelor (varibile, vectori, structuri etc.) ct i a codului (funcii i proceduri). Pentru a nelege ce este un pointer la o funcie trebuie tiut nti i nti c, pentru calculator, ntre date i cod nu exist nici o diferen (la fel cum pentru personajul nostru prezentat mai sus nu exista nici o diferen ntre sunetele emise, dintre care spicuim : aaarrrg,aaaaaa,uuuuuu,a). Astfel, dac nite variabile declarate ca
int a = 10; char b = 65; char c = a;

vor fi reprezentate n memorie sub forma a 4 octei cu valorile respectiv 10,0,65,97, o funcie precum
void NuAmShtiutCeNumeSaDauFunctzieiAsteiaAsaCaAmScrisChestiaAsta() { a = 2; }

va fi mai nti tradus n instruciunea primar pentru atribuire a procesorului (mov) , linia
a = 2;

devenind :
mov [a],2

care va fi apoi codificat n 6 octei cu valorile respectiv 199, 6, XL, XH, 2, 0, unde XL este octetul cel mai puin semnificativ al adresei lui a iar XH este octetul cel mai semnificativ al aceleiai adrese (presupunnd un model de memorie n care adresa se reprezint pe 2 octei). Un pointer la funcia artat mai sus va fi o variabil care va conne adresa octetului cu valoarea 192. Generaliznd, un pointer la o funcie oarecare este adresa primului octet al reprezentrii n memorie a codului acelei funcii. Acestea fiind spuse, nu ne rmne dect s artm cum se pot folosi aceti pointeri la funcii ntrun program C :
#include <stdio.h> // Asha se declara un pointer la o functzie : void (AstaEUnPointerLaOFunctzieCareAcceptaUnParametruIntreg*)(int a); void AstaEOFunctzieCareScriePeEcranParametrulIntregPrimit( int a ) { printf( %d,a ); } void main() { // Asha se face o atribuire a unui pointer la o functzie : // ( numele functziei fara parantezele subfixate inseamna pointer la acea // functzie ) AstaEUnPointerLaOFunctzieCareAcceptaUnParametruIntreg = AstaEOFunctzieCareScriePeEcranParametrulIntregPrimit; // Iar acum putem apela functzia de mai sus prin pointerul la ea : AstaEUnPointerLaOFunctzieCareAcceptaUnParametruIntreg( 666 ); }

2. Efectul de suprancrcare (ntructva) a funciilor

Apelul funciilor ntr-un program nu este foarte diferit de metoda rustic prin care atenia unui individ este solicitat dup sistemul : B Ghorgheeeeeee !!!!!!". La fel o funcie este chemat s se execute dup numele su. Problema apare ns cnd mai multe funcii au acelai nume i nu se poate decide care dintre ele trebuie chemat. n aceast situaie geniul popular i dovedete nc o dat, dac mai era nevoie, valoarea sa incontestabil prin gsirea unui expedient ce face ca aceast problem s par eminamente facil, eludnd astfel de o manier existenial categoric impasul iniial. Soluia creatorului anonim const n unicizarea obiectului apelului su prin suplimentarea interpelrii cu o serie de entiti intrinsec informaionale i coerent formale. Astfel, n momentul n care o solicitare i pierde comprehensibilitatea devenind echivoc (precum ar face precedentul nostru exemplu n prezumia apariei unui al doilea Gheorghe), aceasta este instinctual transfigurat i coercitiv reformat pentru a reflecta n mod irefutabil elocvent intenionalitatea iniial a apelantului, numelui adresatului fiindu-i adiionate o serie de atribute a cror juxtapunere i confer acestuia o unicitate relaional cognitiv : Gheorghe a Marii Gherghinii lu nea Fane tractoristu d-a inut p-aia lu Marin a lu Gheorghe-al Janii dn capu satului. Pornind de la ideea geniului popular, compilatorul de C va reui s fac diferena ntre dou funcii cu acelai nume doar folosind unele informaii auxiliare. Concret, aceste informaii sunt reprezentate de tipul i respectiv de numrul parametrilor acceptai. Putem spune, deci, c exist o diferen fundamental irecuzabil ntre funcia
char Functzie( int a ); (1)

i funcia
void Functzie( char a ); (2)

deoarece, chiar dac numrul de parametrii acceptai coincide, tipul acestora difer n mod indubitabil. Deasemenea compilatorul de C nu ntlnete nici un impediment de ordin major n a deosebi funciile
void Functzie( int a );

i respectiv
int Functzie( int a, int b ); (3)

ntruct acestea accept numere axiomatic distincte de parametrii ( 1 i respectiv 2 ). Intern, aceast abilitate a compilatorului este posibil datorit redenumirii oricrei funcii ntlnite dup numrul i tipul parametrilor fiecreia. Astfel, funciile din exemplele precedente vor fi recunoscute intern eventual exportate n alte module sub numele :
(1) (2) (3) - @Functzie$qi - @Functzie$qzc - @Functzie$qii

Se impune s precizm aici c, dei dou funcii cu acelai nume se pot deosebi dup tipul i respectiv numrul parametrilor primi, aceast diferen nu se poate realiza i n funcie de tipul rezultatului ntors, caz n care compilatorul va semnala o erorare. Mai concret, funciile
char Functzie();

i respectiv
int Functzie();

nu pot coexista n acela fiier surs. n ncheiere prezentm o surs C care va evidenia modul n care se pot folosi n acelai program dou funcii cu acelai nume i totui fundamental irefutabil distincte :
#include <stdio.h> #include <stdlib.h> #include <time.h> void Medie( char a, char b, int& rezultat ) { rezultat = (a+b)>>1; } int Medie( char a, char b ) { return (a+b)>>1; } void main() { char a,b; int med; randomize(); a = rand() % 32768; b = rand() % 32768; Medie( a,b,med ); printf( \n\nNumerele : %d,%d\n,a,b ); printf( Media intoarsa : %d\n, Medie( a,b ) ); printf( Media pasata ca parametru : %d,med ); }

3. Funcii cu numr (oarecum) variabil de parametrii


Dup cum am artat n seciunea prcedent a prezentei lucrri, ntre apelul funciilor n C i o interpelare tradiional nu apare nici o discrepan de fond. Vom vedea n cele ce urmeaz cum se aplic aceasta situaiilor n care apelului propriu-zis i este aditivat un numr nedefinit de anexe informaionale, precum parametrii, cu scop n instanierea categoric a funciei pe baza valorilor existenial concrete ale datelor de intrare i respectiv ieire. Un exemplu de cerere rupt din genialitate providenial exhaustiv a creatorului anonim i frecvent ntlnit n lumea instinctual empiric a satului ar fi : Gheorgheeeeee, du, b, d ia tu o sticl d votc !. Transpare din fiecare cuvnt al acestei fraze mpcarea transcedental a omului cu sentimentul inexorabilitii sucombrii prin aciunea nociv a gruprii radical-hidroxil asupra celulelor hepatice, fapt ce exacerbeaz luciditatea intrinsec matematic inerent intelectului geniului popular care sintetizeaz aceast solicitatre unind laolat structuri profund informaionale ce confer propoziiei exactitatea logic dorit. Se nelge, aadar, c obiectul apelului nu poate fi altul dect Gheorghe, scopul fiind clar, procurarea unui bun esenal pentru dezvoltarea biologic a locuitorilor spaiului rustic mai sus amintit. Continund asemnarea nceput mai devreme, putem spune c i la chemarea unei funcii C, trebuie bine precizate obiectul apelului (funcia) i scopul lui (parametrii). Mergnd mai departe cu analiza noastr asupra comunicrii informaonale n universul rustic, vom realiza c geniul anonim descoperise cu mult nainte de inventarea calculatorului o metod intrinsec folositoare, introdus n tehnologia informaional de limbajul de preogramare C, o metod de formatare a unei cereri astfel nct numrul de parametrii trimii s poat diferi de la apel la apel. Astfel, creatorul popular poate exprima fr team de echivoc urmtoarea solicitare aceluiai Gheorghe : Gheorgheeee, du, b, tu d ia cinci sticle d bautur : patru d votc i trei d rom ! (se poate observa c numrul anexelor informaionale sufixate cererii a crescut simitor fa de primul apel dei obiectul a rmas neschimbat). Vizibil fondat pe geniul autorului popular, compilatorul C va putea genera funcii care accept un numr variabil de parametrii. n pseudocod, un prototip de astfel de funcie ar fi :
tip_intors NumeFunctzie( lista_normala_de_parametrii,... );

unde lista_normala_de_parametrii este un ir normal de declaraii de parametrii, ca de exemplu


int a, char c

caz n care prototipul de mai sus devine :


tip_intors NumeFunctzie( int a, char c,... );

Ca i n cazul autorului anonim, analiza parametrilor opionali se va face, n general, pe baza parametrilor fici. Prin urmare, o funcie ca

long Medie( int n,... );

va ti ci parametrii primete la un anumit apel dup valoarea din parametrul fix, n, un apel corect al acestei funcii preciznd n acest intreg, numrul de parametrii opionali, aa cum face codul :
m = Medie( 3,a,b,c );

Este cazul s precizm c o funcie cu parametrii opionali nu poate fi declarat dect folosind standardul cdecl (implicit n compilatorul C), adic parametrul cel mai din dreapta va fi mpins primul n stiv iar cel mai din stnga ultimul, apelantul golind stiva dupa execuia funciei. Din cele spuse mai sus, este uor de observat c, la intrarea ntr-o astfel de funcie, primul parametru opional se va gsi n memorie imediat dup ultimul parametru fix iar urmtorii n continuare, liniar. tiind acestea, putem scrie acum corpul funciei Medie :
long Medie( int n,... ) { int *a = &n + 1; long sum = 0; for ( int i=0; i<n; i++,sum+=a[i] ); return sum/n; }

S-ar mai putea aminti aici cele 4 funcii ale bibliotecii C special concepute pentru folosirea n funcii cu numr variabil de parametrii care ns sunt mult mai greoi de folosit dect accesarea direct a memoriei i nu ar face altceva dect s sporeasc inutil consumul de foi i cerneal necesar pentru tiprirea acestei lucrri, i aa inutile. n ncheiere prezentm un program care unete toate toate funciile definite pn acum n prezentul studiu, demonstrndu-le modul de folosire :
#include <stdio.h> #include <stdlib.h> #include <time.h> void Medie( char a, char b, int& rezultat ) { rezultat = (a+b)>>1; } int Medie( char a, char b ) { return (a+b)>>1; } long Medie( int n,... ) { int *a = &n + 1;

long sum = 0; for ( int i=0; i<n; i++,sum+=a[i] ); return sum/n; } void main() { char a,b,c; int med; randomize(); a = rand() % 32768; b = rand() % 32768; c = rand() % 32768; Medie( a,b,med ); printf( "\n\nNumerele : %d,%d,%d\n",a,b,c ); printf( "Media intoarsa a primelor doua: %d\n", Medie( a,b ) ); printf( "Media primelor doua pasata ca parametru : %d\n",med ); printf( "Media cu parametrii optionali : %d",Medie( 3,a,b,c) ); }

Not : Pentru facilitarea analizei textului subiectele au fost subliniate cu cte o linie iar predicatele cu cte dou, tema mpririi frazelor n propoziii fiind lsat de autor ca tem de gndire cititorului.

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