c

La diferencia real entre "int" y "unsigned int"



(9)

int :

El tipo de datos int de 32 bits puede contener valores enteros en el rango de -2,147,483,648 a 2,147,483,647. También puede referirse a este tipo de datos como firmado int o firmado.

unsigned int :

El tipo de datos int no firmado de 32 bits puede contener valores enteros en el rango de 0 a 4.294.967.295. También puede referirse a este tipo de datos simplemente como sin firmar.

Ok, pero, en la práctica:

int x = 0xFFFFFFFF; unsigned int y = 0xFFFFFFFF; printf("%d, %d, %u, %u", x, y, x, y); // -1, -1, 4294967295, 4294967295

no hay diferencia, estoy un poco confundido.


Él está preguntando sobre la diferencia real . Cuando habla de un comportamiento indefinido, se encuentra en el nivel de garantía proporcionado por la especificación del lenguaje: está lejos de la realidad. Para comprender la diferencia real, compruebe este fragmento (por supuesto, esto es UB, pero está perfectamente definido en su compilador favorito):

#include <stdio.h> int main() { int i1 = ~0; int i2 = i1 >> 1; unsigned u1 = ~0; unsigned u2 = u1 >> 1; printf("int : %X -> %X/n", i1, i2); printf("unsigned int: %X -> %X/n", u1, u2); }


El problema es que invocas Comportamiento no definido .

Cuando invocas a UB cualquier cosa puede suceder.

Las asignaciones están bien; hay una conversión implícita en la primera línea

int x = 0xFFFFFFFF; unsigned int y = 0xFFFFFFFF;

Sin embargo, la llamada a printf no está bien

printf("%d, %d, %u, %u", x, y, x, y);

UB no coincide con el especificador % y el tipo del argumento.
En su caso, especifique 2 int s y 2 unsigned int s en este orden proporcionando 1 int , 1 unsigned int , 1 int y 1 unsigned int .

No hagas UB !


Este es bastante directo. La representación binaria es la clave que se menciona pero nunca se muestra. Sin signo en HEX si 0XFFFFFFF = código máquina = 1111 1111 1111 1111 1111 1111 1111 1111 = 4,294,967,295 representaciones positivas de un número. Eso está bien y muy bien, pero necesitamos una forma de representar los números negativos. Entonces los cerebros decidieron complementarse a dos. ¿Qué significa esto, en resumen, tomaron el dígito más a la izquierda y decidieron que cuando es un 1 (seguido de todos hasta llegar al bit más significativo de la izquierda) el número será negativo si es 0 es positivo. Ahora veamos qué sucede 0000 0000 0000 0000 0000 0000 0000 0011 = 3 . Ahora continuemos agregando a este número 0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645 el número positivo más alto con un int firmado. Vamos a agregar 1 (aquí es posible que desee buscar la adición binaria) debemos llevar el uno hasta el final. 1111 1111 1111 1111 1111 1111 1111 1110 = -1 Así que, en resumen, podríamos decir que la diferencia es que permite números negativos, el otro no, que se debe al bit de signo o al bit más a la izquierda o al bit más significativo.


Jeje. Aquí tienes un elenco implícito, porque le estás diciendo a printf qué tipo esperar.

Pruebe esto en vez de tamaño:

unsigned int x = 0xFFFFFFFF; int y = 0xFFFFFFFF; if (x < 0) printf("one/n"); else printf("two/n"); if (y < 0) printf("three/n"); else printf("four/n");


La función printf interpreta el valor que usted pasa de acuerdo con el especificador de formato en una posición coincidente. Si le dice a printf que pasa un int , pero pasa unsigned lugar, printf volverá a interpretar uno como el otro e imprimirá los resultados que ve.


La representación interna de int y unsigned int es la misma.

Por lo tanto, cuando pasa la misma cadena de formato a printf , se imprimirá igual.

Sin embargo, existen diferencias cuando los comparas. Considerar:

int x = 0x7FFFFFFF; int y = 0xFFFFFFFF; x < y // false x > y // true (unsigned int) x < (unsigned int y) // true (unsigned int) x > (unsigned int y) // false

Esto también puede ser una advertencia, ya que cuando se compara el entero firmado y el no firmado, uno de ellos se convertirá implícitamente para que coincida con los tipos.


No hay diferencia entre los dos en la forma en que se almacenan en la memoria y los registros, no hay una versión firmada y no firmada de los registros int, no hay información firmada almacenada con el int, la diferencia solo se vuelve relevante cuando se realizan operaciones matemáticas, hay La versión firmada y sin firmar de las Operaciones de Matemáticas integradas en la CPU y la Firma le dicen al compilador qué versión usar.


Sí, porque en su caso usan la misma representación .

El patrón de bits 0xFFFFFFFF parece tener el aspecto -1 cuando se interpreta como un entero con signo 32b y como 4294967295 cuando se interpreta como un entero sin signo 32b.

Es lo mismo que char c = 65 . Si lo interpreta como un entero con signo, es 65. Si lo interpreta como un personaje, es a .

Como señalan R y pmg, técnicamente es un comportamiento indefinido pasar argumentos que no coinciden con los especificadores de formato. De modo que el programa podría hacer cualquier cosa (desde imprimir valores aleatorios hasta colgar, imprimir lo "correcto", etc.).

El estándar lo señala en 7.19.6.1-9

Si una especificación de conversión no es válida, el comportamiento es indefinido. Si algún argumento no es del tipo correcto para la especificación de conversión correspondiente, el comportamiento es indefinido.


el tipo simplemente te dice qué se supone que representa el patrón de bits. los bits son solo lo que haces de ellos. las mismas secuencias se pueden interpretar de diferentes maneras.