punteros - Mi puntero de char apunta a un valor no válido después de ser lanzado desde int*
que es un apuntador en informatica (7)
Dado que está ocultando int * a char *, ptr [0] = 1, ptr [4] = 2, ptr [8] = 3, ptr [12] = 4, ptr [16] = 5 y todos los demás igual a 0 .ptr + 4 puntos al 4 ° elemento en la matriz ptr. Entonces el resultado es 2.
Estoy aprendiendo el lenguaje de programación C, recién comencé a aprender matrices con punteros . Tengo un problema en esta pregunta, espero que la salida sea 5
pero es 2
, ¿alguien puede explicar por qué?
int main(){
int arr[] = {1, 2, 3, 4, 5};
char *ptr = (char *) arr;
printf("%d", *(ptr+4));
return 0;
}
En una plataforma de 32 bits, int
es cuatro veces el tamaño de char
. Cuando agrega 4 a ptr
, agrega 4 veces el tamaño de lo que ptr apunta a ptr (que a su vez es una ubicación de memoria). Esa es la dirección del segundo elemento en la matriz int
.
En una plataforma de 64 bits, int
es ocho veces el tamaño de char
; y tu salida sería muy diferente.
Para abreviar, su código no es portable, (también vea la respuesta de Joachim Pileborg como endosante) pero divertido de descubrir.
Es porque el tamaño de char
es uno, y el tamaño de int
es cuatro. Esto significa que agregar 4
a ptr
hace que el punto de resultado sea la segunda entrada en la matriz int
.
Si compiló esto en un sistema big endian , habría impreso 33554432 en su lugar.
Lo que se hace definitivamente no se recomienda en el código de producción, pero definitivamente es excelente para entender punteros, moldes, etc. en el proceso de aprendizaje, por lo que para este su ejemplo es genial. Entonces, por qué obtienes 2. Es porque tu matriz es una matriz de entradas, que dependiendo de tu arquitectura tiene un tamaño diferente (en tu caso, sizeof(int)
es 4). Usted define ptr
como un puntero de char, char tiene un tamaño de 1 byte. La aritmética del puntero (eso es lo que se hace cuando se escribe ptr+4
) funciona con el tamaño de los objetos a los que hace referencia el puntero, en su caso con caracteres. Por ptr+4
tanto, ptr+4
está a 4 bytes del comienzo de la matriz y, por lo tanto, en la 2ª posición de la matriz int
. Eso es. Prueba ptr+5
, deberías obtener 0.
Se presupuso una pequeña arquitectura endian donde un int es de 32 bits (4 bytes), los bytes individuales de int arr[]
ven así (el byte menos significativo en la dirección inferior. Todos los valores en hexadecimal):
|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;
Ahora, ptr
apunta al primer byte: dado que has convertido a char*
, se trata como una matriz de caracteres en adelante:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- ptr
Entonces, *(ptr+4)
accede al quinto elemento de la matriz char y devuelve el valor de char
correspondiente:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- *(ptr + 4) = 2
Por lo tanto, printf()
imprime 2
.
En un sistema Big Endian , el orden de los bytes dentro de cada int
se invierte, lo que da como resultado
|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
^
+-- *(ptr + 4) = 0
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Cada caso de arr
tiene un tamaño de tamaño sizeof(int)
(que puede ser 4 en su implementación).
Como ptr
es un puntero a char
, la aritmética del puntero hace que ptr + 4
puntos 4 bytes después de &arr[0]
, que puede ser &arr[1]
.
En la memoria, se ve algo así como:
Address | 0 1 2 3 | 4 5 6 7 | ...
Value | arr[0] | arr[1] | ...
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Imagine arr
se almacena en la dirección 100
(dirección totalmente tonta). Entonces usted tiene: arr[0]
se almacena en la dirección 100. arr[1]
se almacena en la dirección 104. (hay +4 debido al tipo int
) arr[2]
se almacena en la dirección 108. arr[3]
se almacena en la dirección 112. Etc, etc.
Ahora estás haciendo char *ptr = (char *) arr;
, entonces ptr
= 100 (lo mismo que arr
). La siguiente declaración es interesante, especialmente el segundo argumento de printf
: *(ptr+4)
. Tenga en mente que ptr
= 100. Entonces ptr + 4
= 104, ¡la misma dirección que arr[1]
! Por lo tanto, imprimirá el valor de arr[1]
, que es 2.