Functies Aanwijzingen in C-programmering met voorbeelden

Inhoudsopgave:

Anonim

Aanwijzers geven enorm veel mogelijkheden aan 'C'-functies waarvan we beperkt zijn om één waarde te retourneren. Met aanwijzerparameters kunnen onze functies nu feitelijke gegevens verwerken in plaats van een kopie van gegevens.

Om de werkelijke waarden van variabelen te wijzigen, geeft de aanroepende instructie adressen door aan pointerparameters in een functie.

In deze tutorial leer je-

  • Functies Aanwijzers Voorbeeld
  • Functies met matrixparameters
  • Functies die een array retourneren
  • Functie Pointers
  • Array van functie-aanwijzers
  • Functies die lege Pointers gebruiken
  • Functie Pointers als argumenten

Functies Aanwijzers Voorbeeld

Het volgende programma wisselt bijvoorbeeld twee waarden van twee:

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

Uitgang:

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

Het programma wisselt de waarden van de feitelijke variabelen om omdat de functie ze benadert door middel van een adres met behulp van pointers. Hier bespreken we het programmaproces:

  1. We verklaren de functie die verantwoordelijk is voor het verwisselen van de twee variabelewaarden, die twee integer-aanwijzers als parameters heeft en elke waarde retourneert wanneer deze wordt aangeroepen.
  2. In de hoofdfunctie declareren en initialiseren we twee integer-variabelen ('m' en 'n') en vervolgens drukken we hun waarden respectievelijk af.
  3. We roepen de functie swap () aan door het adres van de twee variabelen als argumenten door te geven met het ampersand-symbool. Daarna drukken we de nieuwe verwisselde waarden van variabelen af.
  4. Hier definiëren we de inhoud van de swap () -functie die twee integer-variabele-adressen als parameters heeft en een tijdelijke integer-variabele declareren die wordt gebruikt als een derde opslagvak om een ​​van de waardevariabelen op te slaan die naar de tweede variabele zal worden gestuurd.
  5. Bewaar de inhoud van de eerste variabele aangeduid met 'a' in de tijdelijke variabele.
  6. Sla de tweede variabele aangeduid met b op in de eerste variabele met a.
  7. Werk de tweede variabele (aangegeven met b) bij met de waarde van de eerste variabele die is opgeslagen in de tijdelijke variabele.

Functies met matrixparameters

In C kunnen we een array op waarde niet doorgeven aan een functie. Terwijl een arraynaam een ​​pointer (adres) is, geven we gewoon een arraynaam door aan een functie, wat betekent dat we een pointer naar de array moeten doorgeven.

We beschouwen bijvoorbeeld het volgende programma:

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

Uitgang:

 Total summation is 471

Hier zullen we de programmacode met zijn details uitleggen

  1. We declareren en definiëren de functie add_array () die een array-adres (pointer) met zijn elementnummer als parameters aanneemt en de totale geaccumuleerde sommatie van deze elementen retourneert. De pointer wordt gebruikt om de array-elementen te itereren (met behulp van de p [k] -notatie), en we verzamelen de sommatie in een lokale variabele die zal worden geretourneerd na iteratie van de hele elementarray.
  2. We declareren en initialiseren een integer-array met vijf integer-elementen. We drukken de totale som af door de arraynaam (die als adres fungeert) en de arraygrootte door te geven aan de add_array () genaamd functie als argumenten.

Functies die een array retourneren

In C kunnen we een pointer naar een array retourneren, zoals in het volgende programma:

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

Uitgang:

12345

En hier bespreken we de programmadetails

  1. We definiëren en declareren een functie die een matrixadres retourneert dat een geheel getal bevat en geen argumenten accepteert.
  2. We declareren een integer-pointer die de volledige array ontvangt die is gebouwd nadat de functie is aangeroepen en we drukken de inhoud af door de volledige array met vijf elementen te herhalen.

Merk op dat een pointer, geen array, is gedefinieerd om het array-adres op te slaan dat door de functie wordt geretourneerd. Merk ook op dat wanneer een lokale variabele wordt geretourneerd door een functie, we deze als statisch moeten declareren in de functie.

Functie Pointers

Zoals we per definitie weten dat pointers naar een adres in elke geheugenlocatie verwijzen, kunnen ze ook verwijzen naar het begin van uitvoerbare code als functies in het geheugen.

Een pointer naar functie wordt gedeclareerd met de *, de algemene verklaring van zijn declaratie is:

return_type (*function_name)(arguments)

Je moet onthouden dat de haakjes rond (* functienaam) belangrijk zijn, want zonder deze zal de compiler denken dat de functienaam een ​​pointer retourneert van return_type.

Nadat we de functiepointer hebben gedefinieerd, moeten we deze aan een functie toewijzen. Het volgende programma declareert bijvoorbeeld een gewone functie, definieert een functiepointer, wijst de functiepointer toe aan de gewone functie en roept daarna de functie op via de pointer:

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

Uitgang:

HiHiHi

  1. We definiëren en declareren een standaardfunctie die een Hi-tekst k keer afdrukt, aangegeven door de parameter keer wanneer de functie wordt aangeroepen
  2. We definiëren een pointerfunctie (met zijn speciale declaratie) die een integer-parameter accepteert en niets retourneert.
  3. We initialiseren onze pointer-functie met de Hi_function, wat betekent dat de pointer naar de Hi_function () wijst.
  4. In plaats van de standaardfunctie aan te roepen door de functienaam met argumenten te tapen, roepen we alleen de pointerfunctie aan door het getal 3 als argumenten door te geven, en dat is alles!

