
Hari
Quiero obtener una explicación detallada sobre la diferencia entre usar %d
y %p
escribir para printing pointer
.
También ¿Por qué %p
devolver hexadecimal? ¿Cuáles son los casos en que %d
y %p
devolver valores diferentes? ¿El tipo de datos solo representa la forma en que el usuario quiere la salida o también tiene algo que ver con las ubicaciones de memoria?

NPE
Para que el programa esté bien definido, el especificador de formato debe coincidir con el tipo del argumento. Por lo tanto puedes usar %p
pero no %d
para imprimir punteros. (Esto último podría funcionar en algunas arquitecturas pero es técnicamente comportamiento indefinido.)
La razón principal por la que no puede intercambiar libremente %d
y %p
es eso ints
y los punteros no tienen que tener el mismo tamaño.
El formato en el que se imprimen los punteros es específico de la arquitectura (los punteros pueden tener un tamaño diferente o incluso diferentes estructura). Sin embargo, es común transcribir direcciones de memoria en hexadecimal, así que esto es lo que %p
normalmente lo hace.
Esas conversiones dependen en gran medida de la arquitectura. Una de las distinciones más claras es con el modo real 8086 donde int
es de 16 bits y un puntero (modelo grande) es de 32 bits pero tiene un segmento y un desplazamiento que siempre se escriben como segmento: desplazamiento.
%d takes 16 bits and displays it as a signed value 123
%p takes a pointer and display it in address format 0fef:0004
Ya que %p
se introdujo hace relativamente poco tiempo. No conozco ninguna implementación, pero una biblioteca PDP-11 debería implementarla mostrando la dirección de 16 bits en octal.
Un puntero de variable en C tiene valor al igual que otro tipo de variable, como int, char, etc. La cadena de formato %p en la función printf solo indica que el tipo de parámetro “i” apunta a printf en lugar de int. Por lo tanto, printf genera el valor hexadecimal del parámetro i porque printf parece el parámetro i como un tipo de puntero. No importa cuál sea el tipo de variable i, el valor es el mismo—-10 o 0xa. La diferencia entre los tipos de i—int o puntero —-son las diferentes formas de usar en C. Si el tipo de i se considera un puntero, puede visitar la memoria especificada por el valor del puntero i u otras operaciones. soportes de tipo puntero. Si el tipo de i es int, podemos hacer algunas operaciones como sumas o restas en lugar de visitar la memoria usando el valor de i, porque la gramática de C no le permite hacer eso (solo advertencia). si sabes lo que quieres hacer, puedes hacerlo.
Terminología incorrecta:
%p
o%d
no son tipos de datos (comoint
ovoid*
), peroprintf
directivas de cadena de formato.– Basile Starynkevitch
2 oct 2014 a las 14:08
Gracias por señalar eso..
– Hari
2 oct 2014 a las 14:13
Por cierto, si se compila con
gcc -Wall -g
probablemente reciba una advertencia cuando haga un mal uso de estas directivas de cadena de formato (al menos cuando la cadena de formato es un argumento constante literal paraprintf
)– Basile Starynkevitch
2 oct 2014 a las 14:16