Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Pointeurs de fonctions en programmation C avec exemples

Les pointeurs donnent de grandes possibilités aux fonctions ‘C’ que nous sommes limités à retourner une valeur. Avec les paramètres de pointeur, nos fonctions peuvent désormais traiter des données réelles plutôt qu'une copie de données.
Afin de modifier les valeurs réelles des variables, l'instruction d'appel transmet des adresses aux paramètres de pointeur dans une fonction.
Dans ce tutoriel, vous apprendrez-

Exemple de pointeurs de fonctions

Par exemple, le programme suivant échange deux valeurs de deux :

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

Sortie :

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

Le programme permute les valeurs réelles des variables car la fonction y accède par adresse à l'aide de pointeurs. Ici, nous allons discuter du processus du programme :

  1. Nous déclarons la fonction responsable de l'échange des deux valeurs de variable, qui prend deux pointeurs entiers comme paramètres et renvoie n'importe quelle valeur lorsqu'elle est appelée.
  2. Dans la fonction main, nous déclarons et initialisons deux variables entières ('m' et 'n') puis nous imprimons leurs valeurs respectivement.
  3. Nous appelons la fonction swap() en passant l'adresse des deux variables comme arguments en utilisant le symbole esperluette. Après cela, nous imprimons les nouvelles valeurs échangées des variables.
  4. Ici, nous définissons le contenu de la fonction swap() qui prend deux adresses de variables entières comme paramètres et déclare une variable entière temporaire utilisée comme troisième boîte de stockage pour enregistrer l'une des variables de valeur qui sera placée dans la deuxième variable.
  5. Enregistrer le contenu de la première variable pointée par "a" dans la variable temporaire.
  6. Stocker la deuxième variable pointée par b dans la première variable pointée par a.
  7. Mettre à jour la deuxième variable (pointée par b) par la valeur de la première variable enregistrée dans la variable temporaire.

Fonctions avec des paramètres de tableau

En C, nous ne pouvons pas passer un tableau par valeur à une fonction. Alors qu'un nom de tableau est un pointeur (adresse), nous passons simplement un nom de tableau à une fonction, ce qui signifie passer un pointeur vers le tableau.

Par exemple, considérons le programme suivant :

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

Sortie :

 Total summation is 471

Ici, nous allons vous expliquer le code du programme avec ses détails

  1. Nous déclarons et définissons la fonction add_array() qui prend une adresse de tableau (pointeur) avec son numéro d'éléments comme paramètres et renvoie la somme totale accumulée de ces éléments. Le pointeur est utilisé pour itérer les éléments du tableau (en utilisant la notation p[k]), et nous accumulons la sommation dans une variable locale qui sera renvoyée après avoir itéré tout le tableau d'éléments.
  2. Nous déclarons et initialisons un tableau d'entiers avec cinq éléments entiers. Nous imprimons la somme totale en transmettant le nom du tableau (qui agit comme adresse) et la taille du tableau à add_array() fonction appelée en tant qu'arguments.

Fonctions qui renvoient un tableau

En C, nous pouvons renvoyer un pointeur vers un tableau, comme dans le programme suivant :

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

Sortie :

1
2
3
4
5

Et ici, nous discuterons des détails du programme

  1. Nous définissons et déclarons une fonction qui renvoie une adresse de tableau contenant une valeur entière et n'a pris aucun argument.
  2. Nous déclarons un pointeur entier qui reçoit le tableau complet construit après l'appel de la fonction et nous imprimons son contenu en itérant l'ensemble du tableau de cinq éléments.

Notez qu'un pointeur, et non un tableau, est défini pour stocker l'adresse du tableau renvoyée par la fonction. Notez également que lorsqu'une variable locale est renvoyée par une fonction, nous devons la déclarer comme statique dans la fonction.

Pointeurs de fonction

Comme nous savons par définition que les pointeurs pointent vers une adresse dans n'importe quel emplacement de la mémoire, ils peuvent également pointer vers le début du code exécutable en tant que fonctions en mémoire.
Un pointeur vers une fonction est déclaré avec le * , l'instruction générale de sa déclaration est :

return_type (*function_name)(arguments)

Vous devez vous rappeler que les parenthèses autour de (*nom_fonction) sont importantes car sans elles, le compilateur pensera que nom_fonction renvoie un pointeur de type_retour.
Après avoir défini le pointeur de fonction, nous devons l'affecter à une fonction. Par exemple, le programme suivant déclare une fonction ordinaire, définit un pointeur de fonction, affecte le pointeur de fonction à la fonction ordinaire et ensuite appelle la fonction via le pointeur :

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

Sortie :

Hi
Hi
Hi

  1. Nous définissons et déclarons une fonction standard qui imprime un texte Hi k fois indiqué par le paramètre fois lorsque la fonction est appelée
  2. Nous définissons une fonction de pointeur (avec sa déclaration spéciale) qui prend un paramètre entier et ne renvoie rien.
  3. Nous initialisons notre fonction de pointeur avec la fonction Hi_function, ce qui signifie que le pointeur pointe vers la fonction Hi_function().
  4. Plutôt que la fonction standard appelant en tapant le nom de la fonction avec des arguments, nous appelons uniquement la fonction de pointeur en passant le nombre 3 comme arguments, et c'est tout !

