当前位置: 首页 > news >正文

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 变 11 变 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系统编程中的进程状态处理。最后简要说明了逗号表达式的执行特性和结构体成员访问符的使用。这些知识点能提升编程效率,特别在需要直接操作二进制数据的场景中。


文章转载自:
http://atelectatic.pzdurr.cn
http://attainable.pzdurr.cn
http://charioteer.pzdurr.cn
http://bomblike.pzdurr.cn
http://ceiling.pzdurr.cn
http://albata.pzdurr.cn
http://bengalee.pzdurr.cn
http://bafflegab.pzdurr.cn
http://causticity.pzdurr.cn
http://balopticon.pzdurr.cn
http://aniseikonic.pzdurr.cn
http://archespore.pzdurr.cn
http://blazonment.pzdurr.cn
http://agglutinin.pzdurr.cn
http://band.pzdurr.cn
http://burnish.pzdurr.cn
http://antatrophic.pzdurr.cn
http://advocate.pzdurr.cn
http://bib.pzdurr.cn
http://aerobiologist.pzdurr.cn
http://algid.pzdurr.cn
http://cctv.pzdurr.cn
http://chincherinchee.pzdurr.cn
http://algiers.pzdurr.cn
http://androstenedione.pzdurr.cn
http://activize.pzdurr.cn
http://absorbency.pzdurr.cn
http://asymptotic.pzdurr.cn
http://affair.pzdurr.cn
http://airwave.pzdurr.cn
http://www.dtcms.com/a/280519.html

相关文章:

  • linux系统------HAProxy 配置
  • 酷淘商场项目【从零到一详解】Web端抓包操作与测试报告(二)
  • 部署项目将dll放到system32?不可取
  • Ubuntu环境下的K3S集群搭建
  • 【如何理解SerializedProperty】
  • 【项目】-番茄时钟设计
  • 云手机隐私保护指南:如何保障账号与数据的云端安全?
  • 编程技能:多文件编译
  • 本地 LLM API Python 项目分步指南
  • 20250715给荣品RD-RK3588开发板刷Android14时打开USB鼠标
  • Android 获取 UserAgent (UA) 的三种方式深度解析:差异、风险与最佳实践
  • Hystrix与Resilience4j在微服务熔断降级中的应用对比与实战
  • 用 K-means 算法实现水果分堆
  • 《大数据技术原理与应用》实验报告四 MapReduce初级编程实践
  • 多网卡环境下访问跨网段设备的排查与配置指南
  • iOS高级开发工程师面试——关于网络
  • Python:消息队列(RabbitMQ)应用开发实践
  • 【C#地图显示教程:实现鼠标绘制图形操作】
  • 开通保存图片权限
  • 如何设计实现开发自助重启工具-01-设计篇
  • eVTOL分布式电推进(DEP)适航审定探究
  • Ajax接收java后端传递的json对象包含长整型被截断导致丢失精度的解决方案
  • 【橘子分布式】Thrift RPC(编程篇)
  • 亚矩阵云手机:破解 Yandex 广告平台多账号风控难题的利器
  • Redis学习系列之——高并发应用的缓存问题(二)
  • JDK1.8函数式编程实战(附日常工作案例,仅此一篇耐心看完彻底搞懂)
  • 17、鸿蒙Harmony Next开发:状态管理(组件拥有的状态和应用拥有的状态)
  • Vue获取上传Excel文件内容并展示在表格中
  • 【人工智能99问】神经网络的工作原理是什么?(4/99)
  • 使用Pydantic开发时,如何将返回数据由snake_case自动转为camel case