type pointer how functions define create constant array c declare

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 un int ; 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];