Gardez à l'esprit que le nom de la fonction pointe vers l'adresse de début du code exécutable comme un nom de tableau qui pointe vers son premier élément. Par conséquent, des instructions telles que function_ptr =&Hi_function et (*funptr)(3) sont correctes.
REMARQUE :Il n'est pas important d'insérer l'opérateur d'adresse &et l'opérateur d'indirection * lors de l'affectation et de l'appel de la fonction.

Tableau de pointeurs de fonction

Un tableau de pointeurs de fonction peut jouer un rôle de commutateur ou d'instruction if pour prendre une décision, comme dans le programme suivant :

#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

Ici, nous discutons des détails du programme :

  1. Nous déclarons et définissons quatre fonctions qui prennent deux arguments entiers et renvoient une valeur entière. Ces fonctions additionnent, soustraient, multiplient et divisent les deux arguments concernant la fonction appelée par l'utilisateur.
  2. Nous déclarons 4 entiers pour gérer respectivement les opérandes, le type d'opération et le résultat. De plus, nous déclarons un tableau de quatre pointeurs de fonction. Chaque pointeur de fonction d'un élément de tableau prend deux paramètres entiers et renvoie une valeur entière.
  3. Nous attribuons et initialisons chaque élément du tableau avec la fonction déjà déclarée. Par exemple, le troisième élément qui est le troisième pointeur de fonction pointera vers la fonction d'opération de multiplication.
  4. On recherche les opérandes et le type d'opération de l'utilisateur tapé au clavier.
  5. Nous avons appelé l'élément de tableau approprié (pointeur de fonction) avec des arguments, et nous stockons le résultat généré par la fonction appropriée.

L'instruction int (*ope[4])(int, int); définit le tableau des pointeurs de fonction. Chaque élément du tableau doit avoir les mêmes paramètres et le même type de retour.
L'instruction result =ope[choice](x, y); exécute la fonction appropriée selon le choix fait par l'utilisateur Les deux entiers saisis sont les arguments passés à la fonction.

Fonctions utilisant des pointeurs vides

Les pointeurs vides sont utilisés lors des déclarations de fonction. Nous utilisons un type de retour void * permettant de retourner n'importe quel type. Si nous supposons que nos paramètres ne changent pas lors du passage à une fonction, nous le déclarons const.
Par exemple :

 void * cube (const void *);

Considérez le programme suivant :

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

Résultat :

 4 cubed is 64

Ici, nous allons discuter des détails du programme :

  1. Nous définissons et déclarons une fonction qui renvoie une valeur entière et prend une adresse de variable non modifiable sans type de données spécifique. Nous calculons la valeur de cube de la variable de contenu (x) pointée par le pointeur num, et comme il s'agit d'un pointeur vide, nous devons le convertir en un type de données entier en utilisant un pointeur de notation spécifique (* type de données), et nous retournons la valeur du cube.
  2. Nous déclarons l'opérande et la variable résultat. De plus, nous initialisons notre opérande avec la valeur "4".
  3. Nous appelons la fonction cube en transmettant l'adresse de l'opérande, et nous gérons la valeur de retour dans la variable de résultat

Pointeurs de fonction comme arguments

Une autre façon d'exploiter un pointeur de fonction en le passant comme argument à une autre fonction parfois appelée "fonction de rappel" car la fonction réceptrice "la rappelle".
Dans le fichier d'en-tête stdlib.h, le Quicksort "qsort() ” La fonction utilise cette technique qui est un algorithme dédié au tri d'un tableau.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))

Le programme suivant trie un tableau d'entiers du petit au grand nombre en utilisant la fonction 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;}

Résultat :

 13 14 48 50 52

Ici, nous allons discuter des détails du programme :

  1. Nous définissons une fonction de comparaison composée de deux arguments et renvoie 0 lorsque les arguments ont la même valeur, <0 lorsque arg1 vient avant arg2 et>0 lorsque arg1 vient après arg2. type de données tableau (entier)
  2. Nous définissons et initialisons un tableau d'entiers La taille du tableau est stockée dans le num et la taille de chaque élément du tableau est stockée dans la variable width à l'aide de l'opérateur C prédéfini sizeof().
  3. Nous appelons le qsort fonction et passez le nom du tableau, la taille, la largeur et la fonction de comparaison définis précédemment par l'utilisateur afin de trier notre tableau dans l'ordre croissant. La comparaison sera effectuée en prenant à chaque itération deux éléments du tableau jusqu'à ce que le tableau entier soit trié.
  4. Nous imprimons les éléments du tableau pour nous assurer que notre tableau est bien trié en itérant le tableau entier à l'aide de la boucle for.

Langue C

  1. Types de fonctions définies par l'utilisateur dans la programmation C
  2. Boucle do…while C++ avec exemples
  3. Pointeurs C++ avec exemples
  4. Surcharge d'opérateur C++ avec des exemples
  5. Fonctions C++ avec exemples de programmes
  6. Tutoriel sur les collections C # avec des exemples
  7. Pointeurs en C :Qu'est-ce qu'un pointeur en programmation C ? Les types
  8. Python String count() avec des EXEMPLES
  9. Fonctions Python Lambda avec EXEMPLES