Funktionszeiger in der C-Programmierung mit Beispielen

Zeiger bieten C-Funktionen viele Mรถglichkeiten, bei denen wir auf die Rรผckgabe eines Werts beschrรคnkt sind. Mit Zeigerparametern kรถnnen unsere Funktionen jetzt tatsรคchliche Daten statt einer Kopie von Daten verarbeiten.

Um die tatsรคchlichen Werte von Variablen zu รคndern, รผbergibt die aufrufende Anweisung Adressen an Zeigerparameter in einer Funktion.

Beispiel fรผr Funktionszeiger

Das nรคchste Programm vertauscht beispielsweise zwei Werte von zwei:

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

Ausgang:

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

Beispiel fรผr Funktionszeiger

Das Programm tauscht die tatsรคchlichen Variablenwerte aus, da die Funktion รผber die Adresse auf sie zugreift Zeiger. Hier besprechen wir den Programmablauf:

  1. Wir deklarieren die fรผr den Tausch zustรคndige Funktion.ping die beiden Variablenwerte, die zwei Integer-Zeiger als Parameter entgegennimmt und bei Aufruf einen beliebigen Wert zurรผckgibt.
  2. In der Hauptfunktion deklarieren und initialisieren wir zwei ganzzahlige Variablen ('m' und 'n') und geben dann jeweils ihre Werte aus.
  3. Wir rufen die Funktion swap() auf, indem wir die Adressen der beiden Variablen als Argumente mit dem kaufmรคnnischen Und-Symbol รผbergeben. Danach drucken wir die neuen ausgetauschten Werte der Variablen aus.
  4. Hier definieren wir den Inhalt der Funktion swap(), die zwei Adressen von Integer-Variablen als Parameter verwendet, und deklarieren eine temporรคre Integer-Variable, die als drittes Speicherfeld zum Speichern einer der Wertvariablen verwendet wird, die in die zweite Variable eingefรผgt wird.
  5. Speichern Sie den Inhalt der ersten Variablen, auf die โ€žaโ€œ zeigt, in der temporรคren Variablen.
  6. Speichern Sie die zweite Variable, auf die b zeigt, in der ersten Variablen, auf die a zeigt.
  7. Aktualisieren Sie die zweite Variable (auf die b zeigt) mit dem Wert der ersten Variablen, der in der temporรคren Variablen gespeichert ist.

Funktionen mit Array-Parametern

In C kรถnnen wir ein Array nicht als Wert an eine Funktion รผbergeben. Wรคhrend ein Array-Name ein Zeiger (Adresse) ist, รผbergeben wir einfach einen Array-Namen an eine Funktion, was bedeutet, dass ein Zeiger auf das Array รผbergeben wird.

Wir betrachten beispielsweise das folgende Programm:

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

Ausgang:

 Total summation is 471

Hier erklรคren wir den Programmcode mit seinen Details

Funktionen mit Array-Parametern

  1. Wir deklarieren und definieren die Funktion add_array(), die eine Array-Adresse (Zeiger) mit der Nummer ihrer Elemente als Parameter verwendet und die akkumulierte Gesamtsumme dieser Elemente zurรผckgibt. Der Zeiger wird verwendet, um die Array-Elemente zu iterieren (unter Verwendung der p[k]-Notation), und wir sammeln die Summe in einer lokalen Variablen, die nach der Iteration des gesamten Elementarrays zurรผckgegeben wird.
  2. Wir deklarieren und initialisieren ein Integer-Array mit fรผnf Integer-Elementen. Wir drucken die Gesamtsumme aus, indem wir den Array-Namen (der als Adresse fungiert) und die Array-GrรถรŸe an รผbergeben add_array()aufgerufene Funktion als Argumente.

Funktionen, die ein Array zurรผckgeben

In C kรถnnen wir einen Zeiger auf ein Array zurรผckgeben, wie im folgenden Programm:

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

Ausgang:

1
2
3
4
5

Und hier besprechen wir die Programmdetails

Funktionen, die ein Array zurรผckgeben

  1. Wir definieren und deklarieren eine Funktion, die eine Array-Adresse zurรผckgibt, die einen ganzzahligen Wert enthรคlt und keine Argumente akzeptiert.
  2. Wir deklarieren einen ganzzahligen Zeiger, der das vollstรคndige Array empfรคngt, das nach dem Aufruf der Funktion erstellt wurde, und geben seinen Inhalt aus, indem wir das gesamte Array mit fรผnf Elementen iterieren.

