【C语言】9.操作符详解(上)

🎬个人主页:缘三水的博客
❄专栏传送门:C语言专栏(新手向)
人生格言:行动是迷茫的最好解药


🎬个人介绍:

文章目录


前言

在前面的章节我们学习过了一些基本的操作符,而在这个章节我们将拓展学习更多的操作符


为了更好的介绍操作符,我们先介绍一些必要知识

(一)操作符的分类

我们一般将操作符分为以下几类

• 算术操作符: + - * / %

• 移位操作符: << >>

• 位操作符: & | ^ ~

• 赋值操作符: = += -= *= /= %= <<= >>= &= |= ^=

• 单目操作符:! ~ ++ -- + - & * sizeof (类型)

• 关系操作符: > >= < <= == !=

• 逻辑操作符: && || !

• 条件操作符: ? :

• 逗号表达式: ,

• 下标引⽤: []

• 函数调用: ()

• 结构成员访问: . ->

(二)二进制和进制转化

通常我们遇到的都是十进制数字

十进制每一位由0~9组成,满十进一

类似十进制,二进制每一位由0~1组成,满二进一

甚至还有八进制,十六进制

八进制,每一位0~7,满八进一

十六进制,每一位0~9 ,a~f,满十六进一

这里的a ~ f是表示10 ~ 15,为了防止混淆而规定,也可以用大写A~F

c 复制代码
例如 3的二进制为11
     9的二进制为1001
     9的八进制为011  八进制数第一位是0,格式0_ _ _
     9的十六进制为0x9 十六进制数前是0x,格式0x_ _ _

了解完进制,我们来学习进制间的相互转化

2.1 二进制转十进制

二进制转十进制

二进制按照每一位的权重转化,最后每一位数字乘上权重,再相加

c 复制代码
例如 二进制1001转化十进制
从低位到高位
1 权重是2的0次方 
0 权重是2的1次方
0 权重是2的2次方
1 权重是2的3次方
那么二进制1001就十进制为1*1 + 0*2 + 0*4 + 1*8 = 9 

所以类似的八进制,十六进制转十进制同理

2.2 十进制转二进制

对于较小的数

我们可以直接记住每一位权重直接转化

例如17= 16+1

那么17转二进制为10001

对于较大的数

我们对数一直除于2,每一次的余数,从后往前写即为二进制

2.3 八进制,十六进制转二进制

  1. 八进制与二进制相互转换

八进制转二进制

八进制每一位数字皆由0~7组成,那么每一位数字转换成三位二进制数字来表示

例如八进制0123转化二进制

3转化成011,2转化成010,1转化成001

那么123转二进制为001010011
反过来也相同

二进制转八进制

001010011

每三位每三位的看,从低位依次向高位转换

001 010 011

011转为3

010转为2

001转为1

则最后转为八进制数字0123

注:八进制数字前面带一个0

  1. 十六进制与二进制相互转化

十六进制转二进制

类似上面的原理,十六进制每一位由1~9 , a~f组成,那么只需要4个二进制数字就可以表示一个十六进制数字

例如 十六进制0x6b转二进制

b转化为1011

6转化为0110

那么就转化为二进制01101011
二进制转十六进制

同样是每四位每四位的看

对二进制01101011

0110 1011

1011转化为11也就是b

0110转化为6

则最后转为十六进制0x6b

注:十六进制数字前带0x

(三)原码、反码、补码

原码,反码,补码是整数的二进制 表示形式

原码,反码,补码一般是32位二进制数字组成

对于有符号整数

第1位是符号位,后31位是数值位

对正数

符号位是0

原码,反码,补码相同

举个例子

对正整数5

符号位是0

则原码,反码,补码相同皆为

0000 0000 0000 0000 0000 0000 0000 0101

对负数

符号位是1

原码,反码,补码各不相同

原码:32位二进制表示,第一位符号位是1表示负数,后31位是数值位

反码:符号位不变,每一位取反,0变1,1变0

补码:反码加1

例如: -6

符号位是1

则原码为

1000 0000 0000 0000 0000 0000 0000 0110

反码是符号位不变,数值位取反

1111 1111 1111 1111 1111 1111 1111 1001

补码是反码加1

1111 1111 1111 1111 1111 1111 1111 1010

对于无符号整数
原码反码补码相同,没有符号位,只有32位数值位

类似有符号正整数的表示

补码怎么变回原码

一个口诀:都是取反,加一

对原码变补码,取反加一

补码变原码,取反加一

在内存中,数值的存储是以补码形式存储的

这样有三个好处

  1. 方便运算,可以统一数值位和符号位的运算
  2. 由于CPU只有加法处理器,那就可以统一加减运算
  3. 由于补码变回原码也是取反加一,这样就无需额外的硬件电路

(四)移位操作符

对于移位操作符,这里的"位"指的都是二进制位

4.1 左移操作符<<

口诀:左移丢弃,右边补0

使用实例

c 复制代码
int n1 = 10;
int n2 = n1 << 1;//n2=20

10原码反码补码相同

0000 0000 0000 0000 0000 0000 0000 1010

左移1位,丢弃

000 0000 0000 0000 0000 0000 0000 1010

右边补0

0000 0000 0000 0000 0000 0000 0001 0100

首位是0,可知这是个正数,原码也是这个

因此转化过来就是20

即 n2=20

值得注意的是,经过移位操作符的运算,原来的数字n1是不变的

