【C语言】操作符大全(保姆级介绍)
🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:C语言
🔥该篇将详细介绍各种操作符的功能。
目录:
- 📘 前言
- ① 算术操作符
- ②移位操作符
- ③位操作符
- ④赋值操作符
- ⑤单目操作符
- ⑥关系操作符
- ⑦逻辑操作符
- ⑧ 条件操作符
- ⑨ 逗号表达式
- ⑩ 下标引用、函数调用和结构成员
- ❤️ 结语
📘 前言
操作符是编程中表示操作的符号或符号组合。它们用于执行算术、逻辑、比较和其他操作。
操作符可以分为这几类:算术操作符;移位操作符;位操作符;赋值操作符;单目操作符;关系操作符;逻辑操作符;条件操作符;逗号表达式;下标引用、函数调用和结构成员。下面将会一 一介绍这些操作符。
① 算术操作符
+ - * / %
📘前面的 + - * 就和数学的逻辑一样,都可以作用于整数和浮点数。
📘 / 计算后的结果是商。并且有两种除法,一个是整数除法,一个是浮点数除法。
- 整数除法 : 假如是 5 / 2 , 两个整数相除,会得到一个整数,即它的商,得到的结果自然就是 2 .
- 浮点数除法: 如果想让 5 /2的结果为 2.5 ,就必须执行浮点数除法,需要保证除数和被除数至少有一个是浮点数 。
例如 : 5.0 / 2 ; 5 / 2.0 ; 5.0 / 2.0
在运用除法时,除数不可以为0。例如: int n = 0;int ret = 6 / n;
。
📘% 被称为取模操作符,也就是算余数。但是需要注意的是,它的操作数只能是整数,不可以是浮点数。 例如:可以 5%2,但是不可以 5% 2.0 。
②移位操作符
>>(右移) <<(左移)
注意:移位操作符的操作数只能是整数。
在计算机中,计算机能够处理的是二进制信息,即由0和1组成的序列,这里的移位操作其实就是在移动二进制。在计算机中将一个十进制的数字转化为二进制,会出现3种不同的表现形式:原码,反码,补码。
注意:
正整数的原码,反码,补码是相同的。
负整数的原码,反码,补码不同,需要计算得到。
- 📙原码:根据正负,将整数直接写成的二进制序列。
例如:15 (十进制)它的二进制其实就是 1111。
但是,15的默认类型为 int ,int 类型是4个字节,即32个bit,一个二进制位占1个bit,所以我们需要向前补充0。需要注意这里规定了最高位是符号位:0表示正,1表示负数。
例如:
-
📙反码:
正整数的原码,反码,补码都相同。
负整数的反码:原码的符号位不变,其它位按位取反(1变为0,0变为1)。 -
📙补码:
正整数的原码,反码,补码都相同。
负整数的补码:反码+1。
例如:
1.整数在内存中存储的是补码。
2.计算的时候是使用补码来计算的。
所以这里移动的就是二进制的补码。
右移分为两种:
- 算术右移:右边丢弃,左边补原来的符号位。
- 逻辑右移:右边丢弃,左边直接补0。
📙 C语言没有明确规定使用哪种右移方式,但是一般编译器(例如:VS)上采用的是算术右移。
使用例子:
因为原码是根据正负直接写出的二进制序列,所以打印的时候是需要原码的。
a = -15
的例子:
a = 15
的例子:
左移只有一种:左边丢弃,右边补0。
使用例子:
说明:
📙根据这些例子,我们可以发现一些信息:
- 右移的操作,可以看成一个数据除以2后,再向下取整。
- 左移的操作,可以看成一个数据乘2。
⚠警告:
1.对于移位运算符,不要移动负数位,这个是标准未定义行为,例如:a>>-1
,这种表达式的结果是不可预料的,甚至不同的编译器处理的行为都是不一样的。
2.需要在合法范围内移位。
3.移位操作不会改变自身的值,例如a>>1
,a本身的值不会改变。
③位操作符
这里操作的也是二进制补码。
& ^ |
注意:操作数必须为整数
- 📙&按位与
规则:对应二进制位有0则为0,两个同时为1才为1。
例子:
说明:
- 📙| 按位或
规则:对应的二进制位有1则为1,两个同时为0才是0。
例子:
说明:
- 📙^ 按位异或
规则:对应的二进制位相同为0,相异为1。
例子:
说明:
📙 ^ 按位异或 拥有一些特性:
1.一个变量 异或本身得到的值是0。例如:a ^ a
结果为0。
2.一个变量 异或0 得到的值是变量本身的值。例如:int a = 5; printf("%d", a ^ 0);
得到的值是 5 。
3.按位异或满足交换律,a^ a^ b
与a^ b^ a
得到的值是一样的。
通过这些特性,我们可以完成不创建临时变量(第三个变量),实现两个整数的交换。
#include<stdio.h>
int main()
{int a = 2;int b = 4;printf("交换前:a = %d b = %d\n", a, b);//交换a = a ^ b;b = a ^ b;a = a ^ b;//printf("交换后:a = %d b = %d\n", a, b);return 0;
}
④赋值操作符
= += -= *= /= &= ^= |= >>= <<=
- = 即为赋值,例如:将 0 赋值给 a ,
a = 0;
. - 赋值操作符可以连续使用。
int a = 0;int x = 1;int y = 2;a = x = y + 1;//从右至左连续赋值
虽然这种方式语法是允许的,但是分开写更加清晰,更易于调试。
int a = 0;int x = 1;int y = 2;x = y + 1;a = x;
- += 这种赋值是复合赋值,
a = a + 1;
和a+=1;
意思是一样的。像-= ,*= 等,其实都是类似的。
⑤单目操作符
只有一个操作数
! - + & sizeof ~ – ++ * (类型)
单目操作符 | |
---|---|
! | 逻辑反操作 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度 |
~ | 对一个数的二进制取反 |
- - | 前置或后置- - |
++ | 前置或后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制转换类型 |
c语言中,0为假,非0为真。
- 📙! (逻辑反操作)
- 可以逻辑反操作,将真变为假,将假变为真。例如:!0 —— 为真 ,结果是1,!2 —— 结果是假 ,为0。
if (flag == 0)
和if (!flag)
意思是相同的。if (flag != 0)
和if (flag)
的意思是相同的。
-
📙 – (负值) 和 +(正值)
–(负值)可以得到一个变量的负值,例如:int a = 3;int b = -a;
,这样b就被赋值为-3 。 -
📙&(取地址)和 *(间接访问操作符)
这两个操作符主要应用于指针。
#include<stdio.h>
int main()
{int a = 10;//pa是指针变量//&-取地址操作符-取出a的地址int* pa = &a;//这里的 * 是指针类型的一部分,不是操作符//*—解引用操作符(间接访问操作符)-通过pa中存放的地址,找到指向的空间(内容)*pa = 20;//找到空间int c = *pa;//找到内容return 0;
}
- 📙sizeof(操作数的类型长度)
sizeof是一个操作符,可以计算变量的大小,例如sizeof(int)
或者sizeof(a)
,对于这种里面是类型的,相当于计算该类型创建的变量的大小,注意:计算变量的时候,()可以去掉,例如sizeof a
,这也正好说明了sizeof是一个操作符,而不是函数(函数的()是不可以省略的),但是括号里面是类型的话,是不可以的省略的sizeof int;//错误
。 - 📙 ~ (对一个数的二进制补码取反)
使用 ~ 可以让二进制补码的 1变成0 ,0变为1 。
例如:
#include<stdio.h>
int main()
{int a = -1;//a的补码为:11111111 11111111 11111111 11111111int b = ~a;//b的补码为:00000000 00000000 00000000 00000000return 0;
}
一些应用:
15 的补码是00000000 00000000 00000000 00001111 , 如何让倒数第5个二进制位变成1 ?变化之后又如何变回原来的值?
#include<stdio.h>
int main()
{int a = 15;//00000000 00000000 00000000 00001111 //与00000000 00000000 00000000 00010000 按位或 就可以完成第一个问题a |= (1 << 4);printf("%d\n", a);//31//00000000 00000000 00000000 00011111 //与11111111 11111111 11111111 11101111 按位与 就可以完成第二个问题a&= ~(1 << 4);printf("%d\n", a);//15return 0;
}
实现多组输入
scanf 读取失败返回的是 EOF(end of file) ,本质是 -1 。又因为~- 1
得到的值是 0,然后将这个特点写在while循环中,就可以实现。
#include<stdio.h>
int main()
{int n = 0;//假设读取失败,就会返回EOF(-1),~ -1 就是0,就会停止循环。while (~scanf("%d", &n)){//一系列操作}return 0;
}
- ++ 和 – (前置 或 后置)
后置++,是先使用,后++,前置++,是先++,后使用 。后置++是在表达式结束后才++,前置++是即刻生效的,遇到就得先++。
例如:int a = 0;int b = a++;
相当于,b = a, a = a + 1,int a = 0;int b = ++a
相当于,a = a + 1, b = a 。-- 的逻辑也是这样的。
- (类型)——(强制转换类型)
例如:int a = (int)2.5;//结果为2
这里把 2.5 (double 类型) 强制转化为 int类型。需要注意,强制转换可能导致数据丢失,所以最好类型匹配。
⑥关系操作符
> >= < <= != ==
这些是用来判断大小关系的。
其中 >= 为 大于等于 ; <= 为 小于等于; == 用于判断相等 ;!= 用于判断不等。这些判断也只能应用于适合的类型上。
⑦逻辑操作符
&& ||
&& 为 逻辑与(并且) ,|| 为逻辑或(或者)。
注意:
逻辑操作符 && 和 || 包括 ! ,只关注真假,假用0表示,真用1表示。int a = 3 && 5;
a 的结果为 1 。
特点:
- 对于&&,左边为假,右边就不计算。
- 对于| | ,左边为真,右边就不计算。
例子:
#include <stdio.h>
int main()
{int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++ && ++b && d++;printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//1 2 3 4return 0;
}
#include <stdio.h>
int main()
{int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++||++b||d++;printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//1 3 3 4return 0;
}
⑧ 条件操作符
exp1 ? exp2 :exp3
c语言中唯一的一个三目操作符(有三个操作数)。
例如:比较一个大小
int max = (firstNum > secondNum ? firstNum : secondNum);
📘这个操作符的效果类似于 if else 的效果,不建议将这个操作符运用的很复杂,这样会影响可读性。
⑨ 逗号表达式
exp1, exp2, exp3, … expN
其实就是用逗号隔开的表达式。
从左向右依次计算,逗号表达式的结果就是最后一个表达式的结果。
例:
// 例1:int a = 1;int b = 2;int c = (a+=1,b+=2,b-a); //2
//例2:int a = 2;int b = 0;if (a--,b += 2, a > 0)//逗号表达式{//处理}
一些代码也可以改写为逗号表达式。
将:
//这个代码有点冗余a = get_val();count_val(a);while (a > 0){ //业务处理a = get_val();count_val(a);}
改写为:
while (a = get_val(), count_val(a), a>0)
{//业务处理
}
不仅代码的逻辑一样,而且还处理了代码冗余的问题。
⑩ 下标引用、函数调用和结构成员
[ ] () . ->
- 📙 [ ] (下标引用)
操作数:一个数组名 + 一个索引值
例如,arr[5]
两个操作数分别为 arr 和 5 。
- 📙( ) (函数调用)
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数(对于函数调用操作符来说,最少有1个操作数 )。
例如:ADD(3,2)
操作数有3个,一个是ADD,一个是参数 3 ,一个是参数 2 。test()
操作数有1个,只有 test。
注意:
- 📙 . 和 -> (用于访问结构成员)
两个操作数的使用方式 :
. 结构体变量.成员名
-> 结构体指针->成员名
例如:
struct Person
{char name[20];int age;
};
int main()
{struct Person s = { "张三",20 };printf("姓名:%s,年龄:%d\n", s.name, s.age);// 用 . 访问struct Person* p = &s;printf("姓名:%s,年龄:%d\n", p->name, p->age); //用-> 访问return 0;
}
❤️ 结语
文章到这里就结束了,如果对你有帮助,你的点赞将会是我的最大动力,如果大家有什么问题或者不同的见解,欢迎大家的留言~
相关文章:

【C语言】操作符大全(保姆级介绍)
🚩纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:C语言 🔥该篇将详细介绍各种操作符的功能。 目录: 📘 前言① 算术操作符②移位操作符③位操作符④赋值操…...

ruoyi-cloud部署
默认你已经安装mysql,nacos,seata,sentinel等(没有的可以先找教程安装) 1、下载源码:git clone https://gitee.com/zhangmrit/ruoyi-cloud 2、项目依赖导入,选择自己的maven环境等,创…...

Vue3(开发h5适配)
在开发移动端的时候需要适配各种机型,有大的,有小的,我们需要一套代码,在不同的分辨率适应各种机型。 因此我们需要设置meta标签 <meta name"viewport" content"widthdevice-width, initial-scale1.0">…...

图的存储:邻接矩阵法
1.邻接矩阵的实现 邻接矩阵的定义:在无向图和有向图中,使用二维数组表示各个顶点的相邻情况:1代表相邻,0表示不相邻。 代码实现: #define MaxVertexNum 100//顶点数目的最大值 typedef struct {char Vex [MaxVertexN…...

如何优雅的使用Git?
第一部分:Git的基本概念和初始设置 Git是一个分布式版本控制系统,它允许多人共同工作,同时跟踪和管理项目的版本历史。使用Git,您可以恢复旧版本、创建新分支进行实验,并与其他开发者进行协作,而不会影响主…...

