vectores una punteros matriz matrices llenar ingresar funciones dinamica datos con como codigo c arrays pointers sizeof

una - Experimentos utilizando sizeof con matrices y punteros.



punteros en c (3)

Por favor responda las preguntas y corríjame si alguna de las observaciones es incorrecta.

  1. ¿Es la salida 20 caso 1 porque b se declaró como una array de int inters, es decir, int[] ? El bloque total en bytes se devuelve como lo confirma Fact1. ¿No es así?

Sí, el resultado muestra la sizeof(int [5]) . Así que a partir de Fact1, el tamaño es 5*4

  1. Supongo que lanzar b to int* hizo la diferencia aquí. Aquí b se considera un puntero. Confirmé esto utilizando Fact2. ¿Bien o mal?

Derecha. Pero agregar más información: sizeof necesita solo el tipo de expresión y no evalúa la expresión (para valor) a menos que sea del tipo VLA. (De la sección 6.5.3.4 El operador sizeof de especificaciones C99 )

Debido a que está aplicando elenco en el resultado final, nada de eso no importa.

  1. &b[0] decae a un puntero b . La salida coincide con Fact2.

No y sí. El tipo de b[0] es int y, por lo tanto, el tipo de &b[0] ya es int * (Recuerde que [...] une más que & ). No hay decadencia. Y sí, la salida coincide con Fact2.

  1. Esperaba 16 aquí pero obtuve 8 como salida. Llegué a la conclusión de que esto se debe a que, después de todo, es un puntero y la salida coincide con Fact2. Tengo la salida similar a la pregunta 2.

como a puntero a la matriz 2 de int . Así que el tamaño impreso es de puntero (a una matriz int ).

int (*a)[2]; declara a puntero a la matriz 2 de int . Así obtienes el tamaño de pointer to array .

Para obtener el resultado deseado (tamaño de la matriz 2 de punteros a int ) use: int *a[2];

int (*a)[2]; a anonymous +----+ +----+----+ | a |----->|int |int | +----+ +----+----+ int *b[2]; b +----+----+ |int*|int*| +----+----+ b[0] b[1]

  1. a[0] es puntero. La salida coincide con Fact2.
  2. a[2] es el puntero. La salida coincide con Fact2.

Como se indicó anteriormente, a es un puntero a la matriz 2 de int . Entonces a[index] es una matriz 2 si es int . Entonces, el tipo de a[0] y a[1] son la matriz 2 de int . Así que la salida es 2*4 de Hecho 1.
Posiblemente irrelevante para esta respuesta, pero no está inicializado y su uso en la expresión causaría un comportamiento indefinido . Aunque está bien para usar en sizeof

Para entender el resultado, analicemos el tipo de argumento de sizeof

printf("sizeof(b) : %zu/n",sizeof(b)); // int [5] printf("sizeof((int*)b) : %zu/n",sizeof((int*)b)); // int * printf("sizeof(&b[0]) : %zu/n",sizeof(&b[0])); // int * printf("sizeof(a) : %zu/n",sizeof(a)); // int (*) [2] printf("sizeof(a[0]) : %zu/n",sizeof(a[0])); // int [2] printf("sizeof(a[1]) : %zu/n",sizeof(a[1])); // int [2]

Un programa portátil (no infalible) para confirmar los tipos se ve así:

assert(sizeof(b) == sizeof(int [5])); assert(sizeof((int*)b) == sizeof(int *)); assert(sizeof(&b[0]) == sizeof(int *)); assert(sizeof(a) == sizeof(int(*)[2])); assert(sizeof(a[0]) == sizeof(int[2])); assert(sizeof(a[1]) == sizeof(int[2]));

Para el programa:

#include<stdio.h> int main(void) { int (*a)[2]; int b[5]; printf("sizeof(int) : %zu/n", sizeof(int)); printf("sizeof(int*) : %zu/n", sizeof(int*)); printf("sizeof(b) : %zu/n",sizeof(b)); printf("sizeof((int*)b) : %zu/n",sizeof((int*)b)); printf("sizeof(&b[0]) : %zu/n",sizeof(&b[0])); printf("sizeof(a) : %zu/n",sizeof(a)); printf("sizeof(a[0]) : %zu/n",sizeof(a[0])); printf("sizeof(a[1]) : %zu/n",sizeof(a[1])); return 0; }

La salida es:

sizeof(int) : 4 -> Fact 1 sizeof(int*) : 8 -> Fact 2 sizeof(b) : 20 -> Case 1 sizeof((int*)b) : 8 -> Case 2 sizeof(&b[0]) : 8 -> Case 3 sizeof(a) : 8 -> Case 4 sizeof(a[0]) : 8 -> Case 5 sizeof(a[1]) : 8 -> Case 6

