【C语言初阶】带你轻松玩转所有常用操作符(1)

在这里插入图片描述

君兮_的个人主页

勤时当勉励 岁月不待人

C/C++ 游戏开发


Hello,这里是君兮_,最近要准备期末复习了,可能更新的就不会那么频繁了,下个星期回复正常更新。

操作符详解1

  • 前言
  • 一.操作符的分类
  • 二.算数操作符
  • 三.移位操作符
    • 1.二进制表示的三种形式
    • 2.左移操作符 <<
    • 3.右移操作符 >>
    • 4.错误的写法
  • 四.位操作符
    • 1.& 按位与
    • 2.| 按位或
    • 3.^ 按位异或
    • 4.位操作符应用实例
  • 总结

前言

今天给大家带来的是操作符详解,由于这部分的内容比较多,可能会分成几部分讲,今天带来的是第一部分的内容,废话不多说,咱们开始吧!

一.操作符的分类

  • 操作符大致分为以下几种
  • 算术操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号表达式
  • 下标引用、函数调用和结构成员
  • 咱们还是先画个图来说明,具体的再一个一个介绍用法及使用场景
    在这里插入图片描述

二.算数操作符

   +   -  *  /  %
    1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
    1. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
    1. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
  • 我们来通过一段代码理解一下:
#include<stdio.h>
int main()
{
	int r = 7 / 2;
	printf("%d\n", r);
	double d = 7 / 2;
	printf("%lf\n", d);//3.5?
	double d1 = 7.0 / 2.0;
	printf("%lf\n", d1);//3.5?

	return 0;
}
  • 运行结果
    在这里插入图片描述
  • 大家可能对打印的第一个数字和第三个数字都没什么疑问,唯一有问题的就是为什么第二个后面的小数部分被省去了,接下来我来讲讲原因
  • 我们可以看到7和2都是整数,那么执行的就是整数除法,在整形中是不存在小数的,因此小数点后面的部分会被直接舍去,此时我们又把7/2得到的3赋给一个浮点型的d,打印出来是要保留小数后面的几位的,因此打印出来的才是屏幕上的结果
  • 总结:
  • 当你想要进行浮点数除法时,除号两边的数得至少有一个浮点型!!!

三.移位操作符

<< 左移操作符
>> 右移操作符
 
注:移位操作符的操作数只能是整数。
  • 在讲这方面内容之前,先给大家简单的补充一些数据在内存中存储的知识,方便大家下面更好的理解,如果你想更具体的了解这方面的知识,不妨去看看我的这两篇博客,以下是链接:
    【C语言进阶】纳尼?这样学数据在内存中的存储竟然如此简单(1)?
    【C语言进阶】纳尼?这样学数据在内存中的存储竟然如此简单(2)?

整型在内存中是以二进制的形式存储的,而内存中存储的是补码,并且是倒着存的。

现在我来具体解释一下上面这段话。

1.二进制表示的三种形式

  • 二进制在内存中表示形式分别是原码,反码,补码。
  • 其中,数据在内存中是以二进制补码的形式进行存储的
  • 以下面的代码说明

int main()
{
	
	int num  = 10;//创建一个整型变量,叫num,这时num向内存申请4个字节来存放数据
	//4个字节-32比特位
	//00000000000000000000000000001010-原码
	//00000000000000000000000000001010-反码
	//00000000000000000000000000001010-补码

	int num2 = -10;//
	//10000000000000000000000000001010 - 原码
	//11111111111111111111111111110101 - 反码
	//11111111111111111111111111110110 - 补码
	


	return 0;
}
  • 十进制数据的二进制表现形式就是原码,原码最左边的一个数字就是符号位,0为正,1为负。
  • 对于正数而言,原码反码补码三者相同,对于负数而言,反码为原码符号位不变,其他位取反(1变为0,0变为1)
  • 对于负数而言,补码为反码+1。

2.左移操作符 <<

  • 移位规则
    左边抛弃,右边补零
  • 注意,以下我们所说的移位,移动的都是补码的二进制序列
int main()
{

	int num = 10;//创建一个整型变量,叫num,这时num向内存申请4个字节来存放数据
	//4个字节-32比特位
	//00000000000000000000000000001010-原码
	//00000000000000000000000000001010-反码
	//00000000000000000000000000001010-补码
	int b=num << 1;
	//00000000000000000000000000010100-补码
	printf("%d\n", num);
	printf("%d\n", b);

	
	return 0;
}

在这里插入图片描述

  • 注意,移位操作并不会改变原来变量的大小!!

3.右移操作符 >>

  • 移位规则:
  • 首先右移运算分两种:
  • 1. 逻辑移位
    左边用0填充,右边丢弃
  • 2. 算术移位
    左边用原该值的符号位填充,右边丢弃
int main()
{

	int num = 10;
	
	//逻辑右移 左边用0填充,右边丢弃
	//00000000000000000000000000001010-补码
	int b=num >> 1;
	//00000000000000000000000000000101-补码
	printf("%d\n", num);
	printf("%d\n", b);
	//算数右移 左边用原该值的符号位填充,右边丢弃
	int num1 = -1;
	//10000000000000000000000000000001-原码
	//11111111111111111111111111111110-反码
	//11111111111111111111111111111111-补码
	int c = num1 >> 1;
	printf("%d", c);
	
	return 0;
}


  • C语言没有明确规定是逻辑右移还是算术右移,但是一般编辑器采用的都是算术右移
    在这里插入图片描述
  • 如图可见,我们当前编译器采用的是逻辑右移,否则符号位应该变为0打印出来的应该是一个正数。

4.错误的写法

  • 另外,要注意这种写法:
int main()
{
	int a = 5;
	int b = a >> -2;//标准未定义行为

	return 0;
}

  • 有些人可能脑子一抽,突然想到,我右移一个负数不就是左移吗?
  • 注意:对于移位运算符,不要移动负数位,这个是标准未定义行为!!

四.位操作符

  • 位操作符有:
 & //按位与
 | //按位或
 ^ //按位异或
  • 注:他们的操作数必须是整数
  • 以下位操作符对应操作的仍然是二进制补码

1.& 按位与

& 按位与 ---- 对应二进制位有0则为0,两个同时为1,才是1

int main()
//{
//	int a = 3;
//	//00000000000000000000000000000011 - 补码
//	int b = -5;
//	//10000000000000000000000000000101
//	//11111111111111111111111111111010
//	//11111111111111111111111111111011 - 补码
//	//
//	int c = a & b;
//	//& -- 对应二进制位有0则为0,两个同时为1,才是1
//	//00000000000000000000000000000011
//	//11111111111111111111111111111011
//	//00000000000000000000000000000011 - 补码
//	//
//	printf("%d\n", c);//3
//
//	return 0;
//}

在这里插入图片描述


2.| 按位或

| 按位或 ---- 对应的二进制位有1则为1,两个同时为0才是0

int main()
{
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101
	//11111111111111111111111111111010
	//11111111111111111111111111111011 - 补码
	//
	int c = a | b;
	//| - 按(2进制)位或 - 对应的二进制位有1则为1,两个同时为0才是0
	//00000000000000000000000000000011
	//11111111111111111111111111111011
	//11111111111111111111111111111011 - 补码
	//11111111111111111111111111111010
	//10000000000000000000000000000101 - -5
	printf("%d\n", c);//3

	return 0;
}

在这里插入图片描述


3.^ 按位异或

^ 按位异或 ----对应的二进制位相同为0,相异为1

int main()
{
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101
	//11111111111111111111111111111010
	//11111111111111111111111111111011 - 补码
	//
	int c = a ^ b;
	//^ - 按二进制位异或 -对应的二进制位相同为0,相异为1
	//00000000000000000000000000000011
	//11111111111111111111111111111011
	//11111111111111111111111111111000 - 补码
	//11111111111111111111111111110111
	//10000000000000000000000000001000 - -8
	printf("%d\n", c);//3

	return 0;
}

在这里插入图片描述


4.位操作符应用实例

  • 看了上面的内容,可能有些人会有疑问,这些位操作符具体都有啥用呢?
  • 以下我们来通过几个例子说明:
  • 1.我们先来看一个简单的例子
int main()
{
int num1 = 1;
int num2 = 2;
num1 & num2;
num1 | num2;
num1 ^ num2;
return 0;
}
  • 上面的这段代码a,b,c的结果是多少?
    在这里插入图片描述
  • 很简单吧?遇到这种问题一定不要偷懒,画图是最好的解决方法!
  • 2.在不创建临时变量(第三个变量)的情况下,实现两个数的交换。
  • 这其实是某公司的一个面试题,如果你能理解上面所讲的内容并学会应用,其实并不复杂。
  • 实现代码如下:
