Pointerii oferă posibilități foarte mari funcțiilor „C”, pe care suntem limitați să le returnăm o valoare. Cu parametrii indicatorului, funcțiile noastre pot procesa acum date reale, mai degrabă decât o copie a datelor.
Pentru a modifica valorile reale ale variabilelor, instrucțiunea de apelare trece adresele către parametrii indicatorului dintr-o funcție.
În acest tutorial, veți învăța-
- Funcții Pointer Exemplu
- Funcții cu parametrii matricei
- Funcții care returnează o matrice
- Funcții Pointer
- Matrice de indicatori de funcții
- Funcții Utilizarea pointerilor void
- Pointerele funcționale ca argumente
Funcții Pointer Exemplu
De exemplu, următorul program schimbă două valori de două:
void swap (int *a, int *b);int main() {int m = 25;int n = 100;printf("m is %d, n is %d\n", m, n);swap(&m, &n);printf("m is %d, n is %d\n", m, n);return 0;}void swap (int *a, int *b) {int temp;temp = *a;*a = *b;*b = temp;}}
Ieșire:
m is 25, n is 100m is 100, n is 25
Programul schimbă valorile variabilelor reale, deoarece funcția le accesează prin adresă folosind pointeri. Aici vom discuta despre procesul programului:
- Declarăm funcția responsabilă pentru schimbul celor două valori variabile, care ia doi indicatori întregi ca parametri și returnează orice valoare atunci când este apelată.
- În funcția principală, declarăm și inițializăm două variabile întregi („m” și „n”), apoi le imprimăm valorile.
- Numim funcția swap () prin trecerea adresei celor două variabile ca argumente folosind simbolul ampersand. După aceea, imprimăm noile valori schimbate ale variabilelor.
- Aici definim conținutul funcției swap () care ia două adrese variabile întregi ca parametri și declarăm o variabilă temporară întreagă utilizată ca a treia casetă de stocare pentru a salva una dintre variabilele de valoare care vor fi puse la a doua variabilă.
- Salvați conținutul primei variabile indicate de „a” în variabila temporară.
- Stocați a doua variabilă indicată de b în prima variabilă indicată de a.
- Actualizați a doua variabilă (indicată de b) cu valoarea primei variabile salvate în variabila temporară.
Funcții cu parametrii matricei
În C, nu putem trece o matrice după valoare unei funcții. În timp ce, un nume de matrice este un pointer (adresă), deci doar trecem un nume de matrice la o funcție care înseamnă să treacă un pointer la matrice.
De exemplu, luăm în considerare următorul program:
int add_array (int *a, int num_elements);int main() {int Tab[5] = {100, 220, 37, 16, 98};printf("Total summation is %d\n", add_array(Tab, 5));return 0;}int add_array (int *p, int size) {int total = 0;int k;for (k = 0; k < size; k++) {total += p[k]; /* it is equivalent to total +=*p ;p++; */}return (total);}
Ieșire:
Total summation is 471
Aici, vom explica codul programului cu detaliile sale
- Declarăm și definim funcția add_array () care ia o adresă matrice (pointer) cu numărul elementelor sale ca parametri și returnează suma totală acumulată a acestor elemente. Pointerul este folosit pentru a itera elementele matricei (folosind notația p [k]) și acumulăm suma într-o variabilă locală care va fi returnată după iterarea întregii matrice de elemente.
- Declarăm și inițializăm un tablou întreg cu cinci elemente întregi. Imprimăm suma totală trecând numele matricei (care acționează ca adresă) și dimensiunea matricei la funcția add_array () numită ca argumente.
Funcții care returnează o matrice
În C, putem returna un pointer către o matrice, ca în următorul program:
#includeint * build_array();int main() {int *a;a = build_array(); /* get first 5 even numbers */for (k = 0; k < 5; k++)printf("%d\n", a[k]);return 0;}int * build_array() {static int Tab[5]={1,2,3,4,5};return (Tab);}
Ieșire:
12345
Și aici, vom discuta detaliile programului
- Definim și declarăm o funcție care returnează o adresă matrice care conține o valoare întreagă și nu a luat niciun argument.
- Declarăm un indicator întreg care primește matricea completă construită după ce funcția este apelată și îi imprimăm conținutul prin iterarea întregii matrice de cinci elemente.
Observați că un indicator, nu o matrice, este definit pentru a stoca adresa matricei returnată de funcție. De asemenea, observați că atunci când o variabilă locală este returnată dintr-o funcție, trebuie să o declarăm statică în funcție.
Funcții Pointer
După cum știm prin definiție că indicii indică o adresă în orice locație de memorie, ei pot indica, de asemenea, la începutul codului executabil ca funcții în memorie.
Un pointer pentru a funcționa este declarat cu *, declarația generală a declarației sale este:
return_type (*function_name)(arguments)
Trebuie să vă amintiți că parantezele din jurul (* nume_funcție) sunt importante, deoarece fără ele, compilatorul va crede că numele_funcție returnează un pointer de tip_întoarcere.
După definirea indicatorului funcției, trebuie să-l atribuim unei funcții. De exemplu, următorul program declară o funcție obișnuită, definește un pointer de funcție, atribuie pointerul funcției funcției obișnuite și după aceea apelează funcția prin pointer:
#includevoid Hi_function (int times); /* function */int main() {void (*function_ptr)(int); /* function pointer Declaration */function_ptr = Hi_function; /* pointer assignment */function_ptr (3); /* function call */return 0;}void Hi_function (int times) {int k;for (k = 0; k < times; k++) printf("Hi\n");}
Ieșire:
HiHiHi
- Definim și declarăm o funcție standard care imprimă un text Hi de k ori indicat de parametrul ori când funcția este apelată
- Definim o funcție pointer (cu declarația sa specială) care ia un parametru întreg și nu returnează nimic.
- Ne inițializăm funcția de pointer cu funcția Hi_, ceea ce înseamnă că pointerul indică funcția Hi_function ().
- Mai degrabă decât apelarea funcției standard prin apăsarea numelui funcției cu argumente, apelăm doar funcția pointer prin trecerea numărului 3 ca argumente, și atât!
Rețineți că numele funcției indică adresa de început a codului executabil ca un nume de matrice care indică primul său element. Prin urmare, instrucțiuni precum function_ptr = & Hi_function și (* funptr) (3) sunt corecte.
NOTĂ: Nu este important să introduceți operatorul de adresă și operatorul de indirectare * în timpul atribuirii funcției și apelului de funcție.
Matrice de indicatori de funcții
O serie de indicatori de funcții pot juca un comutator sau un rol de instrucțiune if pentru luarea unei decizii, ca în următorul program:
#includeint sum(int num1, int num2);int sub(int num1, int num2);int mult(int num1, int num2);int div(int num1, int num2);int main(){ int x, y, choice, result;int (*ope[4])(int, int);ope[0] = sum;ope[1] = sub;ope[2] = mult;ope[3] = div;printf("Enter two integer numbers: ");scanf("%d%d", &x, &y);printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");scanf("%d", &choice);result = ope[choice](x, y);printf("%d", result);return 0;}int sum(int x, int y) {return(x + y);}int sub(int x, int y) {return(x - y);}int mult(int x, int y) {return(x * y);}int div(int x, int y) {if (y != 0) return (x / y); else return 0;}
Enter two integer numbers: 13 48Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2624
Aici discutăm detaliile programului:
- Declarăm și definim patru funcții care iau două argumente întregi și returnează o valoare întreagă. Aceste funcții adună, scad, înmulțesc și împart cele două argumente privind funcția care este apelată de utilizator.
- Declarăm 4 numere întregi pentru a gestiona operanzi, tipul operației și respectiv rezultatul. De asemenea, declarăm o matrice de pointer cu patru funcții. Fiecare indicator al funcției elementului matrice ia doi parametri întregi și returnează o valoare întreagă.
- Atribuim și inițializăm fiecare element de matrice cu funcția deja declarată. De exemplu, al treilea element care este al treilea indicator al funcției va indica funcția de operație de multiplicare.
- Căutăm operanzi și tipul de operație de la utilizatorul tastat cu tastatura.
- Am numit elementul matricei corespunzătoare (indicatorul funcției) cu argumente și stocăm rezultatul generat de funcția corespunzătoare.
Instrucțiunea int (* ope [4]) (int, int); definește matricea de indicatori de funcții. Fiecare element de matrice trebuie să aibă aceiași parametri și același tip de returnare.
Declarația rezultat = ope [alegere] (x, y); rulează funcția corespunzătoare în funcție de alegerea făcută de utilizator Cele două numere întregi introduse sunt argumentele transmise funcției.
Funcții Utilizarea pointerilor void
Indicatorii de vid sunt utilizați în timpul declarațiilor de funcție. Folosim un permis de tip return * nul * pentru a returna orice tip. Dacă presupunem că parametrii noștri nu se schimbă atunci când trecem la o funcție, o declarăm ca fiind const.
De exemplu:
void * cube (const void *);
Luați în considerare următorul program:
#includevoid* cube (const void* num);int main() {int x, cube_int;x = 4;cube_int = cube (&x);printf("%d cubed is %d\n", x, cube_int);return 0;}void* cube (const void *num) {int result;result = (*(int *)num) * (*(int *)num) * (*(int *)num);return result;}
Rezultat:
4 cubed is 64
Aici vom discuta detaliile programului:
- Definim și declarăm o funcție care returnează o valoare întreagă și care ia o adresă de variabilă neschimbabilă fără un anumit tip de date. Calculăm valoarea cubului variabilei de conținut (x) indicată de pointerul num și, deoarece este un pointer gol, trebuie să tastați cast-o într-un tip de date întregi folosind un pointer de notație specific (* tip de date) și returnăm valoarea cubului.
- Declarăm operandul și variabila de rezultat. De asemenea, ne inițializăm operandul cu valoarea „4.”
- Apelăm funcția cub prin trecerea adresei de operand și gestionăm valoarea returnată în variabila rezultat
Pointerele funcționale ca argumente
O altă modalitate de a exploata un indicator de funcție trecându-l ca argument către o altă funcție numită uneori „funcție de apel invers”, deoarece funcția de recepție „îl apelează înapoi”.
În fișierul antet stdlib.h, funcția Quicksort "qsort ()" folosește această tehnică care este un algoritm dedicat sortării unei matrice.
void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
- void * base: pointer void către matrice.
- size_t num: numărul elementului matricei.
- size_t width Dimensiunea elementului.
- int (* compare (const void *, const void *): indicatorul funcției compus din două argumente și returnează 0 atunci când argumentele au aceeași valoare, <0 când arg1 vine înainte de arg2 și> 0 când arg1 vine după arg2.
Următorul program sortează o matrice de numere întregi de la număr mic la număr mare folosind funcția qsort ():
#include#include int compare (const void *, const void *);int main() {int arr[5] = {52, 14, 50, 48, 13};int num, width, i;num = sizeof(arr)/sizeof(arr[0]);width = sizeof(arr[0]);qsort((void *)arr, num, width, compare);for (i = 0; i < 5; i++)printf("%d ", arr[ i ]);return 0;}int compare (const void *elem1, const void *elem2) {if ((*(int *)elem1) == (*(int *)elem2)) return 0;else if ((*(int *)elem1) < (*(int *)elem2)) return -1;else return 1;}
Rezultat:
13 14 48 50 52
Aici vom discuta detaliile programului:
- Definiți funcția de comparare compusă din două argumente și returnează 0 atunci când argumentele au aceeași valoare, <0 când arg1 vine înainte de arg2 și> 0 când arg1 vine după arg2. Parametrii sunt un tip de pointeri de gol turnat la tipul de date matrice adecvat. (întreg)
- Definim și inițializăm o matrice întreagă Mărimea matricei este stocată în variabila num și mărimea fiecărui element matrice este stocată în variabila lățime folosind operatorul C predefinit sizeof ().
- Noi numim qsort funcția și treci numele matrice, dimensiunea, lățimea, și funcția de comparare definită anterior de către utilizator pentru a sorta matrice noastre în comparație order.The ascendentă va fi realizată prin luarea în fiecare iteratie două elemente de matrice până când întreaga matrice vor fi sortate.
- Tipărim elementele matricei pentru a ne asigura că matricea noastră este bine sortată iterând întreaga matrice folosind bucla for.