C语言操作符(上)

操作符

  • 一,操作符的分类
    • 1,算数操作符
    • 2,赋值操作符
    • 3,逻辑操作符
    • 4,条件操作符
    • 4,单目操作符
    • 5,函数调用和下表访问操作符
  • 二,原码反码补码
  • 三,移位操作符
    • 1,左移操作符
    • 2,右移操作符
  • 四,位操作符
    • 1,&按位与的妙用
    • 2,|按位或的妙用

一,操作符的分类

C语言中提供的操作符有一下这么几种:
• 算术操作符: + 、- 、* 、/ 、%
• 移位操作符: << >>
• 位操作符: & | ^
• 赋值操作符: = 、+= 、 -= 、 = 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
• 单⽬操作符: !、++、–、&、
、+、-、~ 、sizeof、(类型)
• 关系操作符: > 、>= 、< 、<= 、 == 、 !=
• 逻辑操作符: && 、||
• 条件操作符: ? :
• 逗号表达式: ,
• 下标引⽤: []
• 函数调⽤: ()
• 结构成员访问: . 、->
看到这些操作符相信有一些是你已经见过并熟练掌握的,但还有一些涉及到位运算的操作符你可能是初次见到。像移位操作符,逗号表达式,位操作符等,本篇文章重点来讲述涉及到位的操作符。
我们先来花小部分篇幅来讲算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单⽬操作符。

1,算数操作符

算术操作符有这几种分别为: + 、- 、* 、/ 、%唯一需要注意的就是取模运算,计算结果得到的是余数。
通过重复除10模10(/10%10)这两个算数运算符可以获得一个多位数的每一位!

2,赋值操作符

赋值操作符有以下几种分别为:= 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^= 。这种写法其实是n=n+m简写成n+=m的写法。赋值运算符要和关系运算符分开,很多初学者搞不清一个等号和两个等号。
一个等号 = -> 赋值
两个等号 ==-> 判断相等

其中包含的<<,>>,&,^是稍后要介绍的设计位的操作符。

3,逻辑操作符

逻辑操作符有两种: && 、||。&&叫逻辑与 ||叫逻辑或
逻辑操作符主要关心的是布尔值,布尔值True表示真,False表示假,而计算机是二进制只有0和1来表示所以1表示真,0表示假。
所以逻辑操作符在运算的时候有几种情况: 0&&0为0 1&&0为0 1||0为1 0||0为0
在学逻辑操作符还要记住一句话,逻辑与有假为假,逻辑或有真为真,非零即真。

4,条件操作符

条件操作符主要为: ? : 。这个操作符具体形式为:表达式?结果一:结果二。
举个简单的例子:

int main()
{int a = 3;int b = 5;int c = 0;c = a > b ? a : b;printf("%d", c);printf("\n");return 0;
}

在这里插入图片描述
从运行结果来看得到的值为5,那为什么是5呢/我们来分析一下代码:
a>b?a:b 从左到右?意思是表达式左边的值为真吗?也就是a是大于b的吗?如果大于结果为a,再将a赋值给c,如果小于,结果为b,再将b赋值给a。
总结:
所以 表达式?结果一:结果二表达式为真,执行结果一;表达式为假,执行结果二。

4,单目操作符

单⽬操作符有以下几种: !、++、–、&、*、+、-、~ 、sizeof、(类型)。其中也有一些位操作符,我们稍后介绍。还有一些像自增,自减已经在之前就介绍过。其中比较重要的就是sizeof和~取反操作。

1. sizeof是用来计算类型大小的,比如sizeof(int/short/long/double)。sizeof也经常用来计算数组元素的个数。
**2. ~取反操作,就是将以二进制形式存储的数据进行取反操作。**这点等介绍完了原码反码补码之后你就会明白了。
3,还要注意的是如果sizeof里面有表达式是不参与计算的,因为sizeof在编译阶段就直接返回类型的大小了,比如int类型大小为4。而表达式计算是在运行时才计算的。

5,函数调用和下表访问操作符

函数调用和下标访问操作符在之前的文章有讲到过,可以参考之前的文章。
传送门函数:函数
传送门数组:数组

二,原码反码补码

在介绍设计位操作符之前我门先要了解数据在计算机的存储形式,上一篇文章我们详细介绍了进制转换,有了进制转换的知识就为我们下面的学习打下了基础。如果还不了解进制转换可以去看上一篇文章:传送门。

在上一篇文章中我们介绍了计算机的底层实际上就是电路,而电路只有高电平和低电平两种状态这就与二进制相似只有0和1这两种状态。这时可能有人问计算机是怎么存储数据的呢?比如在我们写代码的时候我们通常会定义一个变量然后给它赋值,那这个值是怎样存储的呢?

首先来介绍一下什么是原码,反码,补码:

1. 原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
2. 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
3. 补码:反码+1就得到补码。