【【STM32分析IO该设置什么模式的问题】】
STM32分析IO该设置什么模式的问题 我们分析而言 我们对于PA0 的设计就从此而来 对于边沿触发的选择我们已经有所了解了 我们下拉,但是当我们摁下开关的时候 从0到1 导通了 所以这个是下拉 上升沿触发 而对于KEY0 我们摁下是使得电路从原来悬空高阻态到地就是0 所以…...

飞天使-k8s基础组件分析-服务与ingress
文章目录 服务的介绍服务代理服务发现连接集群外服务服务发布无头服务 服务,pod和dns的关系端口转发通过expose 暴露应用服务案例INGRESSMetalLB使用参考文档 服务的介绍 服务的作用是啥? 提供外部调用,保证podip的真实性看看服务解决了什么…...

Unity——拖尾特效
拖尾是一种很酷的特效。拖尾的原理来自人类的视觉残留:观察快速移动的明亮物体,会看到物体移动的轨迹。摄像机通过调整快门时间,也可以拍出具有拖尾效果的照片,如在城市的夜景中,汽车的尾灯拖曳出红色的线条。 在较老…...

java开发之fastjson
依赖 <!-- fastjson依赖 --> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> <…...

第一个C语言程序:HelloWorld
第一个C语言程序 注释 注释 对代码的解释和说明 特点 ○ 不会被执行 目的 让人们能够更加轻松地看懂代码 分类 行注释 // 快键键 ctrl/ 块注释 /**/ 快捷键 shiftalta 示例代码: #include <stdio.h>int main() {// 行注释/*块注释*/printf("hello w…...

