C语言入门篇——操作符篇
目录
1、操作符分类
2、操作符的属性
3、算术操作符
4、移位操作符
5、位操作符
6、赋值操作符
7、单目操作符
8、关系操作符
9、逻辑操作符
10、条件操作符
11、逗号操作符
12、下标引用、函数调用和结构成员
1、操作符分类
算术操作符(+,-,*,/,%)
移位操作符(<<,>>)
位操作符(&,|,^)
赋值操作符(=,+=,-=,/=,*=,%=,<<=,>>=)
单目操作符(!,-,+,&,sizeof,~,--,++,*,(类型))
关系操作符(>,>=,<,<=,!=,==)
逻辑操作符(&&,||)
条件操作符(exp1?exp2:exp3)
逗号表达式(exp1,exp2,exp3,-expN)
下标引用、函数调用和结构成员([],(),->)
2、操作符的属性
复杂表达式的求值有三个影响的因素:
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序
两个相邻的操作符先执行哪一个?取决于它们的优先级。如果两者的优先级相同,取决于它们的结合性
| 操作符 | 描述用 | 用法示例 | 结果类型 | 结合性 | 是否控制求值顺序 |
| () | 聚组 | (表达式) | 与表达式相同 | N/A | 否 |
| () | 函数调用 | rexp(rexp,...,rexp) | rexp | L-R | 否 |
| [] | 下标引用 | rexp[rexp] | lexp | L-R | 否 |
| . | 访问结构成员 | lexp.member_name | lexp | L-R | 否 |
| .> | 访问结构指针成员 | rexp->member_name | lexp | L-R | 否 |
| ++ | 后缀自增 | lexp ++ | rexp | L-R | 否 |
| -- | 后缀自减 | lexp -- | rexp | L-R | 否 |
| ! | 逻辑反 | ! rexp | rexp | R-L | 否 |
| ~ | 按位取反 | ~ rexp | rexp | R-L | 否 |
| + | 单目,表示正值 | + rexp | rexp | R-L | 否 |
| - | 单目,表示负值 | - rexp | rexp | R-L | 否 |
| ++ | 前缀自增 | ++ lexp | rexp | R-L | 否 |
| -- | 前缀自减 | -- lexp | rexp | R-L | 否 |
| * | 间接访问 | * rexp | lexp | R-L | 否 |
| & | 取地址 | & lexp | rexp | R-L | 否 |
| sizeof | 取其长度,以字节 表示 | sizeof rexp sizeof(类型) | rexp | R-L | 否 |
| (类型) | 类型转换 | (类型) rexp | rexp | R-L | 否 |
| * | 乘法 | rexp * rexp | rexp | L-R | 否 |
| / | 除法 | rexp / rexp | rexp | L-R | 否 |
| % | 整数取余 | rexp % rexp | rexp | L-R | 否 |
| + | 加法 | rexp + rexp | rexp | L-R | 否 |
| - | 减法 | rexp - rexp | rexp | L-R | 否 |
| << | 左移位 | rexp << rexp | rexp | L-R | 否 |
| >> | 右移位 | rexp >> rexp | rexp | L-R | 否 |
| > | 大于 | rexp > rexp | rexp | L-R | 否 |
| >= | 大于等于 | rexp >= rexp | rexp | L-R | 否 |
| < | 小于 | rexp < rexp | rexp | L-R | 否 |
| <= | 小于等于 | rexp <= rexp | rexp | L-R | 否 |
| == | 等于 | rexp == rexp | rexp | L-R | 否 |
| != | 不等于 | rexp != rexp | rexp | L-R | 否 |
| & | 位与 | rexp & rexp | rexp | L-R | 否 |
| ^ | 位异或 | rexp ^ rexp | rexp | L-R | 否 |
| | | 位或 | rexp | rexp | rexp | L-R | 否 |
| && | 逻辑与 | rexp && rexp | rexp | L-R | 是 |
| || | 逻辑或 | rexp || rexp | rexp | L-R | 是 |
| ?: | 条件操作符 | rexp ? rexp : rexp | rexp | N/A | 是 |
| = | 赋值 | lexp = rexp | rexp | R-L | 否 |
| += | 以...加 | lexp += rexp | rexp | R-L | 否 |
| -= | 以...减 | lexp -= rexp | rexp | R-L | 否 |
| *= | 以...乘 | lexp *= rexp | rexp | R-L | 否 |
| /= | 以...除 | lexp /= rexp | rexp | R-L | 否 |
| %= | 以...取模 | lexp %= rexp | rexp | R-L | 否 |
| <<= | 以...左移 | lexp <<= rexp | rexp | R-L | 否 |
| >>= | 以...右移 | lexp >>= rexp | rexp | R-L | 否 |
| &= | 以...与 | lexp &= rexp | rexp | R-L | 否 |
| ^= | 以...异或 | lexp ^= rexp | rexp | R-L | 否 |
| |= | 以...或 | lexp |= rexp | rexp | R-L | 否 |
| , | 以...或 | rexp,rexp | rexp | L-R | 是 |
3、算术操作符
算数操作符有+,-,*,/,%
加法运算符用于加法运算,使其两侧的值相加。相加的值(运算对象)可以是变量,也可以是常量
sum = num1 + num2
计算机会查看加法运算符右侧的两个变量,把它们相加,然后把和赋给变量sum
sum,num1,num2都是可修改的左值,每个变量都标识了一个可被赋值的数据对象。
但是表达式num1+num2是一个右值
减法运算符用于减法运算,使其左侧的数减去右侧的数,+和-运算符被称为二元运算符,这些运算符需要两个运算对象才能完成操作。
但+和-也能作为符号运算符,减号可用于标明或改变一个值的代数符号。
a = -100;
b = -a;
以这种形式使用的负号被称为一元运算符,一元运算符只需要一个运算对象,C90标准添加了一元+运算符,它不会改变运算对象的值或符号。
乘法运算符用*号来表示,使其两侧的值相乘。相乘的值(运算对象)可以是变量,也可以是常量
除法运算符用/号来表示,/左侧的值是被除数,右侧的值是除数。有着整数除法和浮点数除法,整数除法和浮点数除法不同。浮点数除法的结果是浮点数,而整数除法的结果是整数。整数是没有小数部分的数。在C语言中,整数除法结果的小数部分被丢弃,在一过程被称为截断。
当/操作符的两个操作符都为整数,执行整数除法;而只要有浮点数执行的就是浮点数除法。
求模运算符用%号来表示,求模运算符用于整数计算。求模运算符给出其左侧整数除以右侧整数的余数。求模运算符的两个操作数必须位整数,返回的是整除之后余数,不能用于浮点数。
4、移位操作符
移位运算符有左移运算符(<<)和右移运算符(>>)。用二进制数做案例。
左移运算符(<<)将其左侧运算对象每一位的值向左移动其右侧运算对象指定的位数。左侧运算对象移出左末尾段位的值丢失,用0填充空出的位置。
(0000 0001)<< 2 //表达式
(0000 0100) //结果值

