int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);
¿Cuál será la salida? ¡Por favor ayuda!¿Qué sucede realmente cuando un entero se convierte en un puntero de char?
int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);
¿Cuál será la salida? ¡Por favor ayuda!¿Qué sucede realmente cuando un entero se convierte en un puntero de char?
aquí estás
int i = 40;
// asignar memoria para el entero i y la asignación de valor 40 a la misma
char *p = (char*)&i;
así que aquí está definiendo una variable puntero y asignándole la dirección de i después de la fundición se a char*
suponen i
se asigna al 1021 address
tan p tendrá esa dirección con el límite de 1 byte por lo que debe mantener first 8 bit from the representation of 40;
como 40 se ha cubierto en los primeros 8 bits de 2 bytes que contendrá un carácter especial de 40, pero como lo está imprimiendo con %d
, imprima 40
;
Excepto que la máquina podría ser Big Endian, en cuyo caso obtendrá 0. – JeremyP
¿Por qué se necesita moldear, cuál es la diferencia entre 'char * p = (char *) & i' y 'char * p = & i'? –
p=(char *)&i;//What actually happens here?
Se toma la dirección de i
y lo convierte en un puntero char
. Entonces, el valor de *p
es ahora el primer byte de i
. Lo que ese valor es, depende de la plataforma.
Lo más probable es que sea 0 o 40 (dependiendo de la endianidad de la máquina). –
¿Por qué se necesita conversión, cuál es la diferencia entre 'char * p = (char *) & i' y 'char * p = & i'? –
Depende. En Windows, la salida será 40, pero esto es solo por una gran cantidad de coincidencias:
En primer lugar, printf no verifica (no puede) el tipo de sus argumentos, ya que ve% d en el formato cadena, asume que el argumento dado es un int. Aunque * p es solo una char, el resultado se promueve a un int (como ocurre con cada argumento que no se especifica en el prototipo de la función).
En segundo lugar, p apuntará a la memoria tomada por la variable i, pero como es un puntero de char, solo tomará un byte de la memoria de i. Dado que Windows/Intel usa la primera convención de Mínimo-Significativo-Byte, 40 se almacenará como un patrón de bytes "40 0 0 0", ya que * p toma el primer byte (char), el resultado será 40. Si tuviera el valor 256 o más grande, el resultado sería incorrecto.
También vea esto http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing –
Empecemos mirando cómo se colocan los contenidos de i
y p
en la memoria (suponiendo orden big-endian):
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x?? 0x?? 0x?? 0x??
Desde p
se declara como una variable automática, no es inicializado a cualquier cosa y contiene un patrón de bits aleatorios representado por 0x??
.
En la línea
p = (char *)&i;
la expresión &i
evalúa a la dirección de i
, o 0x08000000, y su tipo es pointer to int
, o int *
. La conversión convierte el tipo de int *
a char *
, y el resultado se asigna a p
.
Así es como se ven las cosas en la memoria después de la asignación:
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x08 0x00 0x00 0x00
lo tanto, el valor de p
es ahora la dirección de de i
. En la línea de
printf("%d", *p);
el tipo de la expresión *p
es char
, y su valor se lo se almacena en la dirección 0x08000000, que en este caso particular es 0. Como printf
es una función variadic, el valor de *p
es promovido del tipo char
al tipo int
.
Por lo tanto, para este caso particular, la salida es "0". Si la orden fuera little-endian, el mapa se vería como
Item Address 0x03 0x02 0x01 0x00 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x08 0x00 0x00 0x00
y la salida sería "40".
Tenga en cuenta que este ejemplo completo supone que los punteros enteros y de caracteres tienen el mismo tamaño y diseño; no está garantizado que sea cierto en todas partes (consulte Online C Standard (n1256 draft), sección 6.2.5, párrafo 27), por lo que no puede confiar en que esto funcione en todas partes de la manera que espera (suponiendo que estoy en lo cierto al pensar que int
y char
no son compatibles tipos definidos por el estándar, pero podría estar equivocado en eso). El tipo de juego de palabras en general no es seguro.
Su descripción asume que los punteros 'int *' y 'char *' tienen el mismo tamaño y diseño, pero el comportamiento visible de el programa no. El estándar C garantiza que se puede acceder a cualquier objeto como una matriz de caracteres, por lo que el código del OP accederá al primer byte (con la dirección más baja) de 'i'. El valor de ese byte, como han señalado otros, depende de la implementación. –
@KeithThompson ¿Por qué se necesita molde, cuál es la diferencia entre 'char * p = (char *) & i' y 'char * p = & i'? –
¿Por qué se necesita conversión, cuál es la diferencia entre 'char * p = (char *) & i' y 'char * p = & i'? –
El título de su pregunta se refiere a convertir un entero a un puntero de char, pero eso no es lo que hace su código. Está emitiendo un puntero int * a un puntero char. –