c++ - sintaxis - tipos de punteros
Significado de la sintaxis compleja C (8)
Posible duplicado:
¿Qué significa esta declaración C?
Que significa esta expresión?
char *(*c[10])(int **p);
Ahora bien, la respuesta que tienes es una matriz de puntero a la función, pero ¿hay alguna manera clara de escribir código como este? Sí, lo hay, y estoy seguro de que este código podría entenderse a primera vista:
typedef char *(*weirdFuncPtr)(int **p);
weirdFuncPtr funcPtrArray[10];
Por cierto. generalmente evito typdefs, los uso cuando declaro punteros a funciones. Esto hace que sea más fácil entender este tipo de código C (C es una abreviatura de Cryptic, ¿o sí?)
Algunos ejemplos y un fragmento al final que usa el decl.
1. Puntero a una función:
void (*foo)(void);
Le daría un puntero a la función foo
que no toma parámetros y no devuelve nada.
Ex. UN:
void fun_1(void)
{
...
}
foo = fun_1;
foo(); /* this would call fun_1() */
Ex. SEGUNDO:
char (*bar)(int);
Le daría una bar
puntero a función que toma 1 parámetro como entero y devuelve un char
.
char fun_2(int x)
{
if (x == 50)
return ''a'';
return ''Z'';
}
char v;
bar = fun_2;
v = bar(50); /* this would call fun_2() with 50 as parameter and return ''a'' */
2. Puntero a un puntero
int **p;
es un puntero que apunta a un puntero de tipo int.
Ex. DO:
int y[3] = {4, 3, 6};
int *w = &y[0];
int **z = &w;
printf("print: %d ", **z);
printf("%d ", *++(*z));
printf("%d/n", *(*z+1));
print: 4 3 6
3. Función devolviendo un puntero
Ex. RE:
char *zez(char *s)
{
s = "def";
return s;
}
char *str = "abc";
printf("%s - ", str);
printf("%s/n", zez(str));
abc - def
4. Puntero de función a una función que devuelve un puntero
Crear un puntero de función a zez()
Ex. MI:
char *(*ptr_zez)(char *);
ptr_zez = zez;
printf("ptr: %s - ", str);
printf("%s/n", ptr_zez(str));
ptr: abc - def
5. Matriz de punteros de función, para funcionar devolviendo un puntero de char, tomando un puntero de char
Ex. F:
char *(*c[10])(char *);
c[0] = zez;
printf("c[0]: %s - ", str);
printf("%s/n", c[0](str));
c[0]: abc - def
6. "Declare c como la matriz 10 del puntero a la función (puntero a puntero a int) retornando el puntero a char"
char *cumlade(int **p)
{
char *c;
int i;
if ((c = malloc(sizeof(char) * 7)) == NULL) {
fprintf(stderr, "Unable to reserve 7 bytes/n");
exit(0);
}
for (i = 0; i < 6; ++i) {
c[i] = (unsigned char)*(*p+i);
}
c[6] = ''/0'';
return c;
}
int main(void)
{
int t[3][3] = {{97 ,98, 99}, {100, 101, 102}};
int *u = &t[0][0];
int **v = &u;
char *ex;
char *(*c[10])(int **p); /* <-- the fun */
c[0] = cumlade;
c[1] = cumlade;
ex = c[0](v);
printf("EX: %s/n", ex);
free(ex);
ex = c[1](v);
printf("AX: %s/n", ex);
free(ex);
return 0;
}
EX: abcdef
AX: abcdef
Declara una matriz de indicadores de función. Hay 10 elementos en la matriz (de c [10] parte de la declaración). la función a la que estos apuntadores pueden apuntar devolverá char * y tomará solo un parámetro, es decir, puntero a puntero a entero (int ** p)
Eche un vistazo a la primera respuesta a esta pregunta. ¿Cómo puedo usar una matriz de indicadores de función? allí encontrará otro ejemplo de declaración de matriz de puntero a función y puede terminar su confusión.
La declaración de tipo implica tres operadores: array [SIZE]
, puntero *
y función (type1 param1, type2 param2, ...)
. Recuerde que los tres operadores son de derecha asociativa .
char *(*c[10])(int **p);
Agreguemos más paréntesis para hacer que la asociatividad sea más clara.
char *((*(c[10]))(int *(*p)))
Comience desde c
, la variable.
c[10]
significa que "c es una matriz de 10 elementos, pero cada elemento es un ..."
Luego, vea el *
al lado. *(c[10])
significa que "c es una matriz de 10 elementos, cada elemento es un puntero que apunta a ..."
Entonces (*(c[10]))(int *(*p))
significa que "c es una matriz de 10 elementos, cada elemento es un puntero a una función, que devuelve ..." Usando métodos similares vemos la función toma un parámetro que es "un puntero a un puntero a un int".
Entonces *((*(c[10]))(int *(*p)))
significa que "c es una matriz de 10 elementos, cada elemento es un puntero a una función, que devuelve un puntero a ..."
Finalmente char *((*(c[10]))(int *(*p)))
significa que "c es una matriz de 10 elementos, cada elemento es un puntero a una función, que devuelve un puntero a un carácter". Eso es.
Encuentro que la Regla de las agujas del reloj / Espiral es muy útil. Ver http://c-faq.com/decl/spiral.anderson.html
Pero prefiero agregar más corchetes que usar espirales.
Si busca una explicación intuitiva para esto, http://www.geeksforgeeks.org/archives/16841
Explicaron esto usando la evaluación de la orden postfix, al igual que la evaluación de la expresión.
cdecl es una buena herramienta para traducir C
gibberish al inglés
$ cdecl explain ''char * (*c[10]) (int **)''
declare c as array 10 of pointer to function (pointer to pointer to int) returning pointer to char
c
es una matriz de 10 punteros de funciones que devuelven un char*
y toman un int**
como argumento.
(*c[10])
^^^^ = array of 10
(*c[10])
^ = function pointer
Así que ahora tenemos una matriz de 10 punteros de función.
char *(*c[10])
^^^^^^ = returns a char*
char *(*c[10])(int** p)
^^^^^ = takes a int** as an argument
Matriz de 10 punteros de función que devuelven un char*
y toman un int**
como argumento.
NOTA: Si escribe código como este, merece ser abofeteado.
c
es una matriz de 10
punteros a funciones que toman un puntero a puntero a int
como su parámetro y devuelven un puntero a char
.