//在不创建临时变量(第三个变量)的情况下,实现两个数的交换。
int main()
{
	int a = 10;
	00000000000000000000000000001010--10的补码
	int b = 20;
	00000000000000000000000000010100--20的补码
	a = a ^b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d", a, b);
	return 0;
}

在这里插入图片描述

  • 成功实现我们的目标,可是为什么呢?
  • 下面我来解释一下,如果你是基础不是特别好的初学者的话,这里还是建议自己先画图感受一下哦!
	a = a ^b;
	//00000000000000000000000000001010--a
	//00000000000000000000000000010100--b
	//00000000000000000000000000011110--a=a^b
  • 此时a已经变成了a ^b

	b = a ^ b;
	//00000000000000000000000000010100--b
	//00000000000000000000000000011110--a=a^b
	//00000000000000000000000000001010-b=a^b    
  • 此时的b已经与a完成交换变成10了
a = a ^ b;
	//00000000000000000000000000011110--a=a^b
	//00000000000000000000000000001010-b=a^b 
	//00000000000000000000000000010100 a=a^b a=20
  • 最后一次异或,把b的值交换给a
  • 逐步分析这段代码是不是就清晰多了?

总结

  • 今天的内容暂时到这里就结束了,我们今天讲了有关算数操作符,移位操作符和位操作符的应用,如果你还有所困惑不妨自己动手实操一下,这方面的知识是稍微有点抽象,需要咱们反复的练习熟悉起来才行。
  • 以上就是关于操作符的第一部分内容,后面其他的操作符应用详解会在近期分批次更新,敬请期待!!
  • 好了,如果你有任何疑问欢迎在评论区或者私信我提出,大家下次再见啦!

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下这个新人博主再走呗。你们的支持就是我更新的动力!!!

**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

在这里插入图片描述

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

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

相关文章

matlab实现语音信号的频域分析及应用

1.语音信号本质上是非平稳信号。但我们可以假设语音信号在一个短时间内是平稳的&#xff0c;这样我们用稳态分析方法处理非平稳信号。应用在傅立叶分析就是短时傅立叶变换。 语音的频域分析&#xff1a;包括语音信号的频谱、功率谱、倒频谱、频谱包络等. 常用频域分析方法&am…

mySql和VSC++

确认主机服务里的mysql服务已打开 使用组合键“winR”运行“services.msc”&#xff0c;进入本地服务窗口&#xff1b; 2.进入本地服务窗口后&#xff0c;在右侧服务列表中&#xff0c;查找到“ mysql ”服务选项&#xff1b; 3.查找到mysql服务选项后&#xff0c;双击打开mysq…

linux安装anaconda

linux安装anaconda 1、下载anaconda&#xff1a; Conda 是一个强大的包管理器和环境管理器&#xff0c;您可以在 Windows 的 Anaconda Prompt 或 macOS 或 Linux 的终端窗口中与命令行命令一起使用。 换句话说&#xff0c;我把Conda理解为前端的npm或yarn&#xff0c;后端的…

二进制部署k8集群(上)搭建单机matser和etcd集群

1. 单机matser预部署设计 组件部署&#xff1a; 2.操作系统初始化配置 注意&#xff1a;该操作在所有node节点上进行&#xff0c;为k8s集群提供适合的初始化部署环境 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -t n…

Java-三种基本控制结构及相关面试题

文章目录 前言一、 顺序控制结构1.1 概念1.2 代码1.3 NS图中体现 二、分支控制结构2.1 概念2.2 if语句2.3 switch语句2.4 NS图中的体现 三、循环控制结构3.1 概念3.2 for循环3.3 while循环3.4 do-while循环3.5 增强 for 循环NS图中的体现 四、相关面试题什么是控制流语句&#…

从零开始:如何用Python建立你的第一个人工智能模型

1. 摘要&#xff1a; 在这篇文章中&#xff0c;我们将介绍如何从零开始使用Python建立你的第一个人工智能模型。无论你是刚接触编程的新手&#xff0c;还是有经验的开发者想进一步探索人工智能领域&#xff0c;这篇文章都将为你提供清晰、详细的指南。我们将一步步探索数据预处…

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Lin…

2023年大学计算机专业实习心得14篇

2023年大学计算机专业实习心得精选篇1 20__年已然向我们挥手告别而去了。在20__年初之际&#xff0c;让我们对过去一年的工作做个总结。忙碌的一年里&#xff0c;在领导及各位同事的帮助下&#xff0c;我顺利的完成了20__年的工作。为了今后更好的工作&#xff0c;总结经验&…

《Java黑皮书基础篇第10版》 第17章【笔记】

