C语言——操作符(2)

前面我们已经提到许多操作符,但是还有一部分没有进行说明。本文是对前面未提到的操作符的补充。

1.二进制与进制转换

二进制可以用于数据存储和传输。在计算机中,所有的数据都是以二进制形式存储和传输的。我们下面所说的操作符就是对二进制进行操作,所以我们先来讲讲二进制。
生活中,我们最熟悉的就是十进制,十进制的规则是满10进1,十进制的每一位的数字都由数字0~9组成。
二进制其实也一样,二进制的规则是满2进1,二进制的每一位数字由0~1组成。

1.1二进制与十进制的相互转换

1.1.1 二进制转换十进制

首先我们要清楚,十进制的每一位是有权重的,10进制的数字从右向左是个位、十位、百位…,分别每⼀位的权重是 100 , 101 , 102 … 所以十进制的123是一百二十三。如下图:
image.png
其实二进制跟十进制类似,不过二进制的每一位权重,从右往左是:20 ,21,22. . .
对于二进制的 1101,我们通过下图来理解一下吧:
image.png

1.1.2 十进制转换二进制

image.png

1.2 二进制转换八进制和十六进制

1.2.1 二进制转换八进制

八进制的每一位是由数字 0~7 组成的,而且 7 的二进制为 111,所以八进制各位上的数字转换二进制最多需要三个二进制位。所以在二进制转八进制数的时候,从二进制序列中右边低位开始向左每3个二进制位会换算一个八进制位,剩余不够3个二进制位的直接换算。
例如:二进制的 11010111,转换八进制为 0327.
注:0 开头的数字在 C语言中会被当作八进制数。
image.png
同理,八进制转换二进制,只不过是顺序颠倒了一下。如下:
八进制的 0327,转换二进制为 11010111
image.png

1.2.2 二进制转换十六进制

十六进制的每一位是由 0~9 ,a~f 组成的。f 的二进制数为 1111,所以十六进制每位最多有 4 个二进制位就够了。所以在二进制转十六进制数的时候,从二进制序列中右边低位开始向左每 4 个二进制位会换算一个十六进制位,剩余不够 4 个2进制位的直接换算。
例如:二进制的 1101101010,转换为十六进制为 0x36a
注:0x 为开头的数字在C语言中被当作十六进制数
image.png
同理,十六进制转换二进制,也只是顺序颠倒了一下,如下:
十六进制的 0x36a,转换二进制为 1101101010
image.png

1.3 原码、反码和补码

整数的2进制表示方法有三种,即原码、反码和补码
有符号整数的三种表示方法均有符号位数值位两部分,2进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。
符号位都是用 0表示“正”,用 1表示“负”。
**正整数的原、反、补码都相同。 **
**负整数的三种表示方法各不相同: **
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
反码得到原码也是可以使用:取反,+1的操作。
image.png
对于整形来说:数据存放内存中其实存放的是补码。

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算 过程是相同的,不需要额外的硬件电路。

2.移位操作符

移位操作符分为<<(左移操作符)和>>(右移操作符)。
注:移位操作符的操作数只能是整数。

2.1 <<(左移操作符)

移位规则:左边抛弃,右边补0.
其示例代码如下:

#include<stdio.h>
int main()
{
	int n = 10;
	int num = n << 1;
	printf("%d\n", n);
	printf("%d\n", num);

	return 0;
}


其运行结果如下:
屏幕截图 2023-11-11 213810.png
有的小伙伴可能还没有明白<<(左移操作符)是如何进行操作的,接下来我来向大家演示一下吧:
屏幕截图 2023-11-11 215450.png

2.2 >>(右移操作符)

右移操作符>>有两种移位规则:

  1. 逻辑右移:左边用0填充,右边丢弃

  2. 算术右移:左边用该原值的符号位填充,右边丢弃

其示例代码如下:

#include<stdio.h>
int main()
{
	int n = 10;
	int num = n >> 1;
	printf("%d\n", n);
	printf("%d\n", num);

	return 0;
}