Houd er rekening mee dat de functienaam verwijst naar het beginadres van de uitvoerbare code, zoals een arraynaam die naar het eerste element verwijst. Daarom zijn instructies zoals function_ptr = & Hi_function en (* funptr) (3) correct.

OPMERKING: Het is niet belangrijk om de adresoperator & en de indirecte operator * in te voeren tijdens de functietoewijzing en functieaanroep.

Array van functie-aanwijzers

Een reeks functiewijzers kan een switch- of if-statementrol spelen bij het nemen van een beslissing, zoals in het volgende programma:

#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

Hier bespreken we de programmadetails:

  1. We declareren en definiëren vier functies die twee integer-argumenten nemen en een integer-waarde retourneren. Deze functies tellen op, trekken af, vermenigvuldigen en delen de twee argumenten met betrekking tot welke functie door de gebruiker wordt aangeroepen.
  2. We declareren 4 gehele getallen om respectievelijk operanden, bewerkingstype en resultaat af te handelen. We declareren ook een reeks van aanwijzer met vier functies. Elke functieaanwijzer van het array-element heeft twee parameters voor gehele getallen en retourneert een geheel getal.
  3. We wijzen elk array-element toe en initialiseren met de functie al gedeclareerd. Het derde element dat de derde functieaanwijzer is, wijst bijvoorbeeld naar de functie voor vermenigvuldiging.
  4. We zoeken operanden en het type bewerking van de gebruiker die met het toetsenbord is getypt.
  5. We hebben het juiste array-element (Functiepointer) aangeroepen met argumenten, en we slaan het resultaat op dat door de juiste functie is gegenereerd.

De instructie int (* ope [4]) (int, int); definieert de reeks functiewijzers. Elk array-element moet dezelfde parameters en hetzelfde retourtype hebben.

Het statement resultaat = ope [keuze] (x, y); voert de juiste functie uit volgens de keuze van de gebruiker. De twee ingevoerde gehele getallen zijn de argumenten die aan de functie worden doorgegeven.

Functies die lege Pointers gebruiken

Ongeldige verwijzingen worden gebruikt tijdens functieverklaringen. We gebruiken een ongeldige * retourtoestemming om elk type te retourneren. Als we aannemen dat onze parameters niet veranderen bij het doorgeven aan een functie, declareren we deze als const.

Bijvoorbeeld:

 void * cube (const void *); 

Beschouw het volgende programma:

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

Resultaat:

 4 cubed is 64 

Hier bespreken we de programmadetails:

  1. We definiëren en declareren een functie die een geheel getal retourneert en een adres aanneemt van een onveranderlijke variabele zonder een specifiek gegevenstype. We berekenen de kubuswaarde van de inhoudsvariabele (x) aangewezen door de num pointer, en aangezien het een lege pointer is, moeten we het casten naar een integer datatype met behulp van een specifieke notatie (* datatype) pointer, en we retourneren de kubuswaarde.
  2. We declareren de operand en de resultaatvariabele. We initialiseren ook onze operand met de waarde "4".
  3. We noemen de kubusfunctie door het operandadres door te geven, en we behandelen de terugkerende waarde in de resultaatvariabele

Functie Pointers als argumenten

Een andere manier om een ​​functiepointer te exploiteren door deze als een argument door te geven aan een andere functie die soms "callback-functie" wordt genoemd, omdat de ontvangende functie hem "terugroept".

In het header-bestand stdlib.h gebruikt de Quicksort "qsort ()" -functie deze techniek, een algoritme dat is toegewijd om een ​​array te sorteren.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
  • void * base: void pointer naar de array.
  • size_t num: Het array-elementnummer.
  • size_t width De elementgrootte.
  • int (* vergelijk (const void *, const void *): functie pointer samengesteld uit twee argumenten en retourneert 0 als de argumenten dezelfde waarde hebben, <0 als arg1 voor arg2 komt, en> 0 als arg1 na arg2 komt.

Het volgende programma sorteert een array met gehele getallen van klein naar groot getal met de functie 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;}

Resultaat:

 13 14 48 50 52 

Hier bespreken we de programmadetails:

  1. We definiëren de vergelijkingsfunctie die is samengesteld uit twee argumenten en retourneert 0 als de argumenten dezelfde waarde hebben, <0 als arg1 voor arg2 komt en> 0 als arg1 na arg2 komt. (geheel getal)
  2. We definiëren en initialiseren een integer-array. De array-grootte wordt opgeslagen in de variabele num en de grootte van elk array-element wordt opgeslagen in de breedtevariabele met behulp van de vooraf gedefinieerde C-operator sizeof ().
  3. We noemen de qsort- functie en geven de arraynaam, grootte, breedte en vergelijkingsfunctie door die eerder door de gebruiker zijn gedefinieerd om onze array in oplopende volgorde te sorteren.De vergelijking wordt uitgevoerd door in elke iteratie twee array-elementen te nemen tot de volledige array zal worden gesorteerd.
  4. We drukken de array-elementen af ​​om er zeker van te zijn dat onze array goed is gesorteerd door de hele array te herhalen met for-lus.