pointer new functions declarar convert array c arrays pointers

c - new - ¿A qué se refiere `int*userMask[3][4]`?



pointer to int (9)

Aplicar la regla de adentro hacia afuera.

int *userMask[3][4] = {0};

Comenzando en la parte de la parte interior de la declaración,

userMask

es el nombre

userMask[3]

asigna espacio para (es un vector de) 3 de ellos

userMask[3][4]

asigna espacio para 4 userMask[3] ''s

int *

nos dice que los elementos de userMask son tipo puntero a int

y luego = {0} es un inicializador donde todos los elementos son 0 . Asi que

int *userMask[3][4] = {0};

es una matriz de 3x4 de int *, inicializada en 0.

Estoy modificando algunos códigos y encontré una declaración que tengo problemas para entender:

int *userMask[3][4] = {0};

¿A qué apunta exactamente esto? ¿Es una matriz donde cada elemento es un puntero? ¿O está apuntando a una matriz de tamaño [3] [4]?

Gracias

Supongo que mi pregunta es cómo userMask[2][maskElement][user] puede funcionar cuando se declara como int . ¿No necesitaría userMask int[] para que funcione correctamente? No debo entender esto bien ...

En una nota lateral, gracias por su sugerencia sobre cdecl Robert. Sin embargo, ¿alguien sabe cómo usarlo en un símbolo del sistema de XP? Todo lo que puedo obtener es un error de sintaxis :(


Creo que esa declaración accede a la tercera fila de la matriz de máscara de usuario, luego accede al puntero maskElement''th en esa fila, y dado que es un puntero int, puede señalar el comienzo de una matriz int (cadenas de caracteres de pensar), que asuma que está haciendo, y esa matriz está subindicada por el usuario.


Es una matriz donde cada elemento es un puntero.

Si apuntaba a una matriz de tamaño [3] [4], el código habría sido

int userMask[3][4]={0};


Esta es una matriz bidimensional donde cada elemento es un puntero a un int , y todos los punteros se inicializan a cero.

En su seguimiento, usted muestra que la matriz se usa así:

if(userMask[2][maskElement][user] && blah) result = true;

En este caso, cada elemento en userMask en realidad debería apuntar a una matriz de int s. (Un int* puede apuntar a una sola int o una matriz de int s). Para determinar esto, verifique el código que asigna valores a userMask . Por ejemplo, es posible escribir:

int userArray[2] = { 10, 20 }; userMask[0][0] = userArray; // userMask[0][0] points to the // first element of userArray.

Luego, el siguiente código indexa en userArray :

int value = userMask[0][0][1]; // sets value = userArray[1], giving 20.


userMask[2] es de tipo int*[] ,
userMask[2][maskElement] es del tipo int* ,
y entonces userMask[2][maskElement][user] es de tipo int .

La declaracion

int *userMask[3][4] = {0};

es una abreviatura de

int *userMask[3][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};

donde cada uno de los ceros se convierte implícitamente en (int*)0 .


if(userMask[2][maskElement][user] && blah) result = true;

La segunda parte aquí es que no hay matrices en C; solo hay aritmética de puntero. Por definición, p[i] siempre es equivalente a *(p+i) entonces

userMask[2][maskElement][user]

es equivalente a

*((userMask[2][maskElement])+user)

El código está en alguna parte asignando un vector (apostaría que es de un malloc (3c) o una llamada similar) al puntero en esa matriz; ahora tu si está diciendo

SI el elemento usuario del vector en userMask [2] [maskElement] no es cero

ENTONCES, si blah no es cero (debido a la evaluación de corto circuito de &&, el segundo conjunto no se evalúa si el primer conjunto es 0)

ENTONCES establezca el resultado = verdadero.


int *userMask[3][4] = {0};

es una matriz bidimensional donde cada miembro es un puntero a int. Además, todos los miembros se inicializan a punteros nulos.

int (*userMask)[3][4];

sería un puntero a una matriz bidimensional de ints. Los corchetes en C se unen con más fuerza que *, por lo que los paréntesis son necesarios para crear un puntero a una matriz.

cdecl es una utilidad simple que puede descargar para explicar declaraciones complejas:

cdecl> explain int *userMask[3][4] declare userMask as array 3 of array 4 of pointer to int

También puede hacer lo opuesto:

cdecl> declare userMask as pointer to array 3 of array 4 of int int (*userMask)[3][4]


ayuda si lo lees así:

type variablename[array_spec];

en este caso: int * usermask [3] [4];

entonces es una matriz de int *.

ahora, dado que c no diferencia entre puntero y matrices, puede usar la indexación de matrices en los punteros.

int* i; int the_int_behind_i = *(i+1); int also_the_int_behind_i = i[1];

Esto necesita apuntar a un área donde varios Ints están alineados uno detrás del otro, por supuesto, como una matriz.

Tenga en cuenta que el operador de índice [] utilizado en los últimos ejemplos se parece al array_spec en el primero, pero los dos son bastante diferentes.

Entonces: userMask [2] [maskElement] [usuario]

selecciona el puntero de máscara de usuario almacenado en [2] [maskElement] y lo evalúa para el usuario


Respuesta corta

Dado userMask se declara como

int *userMask[3][4];

entonces userMask tiene tipo int*[3][4] . Es un conjunto 2d de punteros a int. El tamaño de la dimensión externa es 3, el tamaño de la dimensión interna es 4. Realmente eso no es más que una matriz de 3 elementos de 1d cuyo tipo de elemento es otra matriz de 4 elementos 1d cuyo tipo de elemento es int* .

Pasos explicados

Entonces si lo haces

userMask[2][maskElement][user]

luego, esencialmente con los dos primeros índices, selecciona el puntero particular de la matriz 2d:

int * p = userMask[2][maskElement];

a continuación, elige un desplazamiento int en algún lugar de ese puntero haciendo

p[user]

ahora ese código está todo en userMask[2][maskElement][user] .

Código C válido

Para hacerlo paso a paso con un código c válido (no se preocupe si no comprende todo aún en lo siguiente):

int * userMask[3][4] = { { 0 } }; int ** pa = userMask[2]; /* int*[4] becomes int** implicitly */ int * pi = pa[maskElement]; int i = pi[user]; assert(i == userMask[2][maskElement][user]);

Diferencia entre matrices y punteros

Entonces creo que te muestro algo importante. El conjunto de arriba no contiene punteros a las matrices. Veamos qué tan diferentes se comportan, lo que muchos programadores de c no esperan:

int array[5][4][3]; /* int[4][3] implicitly converts to int(*)[3] (pointer to first element) */ int (*parray)[3] = array[0]; int ** pint = (int**) array[0]; /* wrong!! */

Ahora, ¿qué pasará si hacemos parray[1] y pint[1] ? El primero avanzará parray por sizeof(int[3]) bytes ( 3 * sizeof(int) ), el segundo avanzará solo por sizeof( int* ) bytes. Entonces, en realidad, mientras que el primero te da la matriz de array[0][1] correcta array[0][1] , la segunda te dará ( char * )array[0] + sizeof( int* ) , que es un lugar en el que realmente no queremos que sea . Pero agarrar el offset equivocado no es todo. Como no sabe que se accede a una matriz, intentará interpretar lo que está en pint[1] como int* . Digamos que su matriz se inicializó con 0x00 . Luego hará el próximo paso de índice basado en la dirección 0x00 (haciendo pint[1][0] por ejemplo). Oh, no, ¡comportamiento completamente indefinido! Entonces, es realmente importante destacar la diferencia.

Conclusión

Esto fue más de lo que pediste, pero creo que es muy importante saber estos detalles. Especialmente si quiere pasar arreglos de 2d a funciones, este conocimiento es realmente útil.