¿Qué es char i = 0x80 y por qué el desbordamiento no ocurrió en el cambio de bits?

Aqui hay un progtwig

#include  main() { unsigned char i=0x80; printf("i=%d",i<<1); } 

La salida que está dando es de 256. No tengo claro qué hace

 unsigned char i=0x80; <-- i is not int it is char so what will it store? 

Sé cosas de bitshift y hexadecimales. ¿Cómo se almacena el valor de i y cómo se cambia a 256?

ACTUALIZAR

¿Por qué no se produjo el desbordamiento cuando ocurrió la operación de cambio de bit?

En C, un char es un tipo entero usado para almacenar datos de caracteres, generalmente 1 byte.

El valor almacenado en i es 0x80 una constante hexidecimal que es igual a 128 .

Una operación aritmética en dos tipos enteros (como i << 1 ) promoverá el tipo más amplio , en este caso a int , ya que 1 es una constante int. En cualquier caso, los argumentos de la función entera se promueven a int.

Luego, envía el resultado a printf , con un especificador de formato %d , que significa "imprimir un número entero".

Creo que K&R tiene la mejor respuesta a esta pregunta:

2.7 Conversiones de tipo Cuando un operador tiene operandos de diferentes tipos, se convierten en un tipo común de acuerdo con un pequeño número de reglas. En general, las únicas conversiones automáticas son aquellas que convierten un narrower'' operand into a “más amplio” sin perder información, como convertir un número entero en un punto flotante en una expresión como f + i. Las expresiones que no tienen sentido, como usar un flotador como un subíndice, no están permitidas. Las expresiones que pueden perder información, como asignar un tipo de entero más largo a un tipo de punto flotante o más corto, pueden dibujar una advertencia, pero no son ilegales. Un char es solo un entero pequeño, por lo que los caracteres se pueden usar libremente en expresiones aritméticas.

Así que i << 1 convierte i a int antes de que se desplace. Ken Vanerlinde tiene razón.

0x80 es hexadecimal para 128 La operación x << 1 significa desplazar a la izquierda por uno, lo que multiplica efectivamente el número por dos y, por lo tanto, el resultado es 256 .

i=0x80 almacena el valor hexadecimal 0x80 en i. 0x80 == 128 .

Al imprimir el valor en la statement de formato printf() , el valor pasado a la statement printf() es i<<1 .

El operador << es el operador a la izquierda con desplazamiento a nivel de bit unario, que mueve los bits en i a la posición izquierda.

128 en binario es `10000000 ', cambiando eso a la derecha un bit da' 100000000 'o 256.

i << 1 no está siendo almacenado en i. Por lo tanto, no hay duda de desbordamiento y 256 es la salida.

El siguiente código dará 0 como salida.

 #include  main() { unsigned char i=0x80; i = i<<1; printf("i=%d",i); }