05操作符和表达式

Posted 再吃一个橘子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了05操作符和表达式相关的知识,希望对你有一定的参考价值。

1.操作符

分类

  • 算术操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号表达式
  • 下标引用、函数调用和结构成员

1.1算数操作符

+           -           *           /           %

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

	int a = 9 / 2;
	double b = 9 / 2;
	printf("%d,%lf\\n", a, b);//4,4.000000

	//对于 /(除号)来说,两边都是整数,执行整数除法,和接收的数据类型无关
	//操作数中有浮点数,才执行浮点数除法

	double c = 9 / 2.0;
	printf("%lf", c);//4.500000

	//  %  得余数
	//  %  取模只能能针对整数类型

	int d = 9 % 2;
	printf("%d ", d);
	//int e = 9.0 % 4.0;//报错

1.2移位操作符

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

1.2.1左移操作符<<

左移操作符移位规则:左边丢弃,右边补0.

步骤:(假设求 值a 左移x位)

  1. 写出a的二进制原码,由原码求出反码,补码。
  2. 将补码左移x位,右边补x个0,得到左移运算符之后的数的补码。
  3. 将该数的补码转换成反码,再进而转换成原码,得到最终求解结果。

见左移运算符的代码,注释内容~~~,来深刻理解:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	// >> —— 右移操作符
	//
	// << —— 左移操作符
	//左边丢弃,右边补0
	 
	//左移操作符
	int a = 5;
	int b = a << 1;
	printf("%d\\n", b);//打印的是原码,在计算机中存储的是补码
	
	//移位操作符,移动的是二进制位
	//对于整数的二进制有3中表现形式:原码,反码,补码。
	//整数在内存中的存储 —— 二进制的补码
	

	//正整数 —— 原码,反码,补码相同
 
	//负整数 —— 
	//原码:直接按照数字的正负写出的二进制序列
	//反码:原码的符号位不变,其他位按位取反
	//补码:反码 + 1


	//正数
    //比如:对于a = 5来说,是个整数,而整数占4个byte,32个bit位:
	//原码:0 00000000000000000000000000000000101
	//反码:0 00000000000000000000000000000000101
	//补码:0 00000000000000000000000000000000101
	//那么a<<1,由于整数在内存中的存储 —— 二进制的补码,那对a向左移动1位,就是对补码向左移动1位。即:
	//a<<1:000000000000000000000000000000001010 ——> 正数的原码二进制也是如此 ——> 10

	int c = -1;
	int d = c << 1;
	printf("%d\\n", d);//打印的是原码

	//负数
	//比如:c = -1
	//原码:1 0000000000000000000000000000001
	//反码:1 1111111111111111111111111111110
	//补码:1 1111111111111111111111111111111
	//那么c<<1,由于整数在内存中的存储 —— 二进制的补码,那对a向左移动1位,就是对补码向左移动1位。即:
	//c<<1:     1 1111111111111111111111111111110 ——> 反码 = 补码 - 1
	//c<<1反码:  1 1111111111111111111111111111101 ——> 原码 = 反码取反
	//c<<1原码:  1 0000000000000000000000000000010 ——> -2

	return 0;
}

 1.2.2右移运算符>>

右移运算符移位规则:

  1. 逻辑右移:右边丢弃,左边补0
  2. 算术右移:右边丢弃,左边补符号位(绝大多数编译器是算术右移)

见右移运算符的代码,注释内容~~~,来深刻理解:

注意:逻辑右移和算术右移的实际区别对比。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	// >> —— 右移操作符
	//逻辑右移:右边丢弃,左边补0
	//算术右移:右边丢弃,左边补符号位
	// << —— 左移操作符
	//

	//右移操作符
	int a = 5;
	int b = a >> 1;
	printf("%d\\n", b);

	//正数
	//比如:对于a = 5来说,是个整数,而整数占4个byte,32个bit位:
	//原码:0 00000000000000000000000000000000101
	//反码:0 00000000000000000000000000000000101
	//补码:0 00000000000000000000000000000000101
	//那么a>>1,由于整数在内存中的存储 —— 二进制的补码,那对a向右移动1位,就是对补码向右移动1位。即:
	//a>>1:000000000000000000000000000000000010 ——> 正数的原码二进制也是如此 ——> 2

	int c = -1;
	int d = c >> 1;
	printf("%d\\n", d);//打印的是原码

	//负数
	//比如:c = -1
	//原码:1 0000000000000000000000000000001
	//反码:1 1111111111111111111111111111110
	//补码:1 1111111111111111111111111111111
	//那么c>>1,由于整数在内存中的存储 —— 二进制的补码,那对a向右移动1位,就是对补码向右移动1位。即:
	//c>>1:     1 1111111111111111111111111111111 ——> 反码 = 补码 - 1
	//c>>1反码:  1 1111111111111111111111111111110 ——> 原码 = 反码取反
	//c>>1原码:  1 0000000000000000000000000000001 ——> -1

	return 0;
}

 此处不再画图赘述,具体细节看上述代码!!一定一定注意逻辑右移和算术右移的区别,但是大多是编译器是算术右移。

警告⚠: 对于移位运算符,不要移动负数位,这个是标准未定义的,即:在不同编译器下可能运算结果不同。 例如:

int num = 10;
num>>-1;//error ——> 标准未定义行为


 

 

 

以上是关于05操作符和表达式的主要内容,如果未能解决你的问题,请参考以下文章

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

片段问题中的 NullPointerException

Android Studio - 片段按钮操作

持久片段和查看器

VSCode 如何操作用户自定义代码片段(快捷键)

VSCode自定义代码片段——git命令操作一个完整流程