Funktionen Zeiger in der C-Programmierung mit Beispielen

Inhaltsverzeichnis:

Anonim

Zeiger bieten große Möglichkeiten für 'C'-Funktionen, bei denen wir nur einen Wert zurückgeben dürfen. Mit Zeigerparametern können unsere Funktionen jetzt tatsächliche Daten anstatt einer Kopie von Daten verarbeiten.

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

In diesem Tutorial lernen Sie:

  • Funktionszeiger Beispiel
  • Funktionen mit Array-Parametern
  • Funktionen, die ein Array zurückgeben
  • Funktionszeiger
  • Array von Funktionszeigern
  • Funktionen mit leeren Zeigern
  • Funktionszeiger als Argumente

Funktionszeiger Beispiel

Zum Beispiel tauscht das nächste Programm zwei Werte von zwei aus:

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

Ausgabe:

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

Das Programm tauscht die tatsächlichen Variablenwerte aus, da die Funktion mithilfe von Zeigern über die Adresse auf sie zugreift. Hier werden wir den Programmprozess diskutieren:

  1. Wir deklarieren die Funktion, die für das Vertauschen der beiden Variablenwerte verantwortlich ist. Dabei werden zwei ganzzahlige Zeiger als Parameter verwendet und beim Aufruf ein beliebiger Wert zurückgegeben.
  2. In der Hauptfunktion deklarieren und initialisieren wir zwei ganzzahlige Variablen ('m' und 'n') und drucken dann ihre jeweiligen Werte.
  3. Wir rufen die Funktion swap () auf, indem wir die Adresse der beiden Variablen als Argumente unter Verwendung des kaufmännischen Und-Symbols übergeben. Danach drucken wir die neuen vertauschten Werte von Variablen.
  4. Hier definieren wir den Funktionsinhalt von swap (), der zwei ganzzahlige Variablenadressen als Parameter verwendet, und deklarieren eine temporäre ganzzahlige Variable, die als drittes Speicherfeld verwendet wird, um eine der Wertvariablen zu speichern, die in die zweite Variable eingefügt werden.
  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 (mit b gekennzeichnet) um den Wert der ersten Variablen, die 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 (eine Adresse) ist, übergeben wir einfach einen Array-Namen an eine Funktion, was bedeutet, dass ein Zeiger an das Array übergeben wird.

Zum Beispiel betrachten wir 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);}

Ausgabe:

 Total summation is 471

Hier erklären wir den Programmcode mit seinen Details

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

Funktionen, die ein Array zurückgeben

In C können wir einen Zeiger auf ein Array zurückgeben, wie im folgenden Programm:

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

Ausgabe:

12345

Und hier werden wir die Programmdetails diskutieren

  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 Ganzzahlzeiger, der das vollständige Array empfängt, das nach dem Aufruf der Funktion erstellt wurde, und drucken seinen Inhalt durch Iteration des gesamten Arrays mit fünf Elementen.

Beachten Sie, dass ein Zeiger und kein Array zum Speichern der von der Funktion zurückgegebenen Array-Adresse definiert ist. Beachten Sie auch, dass eine lokale Variable, die von einer Funktion zurückgegeben wird, in der Funktion als statisch deklariert werden muss.

Funktionszeiger

Da wir per Definition wissen, dass Zeiger auf eine Adresse an einem beliebigen Speicherort verweisen, können sie auch auf Funktionen am Anfang des ausführbaren Codes als Funktionen im Speicher verweisen.

Ein Zeiger auf eine Funktion wird mit dem * deklariert. Die allgemeine Anweisung seiner Deklaration lautet:

return_type (*function_name)(arguments)

Sie müssen sich daran erinnern, dass die Klammern um (* Funktionsname) wichtig sind, da der Compiler ohne sie denkt, dass der Funktionsname einen Zeiger vom Typ return_type zurückgibt.

Nachdem wir den Funktionszeiger definiert haben, müssen wir ihn einer Funktion zuweisen. Zum Beispiel deklariert das nächste Programm eine gewöhnliche Funktion, definiert einen Funktionszeiger, weist den Funktionszeiger der gewöhnlichen Funktion zu und ruft danach die Funktion über den Zeiger auf:

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

Ausgabe:

HiHiHi

  1. Wir definieren und deklarieren eine Standardfunktion, die einen Hi-Text k-mal druckt, der durch die Parameterzeiten angegeben wird, wenn die Funktion aufgerufen wird
  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. Anstelle der Standardfunktion, die durch Tippen auf den Funktionsnamen mit Argumenten aufgerufen wird, rufen wir nur die Zeigerfunktion auf, indem wir die Nummer 3 als Argumente übergeben, und das war's!

