pointer - Sintaxis de puntero de función C
define constant c (4)
Mi pregunta es muy simple.
Normalmente, al declarar alguna variable, pones su tipo delante, como
int a;
un puntero de función puede tener un tipo como: int (*) (int, int), en caso de que señalemos una función que tome dos int y devuelva un int. Pero, al declarar tal puntero, su identificador no está detrás del tipo, como:
int(*)(int,int) mypointer;
en su lugar, debe escribir el identificador en el medio:
int(*mypointer)(int,int);
¿por qué esto es tan? Lo siento, sé que es una pregunta vergonzosamente fácil ...
Gracias a todos por responder. COMO
Esta estructura refleja cómo se declara (y usa) una función normal.
Considere una definición de función normal:
int foo (int bar, int baz, int quux);
Ahora considere la posibilidad de definir un puntero a una función de la misma firma:
int (*foo) (int, int, int);
¿Observa cómo las dos estructuras se reflejan entre sí? Eso hace que *foo
sea mucho más fácil de identificar como un puntero de función en lugar de como otra cosa.
Explico esto en mi respuesta a ¿Por qué la sintaxis de C para matrices, indicadores y funciones se diseñó de esta manera? , y básicamente se reduce a:
los autores de los idiomas preferían que la sintaxis fuera centrada en variables en lugar de centrada en tipos. Es decir, querían que un programador mirara la declaración y pensara "si escribo la expresión
*func(arg)
, eso dará como resultado unint
; si escribo*arg[N]
tendré un flotador" en lugar de que "func
debe ser un puntero a una función tomando esto y devolviéndolo".La entrada C en Wikipedia afirma que:
La idea de Ritchie era declarar identificadores en contextos que se parecían a su uso: "declaración refleja uso".
... citando la p122 de K & R2.
He visto en algunos lugares los punteros de función están declarados como
int (* foo) (int a, int b);
y en algunos lugares a y b no se mencionan y ambos todavía funcionan.
así que int (* foo) (int, int) también es correcto.
Una forma muy simple que encontré para recordar es como se menciona a continuación
supongamos que la función se declara como: int function (int a, int b); Paso 1: simplemente ponga la función en parantemos: int (function) (int a, int b); Paso 2: coloque un * delante del nombre de la función y cambie el nombre: int (* funcPntr) (int a, int b);
PD: No estoy siguiendo las directrices de codificación adecuadas para la convención de nomenclatura, etc. en esta respuesta.
Si está tratando con una función (no un puntero a uno), el nombre también está en el medio. Funciona como: return-type function-name "(" argument-list ")" ...
Por ejemplo, en int foo(int)
, int
es el tipo de retorno, foo
el nombre y int
la lista de argumentos.
Un puntero a una función funciona de la misma manera: tipo de retorno, luego nombre, luego lista de argumentos. En este caso, debemos agregar un *
para convertirlo en un puntero, y (dado que el prefijo *
para un puntero es un par de paréntesis para vincular el *
al nombre en lugar del tipo de retorno). Por ejemplo, int *foo(int)
significaría una función llamada foo que toma un parámetro int y devuelve un puntero a un int. Para obtener el * enlazado a foo
, necesitamos paréntesis, dando int (*foo)(int)
.
Esto se vuelve particularmente feo cuando se necesita una serie de punteros a las funciones. En tal caso, a la mayoría de las personas les resulta más fácil usar typedef para el tipo de puntero y luego crear una matriz de ese tipo:
typedef int (*fptr)(int);
fptr array[10];