【C语言学习记录】(五)——操作符详解①——算数操作符、移位操作符

一、最常用的算数运算符

运算符含义举例结果
+正号运算符(单目运算符)+aa的值
-负号运算符(单目运算符)-aa的算数负值
*乘法运算符a * ba和b的乘积
/除法运算符a / ba除以b的商
%取模(求余)运算符a % ba除以b的余数
+加法运算符a + ba和b的和
-减法运算符a - ba和b的差

使用时的注意事项:

1、除了 % 操作符之外,其他几个操作符可以作用于整数浮点数
2、对于 / 操作符,如果两个操作数都为整数,执行整数除法。而只要有浮点数,执行的就是浮点数除法

int main()
{
	int a = 3 / 5;   //0.6
	printf("%d\n", a);   //a是整型,所以结果为0,不是小数。商0余3
	return 0;
}

在这里插入图片描述

int main()
{
	float a = 6 / 5;
	printf("%f\n", a);
}

在这里插入图片描述
在这其中,6和5是整型,6/5是整型除法,其结果本身就是1。1赋值给a后就是1.000000。

问题一:如何得到一个商,并且它是小数?

int main()
{
	float a = 6.0 / 5.0;//除号两边至少有一个数是浮点数,结果才能是小数。
	printf("%f\n", a);//1.200000
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里,编译器会默认6.0和5.0是double类型的,而a是float类型,由于6.0 / 5.0的结果仍是double类型,此时双精度的值赋值给单精度的a,容易丢失精度。 所以编译器会报一个警告出来。
答案:可以改成

	double a = 6.0 / 5.0;
	printf("%lf\n", a);
	
//或者

	float a = 6.0f / 5.0f;
	printf("%f\n", a);

3、% 操作符的两个操作数必须为整数,返回的是整数之后的余数

int main()
{
	int a = 7 % 3;  //求余数,商2余1
	printf("%d\n", a);
	return 0;
}

在这里插入图片描述

二、移位操作符

操作符含义
<<左移操作符
>>右移操作符

1.左移操作符 <<

示例1:

int main()
{
	int a = 2;
	int b = a << 1;      //把a的二进制位向左移动一位,并把结果赋值给b
	printf("b = %d\n", b);
	return 0;
}

在这里插入图片描述
把2赋给a,而a是一个int类型的变量,占4个字节,即意味着32个bit位。
2的二进制序列为:(方框内共32位)
在这里插入图片描述
其中2的权重我们可以看作21。最右端的0的权重是20。把a的二进制位向左移一位的结果就是:在这里插入图片描述
最左端的0位于方框外面,意味着被丢弃了,方框内共31位。所以要在最右端补上一个0。即:在这里插入图片描述
此时,1位于右端第三位,权重为22=4,所以整个数字变成了4,即:b=4。

左移操作符的作用:

将一个数的二进制编码向左移动,高位溢出的舍弃,低位补零
即:左边丢弃,右边补0
左移2位——左边溢出2位,右边补上2个0。

2.右移操作符 >>

示例2:正数的二进制位右移

int main()  
{
	int a = 10;
	int b = a >> 1;      //把a的二进制位向右移动一位,并把结果赋值给b
	printf("b = %d\n", b);
	return 0;
}

在这里插入图片描述
10的二进制序列:00000000000000000000000000001010
其中:①是23=8,②是21=2。
在这里插入图片描述
右移一位后:
在这里插入图片描述
最右边溢出的0舍弃,①是22=4,②是20=1,③是需要补位的地方,也是二进制序列的开头。
在内存中存储一个整数的二进制序列的的时候,二进制位最左边的(最高位)是0,表示是一个正数,是1表示是一个负数。
右移操作符分为两种右移情况
(1)算数右移
右边丢弃,左边补原符号位。
(2)逻辑右移
右边丢弃,左边补0。
如果按算数右移,补原来的符号位,则补0;
如果按逻辑右移,则无论原本的数是正或负,都要在③所指的开头补0。
而因为10是正数,所以都必须补0,再补上0之后的二进制序列就是:在这里插入图片描述
所以b的值为5。

示例3:负数的二进制位右移

int main()
{
	int a = -1;
	int b = a >> 1;      //把a的二进制位向右移动一位,并把结果赋值给b
	printf("b = %d\n", b);
	return 0;
}

我们将负数:-1 存放在内存中(存放的是二进制的补码)
整数的二进制表示形式:其实有
原码:直接根据数值写出的二进制序列

反码:原码的符号位(左侧开头第一位)不变,其他位按原码取反

补码:反码+1
-1为例:
原码:10000000000000000000000000000001
反码:111111111111111111111111111111111110
补码:111111111111111111111111111111111111(最低位+1)
数据内存中储存是以二进制的补码形式存储的。对于一个正整数来说,原码、反码和补码是相同的
在这里插入图片描述
补码向右移动一位后,右侧的1溢出一位,如上图所示。那么问题一:③应该补1还是0?
若采用算数右移,由于-1是负数,所以③应该补1,结果没变,还是-1;
若采用逻辑右移,则③应该补0,成为一个正数。
答案:在这里插入图片描述
当前的右移操作符采用的是:算数右移
问题二:当a=10的时候,把a的二进制位向右移动1为,得到b=5,那么a是否发生改变?

int main()
{
	int a = 10;
	int b = a >> 1;
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	return 0;
}

答案:在这里插入图片描述
a不发生改变,仍为10。b的值是表达式a >> 1的结果。

总结 :

左移操作符移位规则——左边抛弃,右边补0;
右移操作符移位规则:
(1)算数右移:右边丢弃,左边补原符号位。(最常采用)
(2)逻辑右移:右边丢弃,左边补0。
警告:对于移位运算符,不要移动负数位,这个标准是C语言未定义的。
例如:

int num = 10;
num >> -1; //错误
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值