Beachten Sie, dass zum Speichern der von der Funktion zurรผckgegebenen Array-Adresse ein Zeiger und kein Array definiert ist. Beachten Sie auch, dass wir eine lokale Variable, die von einer Funktion zurรผckgegeben wird, in der Funktion als statisch deklarieren mรผssen.

Funktionszeiger

Da wir per Definition wissen, dass Zeiger auf eine Adresse an einem beliebigen Speicherort verweisen, kรถnnen sie auch auf den Anfang von ausfรผhrbarem Code als Funktionen im Speicher verweisen.
Ein Zeiger auf eine Funktion wird mit * deklariert. Die allgemeine Aussage seiner Deklaration lautet:

return_type (*function_name)(arguments)

Sie mรผssen bedenken, dass die Klammern um (*Funktionsname) wichtig sind, denn ohne sie geht der Compiler davon aus, dass der Funktionsname einen Zeiger vom Rรผckgabetyp zurรผckgibt.
Nachdem wir den Funktionszeiger definiert haben, mรผssen wir ihn einer Funktion zuweisen. Das nรคchste Programm deklariert beispielsweise eine normale Funktion, definiert einen Funktionszeiger, weist den Funktionszeiger der normalen Funktion zu und ruft danach die Funktion รผber den Zeiger auf:

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

Ausgang:

Hi
Hi
Hi

Funktionszeiger in C

  1. Wir definieren und deklarieren eine Standardfunktion, die beim Aufruf der Funktion k-mal einen durch den Parameter angegebenen Hi-Text ausgibt
  2. Wir definieren eine Zeigerfunktion (mit ihrer speziellen Deklaration), die einen ganzzahligen Parameter akzeptiert und nichts zurรผckgibt.
  3. Wir initialisieren unsere Zeigerfunktion mit der Hi_function, was bedeutet, dass der Zeiger auf die Hi_function() zeigt.
  4. Anstatt des Standardfunktionsaufrufs durch taping den Funktionsnamen mit Argumenten, wir rufen nur die Zeigerfunktion auf, indem wir die Zahl 3 als Argumente รผbergeben, und das war's!

Beachten Sie, dass der Funktionsname auf die Anfangsadresse des ausfรผhrbaren Codes verweist, wie ein Array-Name, der auf sein erstes Element verweist. Daher sind Anweisungen wie function_ptr = &Hi_function und (*funptr)(3) korrekt.
HINWEIS: Es ist nicht wichtig, den Adressoperator & und den Indirektionsoperator * wรคhrend der Funktionszuweisung und des Funktionsaufrufs einzufรผgen.

Array von Funktionszeigern

Ein Array von Funktionszeigern kann bei der Entscheidungsfindung eine Schalter- oder if-Anweisungsrolle spielen, wie im nรคchsten Programm:

#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

Hier besprechen wir die Programmdetails:

Array von Funktionszeigern

  1. Wir deklarieren und definieren vier Funktionen Diese Funktionen nehmen zwei ganzzahlige Argumente entgegen und geben einen ganzzahligen Wert zurรผck. Sie addieren und subtrahieren.tract, multipliziere und dividiere die beiden Argumente, die angeben, welche Funktion vom Benutzer aufgerufen wird.
  2. Wir deklarieren 4 Ganzzahlen, um Operanden, Operationstyp und Ergebnis zu verarbeiten. AuรŸerdem deklarieren wir ein Array mit vier Funktionszeigern. Jeder Funktionszeiger eines Array-Elements nimmt zwei Ganzzahlparameter an und gibt einen Ganzzahlwert zurรผck.
  3. Wir weisen jedem Array-Element die bereits deklarierte Funktion zu und initialisieren es. Beispielsweise zeigt das dritte Element, das der dritte Funktionszeiger ist, auf die Multiplikationsoperationsfunktion.
  4. Wir suchen nach Operanden und Operationstypen, die der Benutzer รผber die Tastatur eingegeben hat.
  5. Wir haben das entsprechende Array-Element (Funktionszeiger) mit Argumenten aufgerufen und das von der entsprechenden Funktion generierte Ergebnis gespeichert.