整数的2进制表示方法有三种,即原码、反码和补码 有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号 位,剩余的都是数值位。 符号位都是⽤0表⽰“正”,⽤1表⽰“负”。一个整型数是占4个字节 一个字节占8比特位 所以是由32位二进制来构成 举个例子:
在这里插入图片描述
而整数又分为有符号整数和无符号整数这两种,而有符号数又分为正整数和负整数这两种。在这里插入图片描述

  • 正整数的原、反、补码都相同。
  • 负整数的三种表方法各不相同。
  • 负整数取反加一为补码 补码取反加一为原码。
    我们来看一个简单的运算:
#include<stdio.h>
int main()
{int a = 10;int b = -5;//10的原码00000000000000000000000000001010//因为10为整数 原码=反码=补码//-5的原码10000000000000000000000000000101//-5的反码11111111111111111111111111111010//-5的补码11111111111111111111111111111011int c=a+b;//a+b 是补码运算//10的补码       00000000000000000000000000001010//-5的补码       11111111111111111111111111111011//相加之后的补码:100000000000000000000000000000101 最左边多出的一位将丢弃掉所以符号位为0是正整数 原反补都相同,直接读出101对应的值是5printf("%d",c);return 0;
}

在这里插入图片描述
由此我们可以总结:
在这里插入图片描述
但是数据存放内存中其实存放的是补码这是为什么呢?

在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使⽤补码,可以将符号位和数值域统⼀ 处理;同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算 过程是相同的,不需要额外的硬件电路。

三,移位操作符

1,左移操作符

移位规则:左边抛弃、右边补0;来看一段代码:

#include<stdio.h>
int main()
{int num=10;int m = num<<1;printf("num = %d",num);printf("m = %d",m);return 0;
}

在这里插入图片描述
从结果上看不知各位读者看出来了吗就是左移是不会改变原来的值。我们给出具体分析
在这里插入图片描述

2,右移操作符

移位规则:⾸先右移运算分两种:

  1. 逻辑右移:左边⽤0填充,右边丢弃
  2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
    一般情况下都是算数右移动。下面来看代码;
#include <stdio.h> int main() { int num = 10; int n = num>>1; printf("n= %d\n", n); printf("num= %d\n", num); return 0; } 
//逻辑右移1位演⽰ 算术右移1位演⽰ 
//警告:对于移位运算符,不要移动负数位,
//这个是标准未//定义的。 例如:1 int num = 10;

我们分别给出逻辑右移和算数右移:
逻辑右移
算数右移
总结:
移位操作符操作数只能是整数!不能是其它的数!

四,位操作符

位操作符有三种分别是: &(按位与) |(按位或) ^(按位异或)~(按位取反)。其中按位的位指的是二进制位。举个例子;

#include<stdio.h>
int main()
{int a = -3;int b = 6;int x = 0;int y = 0;int r = 0;int c = 0;x = a & b;y = a|b;r = a^b;c = ~a;printf("a&b = %d\n",x);printf("a|b = %d\n",y);printf("a^b = %d\n",r);printf("~a = %d\n",c);return 0;
}

在这里插入图片描述

紧接着我们来分析为什么是这个结果。大家请看图

在这里插入图片描述

在这里插入图片描述
通过图片已经能非常直观的能看清楚每一步的运算过程了。但有一点要注意就是按位操作符他们的操作数必须是整数。

学习完上面的知识后我们来看一道比较变态的面试题,题目是不创建第三变量怎样实现两个数的交换。这里我们不卖关子直接给出代码然后分析:

#include<stdio.h>
int main()
{int a = 3;int b = 6;printf("交换前a=%d b=%d\n",a,b);a = a ^ b;b = a ^ b;a = a ^ b;printf("交换后a=%d b=%d",a,b);return 0;
}

在这里插入图片描述
是不是很神奇,那为什么这样就能直接交换了呢?我们给出相应的图解;
在这里插入图片描述
紧接着我们扩展学习一些按位操作符的妙用。

1,&按位与的妙用

我们用一道编程题来举例,求⼀个整数存储在内存中的⼆进制中1的个数。(一下都以这道题为例)我们直接给出代码:

#include<stdio.h>
int main()
{int n = 0;scanf("%d",&n);int count = 0;while(n){if(n%2==1){count++;}n=n/2;}printf("count=%d",count);return 0;
}

在这里插入图片描述
在这里插入图片描述

15的二进制序列为00000000000000000000000000001111 写出其补码后发现有4个一这与结果是吻合的,但当我们输入负一结果就不对了显然这种方法有缺陷。我们给出改进方法:

#include<stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;for (int i = 0;i < 32;i++){if (n&1==1){count++;}n = n >> i;}printf("count=%d", count);return 0;
}

在这里插入图片描述