golang 使用 viper 加载配置文件 自动反序列化到结构
文章博客地址:golang 使用 viper 加载配置 自动反序列化到结构 golang使用 viper 无需设置 mapstructure tag 根据配置文件后缀 自动返序列化到结构解决结构有下划线的字段解析不成功问题 viper 正常加载配置文件 golang viper 其中可以用来 查找、加载和反序列化JSON、TOML…...

C#设计模式六大原则之--接口隔离原则
设计模式六大原则是单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则。它们不是要我们刻板的遵守,而是根据实际需要灵活运用。只要对它们的遵守程度在一个合理的范围内,努为做到一个良好的设计。本文主要介绍一下.NET(C#)…...

【面试题】:axios二次封装都进行了哪些配置以及如果项目里面有两个baseURL你怎么解决?
一.axios的概念 Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 二.axios的特点…...

谈谈对 GMP 的简单认识
犹记得最开始学习 golang 的时候,大佬们分享 GMP 模型的时候,总感觉云里雾里,听了半天,并没有一个很清晰的概念,不知 xmd 是否会有这样的体会 虽然 golang 入门很简单,但是对于理解 golang 的设计思想和原…...

Java正则表达式系列--从字符串中提取字符串或数字
原文网址:Java正则表达式系列--从字符串中提取字符串或数字_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍Java如何使用正则表达式从字符串中提取想要的内容(字符串或者数字等)。 例1:提取一次不同内容 需求 从字符串中找到…...

机器学习实战之模型的解释性:Scikit-Learn的SHAP和LIME库
概要 机器学习模型的“黑箱”困境 机器学习模型的崛起让我们惊叹不已!不论是预测房价、识别图片中的猫狗,还是推荐给你喜欢的音乐,这些模型都表现得非常出色。但是,有没有想过,这些模型到底是如何做出这些决策的呢&a…...

Go 语言进阶与依赖管理 | 青训营
Powered by:NEFU AB-IN 文章目录 Go 语言进阶与依赖管理 | 青训营 语言进阶依赖管理测试 Go 语言进阶与依赖管理 | 青训营 GO语言工程实践课后作业:实现思路、代码以及路径记录 语言进阶 Go可以充分发挥多核优势,高效运行 Goroutine是Go语言中的协程…...

hyperf 十三 视图
教程:Hyperf composer地址:hyperf/view - Packagist 本次测试使用twig twig composedr地址:twig/twig - Packagist twig 文档地址:Home - Twig - The flexible, fast, and secure PHP template engine 一、安装 composer re…...

请你说说前端图形图像的框架
前端图形图像方面有许多强大的框架和库,使得开发者能够更容易地创建丰富的视觉效果和复杂的图形应用。下面列举了一些主要的框架和库: 1. Three.js Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了…...

C++数据结构学习——栈
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、栈二、C语言实现1.声明代码2.实现增删查改代码3.测试代码 总结 前言 栈(Stack)是计算机科学中一种常见的数据结构,它是…...

【C++笔记】C++之类与对象(下)
【C笔记】C之类与对象(下) 1、再看构造函数1.1、构造函数的初始化列表1.2、C支持单参数的构造函数的隐式类型转换1.3、匿名对象 2、Static成员2.1、为什么要有静态成员变量?2.2、一个类的静态成员变量属于这个类的所有对象2.3、静态成员函数 3、友元3.1、…...

管理类联考——英语——实战篇——大作文——图表——动态图表——整体效果
动态图表模板 What is clearly presented in the above 图表类型 is that dramatic changes have taken place in 主题词1 from 年份1 to 年份2.During the period, there was a marked jump from 数字1 to 数字2 in 事物1,while that of 事物2 declined significantly from 数…...

threejs纹理加载三(视频加载)
threejs中除了能把图片作为纹理进行几何体贴图以外,还可以把视频作为纹理进行贴图设置。纹理的类型有很多,我们可以用不同的加载器来加载,而对于视频作为纹理,我们需要用到今天的主角:VideoTexture。我们先看效果&…...

VUE笔记(三)vue的语法
一、计算属性 1、计算属性的概念 计算属性是依赖于源数据(data或者属性中的数据),在元数据的基础上进行逻辑运算后得到的新的数据,计算属性要依赖于源数据,源数据数据变化计算属性也会变化 2、计算属性的语法 在vue2中使用computed这个选…...

探讨uniapp的路由与页面生命周期问题
1 首先我们引入页面路由 2 页面生命周期函数 onLoad() {console.log(页面加载)},onShow() {console.log(页面显示)},onReady(){console.log(页面初次显示)},onHide() {console.log(页面隐藏)},onUnload() {console.log(页面卸载)},onBackPress(){console.log(页面返回)}3 页面…...

咸鱼之王俱乐部网站开发
我的俱乐部 最新兑换码 *注意区分大小写,中间不能有空格! APP666 HAPPY666 QQ888 QQXY888 vip666 VIP666 XY888 app666 bdvip666 douyin666 douyin777 douyin888 happy666 huhushengwei888 taptap666 周活动 宝箱周 宝箱说明 1.木质宝箱开启1个…...

Electron+Vue3+TS 打包exe客户端
Electron Vue3 TS 实战 - 掘金 如果报错loaderContext.getOptions is not a function ts-loader版本不一致导致的问题。 解决方案:npm install ts-loader8.0.0 --save...

vue3范围选择组件封装
个人项目地址: SubTopH前端开发个人站 (自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面) SubTopH前端开发个人站…...

能被整除的数(容斥原理)
思路: (1)需求:求对于1~n中至少能被p1~pm至少1个整除的数的个数,由于都是质数,彼此互质,不需要进行质因子分解,根据容斥原理, res n/p1 n/p2 ... n/pm - n /(p1p2) -…...

Modbus转Profinet网关与流量变送器兼容转ModbusTCP协议博图配置
首先,我们需要明确电磁流量计的通信协议是Modbus,而西门子1200PLC的通信协议是Profinet。这两种协议在功能和特性上存在一定的差异,因此需要使用兴达易控Modbus转Profinet网关设备进行转换。兴达易控的XD-MDPN100是Profinet转ModbusTCP的网关…...