Documente Academic
Documente Profesional
Documente Cultură
Functii
Functii
Functii
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 ); }
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 ); }
Ca i n cazul autorului anonim, analiza parametrilor opionali se va face, n general, pe baza parametrilor fici. Prin urmare, o funcie ca
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.