右移运算符(>>)将左侧运算对象每一位的值向右移动其右侧对象指定的位数。左侧运算对象移出右末端位的值。对于无符号类型,用0填充空出的位置(逻辑移位);对于有符号类型,其结果取决于机器,空出的位置可用0填充,或者用符号位(最左端的位)的副本填充(算术右移)。

移位运算符针对2的幂提供快速有效的乘法和除法:
number << n number乘于2的n次幂
number >> n 如果number为非负,则用number除以2的n次幂
移位运算符还可用于从较大单元中提取一些位
5、位操作符
位运算符有按位取反~,按位与&,按位或|,按位异或^
都是作用于整形数据,包括char。之所以叫位运算符,是因为整型操作都是针对每一个位进行,不影响它左右两边的位。
一元运算符~把1变为0,把0变为1。
~(1001 1010) --- 》 (0110 0101)
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中响应的位都为1时,结果才为1(从真/假方面看,只有当两个位为都为真时,结果才为真)
(1001 0011) & (0011 1101) --- 》 (0001 0001 )
二元运算符|,通过逐位比较两个运算对象,生成一个新值。对于每个 位,如果两个运算对象中相应的位为1,结果就为1(从真/假方面看,如果两个运算对象中相应的一个位为真或两个位都为真,那么结果为真)。
(1001 0011) | (0011 1101) ---》 (1011 1111)
二元运算符^逐位比较两个运算对象。对于每个位,如果两个运算对象 中相应的位一个为1(但不是两个为1),结果为1(从真/假方面看,如果两 个运算对象中相应的一个位为真且不是两个为同为1,那么结果为真)。
(1001 0011) ^ (0011 1101) ---》 (1010 1110)
一道有趣的面试题:不能利用临时变量,如何实现两个数的交换,读者可以想想有哪几种方法?