4.2 右移操作符>>

右移操作符分为两种:逻辑右移和算术右移

具体是哪种由编译器决定,例如在VS2022上就是采用算术右移

使用实例

c 复制代码
int n1 = -1
int n2 = n1 >> 1
  1. 逻辑右移
    右移丢弃,左边补0

对-1的逻辑右移

先写出原码反码补码

原码1000 0000 0000 0000 0000 0000 0000 0001

反码1111 1111 1111 1111 1111 1111 1111 1110

补码1111 1111 1111 1111 1111 1111 1111 1111

右移1位丢弃,左边补0

0111 1111 1111 1111 1111 1111 1111 1111

  1. 算术右移
    右移丢弃,左边补符号位

对-1的算术右移

-1的补码 1111 1111 1111 1111 1111 1111 1111 1111

右移1位丢弃,左边补符号位

得出1111 1111 1111 1111 1111 1111 1111 1111

符号位不变,取反加一

1000 0000 0000 0000 0000 0000 0000 0001

即为-1

注意:移的位数不可以是负数

(五)位操作符

位操作符有如下几个

&:按位与

|:按位或

^:按位异或

~:按位取反

5.1 &按位与

按位与的运算过程

对两个整数的补码,同一位上,有0为0,全1才为1

使用实例

c 复制代码
int a = -3;
int b = 6;
int c = a & b;

先写出-3和6的补码

-3原码1000 0000 0000 0000 0000 0000 0000 0011

反码 1111 1111 1111 1111 1111 1111 1111 1100

补码 1111 1111 1111 1111 1111 1111 1111 1101

6的原码反码补码相同

0000 0000 0000 0000 0000 0000 0000 0110

对-3&6,同一位上,有0则为0,全为1才为1

1111 1111 1111 1111 1111 1111 1111 1101

&0000 0000 0000 0000 0000 0000 0000 0110

则为0000 0000 0000 0000 0000 0000 0100(补码)

则-3&6为4

5.2 |按位或

按位或的运算过程

对两个整数的补码,同一位上,有1为1,全0才为0

c 复制代码
int a = -3;
int b = 6;
int c = a | b;

对-3|6,有1就为1,全为0才为0

1111 1111 1111 1111 1111 1111 1111 1101

|0000 0000 0000 0000 0000 0000 0000 0110

得到1111 1111 1111 1111 1111 1111 1111 1111

取反加一

1000 0000 0000 0000 0000 0000 0000 0001

-3|6=-1

5.3 ^按位异或

按位异或的运算过程

对两个整数的补码,同一位上,相同为0,相异为1

c 复制代码
int a = -3;
int b = 6;
int c = a ^ b;

对-3^6,相同为0,相异为1

1111 1111 1111 1111 1111 1111 1111 1101

^0000 0000 0000 0000 0000 0000 0000 0110

得到1111 1111 1111 1111 1111 1111 1111 1011

取反加一

1000 0000 0000 0000 0000 0000 0000 0101

-3^6=-5

(六)单目操作符

! ~ ++ -- + - & * sizeof (类型)

以上部分单目操作符在前面有所讲述便不再多说
【C语言】4.变量与操作符

& 和 *则会在我们学习指针时介绍

(七)逗号表达式

格式

c 复制代码
表达式1,表达式2,表达式3,......,表达式n

逗号表达式运算顺序是从左至右

最终结果是最后一个表达式的结果

例子

c 复制代码
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
                 a = 12     12     b=13

从左至右,c=13

(八)下标引用操作符[],函数调用()

8.1 下标引用操作符[]

下标引用操作符[]一般在数组部分出现

\]的操作数是数组名和下标 例子 ```c int arr[10] = {0};//创建数组并且初始化 arr[9] = 9;//使用下标引用操作符 这里的arr,9是[]的操作数 ``` ### 8.2 函数调用操作符() ()的操作数是函数名和参数 例子 ```c int c = Add(a,b); ``` 这里的函数名Add和参数a,b是()的操作数 *** ** * ** *** ## 总结 这篇文章我们介绍了进制,进制间的转化,原反补码,移位操作符,位操作符,逗号操作符,逗号表达式,下标引用操作符和函数调用操作符 下一篇我们还会介绍剩下的操作符和操作符的属性 > 有错误的地方希望可以得到大佬的指正 > > 最后不要吝啬你的点赞,收藏和评论!!!

相关推荐
木婉清fresh1 小时前
测开python高频面试精选100题
开发语言·python·面试
刃神太酷啦1 小时前
C++的IO流和C++的类型转换----《Hello C++ Wrold!》(29)--(C/C++)
java·c语言·开发语言·c++·qt·算法·leetcode
不想写笔记1 小时前
C语言 函数
c语言·笔记
Gomiko1 小时前
JavaScript基础(七):数组
开发语言·javascript·ecmascript
一只乔哇噻1 小时前
java后端工程师+AI大模型进修ing(研一版‖day58)
java·开发语言
大海里的番茄1 小时前
让操作系统的远程管理更简单用openEuler+cpolar
linux·c语言·c++
JHC0000001 小时前
47. 全排列 II
开发语言·python·面试
g***86691 小时前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
Drone_xjw1 小时前
【Qt经验】QT软件打包报错 无法定位程序输入点_ZdlPvj于动态链接库 Qt5Sql.dll上
开发语言·qt