2008-10-28 27 views

Respuesta

37

¿Cuáles son los paréntesis?

Entre paréntesis C [] tener una prioridad más alta que el asterisco *

Buena explicación de Wikipedia:

Declarar una variable como un puntero a una matriz, debemos hacer uso de paréntesis. Esto se debe a que en C , los paréntesis ([]) tienen una precedencia más alta que el asterisco (*). Por lo tanto, si deseamos declarar un puntero a una matriz, tenemos que suministrar paréntesis para modificar esto:

double (*elephant)[20]; 

Esto declara que el elefante es un puntero , y el tipo que apunta a es una matriz de 20 valores dobles. Para declarar un puntero a un conjunto de punteros , simplemente combine las anotaciones .

int *(*crocodile)[15]; 

Source.

Y el caso real:

int (*data[2])[5]; 

de datos es una matriz de 2 elementos. Cada elemento contiene un puntero a una matriz de 5 ints.

Así que usted podría tener en el código utilizando el tipo de 'datos':

int (*data[2])[5]; 
int x1[5]; 
data[0] = &x1; 
data[1] = &x1; 

data[2] = &x1;//<--- out of bounds, crash data has no 3rd element 
int y1[10]; 
data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10] 
+0

¡respuesta perfecta! – J3STER

14

Hay un programa muy fresco llamado "cdecl" que se puede descargar para Linux/Unix y probablemente para Windows también. Pega una declaración de variable C (o C++ si usa C++ decl) y la deletrea en palabras simples.

+1

+1 por mencionar cdecl – user7116

+1

Con un nombre como @sixlettervariables, asumo que eres aún más viejo que yo. Por favor dime que recuerdas los mandamientos de Henry Spencer? –

+1

Figura mencionaría que cdecl ahora es un sitio web: [cdecl.org] (http://cdecl.org/) – Urchin

-1

datos [2] - una matriz de dos enteros

* datos [2] - un puntero a una matriz de dos enteros

(* datos [2]) - "

(* datos [2]) [2] - una matriz de 2 punteros a las matrices de dos números enteros

+1

El segundo elemento no es lo que usted dijo. Además del tipo que falta (que ha asumido que son enteros), es una matriz de 2 punteros a enteros. El tercero no es C. El cuarto es probablemente correcto. –

+0

Hmmm, supongo que tal vez la cita es una marca ídem. Sigo pensando que la explicación deja algo que desear. –

4

Si sabe cómo leer expresiones en C, entonces usted es un paso de la lectura de las declaraciones complicadas

..

¿Qué

char *p; 

realmente? Significa que *p es un char.¿Qué

int (*data[2])[5]; 

significa? Significa que (*data[x])[y] es un int (proporcionado 0 < = x < 2 y 0 < = y < 5). Ahora, solo piense cuáles son las implicaciones de eso. data tiene que ser ... una matriz de 2 ... punteros ... a matrices de 5 ... enteros.

¿No crees que es bastante elegante? Todo lo que estás haciendo es indicar el tipo de expresión. ¡Una vez que entiendas eso, las declaraciones nunca te intimidaran de nuevo!

La "regla rápida" es comenzar con el nombre de la variable, escanear a la derecha hasta que toques a), volver al nombre de la variable y escanear a la izquierda hasta que toques un (. Luego "salir" de el par de paréntesis, y repetir el proceso

vamos a aplicarlo a algo ridículo:.

void **(*(*weird)[6])(char, int); 

weird es un puntero a una matriz de 6 punteros a funciones de cada uno aceptar un char y un int como argumento, y cada uno devuelve un puntero a un puntero para anular

Ahora que ya sabe qué es y cómo se hace ... no lo haga hágalo. Use typedefs para dividir sus declaraciones en fragmentos más manejables. P.ej.

typedef void **(*sillyFunction)(char, int); 

sillyFunction (*weird)[6]; 
+0

Y hoy en día, use 'using' para asignar un nombre a un tipo. – IllidanS4

+0

Eso sería C++ ... – Artelius

+0

Y hoy en día, use C++ :-P – IllidanS4

-1

Si tiene una matriz:

int myArray[5]; 
int * myArrayPtr = myArray; 

sería perfectamente razonable. myArray sin los soportes es un puntero a int. Cuando agrega los corchetes es como si tuviera deferencia el puntero myArray. Puede escribir ...

myArrayPtr[1] = 3; 

Lo cual es perfectamente razonable. El uso de paréntesis hace que sea más difícil leer y entender la OMI. Y muestran que las personas no entienden los punteros, arreglos y aritmética del puntero, que es la forma en que el compilador o el enlazador pasa de uno a otro. Sin embargo, parece que, con el paréntesis, se obtienen límites comprobando.

Cuestiones relacionadas