Beachten Sie, dass der Funktionsname wie ein Array-Name, der auf sein erstes Element verweist, auf die Anfangsadresse des ausführbaren Codes 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 einen Schalter oder eine if-Anweisungsrolle spielen, um eine Entscheidung zu treffen, wie im nächsten Programm:

#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 diskutieren wir die Programmdetails:

  1. Wir deklarieren und definieren vier Funktionen, die zwei ganzzahlige Argumente annehmen und einen ganzzahligen Wert zurückgeben. Diese Funktionen addieren, subtrahieren, multiplizieren und dividieren die beiden Argumente, welche Funktion vom Benutzer aufgerufen wird.
  2. Wir deklarieren 4 Ganzzahlen, um Operanden, Operationstyp und Ergebnis zu behandeln. Außerdem deklarieren wir ein Array mit vier Funktionszeigern. Jeder Funktionszeiger des Array-Elements akzeptiert zwei ganzzahlige Parameter und gibt einen ganzzahligen Wert zurück.
  3. Wir weisen jedes Array-Element mit der bereits deklarierten Funktion zu und initialisieren sie. Zum Beispiel zeigt das dritte Element, das der dritte Funktionszeiger ist, auf die Multiplikationsoperationsfunktion.
  4. Wir suchen Operanden und Art der Operation von dem Benutzer, der mit der 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 dieselben Parameter und denselben Rückgabetyp haben.

Die Anweisung result = ope [Auswahl] (x, y); führt die entsprechende Funktion gemäß der vom Benutzer getroffenen Auswahl aus. Die beiden eingegebenen Ganzzahlen sind die Argumente, die an die Funktion übergeben werden.

Funktionen mit leeren Zeigern

Leere Zeiger werden bei Funktionsdeklarationen verwendet. Wir verwenden einen ungültigen * Rückgabetyp, um einen beliebigen Typ zurückzugeben. Wenn wir davon ausgehen, dass sich unsere Parameter beim Übergeben an eine Funktion nicht ändern, deklarieren wir sie als const.

Zum Beispiel:

 void * cube (const void *); 

Betrachten Sie das folgende Programm:

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

Ergebnis:

 4 cubed is 64 

Hier werden wir die Programmdetails diskutieren:

  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 Cube-Wert der Inhaltsvariablen (x), auf die der num-Zeiger zeigt, und da es sich um einen ungültigen Zeiger handelt, müssen wir ihn mit einem bestimmten Notationszeiger (* Datentyp) 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 wir behandeln den Rückgabewert in der Ergebnisvariablen

Funktionszeiger als Argumente

Eine andere Möglichkeit, einen Funktionszeiger auszunutzen, indem er als Argument an eine andere Funktion übergeben wird, die manchmal als "Rückruffunktion" bezeichnet 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, der aus zwei Argumenten besteht und 0 zurückgibt, wenn die Argumente denselben Wert haben, <0, wenn arg1 vor arg2 steht, und> 0, wenn arg1 nach arg2 steht.

Das folgende Programm sortiert ein ganzzahliges Array mit der Funktion qsort () von einer kleinen zu einer großen Zahl:

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

Ergebnis:

 13 14 48 50 52 

Hier werden wir die Programmdetails diskutieren:

  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 steht, und> 0, wenn arg1 nach arg2 steht. Die Parameter sind ein ungültiger Zeigertyp, der in den entsprechenden Array-Datentyp umgewandelt wird (ganze Zahl)
  2. Wir definieren und initialisieren ein ganzzahliges Array. Die Arraygröße wird in der Variablen num gespeichert , und die Größe jedes Arrayelements wird in der Variablen width unter Verwendung des vordefinierten C-Operators sizeof () gespeichert.
  3. Wir rufen die qsort- Funktion auf und übergeben den zuvor vom Benutzer definierten Namen, die Größe, die Breite und die Vergleichsfunktion des Arrays, um unser Array in aufsteigender Reihenfolge zu sortieren. Der Vergleich wird durchgeführt, indem in jeder Iteration zwei Array-Elemente bis zum gesamten Array berücksichtigt werden wird sortiert.
  4. Wir drucken die Array-Elemente, um sicherzustellen, dass unser Array gut sortiert ist, indem wir das gesamte Array mit der for-Schleife iterieren.