6、赋值操作符
赋值运算符可以给自己定义的变量重新赋值,例如:
int score = 60;
score = 99;
赋值运算符可以和前面的算术运算符,位运算符,移位运算符组成复合赋值符,这是C语言语法所允许的。
赋值运算符允许连续使用,例如:
a = b = c + 1;
7、单目操作符
单目操作符包括!,~,+,-,&,sizeof,--,++,*,(类型)
这里就不介绍!,~,+,-,前面或后面已经有介绍了,这里主要介绍其他几个。
这里的&可不是按位与&,而是取地址符&,取地址符就是获取当前变量的内存地址,想要获得那个变量的地址,就用&后面跟上那个变量。&后只能跟变量,不能跟常量,因为常量是一个立即数,不是容器,没有地址。

前面就提到过sizeof一嘴,这里再对sizeof进行进一步了解,sizeof运算符以字节为单位返回运算对象的大小(在C中,1字节定义为char类型占用的空间大小。过去,1字节通常是8位,但是一些字符集可能使用更大的字节)。运算对象可 以是具体的数据对象(如,变量名)或类型。如果运算对象是类型(如, float),则必须用圆括号将其括起来。
C 语言规定,sizeof 返回 size_t 类型的值。这是一个无符号整数类型, 但它不是新类型。C有一个 typedef机制(后面再介绍),允许程序员为现有类型创建别名。
++和--,递增运算符和递减运算符,执行简单的任务,将其运算对象递增(减)1,该类运算符以两种形式出现。第1种方式,++出现在其作用的变量前面, 这是前缀模式;第2种方式,++出现在其作用的变量后面,这是后缀模式。 两种模式的区别在于递增行为发生的时间不同。下面用一些例子来仔细地查看两者地区别:

num1后缀递加是原来的值,num2前缀递加是原来的值+1,当我们再次打印num1的值的时候,发现num1的值实际上是加1了,这里就是前缀和后缀的区别了,前缀++先加1再赋值,后缀++先赋值再加1。初学者有可能在这里会陷入混乱。但是提供一个记忆方法:
“前缀++处于前,所以理应先++后赋值;后缀++处于后,所以理应先赋值后++”
前缀加加和后缀加加除了上面的区别,还有着操作符优先级的优先关系,后缀比前缀的优先级要高,这是要牢记的!
间接访问操作符,通过一个指针访问它所指向的地址的过程称为间接访问或解引用指针。这个用于执行间接访问的操作符是单目操作符*。当我们定义了一个指针变量的时候,当我们使用*得到的值就是该指针变量指向地址的变量的值。