这时候我们来看就会发现已经得到我们想要的结果了,按位与是不是非常的神奇呢我们来分析一下原理。
在这里插入图片描述
还有一个更加巧妙的方法,我们直接给出代码让你体会体会这种巧妙:

#include<stdio.h>
int main()
{int num = 0;scanf("%d", &num);int count = 0;while (num){num = num & (num - 1);count++;}printf("count=%d\n", count);return 0;
}

在这里插入图片描述
这段代码明显又要比上面的代码更加高效了,上面无论怎样都要执行32次循环,而下面这段代码有几个1就循环几次效率大幅提升。那为什么是这样呢?我们画个图分析一下;
在这里插入图片描述

2,|按位或的妙用

先来看一道题目,将13二进制序列的第5位修改为1,然后再改回0;
先画个图分析:
在这里插入图片描述
我们给出代码:

#include<stdio.h>
int main()
{int m = 13;int n = 5;m = m|(1 << (n - 1));printf("%d", m);return 0;
}

在这里插入图片描述
这里如果为什么变成了29还不知道的话那就要去看一下我之前的文章进制转换啦传送门:
那怎么换回来呢?其实也简单,我们画图来分析:

在这里插入图片描述
我们给出代码:

#include<stdio.h>
int main()
{int m = 13;int n = 5;m = m|(1 << (n - 1));printf("%d", m);m=m&~(1 << (n - 1));printf("%d",m);return 0;
}

在这里插入图片描述

由于文章篇幅有限以上就是本篇文章的所有内容啦,还有些内容将在下期发布敬请期待!

文章有点长感谢能够看到这里的读者,给你们点赞!如果这篇文章能够帮到你,制作不易还请各位读者给一个三连!你们的支持就是我最大的动力!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)

流域综合处理 流域综合治理是根据流域自然和社会经济状况及区域国民经济发展的要求,以流域水流失治理为中心,以提高生态经济效益和社会经济持续发展为目标,以基本农田优化结构和高效利用及植被建设为重点,建立具有水土保持兼高效生态经济功能的半山区流域综合治理模式。数字高程…

k8s的CICD实施项目

环境需求&#xff1a; 目前领导需要做一个需求&#xff0c;临时把我从运维岗位&#xff0c;把我调度到到专家组让我主导cicd的项目实施 目前环境资源 k8s环境&#xff0c;28台服务器&#xff0c;上面是k8s集群&#xff0c;要实施一个测试环境的cicd以及一个生产环境的cicd gitl…

OpenEuler学习笔记(四):OpenEuler与CentOS的区别在那里?

OpenEuler与CentOS的对比 一、基本信息 起源与背景&#xff1a; OpenEuler&#xff1a;由华为发起&#xff0c;后捐赠给开放原子开源基金会&#xff0c;旨在构建一个开放、多元化的云计算和边缘计算平台&#xff0c;以满足华为及其他企业的硬件和软件需求。CentOS&#xff1a;…

全面解析计算机网络:从局域网基础到以太网交换机!!!

一、局域网的基本概念和体系结构 特点: 覆盖较小的地理范围较低的时延和误码率局域网内的各节点之间以“帧"为单位进行传输支持单播、广播、多播 单播(一对一发送帧)&#xff1a;如 A->B广播(一对全部发送帧)&#xff1a;如 A->BCDEFG多播(一对部分发送帧)&#xff…

实战经验:使用 Python 的 PyPDF 进行 PDF 操作

文章目录 1. 为什么选择 PyPDF&#xff1f;2. 安装 PyPDF3. PDF 文件的合并与拆分3.1 合并 PDF 文件3.2 拆分 PDF 文件 4. 提取 PDF 文本5. 修改 PDF 元信息6. PDF 加密与解密6.1 加密 PDF6.2 解密 PDF 7. 页面旋转与裁剪7.1 旋转页面7.2 裁剪页面 8. 实战经验总结 PDF 是一种非…

不重启JVM,替换掉已经加载的类

不重启JVM&#xff0c;替换掉已经加载的类 直接操作字节码 使用ASM框架直接操作class文件&#xff0c;在类中修改代码&#xff0c;然后retransform就可以了 下边是BTrace官方提供的一个简单例子&#xff1a; package com.sun.btrace.samples;import com.sun.btrace.annotati…

Android系统开发(十五):从 60Hz 到 120Hz,多刷新率进化简史

引言 欢迎来到“帧率探索实验室”&#xff01;今天&#xff0c;我们要聊聊 Android 11 中对多种刷新率设备的支持。你可能会问&#xff1a;“这和我写代码有什么关系&#xff1f;”别急&#xff0c;高刷新率不仅仅让屏幕更顺滑&#xff0c;还会直接影响用户体验。想象一下&…

Genetic Prompt Search via Exploiting Language Model Probabilities

