Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

258
Vistas
¿Por qué `(char)~0` y `(unsigned char)~0` devuelven valores de diferentes anchos?

Me encontré con esto mientras escribía un programa que intentaba imprimir los valores de bytes constituyentes de los caracteres UTF-8.

Este es el programa que escribí para probar las diversas operaciones ~0 :

 #include <stdio.h> int main() { printf("%x\n", (char)~0); // ffffffff printf("%x\n", (unsigned char)~0); // ff printf("%d\n", sizeof(char) == sizeof(unsigned char)); // 1 printf("%d\n", sizeof(char) == sizeof(unsigned int)); // 0 printf("%d\n", (char)~0 == (unsigned int)~0); // 1 }

Estoy luchando por entender por qué char produciría un valor de tamaño int , cuando unsigned char produce un valor de tamaño char .

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Al pasar un tipo más pequeño que int a una función variable como printf , se promociona a tipo int .

En el primer caso, está pasando char con valor -1 cuya representación (asumiendo el complemento de 2) es 0xff. Esto se promociona a un int con valor -1 y representación 0xffffffff, así que esto es lo que se imprime.

En el segundo caso, está pasando un unsigned char con valor 255 cuya representación es 0xff. Esto se promociona a un int con valor 255 y representación 0x000000ff, por lo que esto es lo que se imprime (sin los ceros iniciales).

over 4 years ago · Santiago Trujillo Denunciar

0

No producen valores de diferentes anchos. Producen valores con diferentes números de bits establecidos en ellos.

En su implementación de C, parece que int es de 32 bits y char está firmado. Los usaré en esta respuesta, pero los lectores deben tener en cuenta que el estándar C permite otras opciones.

Usaré hexadecimal para indicar los bits que representan valores.

En (char)~0 , 0 es un int . ~0 luego tiene bits FFFFFFFF. En un complemento a dos de 32 bits int , esto representa −1. (char) convierte esto en char .

En este punto, tenemos un char con valor −1, representado con bits FF. Cuando eso se pasa como argumento a printf , se convierte automáticamente en un int . Como su valor es −1, se convierte en un int con valor −1. Los bits que representan ese int son FFFFFFFF. Le pides a printf que formatee esto con %x . Técnicamente, eso es un error; %x es para un unsigned int , pero su implementación de printf formatea los bits FFFFFFFF como si fueran un unsigned int , produciendo una salida de "ffffffff".

En (unsigned char)~0) , ~0 nuevamente tiene el valor −1 representado con bits FFFFFFFF, pero ahora la conversión es a unsigned char . La conversión a un tipo entero sin signo envuelve el módulo M , donde M es uno más que el valor máximo del tipo, por lo que 256 para un unsigned char de ocho bits. Matemáticamente, la conversión es −1 + 1•256 = 255, que es el valor inicial más el múltiplo de 256 necesario para llevar el valor al rango de unsigned char . El resultado es 255. Prácticamente, se implementa tomando los ocho bits inferiores, por lo que FFFFFFFF se convierte en FF. Sin embargo, en unsigned char , los bits FF representan 255 en lugar de −1.

Ahora tenemos un unsigned char con valor 255, representado con bits FF. Pasar eso a printf da como resultado una conversión automática a un int . Dado que su valor de unsigned char es 255, el resultado de la conversión a int es 255. Cuando le pide a printf que formatee esto con %x (lo cual es un error como el anterior), printf lo formatea como si los bits fueran un unsigned int , produciendo una salida de "ff".

over 4 years ago · Santiago Trujillo Denunciar

0

En estas dos llamadas

 printf("%x\n", (char)~0); // ffffffff printf("%x\n", (unsigned char)~0); // ff

las expresiones (char)~0) y (unsigned char)~0) se convierten al tipo int debido a las promociones de enteros.

En el sistema utilizado, el tipo char se comporta como el tipo signed char . Entonces, el bit de signo en esta expresión se propaga cuando la expresión se promociona al tipo int .

Por otro lado, antes de las promociones de enteros, esta expresión (unsigned char)~0 tiene el tipo unsigned char debido a la conversión al tipo sin signo. Por lo tanto, ningún bit de signo se propaga cuando la expresión se promueve al tipo int .

Preste atención a que el especificador de conversión x se aplica a objetos del tipo unsigned int. Entonces, la primera llamada de printf debe escribirse como

 printf("%x\n", ( unsigned int )(char)~0);
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda