【c语言】详解操作符(上)

1. 操作符的分类

2. 原码、反码、补码

整数的2进制表示方法有三种,即原码、反码、补码

有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号位其余都是数值位。

符号位都是用0表示“正”,用1表示“负”。

例:分别写出1、-1的2进制

int a = 1;
int b = -1;

其中a、b都是整形变量,是4个字节,32bit位,那么a、b的2进制为:

a:00000000000000000000000000000001

b:10000000000000000000000000000001

正整数的原码、反码、补码都相同

负数的三种表示方法各有不同

原码:直接将数值按照正负数形式翻译成2进制得到的就是原码。

反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码:反码加1就可以得到补码。

补码得到原码也是可以使用取反加1的操作。

例:分别写出-10的原码、反码、补码

原码:10000000000000000000000000001010

反码:11111111111111111111111111110101

补码:11111111111111111111111111110110

对于整形来说:数据存放内存中其实存放的是补码。

为什么呢?

  1. 简化计算:使用补码可以将符号位和数值位统一处理,这样无论是正数还是负数,都可以用同一套逻辑来进行加减运算。由于计算机的CPU只有加法器,没有减法器,通过补码可以将减法运算转换为加法运算,从而简化了硬件设计。
  2. 避免歧义:补码的表示方法确保了0的编码只有一个,不会出现两个不同的编码对应同一个数0的情况。这对于避免数据表示上的歧义非常重要。
  3. 提高存储效率:原码、反码和补码是二进制数的三种不同表示方法。原码是最直观的表示方法,但它在表示负数时需要额外的符号位,并且在进行运算时需要分别处理正负号。反码是对原码的改进,它将负数的符号位保持不变,数值位取反。而补码则是在反码的基础上加1,它不仅解决了0的表示问题,还可以通过补码直接进行加减运算,无需额外的硬件电路。
  4. 方便逻辑电路实现:计算机由逻辑电路组成,逻辑电路通常只有两种状态,即开关的接通与断开,刚好可以表示成‘1’和‘0’。因此,计算机只存储二进制数据,而补码作为一种二进制表示方法,非常适合于计算机的逻辑电路实现。

3. 移位操作符(移动的是二进制位)

<< 左移操作符

>> 右移操作符 

注:移位操作符的操作数只能是整数。

3.1 左移操作符

左移操作符有一个乘以2的n次方的效果(n为<<后面的数字)

移位规则:左边抛弃,右边补0.

例1:

上图中a的补码为:

00000000000000000000000000000110

其中b = a << 1,那么在a的补码的基础上抛弃左边的1位,然后在右边补上一个0,可得b的补码:

00000000000000000000000000001100

例2:

a的补码为:11111111111111111111111111111010

b得到的补码:11111111111111111111111111110100

3.2 右移操作符

左移操作符有一个除以2的n次方的效果(n为>>后面的数字)

移位规则:

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

2. 算术右移,左边用原值的符号位(原值是正数就用0,是负数就用1)填充,右边丢弃。 

注:是逻辑右移还是算术右移是取决于编译器的实现,常见的编译器都是算术右移。 

算术右移: 

 a的补码为:11111111111111111111111111111010

b得到的补码:11111111111111111111111111111101

 4. 位操作符:&、|、^、~

1. &                     按位与

2.  |                      按位或

3. ^                      按位异或

4. ~                     按位取反

注:它们的操作数必须是整数 

4.1 &

运算规则:

&左右两个数的补码中有0就取0,两个同时为1才取1

例:

3的补码为 :0000000000000000000000000000011

-5的补码为:11111111111111111111111111111011

c得到的补码为:0000000000000000000000000000011

4.2 |

运算规则:

|左右两个数的补码中有1就取1,两个同时为0才取0

例:

3的补码为 :0000000000000000000000000000011

-5的补码为:11111111111111111111111111111011

c得到的补码为:11111111111111111111111111111011

4.3 ^ 

运算规则:

相同为0,相异位1. 

3的补码为 :0000000000000000000000000000011

-5的补码为:11111111111111111111111111111011

c得到的补码为:11111111111111111111111111111000

例题:不使用临时变量的情况下,交换a和b的值

由^的运算规则我们可以知道当^两边的数相同时,所得到的结果为0,而0^a=a,所以我们利用这个规律我们就可以在不使用临时变量的情况下,交换a和b的值,如下图:

4.4  ~

运算结果为~右边的数+1然后取相反数,例如:~1 = -2,~-1 = 0

运算规则:

对~右边的数的2进制按位取反

0的2进制为: 0000000000000000000000000000000

b得到的补码为:11111111111111111111111111111111

5练习:

练习1:

编写代码实现:求一个整数存储在内存中补码中1的个数。

法1:

由&的运算规则我们可以知道a&1=1的式子成立时,就说明a的补码最右边的数为1,从这里可以知道,依次将a的补码的32个数依次移动到最右边(这里可以使用右移操作符(>>)移动),然后统计有几个符合a&1=1,就可以求出这个整数存储在内存中补码中1的个数。

