繁体   English   中英

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整数提升。

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

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

你必须写

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM