Funksjoner Pekere i C-programmering med eksempler
⚡ Smart oppsummering
Funksjonspekere i C lagrer adressen til kjørbar kode, slik at programmer kan kalle funksjoner indirekte, sende dem som argumenter, bygge forsendelsestabeller fra arrayer og implementere tilbakeringinger som qsort-sammenligningsrutinen for fleksible, gjenbrukbare design.
Pekere gir store muligheter til 'C'-funksjoner som vi er begrenset til å returnere én verdi. Med pekerparametere kan funksjonene våre nå behandle faktiske data i stedet for en kopi av data.
For å endre de faktiske verdiene til variabler, sender den kallende setningen adresser til pekerparametere i en funksjon.
Funksjoner Pekere Eksempel
For eksempel bytter det neste programmet to verdier av to:
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;} }
Utgang:
m is 25, n is 100 m is 100, n is 25
Programmet bytter de faktiske variabelverdiene fordi funksjonen får tilgang til dem ved å bruke adresse pekeren. Her vil vi diskutere programprosessen:
- Vi erklærer funksjonen som er ansvarlig for byttetping de to variabelverdiene, som tar to heltallspekere som parametere og returnerer en hvilken som helst verdi når den kalles.
- I hovedfunksjonen deklarerer og initialiserer vi to heltallsvariabler ('m' og 'n'), så skriver vi ut verdiene deres.
- Vi kaller swap()-funksjonen ved å sende adressen til de to variablene som argumenter ved å bruke og-tegnet. Etter det skriver vi ut de nye byttede verdiene til variabler.
- Her definerer vi swap()-funksjonen innhold som tar to heltallsvariabeladresser som parametere og erklærer en midlertidig heltallsvariabel brukt som en tredje lagringsboks for å lagre en av verdivariablene som vil bli satt til den andre variabelen.
- Lagre innholdet i den første variabelen pekt med 'a' i den midlertidige variabelen.
- Lagre den andre variabelen pekt med b i den første variabelen pekt med a.
- Oppdater den andre variabelen (pekt med b) med verdien av den første variabelen lagret i den midlertidige variabelen.
Fungerer med matriseparametere
I C kan vi ikke sende en matrise etter verdi til en funksjon. Mens et matrisenavn er en peker (adresse), så vi sender bare et matrisenavn til en funksjon som betyr å sende en peker til matrisen.
For eksempel vurderer vi følgende 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);}
Utgang:
Total summation is 471
Her vil vi forklare programkoden med detaljer
- Vi erklærer og definerer add_array()-funksjonen som tar en matriseadresse(peker) med elementnummeret som parametere og returnerer den totale akkumulerte summeringen av disse elementene. Pekeren brukes til å iterere array-elementene (ved å bruke p[k]-notasjonen), og vi akkumulerer summeringen i en lokal variabel som vil bli returnert etter iterasjon av hele element-arrayen.
- Vi erklærer og initialiserer en heltallsmatrise med fem heltallselementer. Vi skriver ut den totale summeringen ved å sende matrisenavnet (som fungerer som adresse) og matrisestørrelsen til add_array()kalt funksjon som argumenter.
Funksjoner som returnerer en matrise
I C kan vi returnere en peker til en matrise, som i følgende program:
#include <stdio.h> int * 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);}
Utgang:
1 2 3 4 5
Og her vil vi diskutere programdetaljene
- Vi definerer og deklarerer en funksjon som returnerer en matriseadresse som inneholder en heltallsverdi og som ikke tok noen argumenter.
- Vi erklærer en heltallspeker som mottar hele matrisen bygget etter at funksjonen er kalt, og vi skriver ut innholdet ved å iterere hele matrisen med fem elementer.
Legg merke til at en peker, ikke en matrise, er definert for å lagre matriseadressen som returneres av funksjonen. Legg også merke til at når en lokal variabel returneres fra en funksjon, må vi erklære den som statisk i funksjonen.
Funksjonspekere
Som vi per definisjon vet at pekere peker til en adresse på en hvilken som helst minneplassering, kan de også peke på i begynnelsen av kjørbar kode som funksjoner i minnet.
En peker til funksjon er deklarert med *, den generelle erklæringen i erklæringen er:
return_type (*function_name)(arguments)
Du må huske at parentesene rundt (*funksjonsnavn) er viktige fordi uten dem vil kompilatoren tro at funksjonsnavnet returnerer en peker av returtype.
Etter å ha definert funksjonspekeren, må vi tilordne den til en funksjon. For eksempel erklærer det neste programmet en ordinær funksjon, definerer en funksjonspeker, tildeler funksjonspekeren til den ordinære funksjonen og kaller deretter funksjonen gjennom pekeren:
#include <stdio.h> void 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");}
Utgang:
Hi Hi Hi
- Vi definerer og deklarerer en standardfunksjon som skriver ut en Hi-tekst k ganger angitt med parametertidene når funksjonen kalles
- Vi definerer en pekerfunksjon (med sin spesielle erklæring) som tar en heltallsparameter og ikke returnerer noe.
- Vi initialiserer pekerfunksjonen vår med Hi_function som betyr at pekeren peker til Hi_function().
- I stedet for standardfunksjonskallet fra taping funksjonsnavnet med argumenter, vi kaller bare pekerfunksjonen ved å sende tallet 3 som argumenter, og det er det!
Husk at funksjonsnavnet peker til startadressen til den kjørbare koden som et matrisenavn som peker til det første elementet. Derfor er instruksjoner som function_ptr = &Hi_function og (*funptr)(3) korrekte.
MERK: Det er ikke viktig å sette inn adresseoperatøren & og indirektionsoperatøren * under funksjonstildelingen og funksjonsanropet.
En rekke funksjonspekere
En rekke funksjonspekere kan spille en bryter eller en if-utsagnsrolle for å ta en beslutning, som i neste program:
#include <stdio.h> int 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 48
Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2
624
Her diskuterer vi programdetaljene:
- Vi erklærer og definerer fire funksjoner som tar to heltallsargumenter og returnerer en heltallsverdi. Disse funksjonene legger til, subtraherertract, multipliser og divider de to argumentene angående hvilken funksjon som kalles av brukeren.
- Vi erklærer 4 heltall for å håndtere henholdsvis operander, operasjonstype og resultat. Dessuten erklærer vi en matrise med fire funksjonspekere. Hver funksjonspeker til matriseelementet tar to heltallsparametere og returnerer en heltallsverdi.
- Vi tildeler og initialiserer hvert array-element med funksjonen som allerede er erklært. For eksempel vil det tredje elementet som er den tredje funksjonspekeren peke på multiplikasjonsoperasjonsfunksjonen.
- Vi søker operander og type operasjon fra brukeren som skrives inn med tastaturet.
- Vi kalte det passende array-elementet (Funksjonspeker) med argumenter, og vi lagrer resultatet generert av den aktuelle funksjonen.
Instruksjonen int (*ope[4])(int, int); definerer utvalget av funksjonspekere. Hvert matriseelement må ha samme parametere og returtype.
Utsagnsresultatet = ope[valg](x, y); kjører den aktuelle funksjonen i henhold til valget gjort av brukeren. De to angitte heltallene er argumentene som sendes til funksjonen.
Funksjoner Bruke void-pekere
Void-pekere brukes under funksjonsdeklarasjoner. Vi bruker en void * returtypetillatelser for å returnere alle typer. Hvis vi antar at parameterne våre ikke endres når de overføres til en funksjon, erklærer vi den som const.
For eksempel:
void * cube (const void *);
Tenk på følgende program:
#include <stdio.h> void* 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;}
Resultat:
4 cubed is 64
Her vil vi diskutere programdetaljene:
- Vi definerer og deklarerer en funksjon som returnerer en heltallsverdi og tar en adresse med uforanderlig variabel uten en spesifikk datatype. Vi beregner kubeverdien til innholdsvariabelen (x) pekt av num-pekeren, og siden det er en void-peker, må vi skrive cast den til en heltallsdatatype ved å bruke en spesifikk notasjon (* datatype)-peker, og vi returnerer kubeverdien.
- Vi erklærer operanden og resultatvariabelen. Vi initialiserer også operanden vår med verdien «4».
- Vi kaller kubefunksjonen ved å sende operandadressen, og vi håndterer returverdien i resultatvariabelen
Fungerer pekere som argumenter
En annen måte å utnytte en funksjonspeker ved å sende den som et argument til en annen funksjon som noen ganger kalles "tilbakeringingsfunksjon" fordi mottakerfunksjonen "kaller den tilbake."
I headerfilen stdlib.h bruker Quicksort "qsort()"-funksjonen denne teknikken som er en algoritme dedikert til å sortere en matrise.
void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
- void *base: void-peker til matrisen.
- size_t num : Matriseelementnummeret.
- size_t width Elementstørrelsen.
- int (*compare (const void *, const void *) : funksjonspeker sammensatt av to argumenter og returnerer 0 når argumentene har samme verdi, <0 når arg1 kommer før arg2, og >0 når arg1 kommer etter arg2.
Følgende program sorterer en heltallsmatrise fra lite til stort tall ved å bruke qsort()-funksjonen:
#include <stdio.h> #include <stdlib.h> 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;}
Resultat:
13 14 48 50 52
Her vil vi diskutere programdetaljene:
- Vi definerer sammenligningsfunksjonen sammensatt av to argumenter og returnerer 0 når argumentene har samme verdi, <0 når arg1 kommer før arg2, og >0 når arg1 kommer etter arg2. Parametrene er en void pointer-type som er castet til den aktuelle matrisedatatypen (heltall)
- Vi definerer og initialiserer en heltallsmatrise Matrisestørrelsen er lagret i NUM variabel og størrelsen på hvert array-element lagres i breddevariabel ved å bruke sizeof() forhåndsdefinert C-operatør.
- Vi kaller qsort-funksjonen og sender arraynavnet, størrelsen, bredden og sammenligningsfunksjonen som brukeren har definert tidligere, for å sortere arrayet vårt i stigende rekkefølge. Sammenligningen utføres ved å ta inn to arrayelementer i hver iterasjon til hele arrayet er sortert.
- Vi skriver ut array-elementene for å være sikre på at arrayet vårt er godt sortert ved å iterere hele arrayet ved å bruke for sløyfe.








