битовый сдвиг разный результат в аналогичных программах


Вот одна программа

#include<stdio.h>
#include<stdlib.h>
int main()
{
 unsigned char a=0x80;
 printf("%dn",a<<1);
}

Выход выше 256 Теперь вот еще одна версия вышеуказанной программы

#include<stdio.h>
#include<stdlib.h>
int main()
{
 unsigned char a=0x80;
  a=a<<1;
 printf("%dn",a);
}

Выход выше

0
Насколько я понимаю, я не вижу никакой разницы между ними? то есть, почему вывод идет 256 в первой и 0 во второй программе, в чем разница в утверждениях в обеих?
4 2

4 ответа:

Выражение a << 1 имеет тип int в соответствии с правилами продвижения типа языка Си. В первой программе вы берете этот int, который теперь имеет значение 0x100, и передаете его непосредственно в printf(), который работает, как и ожидалось.

Во второй программе ваш int присваивается unsigned char, что приводит к усечению 0x100 до 0x00.

На вашей платформе unsigned char имеет ширину всего 8 бит, поэтому a << 1 смещает 1 из левого конца, когда вы назначаете его обратно узкому a. В вызове printf, с другой стороны, a сначала повышается до целого числа (которое шире, чем 8 бит на вашей платформе), и таким образом бит выживает.

<< повышает результат до (unsigned) int, но во втором примере вы принудительно возвращаете его в (unsigned) char, где он переполняется обратно до 0.

Во втором случае a имеет длину всего 8 бит, 0x80 << 1 - это 0x100 , а затем приводится к символу верхнего Бита, Поэтому становится 0x00

Когда непосредственно в операторе printf, он ищет int, поэтому он не будет обрезать его...