int *columns[32];
Estoy definiendo una matriz con 32 punteros a int
s?
¿O es un puntero a una matriz de 32 int
s?
¿Cómo puedo diferenciar entre los dos? ¿Hay una diferencia?
int *columns[32];
Estoy definiendo una matriz con 32 punteros a int
s?
¿O es un puntero a una matriz de 32 int
s?
¿Cómo puedo diferenciar entre los dos? ¿Hay una diferencia?
En caso de duda - pida cdecl
$> cdecl
Type `help' or `?' for help
cdecl> explain int *columns[32]
declare columns as array 32 of pointer to int
EDITAR En respuesta a los comentarios: He encontrado la fuente cdecl en Google Code Search. Requiere la biblioteca GNU readline. Creo que no debería ser un problema compilarlo en Mac OS X o Windows.
Un programa de prueba es ilustrativa, especialmente a aquellos de nosotros que no son abogados idioma:
$ gcc -x c -
#include <stdio.h>
int main(void)
{
int *columns[32];
printf("%lu\n%lu\n", sizeof(columns), sizeof(columns[0]));
return 0;
}
$ ./a.out
128
4
$
que parece ser una matriz de punteros.
No me gustaría decir que entender las declaraciones requiere el estado de "abogado de idiomas". – GManNickG
Lo sé, pero nunca podría recordar cuál era, y OS X no tiene una buena versión de 'cdecl' instalada. –
La mayoría de los que no son abogados no podrían decirle qué 'void (* (* (* p) [N] [M]) [O]) (char c) = 0;' declara sin usar 'cdecl' o 'geordi' u otras trampas, creo. –
Usted está definiendo una matriz de 32 punteros.
Para definir un puntero a un array de 32 enteros que tiene que hacer
int (*columns)[32];
La declaración anterior crea una instancia de una matriz con espacio para 32 * sizeof (int). Por otra parte, esta última instancia un único puntero no inicializado que luego se puede utilizar de la siguiente manera:
int myintegers[32] = {0, 1, 2, ..., 31};
int (*columns)[32];
columns = &myintegers;
printf("%d\n", (*columns)[2]);
espero haber dejado la diferencia un poco clara.
lo hizo, gracias –
Es una matriz de 32 punteros a int
y sí, sí importa.
reglas gramaticales El C especifican que array de acceso ([]
) se une más apretado que dereference (*
) y declaraciones espejo uso.
La declaración int *columns[32];
significa que la expresión *columns[n]
(donde n
es un número entre 0 y 31) es una int
. Esta expresión es la misma que *(columns[n])
. La declaración asigna el espacio para 32 punteros, pero no hay int
s asignados y (suponiendo que se trate de una declaración local de función) ninguno de los punteros se inicializa.
Tenía la declaración ha sido int (*columns)[32];
entonces la expresión (*columns)[n]
habría sido una int
, lo que significa que el *
eliminar la referencia ocurre antes de que el acceso a la matriz, por lo que las columnas habrían sido un puntero a un array de 32 int
s. La declaración debería haber asignado un puntero, pero no matrices de int
s.
No soy muy usuario de C/C++, pero el idioma me interesa. Esto parece algo contrario a la intuición, tal vez porque vengo de un fondo de C#. Si declara int (* columns) [32], esperaría que obtenga una matriz de 32 punteros. Lo percibo de tal manera que la expresión entre paréntesis especifica un tipo de puntero, y el especificador de matriz significa "32 instancias del tipo a la izquierda". Por lo tanto, 32 punteros. Lo mismo ocurre a la inversa: si dices int * columnas [32] y los corchetes se unen más, la forma intuitiva es una matriz de 32 elementos y luego un puntero a ella. –
¿Por qué es al revés? También he visto la sintaxis de paréntesis en otros lugares, sobre todo los punteros de función. Y tampoco tiene sentido para mí allí. ¿Cómo debería pensarlo para que tenga sentido? –
K & R son probablemente más adecuados para responder 'por qué'. :) Estoy de acuerdo con tu intuición, sin embargo. –
Estas son algunas declaraciones de diversión para usted:
int *arrayOfIntP[32];
int (*pointerToArrayOf32)[32];
Para más diversión con matrices multidimensionales tienen en cuenta estos mensajes:
Un truco es leer De derecha a izquierda.
Given int * cols [32];
Todo lo que queda de matriz es el tipo de los elementos en la matriz. Entonces lo leemos como una matriz de punteros a int (y del recuento 32).
Ampliando un comentario a otra respuesta:
Hay un procedimiento bastante sencillo para la lectura de declaraciones de C. Comience con el identificador situado más a la izquierda en el declarador y continúe su camino de salida, recordando que []
y ()
se enlazan antes de *
. Teniendo en cuenta la declaración
int *columns[32];
ruptura hacia abajo como
columns -- columns
columns[32] -- is a 32-element array
*columns[32] -- of pointers
int *columns[32] -- to int.
Si la declaración había sido
int (*columns)[32];
entonces se rompería como
columns -- columns
(*columns) -- is a pointer
(*columns)[32] -- to a 32-element array
int (*columns)[32] -- of int.
Esto también ayudará usted construye decl complejo araciones. Suponga que desea declarar una matriz de punteros a funciones que devuelven punteros a las matrices de carbón:
f -- f
f[N] -- is an N-element array
*f[N] -- of pointers
(*f[N])() -- to functions
*(*f[N])() -- returning pointers
(*(*f[N])())[M] -- to M-element arrays
*(*(*f[N])())[M] -- of pointers
char *(*(*f[N])())[M]; -- to char
cdecl es una buena herramienta, pero después de que había hecho este ejercicio un par de veces, no lo necesita.
Me gusta mucho esta respuesta –
Esta es una respuesta en la que deseo que StackOverflow tuviera una función de "Respuesta favorita". : -/puntaje + = 1; –
refiérase a la pregunta # 5 de A 'C' Test: The 0x10 Best Questions for Would-be Embedded Programmers por Nigel Jones *
a) int a; // Un entero
b) int * a; // Un puntero a un entero
c) int ** a; // Un puntero a un puntero a un entero
d) int a [10]; // Una matriz de 10 enteros
e) int * a [10]; // Una matriz de 10 punteros a enteros
f) int (* a) [10]; // Un puntero a una matriz de 10 enteros
g) int (* a) (int); // Un puntero a una función a que toma un argumento entero y devuelve un entero
h) int (* a [10]) (int); // Una serie de 10 punteros a funciones que toman un argumento entero y devuelven un entero
* Por desgracia, el artículo original en embedded.com ya no se puede conocer en su página web.
Por curiosidad, ¿sabes dónde conseguir 'cdecl'? Los cerdos capitalistas de Apple no tuvieron la amabilidad de proporcionarle sus herramientas de desarrollo. –
+1 señor, nunca antes había visto esa herramienta, leyendo la página del manual ahora ... –
@Chris Mac OS X no incluye cdecl? Pensé que es una herramienta estándar para todos los Unixes. Puede tomar la fuente cdecl de cualquier distribución de Linux y compilarla en Mac OS X. No creo que tenga ninguna dependencia (bueno, tal vez readline) – qrdl