Die Anweisung int (*ope[4])(int, int); definiert das Array von Funktionszeigern. Jedes Array-Element muss die gleichen Parameter und den gleichen Rรผckgabetyp haben.
Die Anweisung result = ope[choice](x, y); fรผhrt die entsprechende Funktion entsprechend der vom Benutzer getroffenen Auswahl aus. Die beiden eingegebenen Ganzzahlen sind die an die Funktion รผbergebenen Argumente.

Funktionen, die leere Zeiger verwenden

Leere Zeiger werden bei Funktionsdeklarationen verwendet. Wir verwenden einen void *-Rรผckgabetyp, der die Rรผckgabe eines beliebigen Typs ermรถglicht. Wenn wir davon ausgehen, dass sich unsere Parameter bei der รœbergabe an eine Funktion nicht รคndern, deklarieren wir sie als const.
Beispielsweise:

 void * cube (const void *);

Betrachten Sie das folgende Programm:

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

Ergebnis:

 4 cubed is 64

Hier besprechen wir die Programmdetails:

Funktionen, die leere Zeiger verwenden

  1. Wir definieren und deklarieren eine Funktion, die einen ganzzahligen Wert zurรผckgibt und eine Adresse einer unverรคnderlichen Variablen ohne einen bestimmten Datentyp annimmt. Wir berechnen den Wรผrfelwert der Inhaltsvariablen (x), auf die der Num-Zeiger zeigt, und da es sich um einen void-Zeiger handelt, mรผssen wir ihn unter Verwendung einer bestimmten Notation (*-Datentyp)-Zeiger in einen ganzzahligen Datentyp umwandeln, und wir kehren zurรผck der Wรผrfelwert.
  2. Wir deklarieren den Operanden und die Ergebnisvariable. AuรŸerdem initialisieren wir unseren Operanden mit dem Wert โ€ž4โ€œ.
  3. Wir rufen die Cube-Funktion auf, indem wir die Operandenadresse รผbergeben, und verarbeiten den Rรผckgabewert in der Ergebnisvariablen

Funktionszeiger als Argumente

Eine andere Mรถglichkeit, einen Funktionszeiger auszunutzen, besteht darin, ihn als Argument an eine andere Funktion zu รผbergeben, die manchmal โ€žRรผckruffunktionโ€œ genannt wird, weil die empfangende Funktion ihn โ€žzurรผckruftโ€œ.
In der Header-Datei stdlib.h verwendet die Quicksort-Funktion โ€žqsort()โ€œ diese Technik, bei der es sich um einen Algorithmus zum Sortieren eines Arrays handelt.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
  • void *base: void-Zeiger auf das Array.
  • size_t num: Die Array-Elementnummer.
  • size_t width Die ElementgrรถรŸe.
  • int (*compare (const void *, const void *) : Funktionszeiger bestehend aus zwei Argumenten und gibt 0 zurรผck, wenn die Argumente denselben Wert haben, <0, wenn arg1 vor arg2 kommt, und >0, wenn arg1 nach arg2 kommt.

Das folgende Programm sortiert ein Array von Ganzzahlen von klein nach groรŸ mithilfe der Funktion qsort():

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

Ergebnis:

 13 14 48 50 52

Hier besprechen wir die Programmdetails:

Funktionszeiger als Argumente

  1. Wir definieren eine Vergleichsfunktion, die aus zwei Argumenten besteht und 0 zurรผckgibt, wenn die Argumente denselben Wert haben, <0, wenn arg1 vor arg2 kommt, und >0, wenn arg1 nach arg2 kommt. Die Parameter sind ein leerer Zeigertyp, der in den entsprechenden Array-Datentyp umgewandelt wird (ganze Zahl)
  2. Wir definieren und initialisieren ein Integer-Array. Die Array-GrรถรŸe wird im gespeichert num Variable und die GrรถรŸe jedes Array-Elements wird in der Breitenvariablen gespeichert, wobei sizeof() vordefiniert ist C-Operator.
  3. Wir nennen das qsort Funktion und รผbergeben Sie den zuvor vom Benutzer definierten Array-Namen, die GrรถรŸe, die Breite und die Vergleichsfunktion, um unser Array in aufsteigender Reihenfolge zu sortieren. Der Vergleich wird durchgefรผhrt, indem in jeder Iteration zwei Array-Elemente aufgenommen werden, bis das gesamte Array sortiert ist.
  4. Wir drucken die Array-Elemente aus, um sicherzustellen, dass unser Array gut sortiert ist, indem wir das gesamte Array mit iterieren for-Schleife.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: