Funkcije Pokazatelji u C programiranju s primjerima

Sadržaj:

Anonim

Pokazivači daju velike mogućnosti funkcijama 'C' kojima smo ograničeni da vratimo jednu vrijednost. S parametrima pokazivača, naše funkcije sada mogu obrađivati ​​stvarne podatke, a ne kopiju podataka.

Da bi se izmijenile stvarne vrijednosti varijabli, pozivni izraz prosljeđuje adrese parametrima pokazivača u funkciji.

U ovom vodiču naučit ćete-

  • Primjer pokazivača na funkcije
  • Funkcije s parametrima niza
  • Funkcije koje vraćaju niz
  • Pokazatelji na funkcije
  • Niz pokazivača na funkcije
  • Funkcije pomoću praznih pokazivača
  • Pokazatelji na funkciju kao argumenti

Primjer pokazivača na funkcije

Na primjer, sljedeći program zamjenjuje dvije vrijednosti dvije:

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;}}

Izlaz:

m is 25, n is 100m is 100, n is 25

Program zamjenjuje stvarne vrijednosti varijabli jer im funkcija pristupa pomoću adrese pomoću pokazivača. Ovdje ćemo razgovarati o programskom procesu:

  1. Deklariramo funkciju odgovornom za zamjenu dviju vrijednosti varijable, koja uzima dva cjelobrojna pokazivača kao parametre i vraća bilo koju vrijednost kad je pozvana.
  2. U glavnoj funkciji deklariramo i inicijaliziramo dvije cjelobrojne varijable ('m' i 'n'), a zatim ispisujemo njihove vrijednosti.
  3. Funkciju swap () nazivamo prosljeđivanjem adrese dviju varijabli kao argumenata pomoću znaka ampersand. Nakon toga ispisujemo nove zamijenjene vrijednosti varijabli.
  4. Ovdje definiramo sadržaj funkcije swap () koji uzima dvije adrese cjelobrojnih varijabli kao parametre i deklarira privremenu cjelobrojnu varijablu koja se koristi kao treći okvir za pohranu za spremanje jedne od varijabli vrijednosti koje će se staviti u drugu varijablu.
  5. Spremite sadržaj prve varijable naznačene s 'a' u privremenu varijablu.
  6. Spremite drugu varijablu uperenu s b u prvu varijablu uperenu s a.
  7. Ažurirajte drugu varijablu (na koju ukazuje b) vrijednošću prve varijable spremljene u privremenoj varijabli.

Funkcije s parametrima niza

U C-u funkciju ne možemo proslijediti niz po vrijednosti. Dok je ime niza pokazivač (adresa), tako da samo prosljeđujemo ime niza funkciji što znači prosljeđivanje pokazivača na niz.

Na primjer, uzimamo u obzir sljedeći 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);}

Izlaz:

 Total summation is 471

Ovdje ćemo objasniti programski kod s njegovim detaljima

  1. Deklariramo i definiramo funkciju add_array () koja kao niz uzima adresu niza (pokazivač) s brojem njegovih elemenata i vraća ukupni akumulirani zbroj tih elemenata. Pokazivač se koristi za iteraciju elemenata niza (pomoću oznake p [k]), a zbrajanje sakupljamo u lokalnoj varijabli koja će se vratiti nakon iteracije cijelog niza elemenata.
  2. Deklariramo i inicijaliziramo cjelobrojni niz s pet cjelobrojnih elemenata. Ukupan zbroj ispisujemo prosljeđivanjem imena polja (koje djeluje kao adresa) i veličine polja u add_array () koja se naziva funkcija kao argumenti.

Funkcije koje vraćaju niz

U C-u možemo vratiti pokazivač na niz, kao u sljedećem programu:

#include 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);}

Izlaz:

12345

I ovdje ćemo razgovarati o detaljima programa

  1. Definiramo i deklariramo funkciju koja vraća adresu niza koja sadrži cijelu vrijednost i nije uzela nikakve argumente.
  2. Deklariramo cjelobrojni pokazivač koji prima kompletan niz izgrađen nakon što je funkcija pozvana i njegov sadržaj ispisujemo iteracijom cijelog niza od pet elemenata.

Primijetite da je pokazivač, a ne niz, definiran za spremanje adrese niza koju vraća funkcija. Također primijetite da kada se lokalna varijabla vraća iz funkcije, moramo je deklarirati kao statičku u funkciji.

Pokazatelji na funkcije

Kao što po definiciji znamo da pokazivači upućuju na adresu na bilo kojem memorijskom mjestu, oni također mogu ukazivati ​​na početak izvršnog koda kao funkcije u memoriji.

Pokazivač na funkciju deklarira se sa *, općeniti iskaz njegove deklaracije je:

return_type (*function_name)(arguments)

Morate imati na umu da su zagrade oko (* ime_funkcije) važne jer će bez njih prevoditelj misliti da funkcija_ime vraća pokazivač return_type.

Nakon definiranja pokazivača funkcije, moramo ga dodijeliti funkciji. Na primjer, sljedeći program deklarira uobičajenu funkciju, definira pokazivač funkcije, dodjeljuje pokazivač funkcije uobičajenoj funkciji i nakon toga poziva funkciju kroz pokazivač:

#include 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");} 

Izlaz:

HiHiHi

  1. Definiramo i deklariramo standardnu ​​funkciju koja ispisuje Hi tekst k puta označena parametrima puta kada je funkcija pozvana
  2. Definiramo pokazivačku funkciju (s njenom posebnom deklaracijom) koja uzima cjelobrojni parametar i ne vraća ništa.
  3. Funkciju pokazivača inicijaliziramo funkcijom Hi_, što znači da pokazivač pokazuje na funkciju Hi_ ().
  4. Umjesto standardnog pozivanja funkcije lijepljenjem imena funkcije argumentima, pozivamo samo funkciju pokazivača dodavanjem broja 3 kao argumenta, i to je to!

Imajte na umu da ime funkcije pokazuje na početnu adresu izvršnog koda poput imena niza koji upućuje na njezin prvi element. Stoga su upute poput function_ptr = & Hi_function i (* funptr) (3) točne.

NAPOMENA: Nije važno umetnuti adresni operator & i indirektni operator * tijekom dodjele funkcije i poziva funkcije.

Niz pokazivača na funkcije

Niz pokazivača na funkcije može igrati prekidač ili ulogu if izraza za donošenje odluke, kao u sljedećem programu:

#include 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 48Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2624

Ovdje razgovaramo o pojedinostima programa:

  1. Deklariramo i definiramo četiri funkcije koje uzimaju dva cjelobrojna argumenta i vraćaju cjelobrojnu vrijednost. Te funkcije dodaju, oduzimaju, množe i dijele dva argumenta u vezi s tim koju funkciju korisnik poziva.
  2. Deklariramo 4 cijele brojeve za obradu operanda, vrste operacije i rezultata. Također, deklariramo niz od četiri pokazivača funkcije. Svaki pokazivač funkcije elementa niza uzima dva cjelobrojna parametra i vraća cijelu vrijednost.
  3. Dodjeljujemo i inicijaliziramo svaki element polja s već deklariranom funkcijom. Na primjer, treći element koji je pokazivač treće funkcije ukazat će na funkciju množenja.
  4. Operande i vrstu radnje tražimo od korisnika koji je upisan tipkovnicom.
  5. Argumenti smo pozvali odgovarajući element niza (pokazivač funkcije) i pohranjujemo rezultat generiran odgovarajućom funkcijom.

Uputa int (* ope [4]) (int, int); definira niz pokazivača na funkcije. Svaki element polja mora imati iste parametre i tip povratka.

Rezultat izjave = ope [izbor] (x, y); pokreće odgovarajuću funkciju prema izboru koji je izvršio korisnik Dvije unesene cijele vrijednosti su argumenti prosljeđeni funkciji.

Funkcije pomoću praznih pokazivača

Prazni pokazivači koriste se tijekom deklaracija funkcije. Za vraćanje bilo koje vrste koristimo dozvole tipa void *. Ako pretpostavimo da se naši parametri ne mijenjaju prilikom prosljeđivanja funkciji, deklariramo je kao const.

Na primjer:

 void * cube (const void *); 

Razmotrite sljedeći program:

#include 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;}

Proizlaziti:

 4 cubed is 64 

Ovdje ćemo razgovarati o pojedinostima programa:

  1. Definiramo i deklariramo funkciju koja vraća cijelu vrijednost i uzima adresu nepromjenjive varijable bez određenog tipa podataka. Izračunavamo vrijednost kocke varijable sadržaja (x) na koju pokazuje pokazivač num, a kako je to void pokazivač, moramo je otkucati u cjelobrojni tip podataka koristeći određeni pokazivač za notaciju (* datatype) i vraćamo vrijednost kocke.
  2. Deklariramo operand i varijablu rezultata. Također, svoj operand inicijaliziramo vrijednošću "4."
  3. Funkciju kocke pozivamo prosljeđivanjem adrese operanda i obrađujemo povratnu vrijednost u varijabli rezultata

Pokazatelji na funkciju kao argumenti

Drugi način iskorištavanja pokazivača na funkciju prosljeđujući ga kao argument drugoj funkciji koja se ponekad naziva "funkcija povratnog poziva", jer ga funkcija primanja "poziva natrag".

U zaglavnoj datoteci stdlib.h, funkcija Quicksort "qsort ()" koristi ovu tehniku ​​koja je algoritam namijenjen sortiranju niza.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
  • void * baza: void pokazivač na niz.
  • size_t num: Broj elementa niza.
  • size_t width Veličina elementa.
  • int (* usporedi (const void *, const void *): pokazivač funkcije sastavljen od dva argumenta i vraća 0 kada argumenti imaju istu vrijednost, <0 kada arg1 dolazi prije arg2, i> 0 kada arg1 dolazi nakon arg2.

Sljedeći program sortira celobrojni niz od malog do većeg broja pomoću funkcije 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;}

Proizlaziti:

 13 14 48 50 52 

Ovdje ćemo razgovarati o pojedinostima programa:

  1. Definiramo funkciju uspoređivanja koja se sastoji od dva argumenta i vraća 0 kada argumenti imaju istu vrijednost, <0 kada arg1 dolazi prije arg2, i> 0 kada arg1 dolazi nakon arg2. Parametri su tip praznih pokazivača lijevan u odgovarajući tip podataka niza (cijeli broj)
  2. Definiramo i inicijaliziramo cjelobrojni niz Veličina polja pohranjuje se u varijablu num, a veličina svakog elementa niza pohranjuje se u varijablu širine pomoću unaprijed definiranog C operatora sizeof ().
  3. Pozivamo funkciju qsort i prosljeđujemo ime niza, veličinu, širinu i funkciju usporedbe koje je korisnik prethodno definirao kako bi sortirali naš niz u rastućem redoslijedu. Usporedba će se izvesti uzimajući u svakoj iteraciji dva elementa niza sve dok cijeli niz bit će sortirano.
  4. Ispisujemo elemente niza kako bismo bili sigurni da je naš niz dobro sortiran iteracijom cijelog niza pomoću petlje for.