【C语言】0x1F<<11等于0还是0xF800 ?

1、左移运算符
格式:a<<b

将a这个数的各二进制位左移b位,要求b必须是非负整数,移动过程中,右边空出的位用0填补,高位左移溢出则舍弃该高位。

2、右移运算符
格式:a>>b

将a这个数的各二进制位右移b位,要求b必须是非负整数,移到右端的低位被舍弃。其中,
①对于无符号数,高位补0;
②对于有符号数,如果采用算术移位,则空出部分用符号位填补,如果采用逻辑移位,则用0填补。

(1)逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补。
(2)算术移位就需要分有符号型值和无符号型值

  • 对于无符号型值,算术移位等同于逻辑移位。
  • 而对于有符号型值 ,算术左移等同于逻辑左移,算术右移补的是符号位,正数补0,负数补1。

(在汇编指令中,shl和shr表示逻辑左移和逻辑右移,sal和sar表示算术左移和算术右移。)

b的值相对于32位系统,要求不能超过32位,如果超过了,编译的时候会产生一个警告。

疑问:0x1F从字面上看,好像是一个字节的常量,如果左移8位,那该常量的结果为0还是0x1F00 ? ? ?

⭐⭐⭐答案:

  • 首先,将0x1F常量视为一个32为的常量,即0x0000001F,然后执行移位操作;此时,当移位超过32位,则结果为0。如果是long long修饰,那么视为一个64位的常量。
  • 如果,将0x1F赋值给一个小于等于32位类型的变量,对该变量进行以为操作时,先将变量的内容扩展成一个32位的值,然后执行移位操作(如果左移k位,则移动 k mod 32),等完成后,将32位的值赋值给变量,因为变量的类型不是32位,所以存在裁减。

示例:常量

#include <stdio.h>

int main(void)
{
    
    
	printf("%lld\n", ((long long)0x1F)<<32);
	printf("%d\n", 0x1F<<31);
	printf("%d\n", 0x80000000);
	printf("%lld\n", 0x1F<<32);
}

/*
运行结果为:
133143986176(0x1F 0000 0000)
-2147483648
-2147483648
0
*/

从左移31和左移32位的结果表明,如果是将0x1F变成64位,那么左移32位就不会变成0。

示例二:变量

#include <stdio.h>

int main(void)
{
    
    
	int a = 0x1f;
	long long b = 0x1F;
	a <<= 32;  //warning:left shift count >= width of type
	//a <<= 33;
	b <<= 32;
	printf("%lld\n", a);
	//printf("%lld\n", a);//62 (0x3E)
	printf("%lld\n", b);
}

/*
运行结果:
31(0x1f)
133143986176(0x1F 0000 0000)
*/

在这里插入图片描述

参考博客:
[1]:C语言之左移和右移运算符
[2]:C语言左移右移运算符详解
[3]:逻辑移位和算术移位的区别

猜你喜欢

转载自blog.csdn.net/weixin_42258222/article/details/108457243