以13为例,求13在内存中补码中1的个数:

13的补码:
00000000000000000000000000001101
1的补码:
00000000000000000000000000000001

法2: 

int main()
{
	int n = 0;
	scanf("%d", &n);
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	printf("%d\n", count);
	return 0;
}

思考题:

如何判断一个数是否是2的次方数?

2的n次方数的二进制中只有1个1,而式子n&(n-1)就可以直接把这个1去掉了,所以要想判断一个数是否是2的次方数,只需要判断等式n&(n-1)== 0是否成立就可以了。

练习2:

二进制位置1或者置0

编码代码将13二进制序列的第5位修改为1,然后再改为0

13的2进制序列:

00000000000000000000000000001101

将5位置为1后:

00000000000000000000000000011101

将5位置为0后:

00000000000000000000000000001101

int main()
{
	int a = 13;
	//将5位置为1
	a |= 1 << 4;
	printf("%d\n", a);
	//将5位置为0
	a &= ~(1 << 4);
	printf("%d\n", a);
	return 0;
}

6. 逗号表达式

exp1,exp2,exp3,....,expN

用逗号隔开的表达式就是逗号表达式。

逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

例1:计算下列表达式c中的结果:

int main()

{
	int a = 1, b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);
	printf("%d\n", c);
	return 0;
}

表达式的运行过程为:a>b(为假,但不影响表达式的结果) -> a=b + 10 -> 12 -> b = a + 1 = 13

因为最终决定表示结果的是表达式:b = a + 1,所以最终的结果为:13

 例2:

逗号表达式在if语句中真正起判断作用的是最后一个表达式 。

7. 下标访问[ ]、函数调用( ) 

7.1 [ ] 下标引用操作符

操作数:一个数组名 + 一个索引值(下标)

7.2 函数调用操作符

接受一个或多个操作数:第一个操作数是函数名,剩下的操作数就是传给函数的参数。

