%u
trata el entero como sin signo, mientras que %d
trata el entero como firmado. Si el número entero está entre 0 y INT_MAX
(que es 2 -1 en sistemas de 32 bits), la salida es idéntica para ambos casos.
que sólo tiene una diferencia si el entero es negativo (para entradas firmados) o entre INT_MAX+1
y UINT_MAX
(por ejemplo entre 2 y 2 -1). En ese caso, si usa el especificador %d
, obtendrá un número negativo, mientras que si usa %u
, obtendrá un número positivo grande.
Las direcciones solo tienen sentido como números sin firmar, por lo que nunca hay motivo para imprimirlas como números con signo. Además, cuando se imprimen, generalmente se imprimen en hexadecimal (con el especificador de formato %x
), no en formato decimal.
En realidad, debería utilizar el especificador de formato %p
para las direcciones; está garantizado que funciona para todos los punteros válidos. Si está en un sistema con enteros de 32 bits pero de 64 bits, si intenta imprimir un puntero con cualquiera de %d
, %u
o %x
sin el modificador de longitud ll
, obtendrá el resultado incorrecto para eso y cualquier otra cosa que se imprima más tarde (porque printf
solo leyó 4 de los 8 bytes del argumento del puntero); si agrega el modificador de longitud ll
, entonces no será portátil para los sistemas de 32 bits.
En pocas palabras: siempre use %p
para la impresión de punteros/direcciones:
printf("The address of n is: %p\n", &n);
// Output (32-bit system): "The address of n is: 0xbffff9ec"
// Output (64-bit system): "The address of n is: 0x7fff5fbff96c"
El formato exacto de salida es definido por la implementación (C99 §7.19.6.1/8), pero casi siempre se imprime como un número hexadecimal sin signo, generalmente con un 0x
principal.
Usaría 'printf ("% x \ n ", & n)' para imprimir la representación hexadecimal de la dirección. Pero solo soy yo. – dappawit
Tire el libro lejos: nunca debe usar ni '% u' ni'% d' para imprimir direcciones, ya que una dirección puede tener más bits que un int - use '% p', o falla ese'% # llx'. –
También debe convertir la dirección para que coincida con el tipo de especificador que elija. 'printf' no puede hacer conversiones automáticas ya que los argumentos no tienen parámetros de prototipos. Con '% p' que es' (void *) ', y con'% # llx' que es '(unsigned long long)', etc. –