第十七章 二进制I/O 17.1 引言 文件可以不严谨的分类为文本文件和二进制文件。文本文件指的是可以用文件编辑器进行查看和修改的&#xff0c;二进制文件则不可以使用文本编辑器查看和修改。 例如&#xff0c;Test.java文件储存在文本文件中&#xff0c;因此可以用文本编辑器…

Web安全测试中常见逻辑漏洞解析(实战篇)

前言&#xff1a; 越权漏洞是比较常见的漏洞类型&#xff0c;越权漏洞可以理解为&#xff0c;一个正常的用户A通常只能够对自己的一些信息进行增删改查&#xff0c;但是由于程序员的一时疏忽&#xff0c;对信息进行增删改查的时候没有进行一个判断&#xff0c;判断所需要操作的…

leetcode188. 买卖股票的最佳时机 IV.动态规划-java

买卖股票的最佳时机 IV leetcode188. 买卖股票的最佳时机 IV题目描述 动态规划代码演示 动态规划专题 leetcode188. 买卖股票的最佳时机 IV 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-st…

从零构建后端项目-创建SpringBoot项目配置MyBatis

目录 主体介绍 创建SpringBoot项目主要步骤 配置MyBatis 整合高级功能 创建SpringBoot项目 配置Tomcat 配置MySQL数据源 配置Redis数据源 配置MongoDB数据源 运行项目&#xff0c;检测配置 配置MyBatis 创建IDEA数据库连接 生成MyBatis各种文件 配置MyBatis 配…

自然语言处理从入门到应用——静态词向量预训练模型:神经网络语言模型(Neural Network Language Model)

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 《自然语言处理从入门到应用——自然语言处理的语言模型&#xff08;Language Model&#xff0c;LM&#xff09;》中介绍了语言模型的基本概念&#xff0c;以及经典的基于离散符号表示的N元语言模型&#xff08;N-gram…

【Redis基础】

Redis基础 Redis基础Note Redis基础1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启1.3.7.wi…

Win7系统提示Windows Defender无法扫描选定的文件解决方法

Win7 64位系统提示“Windows Defender无法扫描选定的文件”怎么办呢?使用Windows Defender扫描文件,结果弹出如下图窗口,该怎么解决呢,参考下文,一起来解决Win7系统提示“Windows Defender无法扫描选定的文件”的解决方法。 原因分析: 这是因为开启Defender扫描压…

rabbitmq第三课-RabbitMQ高级功能详解以及常用插件实战

一、选择合适的队列. 实际上是可以选择三种队列类型的&#xff0c;classic经典队列&#xff0c;Quorum仲裁队列&#xff0c;Stream流式队列。 后面这两种队列也是RabbitMQ在最近的几个大的版本中推出的新的队列类型。3.8.x推出了Quorum仲裁队列&#xff0c;3.9.x推出了Stream流…

计算机网络基础知识(九)—— 什么是TelnetS?Telnet Over TLS

文章目录 01 | TelnetS02 | OpenSSL03 | 实现思路服务器处理流程客户端处理流程 04 | 代码实现服务端代码客户端代码编译过程 & 执行结果 前面学习了什么是HTTPS协议&#xff0c;了解了HTTPS的工作原理以及具体的工作流程&#xff0c;了解了HTTP协议和HTTPS协议之间的区别。…

Elasticsearch 安装(Linux)

ElasticSearch 概念安装安装es 后台启动 & 停止启动nohup 记录pid 停止 其他启动错误max number of threads内存不足 Cannot allocate memoryfailed to obtain node locks 概念 ES是一款分布式全文搜索引擎&#xff0c;基于Lucene&#xff0c;进行了二次封装&#xff0c;更…

ElasticSearch-安装Head可视化插件

安装Head可视化插件 首先需要依赖node.js和npm环境 1 安装node.js 官方下载地址:http://nodejs.cn/download/ 下载LTS版本&#xff08;长期稳定版本&#xff09; 安装可以更改安装路径,其余的都是选择 下一步傻瓜是安装 安装成功后如下 命令测试 node -v 查看node的版本 n…

Redis 2023面试5题(二)

一、Redis key没设置过期时间却被redis主动删除了 如果一个 Redis 键没有设置过期时间&#xff0c;那么 Redis 无法判断该键是否应该自动删除。因此&#xff0c;如果一个没有设置过期时间的键被 Redis 主动删除了&#xff0c;可能是以下原因之一&#xff1a; 内存不足&#x…