2012-04-27 7 views

Respuesta

25

declaraciones de tipo tienen una sintaxis de expresión similar, por lo que analizan como lo haría con una expresión:

 x  x is 
    *x  a pointer 
    (*x)[] to an array of unknown dimensions 
int (*x)[] of int 

La regla de precedencia es que los operadores al unen derecho apretado que aquellos a la izquierda, en cada caso, el operador más cerca del elemento se une con más fuerza, y por último, que los paréntesis se pueden utilizar para cambiar estos fijaciones, así que:

int *x[]; is an array of pointers, 
int *(x[]); as is this. 
int (*x)[]; whereas here, the parentheses change the bindings. 
+1

+1 .... ¡Impresionante! – Nawaz

13

Usando cdecl, se puede determinar fácilmente el tipo:

declare x as pointer to array of int

Así puede inicializar x con la dirección de una matriz:

int a[]; // conceptual: error if compiled 
x = &a; 

Tenga en cuenta que el tamaño de la matriz es parte de su tipo, por lo que no puede asignar la dirección de una matriz de tamaño N a un puntero a la matriz de tamaño M, donde N!=M (esta es la razón del error anterior: necesita saber el tamaño de la matriz declararla)

int b[5]; 
int c[6]; 
int (*y)[6]; 
y = &b; // error 
y = &c; // OK 
+0

Uptick por mencionar 'cdecl' - Olvidé que existía, aunque estrictamente, solo es compatible con la sintaxis C. –

+0

Gracias por el enlace, ¡es útil! – Chlind

3

int (*x)[] de usar por un puntero a una matriz int vacía. Pero inicializa una matriz vacía que no es posible en C++. Solo tú puedes definirlo. Debe utilizar un conjunto no vacío:

int a[2] = {1, 2}; 
int (*x)[2] = &a; 
+1

GCC se queja de que no puede convertir 'int (*) [2]' a 'int (*) []'. Editar: Ahora se desvía de la pregunta;) – chris

+0

tiene razón, lo corregí. –

2

int (*x)[] significa x es un puntero a int matriz. Puede hacerlo de esta manera:

int a[] = {1, 2}; 
int (* b)[2] = &a; 

Cuando se interpreta variable de matriz-mecanografiado, debemos ir de derecha a izquierda. p.ej.

int *x[] 

indica que x es una matriz, elementos de la matriz se escribe como int * es decir puntero a int. Por lo tanto, x representa una matriz cuyos elementos son puntero int. Sin embargo, los paréntesis cambian la precedencia del operador. Ahora * se interpreta por primera vez indicando x es un puntero, cuyo tipo es int []. Por lo tanto, x en int (*x)[] es un puntero a la matriz int y debe inicializar en consecuencia.

+0

No compila: error: no se puede convertir 'int (*) [2]' a 'int (*) []' en la asignación – Attila

+0

@Attila ¿Cuál es su compilador, funciona bien en 'gcc 4.1.2'. :) –

+0

http : // ideone.com/- Creo que usa gcc en la parte posterior, pero no sé qué versión/opciones – Attila

1

I Solía ​​tener problemas con la tipificación C también, hasta que supe cómo se creó.

En C, el tipo se describe de la manera en que usaría una variable de ese tipo.

Por lo tanto, cuando vea:

int *x; 

que significa que la expresión es de tipo *xint, por lo que es x variable de tipo int puntero a.

y si ves:

int x[5]; 

que significa que la expresión es de tipo x[3]int, por lo x es una variable de tipo array de int.

Por lo tanto, para llegar a su expresión:

int (*x)[]; 

que significa que la expresión es de tipo *xint[] (es decir, una serie de int de tamaño desconocido). Por lo tanto, x es una variable de tipo puntero-a-una-matriz-de-int.

+1

Usted es esencialmente correcto, pero podría ser aún más claro. Cuando ve 'int * x' eso significa que' * x' es * una variable * de tipo int. En la forma en que lo dijiste, no está claro si quisiste decir que '* x' era un * valor * de tipo int o una * variable * de tipo int. –

+0

@EricLippert: '* x' no es una variable, es una expresión. Introduje "expresión" y "variable" en todo el lugar para marcar la distinción y, con suerte, aclarar las cosas. –

+2

Por supuesto '* x' es una * variable *; representa una * ubicación de almacenamiento * que * puede asignar valores a *, por lo que es una * variable *; eso es lo que una variable * es *: una ubicación de almacenamiento a la que puede asignar valores. C programadores, por supuesto, tienden a llamar tales cosas "lvalues" en lugar de "variables", que es desafortunado; "lvalue" es una forma confusa e innecesariamente jerga para decir "variable". –

0

int (* x) [] Esto significa x es un puntero a una matriz int Inicializar como: int (* x) []; int a [10]; x = & a;

int * x [] Esto significa x es una matriz de punteros a int int * x [10]; int a [10]; x [0] = a;

En mi opinión, utilice siempre variables de matriz inicializadas o utilice int ** x en lugar de * x [] y luego asigne memoria en tiempo de ejecución.

+0

El primer ejemplo de uso no se compila: error: no se puede convertir 'int() [10]' en 'int() []' en la asignación – Attila