运行结果如下:
屏幕截图 2023-11-11 220455.png
当然,这里我也给大家演示一下吧:
int n=-1屏幕截图 2023-11-11 221932.png屏幕截图 2023-11-11 222237.png
可能有的小伙伴会有疑问:“既然 >>(右移操作符)有两种移位规则,那什么情况下用逻辑右移,什么情况下用算术右移呢?”
其实,这个取决于编译器的实现,大多数的编译器都是支持算术右移的。
注意:移位操作符的操作数不能为负数。如:
image.png

3. 位操作符

位操作符分为四种:

3.1 &(按位与 )

计算规则:对应的二进制位进行与运算,只要有0就是0,两个同时为1才是1。
image.png
我们再来写个代码看一下吧:

#include<stdio.h>
int main()
{
int a = -3;
int b = 5;
printf(%d\n”, a & b);
return 0;
}

运行结果如下:
image.png

3.2 |(按位或)

计算规则:对应的二进制位进行或运算,只要有 1 就是 1,两个同时为 0 才是 0。
image.png
代码如下:

#include<stdio.h>
int main()
{
int a = -3;
int b = 5;
printf(%d\n”, a | b);
return 0;
}

运行结果为
image.png

3.3 ^按位异或

计算规则:对应的二进制位进行或运算,相同为 0,相异为 1。
image.png
代码如下:

#include<stdio.h>
int main()
{
int a = -3;
int b = 5;
printf(%d\n”, a ^ b);
return 0;
}

运行结果为
image.png

3.4 ~(按位取反)

计算规则:对应的二进制位取反。
image.png
代码如下:

#include<stdio.h>
int main()
{
printf(%d\n”,~0);
return 0;
}

运行结果如下
image.png
注意:它们的代码必须为整数。

4. 赋值操作符

前面我们已经讲了一部分,现在我们来进行补充剩下的吧!

4.1 <<= 、 >>=

C语言中的 **<<= **是左移并赋值运算符,它将左操作数的位向左移动右操作数指定的位数,并将结果赋值给左操作数。
C语言中的 **>>= **是右移并赋值运算符,它将左操作数的位向右移动右操作数指定的位数,并将结果赋值给左操作数。
如图所示:
image.png

4.2 &= 、|=、^=

C语言中的 **&=**是按位与后赋值,将左操作数与右操作数按位与后的值赋给左操作数。
C语言中的 **|= **是按位或后赋值,将左操作数与右操作数按位或后的值赋给左操作数。
C语言中的 **^= **是按位异或后赋值,将左操作数与右操作数按位异或后的值赋给左操作数。
如图所示:
image.png

5.下标访问 [ ] 和函数调用()

5.1 下标访问 [ ]

操作数:⼀个数组名 + ⼀个索引值
如图:
image.png

5.2 函数调用()

接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
如图:
image.png

6.& 、*

&(取地址操作符)与 *(解引用操作符)是与指针相关的,所以我们这里先不进行说明,在后面指针中会为大家进行详细解释。

7. 操作符的属性

C语言的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

7.1 操作符的优先性

优先级指的是,如果一个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不一样的。
3 + 4 * 7
上面的式子中,既有加法运算符(+)又有乘法运算符( * ),因为 * 的优先级大于 +,所以我们先算 4*7,而不是先算 3+4.

7.2 操作符的结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符( = )。
3 / 4 * 7
上面的式子中乘法运算符( * )与除法运算符( / )优先级相同,因为它们都是左结合,所以我们先算 3/4,而不是先算 4*7.
运算符的优先级顺序很多,下面是部分运算符的优先级顺序(按照优先级从高到低排列),建议大概记住这些操作符的优先级就行,其他操作符在使用的时候查看下面网站就可以了。
• 圆括号( () )
• 自增运算符( ++ ),自减运算符( – )
• 单目运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )
由于圆括号的优先级最高,可以使用它改变其他运算符的优先级。
参考相关网站:
https://zh.cppreference.com/w/c/language/operator_precedence

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值