Saltar al contenido

Puntero de función en C – GeeksforGeeks

septiembre 24, 2021
gfg 200x200 min

En C, al igual que los punteros de datos normales (int *, char *, etc.), podemos tener punteros a funciones. A continuación se muestra un ejemplo simple que muestra la declaración y la llamada de función utilizando el puntero de función.

#include <stdio.h>

void fun(int a)

{

    printf("Value of a is %dn", a);

}

 

int main()

{

    

    void (*fun_ptr)(int) = &fun;

 

    

       

       

    

 

    

    (*fun_ptr)(10);

 

    return 0;

}

Producción:

Value of a is 10

¿Por qué necesitamos un corchete adicional alrededor de punteros de función como fun_ptr en el ejemplo anterior?
Si quitamos el corchete, entonces la expresión «void (* fun_ptr) (int)» se convierte en «void * fun_ptr (int)», que es la declaración de una función que devuelve un puntero vacío. Consulte la siguiente publicación para obtener más detalles.
¿Cómo declarar un puntero a una función?

A continuación se presentan algunos datos interesantes sobre los punteros de función.

1) A diferencia de los punteros normales, un puntero de función apunta al código, no a los datos. Normalmente, un puntero de función almacena el inicio del código ejecutable.

2) A diferencia de los punteros normales, no asignamos desasignar memoria utilizando punteros de función.

3) El nombre de una función también se puede usar para obtener la dirección de las funciones. Por ejemplo, en el programa siguiente, hemos eliminado el operador de dirección ‘&’ en la asignación. También hemos cambiado la llamada a la función eliminando *, el programa aún funciona.

#include <stdio.h>

void fun(int a)

{

    printf("Value of a is %dn", a);

}

 

int main()

    void (*fun_ptr)(int) = fun; 

 

    fun_ptr(10); 

 

    return 0;

}

Producción:

Value of a is 10

4) Como punteros normales, podemos tener una matriz de punteros de función. El siguiente ejemplo en el punto 5 muestra la sintaxis de la matriz de punteros.

5) El puntero de función se puede utilizar en lugar de la caja del interruptor. Por ejemplo, en el programa siguiente, se le pide al usuario que elija entre 0 y 2 para realizar diferentes tareas.

#include <stdio.h>

void add(int a, int b)

{

    printf("Addition is %dn", a+b);

}

void subtract(int a, int b)

{

    printf("Subtraction is %dn", a-b);

}

void multiply(int a, int b)

{

    printf("Multiplication is %dn", a*b);

}

 

int main()

{

    

    void (*fun_ptr_arr[])(int, int) = {add, subtract, multiply};

    unsigned int ch, a = 15, b = 10;

 

    printf("Enter Choice: 0 for add, 1 for subtract and 2 "

            "for multiplyn");

    scanf("%d", &ch);

 

    if (ch > 2) return 0;

 

    (*fun_ptr_arr[ch])(a, b);

 

    return 0;

}

Enter Choice: 0 for add, 1 for subtract and 2 for multiply
2
Multiplication is 150 

6) Al igual que los punteros de datos normales, un puntero de función se puede pasar como argumento y también se puede devolver desde una función.
Por ejemplo, considere el siguiente programa en C donde wrapper () recibe un void fun () como parámetro y llama a la función pasada.

#include <stdio.h>

 

void fun1() { printf("Fun1n"); }

void fun2() { printf("Fun2n"); }

 

void wrapper(void (*fun)())

{

    fun();

}

 

int main()

{

    wrapper(fun1);

    wrapper(fun2);

    return 0;

}

Este punto en particular es muy útil en C. En C, podemos usar punteros de función para evitar la redundancia de código. Por ejemplo, un simple qsort () La función se puede utilizar para clasificar matrices en orden ascendente o descendente o por cualquier otro orden en el caso de una matriz de estructuras. No solo esto, con punteros de función y punteros de vacío, es posible usar qsort para cualquier tipo de datos.

#include <stdio.h>

#include <stdlib.h>

 

int compare (const void * a, const void * b)

{

  return ( *(int*)a - *(int*)b );

}

 

int main ()

{

  int arr[] = {10, 5, 15, 12, 90, 80};

  int n = sizeof(arr)/sizeof(arr[0]), i;

 

  qsort (arr, n, sizeof(int), compare);

 

  for (i=0; i<n; i++)

     printf ("%d ", arr[i]);

  return 0;

}

Producción:

5 10 12 15 80 90

De manera similar a qsort (), podemos escribir nuestras propias funciones que se pueden usar para cualquier tipo de datos y pueden realizar diferentes tareas sin redundancia de código. A continuación se muestra una función de búsqueda de ejemplo que se puede utilizar para cualquier tipo de datos. De hecho, podemos usar esta función de búsqueda para encontrar elementos cercanos (por debajo de un umbral) escribiendo una función de comparación personalizada.

#include <stdio.h>

#include <stdbool.h>

 

bool compare (const void * a, const void * b)

{

  return ( *(int*)a == *(int*)b );

}

 

int search(void *arr, int arr_size, int ele_size, void *x,

           bool compare (const void * , const void *))

{

    

    

    

    

    char *ptr = (char *)arr;

 

    int i;

    for (i=0; i<arr_size; i++)

        if (compare(ptr + i*ele_size, x))

           return i;

 

    

    return -1;

}

 

int main()

{

    int arr[] = {2, 5, 7, 90, 70};

    int n = sizeof(arr)/sizeof(arr[0]);

    int x = 7;

    printf ("Returned index is %d ", search(arr, n,

                               sizeof(int), &x, compare));

    return 0;

}

Producción:

Returned index is 2

La función de búsqueda anterior se puede utilizar para cualquier tipo de datos escribiendo una comparación personalizada separada ().

7) Muchas características orientadas a objetos en C ++ se implementan usando punteros de función en C. Por ejemplo, funciones virtuales. Los métodos de clase son otro ejemplo implementado usando punteros de función. Referir este libro para más detalles.

Artículo relacionado:Punteros en C y C ++ | Conjunto 1 (Introducción, Aritmética y Matriz)

Referencias:
http://www.cs.cmu.edu/~ab/15-123S11/AnnotatedNotes/Lecture14.pdf

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-087-practical-programming-in-c-january-iap-2010/lecture-notes/MIT6_087IAP10_lec08.pdf

http://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture14.pdf

Este artículo es una contribución de Abhay Rathi. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema discutido anteriormente.

Si desea aprender de los mejores videos seleccionados y problemas de práctica, consulte el Curso básico de C de Básico a Avanzado C.

close