C语言操作符补充
目录
前言
一、原码、反码、补码介绍
二、操作符补充
1.移位操作符
规则
演示
为什么用移位操作符?
2.位操作符
1.&与
2.| 或
3.^ 异或
4.~非
小结
位操作符有什么用?
3.逗号表达式
4.结构体成员访问符
总结
前言
C语言中的操作符种类较多,平常使用的也就是那几种,可一旦要用到一些不太常见的操作符时,又免不了去查翻资料。
本文主要介绍一些平常不太常用的操作符,一是方便后续查找,二是增加作为程序猿的知识积累。
C语言中的操作符大概分为:
一、原码、反码、补码介绍
为什么要了解原码、反码、补码?因为计算机中数据是以二进制存储的,实际上数据在计算机中都是以补码形式存储的,一些操作符直接作用于二进制的补码。
为什么计算机要以补码存储数据?
在计算机系统中,数值⽤补码来表⽰和存储。
①使⽤补码,可以将符号位和数值域统⼀处理;
②同时,加法和减法也可以统⼀处理(CPU只有加法器)。
以下详细介绍原码、反码、和补码的概念,即互相转换方法。
整数的二进制表⽰⽅法有三种:即原码、反码和补码。
在整数的二进制序列中,最⾼位的1位是被当做符号位,剩余的都是数值位。 符号位都是⽤0表⽰“正”,⽤1表⽰“负”。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
正整数的原、反、补码都相同。
负整数的三种表示方法法各不相同。
例如:
假如在32位系统下:
int a = 10;//十进制
//正整数的原、反、补一致: 0000 0000 0000 0000 0000 0000 0000 1010int b = -10;//十进制
//负数的原、反、补不一致:
首先以绝对值计算原码,然后再将符号位置为1。
原: 1000 0000 0000 0000 0000 0000 0000 1010,符号位为1其余不变
反码,将原码按位取反:
反: 0111 1111 1111 1111 1111 1111 1111 0101
补码,在反码末尾+1,注意进位
补: 0111 1111 1111 1111 1111 1111 1111 0110
二、操作符补充
1.移位操作符
<< 左移操作符
>> 右移操作符
注: 移位操作符的操作数只能是整数。
位移运算符的核心作用:高效地操作二进制位。
规则
左移操作符:左边抛弃、右边补0。
右移操作符:分两种情况。
①逻辑右移:左边⽤0填充,右边丢弃;
②算术右移:左边⽤原该值的符号位填充,右边丢弃
实质解读:左移n位,就是在原数的基础上 * 2^n;右移n位,就是 / 2^n。
演示
以左操作符演示
代码演示
//1.移位操作符int a = 10;printf("%d\n", a << 1);//左移1位,*2printf("%d\n", a >> 1);//右移1位,/2
注意:对于移位运算符,不要移动负数位,这个是标准未定义的。
如
int num = 10;num>>-1;
为什么用移位操作符?
-
速度: 在绝大多数CPU架构上,一条位移指令的执行速度远快于一条乘法或除法指令。在需要极致性能的循环或内核代码中,这种优化非常关键。
2.位操作符
位操作符包括:&、|、^、~
注: 位操作符的操作数必须是整数。
位操作符依旧作用于操作数的二进制。
1.&与
规则: 只要有一个对应的位是 1
,结果位就是 1
;只有两个位都是 0
时,结果位才是 0
。
如:
代码验证:
//2.位操作符int x = 5, y = 3;printf("%d\n", x & y);
结果
2.| 或
规则: 当两个对应的位不同时,结果位是 1
;当两个位相同时,结果位是 0
。
如:
代码验证:
//2.位操作符int x = 5, y = 3;printf("%d\n", x | y);
结果
3.^ 异或
规则: 当两个对应的位不同时,结果位是 1
;当两个位相同时,结果位是 0
。
如:
代码验证:
int x = 5, y = 3;printf("%d\n", x ^ y);
结果:
4.~非
规则: 将操作数的每一位取反(0
变 1
,1
变 0
)。
注意:位操作符中只有!是单目操作符。~
的结果取决于操作数的类型(有符号还是无符号)。对有符号数进行 ~
操作会影响符号位。
如:
代码验证:
int x = 5;printf("%d\n", ~5);
结果
小结
位操作符有什么用?
场景:在 Linux 系统编程中处理子进程状态
当你在 Linux中使用 fork()
创建子进程,然后使用 waitpid()
等待子进程结束时,内核会通过 waitpid()
的 status
参数返回一个整数值(通常是 int
类型)。这个 status
变量并非简单的退出码,而是一个打包了多种信息的位字段(bit field)。而status
的低七位二进制就是我们需要的子进程退出信息。
我们获取子进程的退出信息时,就需要用到&操作符:
这里只是强调位操作符的作用,对进程等待感兴趣的读者可以参看笔者往期博客:
Linux环境下的进程创建-fork函数的使用与写时拷贝, 进程退出exit和_exit的区别,以及进程等待waitpid和status数据的提取方法_fork 怎么使用-CSDN博客
3.逗号表达式
逗号表达式,就是⽤逗号隔开的多个表达式。
逗号表达式,从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。
如:
4.结构体成员访问符
结构体成员的直接访问结构体成员的直接访问是通过点操作符(.)和->访问的。
‘.’操作符用于直接访问结构体对象的成员。
使用方式:结构体变量.成员名
如
‘->’操作符用于访问,结构体指针所指向的结构体对象中的成员变量。
如
总结
本文介绍了C语言中不常用但重要的操作符知识。
首先讲解了原码、反码和补码的概念及转换方法,说明计算机中数据以补码存储的原因。重点解析了移位操作符(<<和>>)的运算规则及其高效性优势,以及四种位操作符(&、|、^、~)的使用方法和实际应用场景,如Linux系统编程中的进程状态处理。最后简要说明了逗号表达式的执行特性和结构体成员访问符的使用。这些知识点能提升编程效率,特别在需要直接操作二进制数据的场景中。