Punteros de funciones en programación C con ejemplos
Los punteros dan grandes posibilidades a las funciones 'C' que estamos limitados a devolver un valor. Con parámetros de puntero, nuestras funciones ahora pueden procesar datos reales en lugar de una copia de datos.
Para modificar los valores reales de las variables, la declaración de llamada pasa direcciones a los parámetros de puntero en una función.
En este tutorial, aprenderás-
- Ejemplo de punteros de funciones
- Funciones con parámetros de matriz
- Funciones que devuelven una matriz
- Puntero de función
- Matriz de punteros de función
- Funciones usando punteros vacíos
- Puntero de función como argumentos
Ejemplo de punteros de funciones
Por ejemplo, el siguiente programa intercambia dos valores de dos:
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;} }
Salida:
m is 25, n is 100 m is 100, n is 25
El programa intercambia los valores de las variables reales porque la función accede a ellos por dirección usando punteros. Aquí discutiremos el proceso del programa:
- Declaramos la función responsable de intercambiar los dos valores de las variables, que toma dos punteros enteros como parámetros y devuelve cualquier valor cuando se llama.
- En la función principal, declaramos e inicializamos dos variables enteras ('m' y 'n') y luego imprimimos sus valores respectivamente.
- Llamamos a la función swap() pasando la dirección de las dos variables como argumentos usando el símbolo ampersand. Después de eso, imprimimos los nuevos valores intercambiados de las variables.
- Aquí definimos el contenido de la función swap() que toma dos direcciones de variables enteras como parámetros y declara una variable entera temporal utilizada como un tercer cuadro de almacenamiento para guardar una de las variables de valor que se colocará en la segunda variable.
- Guarde el contenido de la primera variable señalada por 'a' en la variable temporal.
- Almacene la segunda variable señalada por b en la primera variable señalada por a.
- Actualice la segunda variable (señalada por b) por el valor de la primera variable guardada en la variable temporal.
Funciones con parámetros de matriz
En C, no podemos pasar una matriz por valor a una función. Mientras que un nombre de matriz es un puntero (dirección), por lo que simplemente pasamos un nombre de matriz a una función que significa pasar un puntero a la matriz.
Por ejemplo, consideramos el siguiente programa:
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);}
Salida:
Total summation is 471
Aquí, explicaremos el código del programa con sus detalles
- Declaramos y definimos la función add_array() que toma una dirección de matriz (puntero) con su número de elementos como parámetros y devuelve la suma total acumulada de estos elementos. El puntero se usa para iterar los elementos de la matriz (usando la notación p[k]), y acumulamos la suma en una variable local que se devolverá después de iterar toda la matriz de elementos.
- Declaramos e inicializamos una matriz de enteros con cinco elementos enteros. Imprimimos la suma total pasando el nombre de la matriz (que actúa como dirección) y el tamaño de la matriz a add_array() función llamada como argumentos.
Funciones que devuelven una matriz
En C, podemos devolver un puntero a una matriz, como en el siguiente programa:
#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);}
Salida:
1 2 3 4 5
Y aquí, discutiremos los detalles del programa
- Definimos y declaramos una función que devuelve una dirección de matriz que contiene un valor entero y no tomó ningún argumento.
- Declaramos un puntero entero que recibe la matriz completa creada después de llamar a la función e imprimimos su contenido iterando toda la matriz de cinco elementos.
Observe que se define un puntero, no una matriz, para almacenar la dirección de la matriz devuelta por la función. También tenga en cuenta que cuando una función devuelve una variable local, tenemos que declararla como estática en la función.
Puntero de función
Como sabemos por definición que los punteros apuntan a una dirección en cualquier ubicación de la memoria, también pueden apuntar al comienzo del código ejecutable como funciones en la memoria.
Un puntero a función se declara con *, la declaración general de su declaración es:
return_type (*function_name)(arguments)
Debe recordar que los paréntesis alrededor de (*nombre_función) son importantes porque sin ellos, el compilador pensará que nombre_función devuelve un puntero de tipo_retorno.
Después de definir el puntero de función, tenemos que asignarlo a una función. Por ejemplo, el siguiente programa declara una función ordinaria, define un puntero de función, asigna el puntero de función a la función ordinaria y luego llama a la función a través del puntero:
#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");}
Salida:
Hi Hi Hi
- Definimos y declaramos una función estándar que imprime un texto Hola k veces indicadas por el parámetro veces cuando se llama a la función
- Definimos una función de puntero (con su declaración especial) que toma un parámetro entero y no devuelve nada.
- Inicializamos nuestra función de puntero con Hi_function, lo que significa que el puntero apunta a Hi_function().
- En lugar de llamar a la función estándar grabando el nombre de la función con argumentos, solo llamamos a la función de puntero pasando el número 3 como argumentos, ¡y eso es todo!
Tenga en cuenta que el nombre de la función apunta a la dirección inicial del código ejecutable como un nombre de matriz que apunta a su primer elemento. Por lo tanto, instrucciones como function_ptr =&Hi_function y (*funptr)(3) son correctas.
NOTA:No es importante insertar el operador de dirección &y el operador de direccionamiento indirecto * durante la asignación y llamada de función.
Matriz de punteros de función
Una matriz de punteros de función puede desempeñar un papel de cambio o declaración if para tomar una decisión, como en el siguiente programa:
#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
Aquí, discutimos los detalles del programa:
- Declaramos y definimos cuatro funciones que toman dos argumentos enteros y devuelven un valor entero. Estas funciones suman, restan, multiplican y dividen los dos argumentos con respecto a qué función llama el usuario.
- Declaramos 4 enteros para manejar operandos, tipo de operación y resultado respectivamente. Además, declaramos una matriz de cuatro punteros de función. Cada puntero de función del elemento de matriz toma dos parámetros enteros y devuelve un valor entero.
- Asignamos e inicializamos cada elemento del arreglo con la función ya declarada. Por ejemplo, el tercer elemento que es el puntero de la tercera función apuntará a la función de operación de multiplicación.
- Buscamos operandos y tipo de operación del usuario tecleado con el teclado.
- Llamamos al elemento de matriz adecuado (puntero de función) con argumentos y almacenamos el resultado generado por la función adecuada.
La instrucción int (*ope[4])(int, int); define la matriz de punteros de función. Cada elemento de la matriz debe tener los mismos parámetros y el mismo tipo de retorno.
El resultado de la declaración =ope[elección](x, y); ejecuta la función adecuada de acuerdo con la elección realizada por el usuario. Los dos números enteros ingresados son los argumentos que se pasan a la función.
Funciones usando punteros vacíos
Los punteros vacíos se utilizan durante las declaraciones de funciones. Utilizamos un tipo de devolución nulo * permisos para devolver cualquier tipo. Si asumimos que nuestros parámetros no cambian al pasar a una función, lo declaramos como const.
Por ejemplo:
void * cube (const void *);
Considere el siguiente programa:
#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;}
Resultado:
4 cubed is 64
Aquí, discutiremos los detalles del programa:
- Definimos y declaramos una función que devuelve un valor entero y toma una dirección de variable inmutable sin un tipo de datos específico. Calculamos el valor del cubo de la variable de contenido (x) señalada por el puntero numérico, y como es un puntero vacío, tenemos que convertirlo a un tipo de datos entero usando un puntero de notación específica (* tipo de datos), y devolvemos el valor del cubo.
- Declaramos el operando y la variable resultado. Además, inicializamos nuestro operando con el valor "4".
- Llamamos a la función de cubo pasando la dirección del operando y manejamos el valor devuelto en la variable de resultado
Puntero de función como argumento
Otra forma de explotar un puntero de función pasándolo como argumento a otra función a veces llamada "función de devolución de llamada" porque la función receptora "la devuelve".
En el archivo de encabezado stdlib.h, Quicksort "qsort() La función ” utiliza esta técnica, que es un algoritmo dedicado a ordenar una matriz.
void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
- void *base :puntero vacío a la matriz.
- size_t num :El número de elemento de la matriz.
- size_t ancho El tamaño del elemento.
- int (*compare (const void *, const void *) :puntero de función compuesto por dos argumentos y devuelve 0 cuando los argumentos tienen el mismo valor, <0 cuando arg1 viene antes que arg2 y>0 cuando arg1 viene después de arg2 .
El siguiente programa ordena una matriz de números enteros de menor a mayor utilizando la función 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;}
Resultado:
13 14 48 50 52
Aquí, discutiremos los detalles del programa:
- Definimos la función de comparación compuesta por dos argumentos y devuelve 0 cuando los argumentos tienen el mismo valor, <0 cuando arg1 viene antes que arg2 y>0 cuando arg1 viene después de arg2. tipo de datos de matriz (entero)
- Definimos e inicializamos una matriz de enteros El tamaño de la matriz se almacena en el num y el tamaño de cada elemento de la matriz se almacena en la variable de ancho utilizando el operador C predefinido sizeof().
- Llamamos al qsort y pase el nombre de la matriz, el tamaño, el ancho y la función de comparación definida previamente por el usuario para ordenar nuestra matriz en orden ascendente. La comparación se realizará tomando en cada iteración dos elementos de la matriz hasta que se ordene la matriz completa.
- Imprimimos los elementos de la matriz para asegurarnos de que nuestra matriz esté bien ordenada al iterar toda la matriz usando el bucle for.
Lenguaje C
- Tipos de funciones definidas por el usuario en programación C
- C++ do...while bucle con ejemplos
- Punteros de C++ con ejemplos
- Sobrecarga de operadores de C++ con ejemplos
- Funciones de C++ con ejemplos de programas
- Tutorial de colecciones de C# con ejemplos
- Punteros en C:¿Qué es un puntero en la programación C? Tipos
- Python String count () con EJEMPLOS
- Funciones Python Lambda con EJEMPLOS
- Función Python round() con EJEMPLOS
- Función Python map() con EJEMPLOS