
villablanca
Tengo el siguiente código:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
La salida es:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
Puedo ver que un valor se interpreta como firmado o sin firmar según el valor pasado a printf
función. En ambos casos, los bytes son los mismos (ffffffff
). Entonces, ¿cuál es el unsigned
palabra para?

chux – Reincorporar a Monica
Asignar un int -1
a una unsigned
: Como -1
no entra en el rango [0...UINT_MAX]
múltiplos de UINT_MAX+1
se agregan hasta que la respuesta está dentro del rango. Evidentemente UINT_MAX
es pow(2,32)-1 or 429496725
en la máquina de OP entonces a
tiene el valor de 4294967295.
unsigned int a = -1;
los "%x"
, "%u"
especificador espera una coincidencia unsigned
. Dado que estos no coinciden, “si una especificación de conversión no es válida, el comportamiento no está definido. Si algún argumento no es del tipo correcto para la especificación de conversión correspondiente, el el comportamiento no está definido.” C11 §7.21.6.1 9. El especificador printf no cambia b
.
printf("%x\n", b); // UB
printf("%u\n", b); // UB
los "%d"
especificador espera una coincidencia int
. Dado que estos no coinciden, más UB.
printf("%d\n", a); // UB
Dado un comportamiento indefinido, las conclusiones no son compatibles.
en ambos casos, los bytes son los mismos (ffffffff).
Incluso con el mismo patrón de bits, diferentes tipos pueden tener valores diferentes. ffffffff
como un unsigned
tiene el valor de 4294967295. Como int
, dependiendo de la codificación de enteros con signo, tiene el valor de -1, -2147483647 o TBD. Como un float
puede ser un YAYA.
¿Para qué sirve la palabra sin signo?
unsigned
almacena un número entero en el rango [0 ... UINT_MAX]
. Nunca tiene un valor negativo. Si el código necesita un número no negativo, utilice unsigned
. Si el código necesita un número de conteo que puede ser +, – o 0, use int
.
Actualización: para evitar una advertencia del compilador sobre la asignación de un firmado int
para unsigned
, utilice el siguiente. Esto es un unsigned
1u
siendo negado – que está bien definido como arriba. El efecto es el mismo que un -1
pero transmite al compilador intenciones directas.
unsigned int a = -1u;
Teniendo unsigned
en la declaración de variables es más útil para los propios programadores; no trate las variables como negativas. Como habrás notado, ambos -1
y 4294967295
tienen exactamente la misma representación de bits para un entero de 4 bytes. Se trata de cómo quieres tratar o ver ellos.
La declaración unsigned int a = -1;
se está convirtiendo -1
en complemento a dos y asignando la representación de bits en a
. los printf()
especificador x
, d
y u
están mostrando cómo la representación de bits almacenada en la variable a
parece en otro formato.

Santosh A
Cuando inicializas unsigned int a to -1;
significa que usted está almacenando el 2's
complemento de -1
en la memoria de a
.
que no es más que 0xffffffff
o 4294967295
.
Por lo tanto, cuando lo imprimes usando %x or %u
especificador de formato obtienes esa salida.
Especificando el signo de una variable para decidir el límite mínimo y máximo de valor que se puede almacenar.
como con unsigned int
: el rango es de 0 to 4,294,967,295
y int
: el rango es de -2,147,483,648 to 2,147,483,647
Para obtener más información sobre la firma, consulte esta

ARAVINTHKUMAR J
En el hexadecimal no puede obtener un valor negativo. Entonces lo muestra como ffffffff.
La ventaja de usar la versión sin firmar (cuando sabe que los valores contenidos no serán negativos) es que a veces la computadora detectará errores por usted (el programa “choque” cuando una valor negativo se asigna a la variable).
Ver: Complemento a dos – Wikipedia, la enciclopedia libre La respuesta corta es “si el bit más significativo es
1
se interpreta como un negativo entero”.–David C. Rankin
2 de septiembre de 2015 a las 4:51
@rvillablanca “si puedo ver una var firmada impresa como firmada o sin firmar” – no puede, imprimiendo un valor sin firmar usando
%d
e imprimiendo un valor firmado usando%u
o%x
es comportamiento indefinido.– El Croissant Paramagnético
2 de septiembre de 2015 a las 5:13
Algunas de sus declaraciones de printf son UB, que domina esta pregunta.
–David Heffernan
2 de septiembre de 2015 a las 5:45
Es un comportamiento indefinido. Nadie puede entender lo que quiere decir con “imprimir ffffffff se puede imprimir como firmado -1 o sin firmar 4294967295”. El mismo patrón de bits se puede tratar como firmado o sin firmar en printf usando el formato correspondiente si convierte el valor al tipo correcto primero.
– phuclv
2 de septiembre de 2015 a las 5:53
posible duplicado de ¿Qué sucede cuando asigno un valor negativo a un int sin firmar?
– Bo Person
2 de septiembre de 2015 a las 7:43