逻辑右移、算数右移的区别与C语言移位运算符解析

在学习汇编语言的时候,对于左移、算数右移、逻辑右移一般有不同的指令,这几者之间有什么区别和联系?
逻辑右移和算数右移的区别
右移是将数据逐位向低位移动,最低位丢弃,而根据最高位以0填充还是以原始数据的符号位填充,分为逻辑右移和算数右移。以8bit数据为例:
假设有一个数0x83 ,即1000 0011。
1、逻辑右移将各个位向最低位方向移动,最高位补0。0x83逻辑右移1位的结果是0100 0001,即0x41
2、对于算数右移来说,它是将各个位向最低位方向移动,最高位用数据原本的符号位进行填充。对于1000 0011,符号位为1,算数右移一位后,最高位用原本的符号位1来填充,也就是保持符号位不变,结果为1100 0001,即0xc1
逻辑左移=算数左移
以8bit的数据为例,左移1位是将最高位丢弃,其余位向左移动1位,最低位补0,由于最高位符号位被丢弃,因此逻辑左移和算数左移实际是一回事。

下面来看C语言中的移位运算符

int main()
{
	char a = 0x83; //a=1000 0011
	unsigned char b = 0x83; //b=1000 0011
	char c = 0x83; //c=1000 0011
	unsigned char d = 0x83; //d=1000 0011
	a >>= 1;
	b >>= 1;
	printf("a=%x  b=%#x\n",a,b); 
	c <<= 1;
	d <<= 1;
	printf("c=%x  d=%#x",c,d); 
	return 0;
}

输出:
在这里插入图片描述
1、根据上面对算数右移和逻辑右移的解释,不难得出:在C语言中,如果定义的是一个有符号的数据类型,例如char型,那么用>>进行右移位,执行的是算数右移,对于无符号数据类型,例如unsigned char型,那么用>>进行右移位,执行的是逻辑右移。(a=ffffffc1是因为printf函数打印char变量时,将其转换为了int型变量,对数据进行了符号位扩展,可以忽略前面的ffffff,就认为实际结果a=0xc1)
2、c和d的结果验证了算数左移和逻辑左移是一回事。
3、一般来说,对于无符号数,左移1位就相当于将这个数扩大两倍,前提是没有发生数据溢出。例如:0x03=0000 0011左移1位后变成 0000 0110 =0x06,。而对于上面的变量d,由于左移后,理论结果是0x83(即十进制131)乘2,等于262,超过了8位无符号数的范围,因此结果并不等于把0x83扩大两倍。
4、对于有符号类型变量,执行算数右移,由于符号位会保持不变,因此结果相当于把这个数除以2,当然如果这个数除以2是有小数出现的(例如5+2=2.5),那么小数部分将会丢失。
5、对于无符号类型变量,执行逻辑右移,结果相当于把这个数除以2,同样会丢失小数部分的结果。

### C语言算术运算符的使用方法示例 C语言提供了多种算术运算符用于执行基本的数学操作。以下是常见的算术运算符及其含义: #### 基本算术运算符 | 符号 | 名称 | 描述 | |------|--------------|--------------------------| | `+` | 加法运算符 | 将两个操作数相加 | | `-` | 减法运算符 | 从第一个操作数中减去第二个操作数 | | `*` | 乘法运算符 | 将两个操作数相乘 | | `/` | 除法运算符 | 将第一个操作数除以第二个操作数 | | `%` | 取模运算符 | 返回整数除法后的余数 | 这些运算符可以应用于变量或常量之间,完成相应的数学计算。 #### 示例代码 以下是一个简单的例子展示如何使用上述算术运算符: ```c #include <stdio.h> int main() { int a = 10, b = 3; printf("a + b = %d\n", a + b); // 输出两数之[^1] printf("a - b = %d\n", a - b); // 输出两数之差 printf("a * b = %d\n", a * b); // 输出两数之积 printf("a / b = %d\n", a / b); // 输出商(注意这是整数除法) printf("a %% b = %d\n", a % b); // 输出取模结果 return 0; } ``` 运行此程序会得到如下输出: ``` a + b = 13 a - b = 7 a * b = 30 a / b = 3 a % b = 1 ``` 需要注意的是,在进行除法运算时,如果涉及的操作数均为整型,则返回的结果也是整型,即只保留整数部分并舍弃小数部分[^2]。 #### 运算符优先级结合性 在复杂表达式中,不同类型的运算符具有不同的优先级。例如,乘法 (`*`) 除法 (`/`) 的优先级高于加法 (`+`) 减法 (`-`)。此外,当存在相同优先级的多个运算符时,它们按照特定的方向结合在一起处理——这被称为 **结合性**。大多数二元运算符是从左到右结合的,而赋值运算符则是从右到左结合的。 #### 特殊情况说明 对于取模运算符 `%` 来说,它仅适用于整数类型的数据,并且其行为可能因编译器实现的不同而在负数参的情况下有所差异。因此建议开发者清楚自己所使用的环境对此特性的定义[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星水天河

如果内容帮助到你请给我打个赏吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值