2009-12-02 19 views
5

Tengo un entero sin signo pero cuando lo imprimo usando% d a veces hay un valor negativo allí?C Unsigned int que proporciona un valor negativo?

+1

Vea si su compilador tiene una opción para advertir sobre este tipo de error. Es -formato con gcc. –

+0

Posible duplicado de [¿Cómo puedo imprimir el valor máximo de un entero sin firmar?] (Http://stackoverflow.com/questions/12812812/how-can-i-print-maximum-value-of-an-unsigned-integer) –

Respuesta

10

Esto debería funcionar:

unsigned int a; 
printf("%u\n", a); 

Explicación: En la mayoría de las arquitecturas, firmaron enteros se representan en two's complement. En este sistema, los números positivos inferiores a 2**(N-1) (donde N = sizeof(int)) están representados de la misma manera, independientemente de si está utilizando un int o un unsigned int. Sin embargo, si el número en su int no firmado es mayor que 2**(N-1), representa un número con signo negativo en complemento a dos, que es lo que printf le dio cuando lo pasó "%d".

26

La impresión %d leerá el entero como un número decimal con signo, independientemente de su tipo definido.

Para imprimir números sin signo, use %u.

Esto ocurre debido a la forma en que C maneja los argumentos variables. El compilador simplemente extrae los valores de la pila (mecanografiados como void* y apuntando a la pila de llamadas) y printf tiene que averiguar qué contienen los datos de la cadena de formato que le da.

Esta es la razón por lo que necesita para abastecer la cadena de formato - C no tiene forma de RTTI o una 'clase base' (Object en Java, por ejemplo) para obtener un genérico o predefinido de toString.

+4

Nitpick: C es llamada por valor, por lo que el compilador extrae valores de argumento, no punteros. No pasa punteros a valores (printf ("% u", & myvariable);), pasa valores directamente (printf ("% u", myvariable);). – unwind

+1

En realidad le da a 'printf' un puntero a la pila. – LiraNuna

+0

@LiraNuna - La implementación de funciones varargs no está especificada, por lo que ni '#define va_copy (dest, src) dest = src' o' #define va_copy (dest, src) memcpy (dest, src, sizeof (va_list))) 'es un reemplazo portátil para la macro' va_copy' en los sistemas donde no se proporciona. Uno de ellos puede funcionar, pero ¿quién sabe cuál? –

4

% d significa que printf interpretará el valor como un int (que está firmado). use% u si es un int sin firmar.

Cuestiones relacionadas