请检查以下拼凑的代码,让我知道为什么这不能给出理想的结果。
#include <stdio.h>
int main()
{
unsigned short y=0;
unsigned char x=0xe0; //binary - 1110 0000
unsigned char z=3;
y = (x<< z);
printf("\n y value is %x\n",y);
return 0;
}
我希望y应该打印0x00但它打印0x0700。你能让我知道左移和分配操作是如何在这里工作的吗?
由于
答案 0 :(得分:3)
通过规范,按位移位运算符的左操作数经历整数提升。
所以:
y = (x<< z);
在这里相当于:
y = ((int) x << z);
<<
表达式的结果是提升的左操作数的类型,i。例如,int
并在转让期间转换为unsigned short
。
答案 1 :(得分:1)
该操作将您的字节提升为整数。所以它在int上做了左移
答案 2 :(得分:1)
原因是x
的整数提升。
对每个操作数执行整数提升。结果的类型是 升级的左操作数。
答案 3 :(得分:0)
你必须写
y = ( unsigned char )(x<< z);
问题是integer promotion
应用于运算符&lt;&lt;的操作数。这是排名小于类型int
的排名的整数数据被隐式转换为类型int
。
所以在这个表达式中
x<< z
x将具有类似
的表示形式00 00 00 E0
在操作之后,结果将显示为
00 00 07 00
即三个设置位将向左移位并占据int
类型对象的下一个字节。 Wneh将结果分配给具有insigned类型的y,结果的两个低字节分配给y,y将等于0x0700
。
答案 4 :(得分:0)
在移位运算符的情况下,对每个操作数执行整数提升。
在您的情况下,x和z将转换为int,结果将转换为short。
请参阅以下规格中的相关部分。
6.5.7按位移位运算符
对每个操作数执行整数提升。结果的类型是 升级的左操作数。
答案 5 :(得分:0)
编译器做的很自然。
您试图将结果放入更大的空间,因此操作员在空间允许的情况下完成其工作,否则您明确地说明了相反的结果:0xff &
掩码或(unsigned char)
。这反映在语言规范中。
你应该知道自己在做什么,如果你期望通过向左移动来增加你的价值,那么unsigned short
是可以的,但你对0x700
的想法是什么呢?
如果您想进行某种过滤 - 为什么不使用最适合的unsigned char
?因为short
明显超出了您的过滤方案(当然您希望保存空间并写入一对一行,但要小心)。