![](/img/trans.png)
[英]What is the difference between directly assigning the result of left shift operation to a variable and the left shift assignment operation in C?
[英]C left shift and assignment
请检查下面的代码,并让我知道为什么这不能达到预期的效果。
#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。 您能告诉我这里的左移和分配操作如何工作吗?
谢谢
通过指定,按位移位运算符的左操作数将进行整数提升。
所以:
y = (x<< z);
在这里等于:
y = ((int) x << z);
<<
表达式的结果属于提升后的左操作数的类型,即int
并且在赋值期间将其转换为unsigned short
。
该操作会将您的字节提升为整数。 所以它在整数上做左移
原因是x
整数提升。
对每个操作数执行整数提升。 结果的类型是提升后的左操作数的类型。
你必须写
y = ( unsigned char )(x<< z);
问题是integer promotion
应用于运算符<<的操作数。 也就是说,具有小于int
类型的等级的整数数据将隐式转换为int
类型。
所以在这个表达
x<< z
x将具有如下表示形式
00 00 00 E0
手术后的结果将显示为
00 00 07 00
也就是说,这三个设置位将向左移,并将占据int
类型对象的下一个字节。 如果将结果分配给类型为insigned short的y,则将结果的两个低字节分配给y,并且y等于0x0700
。
如果使用移位运算符,则对每个操作数执行整数提升。
在您的情况下,x和z转换为int,结果转换回short。
请参阅以下规范的相关部分。
6.5.7按位移位运算符
对每个操作数执行整数提升。 结果的类型是提升后的左操作数的类型。
编译器所做的事情很自然。
您试图将结果放置在更大的空间中,所以操作员会在空间允许的范围内进行操作,否则您将明确地相反: 0xff &
mask或(unsigned char)
。 这反映在语言规范中。
您应该知道自己在做什么,如果您期望通过向左移动来增加价值, unsigned short
0x700
那么使用0x700
时您有什么想知道的呢?
如果您想进行某种过滤-为什么不使用最合适的unsigned char
? 造成short
原因显然是过滤方案的出站(当然,您想节省空间并编写多合一的行,但要小心)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.