我刚开始学习c语言。我对按位运算的结果有疑问。在下面的代码中,为什么我们从c和d得到不同的结果?我们如何将72作为d的值?
char a = 41;//101001
char b = (a<<5);//32 or 100000
char c = (b>>2);//8 or 1000
char d = (a<<5)>>2;//72 or 1001000
printf("a= %d , b=%d, b=%d , d=%d\n", a, b,c,d);
答案 0 :(得分:3)
当对小于int
的类型执行任何类型或算术运算时,该值将在表达式中提升为int
。然后,当结果保存到char
时,除了最低位字节之外的所有字节都将被截断。
这涵盖在C standard:
的第6.3.1.1节中2 如果可以使用
int
或unsigned int
,则可以在表达式中使用以下内容:- 具有整数类型的对象或表达式(除了 整数转化率小于的
int
或unsigned int
) 或等于int
和unsigned int
的等级。- 类型为
_Bool
,int
,signed int
或unsigned int
的位字段。如果
int
可以表示原始类型的所有值(如 受宽度限制,对于位域而言,值为 转换为int
;否则,它被转换为unsigned int
。这些被称为整数促销。所有其他 整数促销不会改变类型。
如果是c
,您首先要a<<5
。在此之前,a
中会提升此表达式中int
的值,因此结果可能会大于char
。
这导致二进制值10100100000
(十进制1312)。然后将其保存到类型为b
的{{1}},因此仅保留低8位(char
,小数8)。所以00100000
现在的值为8。
然后我们执行b
给我们二进制b>>2
(十进制8),保存在00001000
。
如果是c
,我们会像以前一样执行d
(a<<5
的值被提升为a
)获取二进制int
。现在这个值右移2,得到10100100000
(十进制328)。然后将其保存到类型为00101001000
的{{1}},因此只保存低8位(d
,小数72)。所以char
现在为72的值。