C左移和分配

时间:2014-09-29 10:10:49

标签: c bit-shift

请检查以下拼凑的代码,让我知道为什么这不能给出理想的结果。

#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。你能让我知道左移和分配操作是如何在这里工作的吗?

由于

6 个答案:

答案 0 :(得分:3)

通过规范,按位移位运算符的左操作数经历整数提升。

所以:

 y = (x<< z);

在这里相当于:

 y = ((int) x << z);

<<表达式的结果是提升的左操作数的类型,i。例如,int并在转让期间转换为unsigned short

答案 1 :(得分:1)

该操作将您的字节提升为整数。所以它在int上做了左移

答案 2 :(得分:1)

原因是x的整数提升。

C11:6.5.7按位移位运算符(p3):

  

对每个操作数执行整数提升。结果的类型是   升级的左操作数。

答案 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明显超出了您的过滤方案(当然您希望保存空间并写入一对一行,但要小心)。