题目 利用语言模型概率的遗传提示搜索 论文地址&#xff1a;https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址&#xff1a;https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力&#xff0c;尤其是在诸如fewshot学习…

css动画水球图

由于echarts水球图动画会导致ios卡顿&#xff0c;所以纯css模拟 展示效果 组件 <template><div class"water-box"><div class"water"><div class"progress" :style"{ --newProgress: newProgress % }"><…

接口 V2 完善:基于责任链模式、Canal 监听 Binlog 实现数据库、缓存的库存最终一致性

&#x1f3af; 本文介绍了一种使用Canal监听MySQL Binlog实现数据库与缓存最终一致性的方案。文章首先讲解了如何修改Canal配置以适应订单表和时间段表的变化&#xff0c;然后详细描述了通过责任链模式优化消息处理逻辑的方法&#xff0c;确保能够灵活应对不同数据表的更新需求…

postgresql15的停止

PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统&#xff0c;且因为许可证的灵活&#xff0c;任何人都可以以任何目的免费使用、修改和分发PostgreSQL。介绍过postgresql的启动方法&#xff0c;就很有必要介绍下postgresql的停止方法。 一、停止…

IP协议格式

在传输层中有两个重要的协议&#xff0c;分别为UDP和TCP。UDP追求高效的效率&#xff0c;TCP追求更可靠的传输。但是这两个协议都太极端了&#xff0c;有没有一个协议可以在保证可靠性的同时又不失较高的效率。 针对上面的问题&#xff0c;网络层的IP协议是更好的解决方案。 …

Qt Creator 15.0.0如何更换主题和字体

1.打开Qt Creator 15.0.0 (Community)&#xff0c; 2.点击编辑栏3.点击Preferences... 4.修改主题&#xff0c;点击环境&#xff0c;修改Theme:栏 5.修改字体大小&#xff0c;点击文本编辑器&#xff0c;修改字号栏。&#xff0c;修改Theme:栏

靶机复现-pikachu靶机文件包含漏洞

本篇文章旨在为网络安全渗透测试靶机复现学习。通过阅读本文&#xff0c;读者将能够对渗透pikachu靶场文件包含漏洞复现有一定的了解 原文学习链接 CSDN博主&#xff1a;One_Blanks主页地址 靶机资源下载 PHPStudy pikachu 一、前言 文件包含漏洞是编程中的一种安全隐患&a…

机器学习-线性回归(简单回归、多元回归)

这一篇文章&#xff0c;我们主要来理解一下&#xff0c;什么是线性回归中的简单回归和多元回归&#xff0c;顺便掌握一下特征向量的概念。 一、简单回归 简单回归是线性回归的一种最基本形式&#xff0c;它用于研究**一个自变量&#xff08;输入&#xff09;与一个因变量&…

5.SQLAlchemy对两张有关联关系表查询

问题 例如&#xff0c;一个用户可以有多个收获地址。 定义表如下&#xff1a; 用户表 地址表 一般情况&#xff0c;我们会先查询用户表&#xff0c;拿到用户id后&#xff0c;再到地址表中查询关联的地址数据。这样就要执行两次查询。 仅仅为了方便查询&#xff0c;需要一些属…

【Unity】ScrollViewContent适配问题(Contentsizefilter不刷新、ContentSizeFilter失效问题)

最近做了一个项目&#xff0c;菜单栏读取数据后自动生成&#xff0c;结果用到了双重布局 父物体 尝试了很多方式&#xff0c;也看过很多大佬的文章&#xff0c;后来自己琢磨了一下&#xff0c;当子物体组件自动生成之后&#xff0c;使用以下以下代码效果会好一些&#xff1a; …

springboot基于微信小程序的商城系统

基于Spring Boot的微信小程序商城系统是一种现代化的电商解决方案&#xff0c;它将Spring Boot框架的强大后端能力与微信小程序的便捷前端体验相结合&#xff0c;为商家和用户提供了高效、稳定的在线购物平台。 一、后端框架 &#xff1a;Spring Boot 1. 简介&#xff1a; 2.…

63,【3】buuctf web Upload-Labs-Linux 1

进入靶场 点击pass1 查看提示 既然是上传文件&#xff0c;先构造一句话木马&#xff0c;便于用蚁剑连接 <?php eval($_POST[123])?> 上传木马 文件后缀写为.php.jpg 右键复制图片地址 打开蚁剑连接 先点击测试连接&#xff0c;显示成功后&#xff0c;再点击添加即可 …

【玩转全栈】----基于ModelForm完成用户管理页面

目录 大致效果 添加用户代码 引入ModelForm ModelForm 与一般表单的区别&#xff1a; ModelForm 与传统 Form 的区别&#xff1a; 使用ModelForm制作用户管理 新建用户 编辑用户&#xff1a; 删除数据 完整代码 在学完前面的部门管理案例后&#xff0c;自己独立写出个用户管理应…