Preguntas / Observaciones (en caso de orden):

  1. ¿Es el caso 1 la salida 20 porque b se declaró como una matriz de enteros, es decir, int[] ? El bloque total en bytes se devuelve como lo confirma Fact1. ¿No es así?

  2. Supongo que lanzar b to int* hizo la diferencia aquí. Aquí b se considera un puntero. Confirmé esto utilizando Fact2. ¿Bien o mal?

  3. &b[0] decae a un puntero b . La salida coincide con Fact2.

  4. Esperaba 16 aquí pero obtuve 8 como salida. Llegué a la conclusión de que esto se debe a que, después de todo, es un puntero y la salida coincide con Fact2. Tengo la salida similar a la pregunta 2.

  5. a[0] es puntero. La salida coincide con Fact2.

  6. a[1] es puntero. La salida coincide con Fact2.

Por favor responda las preguntas y corríjame si alguna de las observaciones es incorrecta.


Aquí hay un poco de investigación individual sobre el tema. He ejecutado su código de prueba en cuatro entornos diferentes, dos de 64 bits y dos de 32 bits.
Utilicé tres compiladores diferentes: llvm, gcc y mipsPro cc.
Aquí está la comparación comentada de los resultados :

// 64-bit environment - all compilers sizeof(int) : 4 -> Fact 1 -32 bit int -> 4 bytes sizeof(int*) : 8 -> Fact 2 -this and other pointers in a 64-bit system are 8-bytes long sizeof(b) : 20 -> Case 1 -array of 5 32 bit ints -> 20 bytes sizeof((int*)b) : 8 -> Case 2 sizeof(&b[0]) : 8 -> Case 3 sizeof(a) : 8 -> Case 4 sizeof(a[0]) : 8 -> Case 5 -array of two 4 byte ints sizeof(a[1]) : 8 -> Case 6 -array of two 4 byte ints // 32-bit environments - all compilers sizeof(int) : 4 -> Fact 1 -32 bit int -> 4 bytes sizeof(int*) : 4 -> Fact 2 -this and other pointers in a 32-bit system are 4-bytes long sizeof(b) : 20 -> Case 1 -array of 5 32 bit ints -> 20 bytes sizeof((int*)b) : 4 -> Case 2 sizeof(&b[0]) : 4 -> Case 3 sizeof(a) : 4- > Case 4 sizeof(a[0]) : 8 -> Case 5 -array of two 4 byte ints sizeof(a[1]) : 8 -> Case 6 -array of two 4 byte ints

Interpretación : todos los resultados coinciden constantemente con el siguiente patrón:

  • El tamaño de int solía depender del compilador, y quizás todavía lo hace, AFAIK Se encuentra en todos los entornos probados y compiladores de 4 bytes (Hecho 1).
  • El tamaño de todos los punteros está predeterminado para el entorno, ya sea 64 bits o 32 bits (Hecho 2, Caso 2, 3, 4).
  • El tamaño de una matriz de dos ints de cuatro bytes es igual a 2*sizeof(int) (Caso 5, 6).
  • a[0] se puede reescribir como *a ; a[1] también se puede escribir como *(a + 1) . El siguiente post de SO lo explica en detalle.

    Espero que esto pueda contribuir a su tema.

El operador sizeof es una de las pocas cosas que pueden distinguir entre una matriz (suponiendo que no sea un parámetro de función) y un puntero.

  1. b se reconoce como una matriz de 5 elementos donde cada uno es de 4 bytes, por lo que sizeof(b) evalúa a 20.
  2. La conversión convierte la matriz en un puntero de forma similar a como lo haría pasarla a una función. Así que el tamaño es 8.
  3. Esto no está realmente decayendo a un puntero. Es un puntero. Está tomando la dirección de un int , por lo que, por supuesto, el tipo es int * . Al abordar uno de sus comentarios, todavía no es exacto decir que la expresión &b[0] descompone en un puntero si lo pasa a una función, porque de hecho es un puntero, no una matriz.
  4. Dado que a es un puntero a una matriz, el tamaño es el tamaño de un puntero, es decir, 8. Esto es diferente de int *c[2] , que es una matriz de punteros y tendría el tamaño 16.
  5. a[0] no es un puntero sino una matriz de tamaño 2 . La sintaxis a[0] es equivalente a *(a + 0) . Entonces, dado que a es un puntero a una matriz, la anulación de la referencia a nos da una matriz. Dado que cada elemento tiene 4 bytes, el tamaño es 8. Si a se definió como int (*a)[3] , sizeof(a[0]) evalúa como 12.
  6. Similar al número 5, a[1] es una matriz de tamaño 2. Por lo tanto, sizeof(a[1]) evalúa como 8 porque es una matriz de 2 elementos de tamaño 4.

Un ejemplo de cómo usar a es el siguiente:

int (*a)[2]; int d[3][2]; a=d; d[0][0]=1; d[0][1]=2; d[1][0]=3; d[1][1]=4; d[2][0]=5; d[3][1]=6; printf("a00=%d/n",a[0][0]); printf("a01=%d/n",a[0][1]); printf("a10=%d/n",a[1][0]); printf("a11=%d/n",a[1][1]); printf("a20=%d/n",a[2][0]); printf("a21=%d/n",a[3][1]);

Salida:

a00=1 a01=2 a10=3 a11=4 a20=5 a21=6

También usas esto cuando pasas una matriz 2D a una función:

void f(int (*a)[2]) { ... } int main() { int x[3][2]; f(x); }