#include<stdio.h>
int main()
{
    printf("hello world!\n");//( )函数调用操作符
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/353839.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式:简介及基本原则

简介 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问&#xff0c;设计模式于己于他人于系统都是多赢的&#xff0c;设计模式使代码编制真正工程化&#xff…

Kotlin快速入门5

Kotlin的继承与重写 kotlin的继承 Kotlin中所有类都继承自Any类&#xff0c;Any类是所有类的超类&#xff0c;对于没有超类型声明的类是默认超类&#xff08;Any 不是 java.lang.Object&#xff09;&#xff1a; class LearnKotlin // 默认继承自Any Any类默认提供三个函数…

Scikit-learn (sklearn)速通 -【莫凡Python学习笔记】

视频教程链接&#xff1a;【莫烦Python】Scikit-learn (sklearn) 优雅地学会机器学习 视频教程代码 scikit-learn官网 莫烦官网学习链接 本人matplotlib、numpy、pandas笔记 1 为什么学习 Scikit learn 也简称 sklearn, 是机器学习领域当中最知名的 python 模块之一. Sk…

IDEA搭建JDK源码学习环境(可添加注释、修改、debug)

工程详见&#xff1a;https://github.com/wenpanwenpan/study-source-jdk1.8.0_281 1、找到src.zip和javafx-src.zip 找到你想要调试的JDK&#xff0c;笔者本地电脑上装了两个版本的JDK&#xff0c;这里以jdk1.8.0_281为例将JDK目录下的javafx-src.zip和src.zip两个压缩包进行…

【GitHub项目推荐--不错的 TypeScript 学习项目】【转载】

在线白板工具 Excalidraw 标星 33k&#xff0c;是一款非常轻量的在线白板工具&#xff0c;可以直接在浏览器打开&#xff0c;轻松绘制具有手绘风格的图形。 如下图所示&#xff0c;Excalidraw 支持最常用的图形元素&#xff1a;方框、圆、菱形、线&#xff0c;可以方便的使用…

【Web】小白也能做的RWCTF体验赛baby题部分wp

遇到不会的题&#xff0c;怎么办&#xff01;有的师傅告诉你完了&#xff0c;废了&#xff0c;寄了&#xff01;只有Z3告诉你&#xff0c;稳辣&#xff01;稳辣&#xff01;都稳辣&#xff01; 这种CVE复现的题型&#xff0c;不可能要求选手从0到1进行0day挖掘&#xff0c;其实…

12.15字符编码(血干JAVA系列)

字符编码 12.15.1 Java常见编码简介12.15.2得到本机的编码显示【例12.68】使用上述方法得到JVM的默认编码 12.15.3乱码产生【例12.69】使用1SO8859-1编码 12.15.1 Java常见编码简介 12.15.2得到本机的编码显示 在 前 面 讲 解 常 用 类 库 的 时 候 曾 经 介 绍 过 &#xff0…

HarmonyOS 沉浸式状态栏实现

比如说 我们代码是这样的 Entry Component struct Index {build() {Column() {Column() {Column() {Text(定标标题).fontSize(20).fontColor(Color.White)}.height(50).justifyContent(FlexAlign.Center)}.width(100%).backgroundColor(#FF0000)}.height(100%)} }你预览器上看…

k8s 版本发布与回滚

一、实验环境准备&#xff1a; kubectl get pods -o wide kubectl get nodes -o wide kubectl get svc 准备两个nginx镜像&#xff0c;版本号一个是V3&#xff0c;一个是V4 二、准备一个nginx.yaml文件 apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploylab…

AutoGen实战应用(二):多代理协作(Multi-Agent Collaboration)

AutoGen是微软推出的一个全新工具&#xff0c;它用来帮助开发者创建基于大语言模型(LLM)的复杂应用程序. AutoGen能让LLM在复杂工作流程启用多个角色代理来共同协作完成人类提出的任务。在我之前的一篇博客: AutoGen实战应用(一)&#xff1a;代码生成、执行和调试 中我们通过一…

CTF CRYPTO 密码学-6

题目名称&#xff1a;敲击 题目描述&#xff1a; 方方格格&#xff0c;不断敲击 “wdvtdz qsxdr werdzxc esxcfr uygbn” 解题过程&#xff1a; step1&#xff1a;根据题目描述敲击&#xff0c;wdvtdz对应的字符为x step2&#xff1a;依此类推r&#xff0c;z&#xff0c;o&…

使用 create-react-app 创建 react 应用

一、创建项目并启动 第一步&#xff1a;全局安装&#xff1a;npm install -g create-react-app 第二步&#xff1a;切换到想创建项目的目录&#xff0c;使用命令create-react-app hello-react 第三步&#xff1a;进入项目目录&#xff0c;cd hello-react 第四步&#xff1a;启…

Pyecharts 风采:从基础到高级,打造炫酷象形柱状图的完整指南【第40篇—python:象形柱状图】

文章目录 引言安装PyechartsPyecharts象形柱状图参数详解1. Bar 类的基本参数2. 自定义图表样式3. 添加标签和提示框 代码实战&#xff1a;绘制多种炫酷象形柱状图进阶技巧&#xff1a;动态数据更新与交互性1. 动态数据更新2. 交互性设计 拓展应用&#xff1a;结合其他图表类型…

Android 基础技术——列表卡顿问题如何分析解决

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于列表卡顿问题如何分析解决 onBindViewHolder 优化 是否有耗时操作、重复创建对象、设置监听器、findViewByID、局部的动画对象等操作 是否存在内存泄漏 发生内存泄露&#xff0c;会导致一些不再使用…

工业4.0开放平台通信 统一架构OPC UA的一种测试方法

工业4.0和工业物联网&#xff08;Industrial Internet of Things, IIoT&#xff09;的核心挑战在于设备、机器以及来自不同行业服务之间的安全和标准化的数据和信息交换。 2016年11月工业4.0平台发布了指导纲要《工业4.0产品需要实现哪些准则》&#xff0c;即对于所有位于工业…

概念抽取:构建认知基础的关键步骤

目录 前言1 概念抽取任务定义1.1 概念知识图谱的关系定义1.2 实体与概念的紧密关联1.3 多样的概念关系 2 概念在认知中的重要角色2.1 语言理解的基础2.2 上下位关系的深化理解 3 概念抽取方法3.1 基于模板的抽取3.2 基于百科的抽取3.3 基于机器学习的方法 4 应用4.1 自然语言理…

一行命令在 wsl-ubuntu 中使用 Docker 启动 Windows

在 wsl-ubuntu 中使用 Docker 启动 Windows 0. 背景1. 验证我的系统是否支持 KVM&#xff1f;2. 使用 Docker 启动 Windows3. 访问 Docker 启动的 Windows4. Docker Hub 地址5. Github 地址 0. 背景 我们可以在 Windows 系统使用安装 wsl-ubuntu&#xff0c;今天玩玩在 wsl-ub…

【Web前端实操16】雪碧图(CSS精灵图)

雪碧图 CSS Sprite也叫CSS精灵图、CSS雪碧图&#xff0c;是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去 雪碧图一般会给一个完整的图片&#xff0c;主要利用background-position 属性设置背景图像的起始位置。 优点 减少图片的字…

API网关-Apinto压缩包方式自动化安装配置教程

文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…

【css揭秘】

文章目录 背景与边框半透明边框多重边框box-shadowoutline 背景定位background-positionbackground-origincalc() 条纹背景水平条纹 形状圆形圆柱自适应的椭圆半椭圆四分之一椭圆 背景与边框 半透明边框 目标&#xff1a;给一个容器设置一层白色背景和一道半透明白色边框 写…