在C语言中,类型之间的转换是允许的。而(类型)就是其中一种,被称为强制类型转换。
强制转发语法:
目标类型 变量名 = (目标类型)源变量名
可以把高类型数据转换为低类型数据,虽然有可能存在隐患,但实际上是可以转换的,高数据类型转换为低数据类型会产生丢失
低数据类型到高数据类型排序如下:
char -> short -> int -> long(unsigned char -> unsigned short -> unsigned int -> unsigned long
8、关系操作符
关系操作符包括>,>=,<,<=,!=,==
就跟数学里的比较一样,但是要记住一点不能使用数学思维去写判断,下面用一个案例来说明原因:

一些初学者可能会写出类似的判断语句,但是结果却不如意,因为当执行完第一个关系运算符之后会返回真(1)或者假(0),此时进行第二个关系运算符运算的时候,结果很有可能和实际的结果不一样,在这种多个比较之间需要用到逻辑操作符(&&,||)
9、逻辑操作符
逻辑操作符有逻辑与&&,逻辑或||和逻辑非!
| 逻辑运算符 | 含义 |
| && | 与 |
| || | 或 |
| ! | 非 |
逻辑运算符两侧的条件必须都为真,整个表达式才为真。逻辑运算符的优先级比关系运算符低,所以不必在子表达式两侧加圆括号。
假设exp1和exp2是两个简单的关系表达式(如a > b或c == 1000),那么:
当且仅当exp1和exp2都为真时,exp1 && exp2才为真;
如果exp1或exp2为真,则exp1 || exp2为真;
如果exp1为假,则!exp1为真;如果exp1为真,则!exp1为假。
同时需要记得一点,逻辑运算符是执行短路求值的,何为短路求值?
在逻辑与&&中,当第一个判断条件为假的时候直接结束,不对第二个判断条件进行判断;在逻辑或||中,当第一个判断条件为真的时候直接结束,不对第二个判断条件进行判断。

10、条件操作符
C提供条件表达式(conditional expression)作为表达if else语句的一种 便捷方式,该表达式使用?:条件运算符。该运算符分为两部分,需要 3 个运算对象。
条件运算符是C语言中唯一的三元运算符。条件操作符的格式:expr1?expr2:expr3
如果 expr1 为真(非 0),那么整个条件表达式的值与 expr2 的值相同;如果expr1为假(0),那么整个条件表达式的值与 expr3的值相同。
但是条件操作符也是一个有趣的操作符,看下面这段代码:
int main(void)
{int a = 10, b = 20;int c = 0;c = (a > b ? a : b);printf("a=%d,b=%d,c=%d\n", a, b, c); //运行之后发现c的值和a的值一样return 0;
}
运行之后发现c的值和a的值是一样的,条件操作符返回的是一个变量,可以赋值。
11、逗号操作符
表达式说明:
表达式1,表达式2,表达式3,...... ,表达式n
逗号表达式的要领:
(1) 逗号表达式的运算过程为:从左往右逐个计算表达式。
(2) 逗号表达式作为一个整体,它的值为最后一个表达式(也即表达式n)的值。
(3) 逗号运算符的优先级别在所有运算符中最低。
12、下标引用、函数调用和结构成员
[]下标引用操作符
操作数:一个数组名+一个索引值
下标引用操作符允许对数组单个元素直接赋值

()函数调用操作符
接收一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数

访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
当我们通过访问结构体变量访问成员变量的时候,我们直接使用直接访问符(.),当我们通过访问结构体指针访问成员变量的时候,我们使用简洁访问(->)。
通过一个案例来展示一下:

相关文章:
C语言入门篇——操作符篇
目录 1、操作符分类 2、操作符的属性 3、算术操作符 4、移位操作符 5、位操作符 6、赋值操作符 7、单目操作符 8、关系操作符 9、逻辑操作符 10、条件操作符 11、逗号操作符 12、下标引用、函数调用和结构成员 1、操作符分类 算术操作符(,-&…...
YOLOv7训练自己的数据集(txt文件,笔记)
目录 1.代码下载 2.数据集准备(.xml转.txt) (1)修改图像文件名 (2)图片和标签文件数量不对应,解决办法 (3).xml转.txt (4).txt文件随机划分出对应的训练…...
防止机械/移动硬盘休眠 - NoSleepHD
防止机械/移动硬盘休眠 - NoSleepHD 前言解决方案计算机硬盘移动硬盘 前言 机械硬盘休眠后唤醒需要一定时间,且频繁的启动和停止并不有利于硬盘的寿命,因此可根据自身需求防止机械硬盘休眠,下文以Win10系统为例介绍解决方案。 值得一提的是…...
(二)app自动化脚本录制回放
上一篇:(一)app自动化测试环境搭建(maciosairtest )_airtest环境搭建_要开朗的spookypop的博客-CSDN博客 注:后续都是用IOS设备来介绍自动化测试,安卓就不赘述了。 接上一篇,搭建好自动化测试环境后&#…...
STM32HAL库USART外设配置流程及库函数讲解
HAL库中USART外设配置流程及库函数讲解 一说到串口通信,及必须说一下aRS-232/485协议。232协议标准物理接口就是我们常用的DB9串口线 RS-232电平: 逻辑1:-15~-3 逻辑0: 3~15 COMS电平: 逻辑1:3.3 逻辑0&a…...
Qt 实现TCP通信和UDP通信
Qt 实现TCP通信和UDP通信 1、TCP通信 QT中实现TCP通信主要用到了以下类:QTcpServer、QTcpSocket、QHostAddress等; 使用QTcpServer来创建一个TCP服务器,在新的连接建立时,将新建立连接的socket添加到列表中,以便发送…...
完成近4亿元C轮融资+自研底盘域控,本土线控制动玩家“拼”了
显然,线控制动赛道已经进入白热化竞争阶段。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)乘用车前装搭载线控制动系统(One-Box,Two-Box)上险交付合计497.39万辆,同…...
【UE】一个简易的游戏计时器
效果 步骤 1. 打开“ThirdPersonGameMode” 创建两个整型变量,分别命名为“Seconds”、“Minutes” 在事件图表中添加如下节点,实现“Seconds”每秒加1 继续添加如下节点: 当秒数大于60时,就让分钟数1,然后将秒数重新…...
Leetcode力扣秋招刷题路-0455
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 455. 分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i]&#x…...
一小时学会CSS (上)
1、CSS是什么? CSS (Cascading Style Sheets)层叠样式表,是一种来为结构化文档,例如HTML 、XML 添加字体,间距和颜色等样式的计算机语言,扩展名是.CSS 。 2、CSS语法规则 CSS写在哪里,CSS写在…...
DockerImage镜像版本说明
参考文章 1、https://medium.com/swlh/alpine-slim-stretch-buster-jessie-bullseye-bookworm-what-are-the-differences-in-docker-62171ed4531d 2、https://stackoverflow.com/questions/52083380/in-docker-image-names-what-is-the-difference-between-alpine-jessie-stret…...
ROS学习第三十三节——Arbotix使用
https://download.csdn.net/download/qq_45685327/87718484 1.介绍 通过 URDF 结合 rviz 可以创建并显示机器人模型,不过,当前实现的只是静态模型,如何控制模型的运动呢?在此,可以调用 Arbotix 实现此功能。 Arboti…...
ElasticSearch第十九讲 ES-best fields,most fields策略
multi-field多字段搜索 假设有个网站允许用户搜索博客的内容,以下面两篇博客内容文档为例: PUT /my_index/my_type/1 {"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen." }PUT /my_index/my_type/2 {&…...
Netty详解,5分钟了解,面试不用慌
1. 概述 1.1 Netty 是什么? Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty 是一个异步的、基于事件驱动的网络应用框架,用…...
Logstash学习
一、Logstash基础 1、什么是Logstash logstash是一个数据抽取工具,将数据从一个地方转移到另一个地方。下载地址:https://www.elastic.co/cn/downloads/logstash logstash之所以功能强大和流行,还与其丰富的过滤器插件是分不开的ÿ…...
【流畅的Python学习笔记】2023.4.22
此栏目记录我学习《流畅的Python》一书的学习笔记,这是一个自用笔记,所以写的比较随意 元组 元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个字段的位置。简单试试元组的特性: char…...
使用django_celery_beat在admin后台配置计划任务
一、依赖包的安装 django中使用celery做异步任务和计划任务最头疼的点就是包之间版本兼容性问题,项目一启动花花报错,大概率都是版本问题。每次都会花很大时间在版本兼容性问题上。本例使用如下版本: Django3.2 celery5.2.7 django-celery-b…...
ARP协议详解
ARP协议详解 文章目录 ARP协议详解ARP协议介绍ARP抓包ARP包解析 ARP协议介绍 ARP(Address Resolution Protocol)是一种用于将网络层地址(如IP地址)转换为数据链路层地址(如MAC地址)的协议,当一…...
不同数量的预测框和Ground Truth框计算IoU
import numpy as npdef calculate_iou(boxes1, boxes2):# 转换为 numpy 数组boxes1 np.array(boxes1)boxes2 np.array(boxes2)# 扩展维度,以便广播计算boxes1 np.expand_dims(boxes1, axis1)boxes2 np.expand_dims(boxes2, axis0)# 计算两组框的交集坐标范围x_m…...
偏好强化学习概述
文章目录 为什么需要了解偏好强化学习什么是偏好强化学习基于偏好的马尔科夫决策过程(Markov decision processes with preferences,MDPP) 反馈类型分类学习算法分类近似策略分布(Approximating the Policy Distribution)比较和排序策略(Comp…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
