C语言基础—运算符及优先级

news2024/11/27 11:41:33

本章主要讲解运算符的优先级和结合顺序

  • 知识点:
  1. 运算符分类,记忆了解13种运算符
  2. 注意运算符的易错点
  3. 运算符的优先级

 

运算符及优先级

  • 运算符分类
  • ❗ 运算符易错
    • 不能直接连续判断“< 值 <”
    • 关于判断两个浮点数是否相等
    • 逻辑表达式(布尔型)的返回值
    • 赋值运算符左右赋
    • 条件运算符?: 和逗号运算符,
      • 🤔 什么是三目运算符?
      • 条件运算符?:
      • 🏷️ 逗号运算符的值取决一个表达式
    • 自增自减 ++ - - 前后缀
      • 如何才能掌握自增、自减运算符?
      • 自增自减运算符不能用于常量
      • 自增自减运算符如果是一个表达式,结果无影响
    • 字符运算符的定义
    • 关于类型转化栈溢出
      • 解决方法
  • ⭐️ 运算符优先级
    • 优先级快速记忆口诀

运算符分类

  • C语言提供了13种类型的运算符,如下:

在这里插入图片描述

算术运算符+ - / %
关系运算符> < == >= <= !=
逻辑运算符! && ||
位运算符<< >> ~ | ^ &
赋值运算符 =及其扩展赋值运算符
条件运算符 ?:
逗号运算符 ,
指针运算符 * &
求字节运算符 sizeof()
强制类型转换运算符 (要转换的类型)值
分量运算符 .->
下标运算符 []
其他运算符 其他函数调用运算符

优先级见后面


❗ 运算符易错

不能直接连续判断“< 值 <”

比如:if(3<a<5)这种是不行的,C语言不支持这种连续判断,所以会直接跳过这个判断直接执行下面的。

举例:

if (3 < a < 10) //如果要判断3<a同时a<10,要用逻辑运算符
printf("a is right\n") ;
else {
printf(" a is wrong' );}

在上述的例子中无论 a 输入什么值, 都是输出 a is right ;


关于判断两个浮点数是否相等

  • 不能直接用== 判断浮点数是否相等

在C语言中,浮点数由于存在精度误差,不能直接用== 来判断两个浮点数是否相等。这是因为在计算机内部,浮点数都是以二进制表示的,在转换为十进制时会有一定的精度损失。因此,如果直接用 ==来比较两个浮点数是否相等,很可能会因为精度误差导致判断错误。

举例:

//判断两个浮点数是否相等,
float f= 234. 56;
if (f == 234.56)
{
printf("f is equal to 234. 56\n") ;
else {
printf("f is not equal to 234. 56\n") ;}
  • 这样的是错误的,需要用差值来判断,如下:

正确的做法是使用一个容错范围来判断两个浮点数的差值是否小于该范围。比如,我们可以使用下面的代码来判断两个浮点数是否相等:

//判断两个浮点数是否相等,必须用下面的方法
float f = 234. 56;|
if (f - 234.56>-0.0001 && f-234.56<0. 0001)
printf("f is equal to 234. 56\n");}
else {
printf("f is not equal to 234. 56\n") ;}

逻辑表达式(布尔型)的返回值

  • 在计算机编程中,布尔型值(或布尔值)用于表示逻辑真假值,通常用来进行逻辑运算。在很多编程语言中,布尔型值 真值通常表示为 1,假值则表示为 0。不过,这个映射关系并不是绝对的,具体应该怎么表示布尔值真假值取决于编程语言的实现。

  • 关于逻辑非的,注意事项,int j = 10 , int i = !! j ; i 的最后的值并不是负负得正为10 而是 1

!!j 表示将 j 的值转换成布尔类型,然后再取反。
因为 j 的值是 10,而在计算机中,非零整数值都被视为 true因此 !!j 的值就是 true取反后就得到 false,而在 C++ 中,false 的整数值为 0,所以 int i = !!j 的最终结果就是 1。true


赋值运算符左右赋

为了理解有些操作符存在的限制,必须理解左值(L-value) 和右值(R-value) 之间的区别.

举例: 右赋值

a=b+25;

其中,a是一个左值,因为它标识了一个可以存储结果值的地点; b+25是-一个右值,因为它指定了一个值。
这就是一个正常的把b+25的结果赋值给a的运算。

举例:左赋值

b+25=a;

因为每个位置都包含一个值, 所以原先用作左值的a此时也可以作为右值;然而,b + 25不能作为左值,因为它并未标识1个特定的位置(并不对应特定的内存空间)。因此,上面这条赋值语句是非法的

而且赋值运算符的优先级很低,仅仅高于逗号运算符。


条件运算符?: 和逗号运算符,

  • 条件运算符是C语言中唯一的一种三目运算符。

🤔 什么是三目运算符?

条件运算符是C语言中唯一的一种三目运算符

三目运算符代表有三个操作数;

双目运算符代表有两个操作数,如逻辑与运算符&&就是双目运算符;

单目运算符代表有一个操作数,如逻辑非运算符就是单目运算符。运算符也称操作符.


条件运算符?:

优先级仅高于赋值和逗号运算符

?:条件运算符表达式1? 表达式2: 表达式3 右到左三目运算符
  • 如果表达式为真返回表达式2,假返回表达式3

条件运算符(也称三元运算符)是一种简洁的运算符,用于在确定一个条件为真或假时选择不同的值。它通常被称为“三元运算符”,因为它接受三个操作数,如下所示:

condition ? value1 : value2

这里,condition 是一个布尔表达式,如果为真,则条件运算符返回 value1;如果为假,则返回 value2。例如,以下语句将 x 设置为 10,如果 y 大于 5,否则设置为 20:

x = y > 5 ? 10 : 20;
这个语句的意思是:如果 y 大于 5,则将 x 设置为 10,否则将 x 设置为 20。

条件运算符可以帮助我们编写简洁易读的代码,而不需要使用复杂的 if-else 语句。它可以让我们快速、简单地执行条件判断,并选择不同的值。


🏷️ 逗号运算符的值取决一个表达式

优先级最低!

, 逗号运算符表达式,表达式,… 左到右从左向右顺序运算

逗号运算符是在 C 和 C++ 等编程语言中的一种运算符。它的作用是在两个表达式之间插入一个逗号,并计算这两个表达式。这两个表达式的值会被忽略,逗号运算符的结果值是它的第二个操作数的值

  • 例如:
int x = 5, y = 10, z;
z = (x++, y++);  

在这个例子中,x 和 y 都会自增 1,但它们的值不会被使用。z 的值将是 y 在自增之后的值,即 11。


通过逗号运算符,我们可以先做一些准备操作

比如下面:最终while循环是否结束取决于scanf(" %d%d%d" ,&a,&b,&c)!=EOF这个表达式的真假

while (fflush (stdin), scanf (" %d%d%d" , &a, &b, &c) !=EOF)

如果是一个表达式,需要看最后一个表达式的真假。


自增自减 ++ - - 前后缀

  • 前后缀的区别:前缀的时候,先+1或者-1,然后带入计算表达式的值。后缀的时候先维持原值计算表达式的值,然后在+1,或者-1。

举例:

   int i=1;
   int s=i++;
   printf("%d\n",s); //后缀++,先s=i,再i+1,输出s等于=1
   int i2=1;
   int d=++i2;
    printf("%d\n",d); //++前缀,先i+1,再d=i2,输出s等于i2+1=2

如何才能掌握自增、自减运算符?

  • 只要做到了分开两条语句来计算,就肯定不会出错。

举例:

int i=-1;
int j;

j=i++>-1; //后++,或者后--; 等价于j=i>-1;i=i+1;
printf("i=%d, j=%d\n", i, j); //i=0, j=0(0是错误表示,表示不成立)

j=!++i;//当前加加时,直接按优先级结合顺序. ++的优先级跟!同级别,按照右到左的结合顺序,先++i,再!i
printf("i=%d,j=%d,sizeof(i)=%d\n", i, j, sizeof(i)); //i=++0=1; j=!1=0; sizeof(i)是求字节数的,i是个整数1,字节数为4个字节
 

在这里插入图片描述


自增自减运算符不能用于常量

5++这种是错误的。
//5++://如果运行该句,会造成编译不通


自增自减运算符如果是一个表达式,结果无影响

比如:

int i=1;
i++; //他自己是一个表达式,那么结果最后i肯定是2

字符运算符的定义

字节运算符是一种运算符,它们可以对一个或多个二进制位进行操作

  • 在 C 和 C++ 中,字节运算符包括 &(按位与)、|(按位或)、^(按位异或)、~(按位取反)和 <<(左移)、>>(右移)。它们可以用来对整型和字符型数据进行位操作,以便快速处理二进制数据。

例如,如果要对两个整型变量 x 和 y 进行按位与运算,可以使用下面的语句:

Copy code
int result = x & y;

这个语句将计算 x 和 y 的按位与,并将结果存储在 result 变量中。


此外,还可以使用位操作符来检查一个整型变量的特定二进制位是否被置位。例如,要检查 x 变量的第 3 位是否被置位,可以使用如下语句:

Copy code
if (x & (1 << 3)) {
    // 第 3 位被置位
}

在这个语句中,1 被左移 3 位,然后与 x 进行按位与运算。如果 x 的第 3 位被置位,那么结果将是一个非零数,表示条件成立,否则结果将是零,表示条件不成立。


关于类型转化栈溢出

类型转换栈溢出 是指当程序试图将 一个大型数据类型转换为较小的数据类型时,可能会发生的错误例如,将一个 long 类型的数据强制转换为 int 类型的数据时,如果 long 类型的数据超出了 int 类型的取值范围,则可能会发生类型转换栈溢出错误。


例如,如果整型的取值范围是 − 2 31 -2^{31} 231 2 31 − 1 2^{31}-1 2311,那么将一个大于 2 31 − 1 2^{31}-1 2311 的数字强制转换为整型就会导致溢出。


解决方法

为了解决类型转换栈溢出问题,需要遵守一些基本的编程原则和技巧。例如:

尽量避免使用强制类型转换,特别是将大型数据类型转换为较小的数据类型。如果确实需要使用强制类型转换,则应当检查转换后的值是否超出了目标类型的取值范围,并在必要时进行特殊处理。

尽量使用更宽容的数据类型,例如 long 或 double,来存储数据。这样可以避免因类型转换栈溢出而导致的数据丢失。

在编写程序时,应当注意程序的结构和逻辑,尽量避免出现死循环和其他导致程序崩溃的错误。

如果在程序运行过程中发现类型转换栈溢出错误,则应当及时修复错误并重新测试程序。

如果程序需要处理大量数据,则应当考虑使用更高级的编程语言或框架,例如 Java 或 C++,来提高程序的运行效率和稳定性。

 


⭐️ 运算符优先级

优先级

运算符

名称或含义

使用形式

结合方向

说明

1

[]

数组下标

数组名[常量表达式]

左到右

 

()

圆括号

(表达式)/函数名(形参表)

 

.

成员选择(对象)

对象.成员名

 

->

成员选择(指针)

对象指针->成员名

 

2

-

负号运算符

-表达式

右到左

单目运算符

(类型)

强制类型转换

(数据类型)表达式

 

++

自增运算符

++变量名/变量名++

单目运算符

--

自减运算符

--变量名/变量名--

单目运算符

*

取值运算符

*指针变量

单目运算符

&

取地址运算符

&变量名

单目运算符

!

逻辑非运算符

!表达式

单目运算符

~

按位取反运算符

~表达式

单目运算符

sizeof

长度运算符

sizeof(表达式)

 

3

/

表达式/表达式

左到右

双目运算符

*

表达式*表达式

双目运算符

%

余数(取模)

整型表达式/整型表达式

双目运算符

4

+

表达式+表达式

左到右

双目运算符

-

表达式-表达式

双目运算符

5

<<

左移

变量<<表达式

左到右

双目运算符

>>

右移

变量>>表达式

双目运算符

6

>

大于

表达式>表达式

左到右

双目运算符

>=

大于等于

表达式>=表达式

双目运算符

<

小于

表达式<表达式

双目运算符

<=

小于等于

表达式<=表达式

双目运算符

7

==

等于

表达式==表达式

左到右

双目运算符

!=

不等于

表达式!= 表达式

双目运算符

8

&

按位与

表达式&表达式

左到右

双目运算符

9

^

按位异或

表达式^表达式

左到右

双目运算符

10

|

按位或

表达式|表达式

左到右

双目运算符

11

&&

逻辑与

表达式&&表达式

左到右

双目运算符

12

||

逻辑或

表达式||表达式

左到右

双目运算符

13

?:

条件运算符

表达式1? 表达式2: 表达式3

右到左

三目运算符

14

=

赋值运算符

变量=表达式

右到左

 

/=

除后赋值

变量/=表达式

 

*=

乘后赋值

变量*=表达式

 

%=

取模后赋值

变量%=表达式

 

+=

加后赋值

变量+=表达式

 

-=

减后赋值

变量-=表达式

 

<<=

左移后赋值

变量<<=表达式

 

>>=

右移后赋值

变量>>=表达式

 

&=

按位与后赋值

变量&=表达式

 

^=

按位异或后赋值

变量^=表达式

 

|=

按位或后赋值

变量|=表达式

 

15

,

逗号运算符

表达式,表达式,…

左到右

从左向右顺序运算

说明:

同一优先级的运算符,运算次序由结合方向所决定。

简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符


优先级快速记忆口诀

从上述表中可以大致归纳出各类运算符优先级:

初等运行符->单目运算符->算术运算符->关系运算符->逻辑运算符->条件运算符->赋值运算符->逗号运算符

 

  • 经过分析总结,编成顺口溜6句以助记忆:

 
 

初等单目一二级, // 初等运算符和单目运算符分别是第1、2优先级

乘除求余加减移, // 这句里面的运算符全归为算术运算符,移表示移位

关系等于不等于, // 关系运算符(< <= > >=)

按位与来异或或, // 位运算符优先级顺序: & -> ^ -> |

逻辑与或条件弱, // 逻辑运算符优先级顺序: && -> ||,后面跟着优先级比较低(弱)的条件运算符

赋值逗号一点破。 // 赋值,逗号最低

 

参考:

C语言运算符优先级 之 快速记忆


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS:border-image

border-image属性对图像的规格和比例比较高&#xff0c;导致使用成本比较高。另外&#xff0c;常见的场景中&#xff0c;大家更倾向于扁平化而不是非拟物化&#xff0c;边框装饰通常在项目中不会出现。 border-image是由多个CSS属性缩写的&#xff0c;比如: border-image-sou…

hc32和stm32 can波特率设置

前言 笔者在调试一款新的mcu的can通信时候&#xff0c;最麻烦的是波特率设置。由于没有弄明白其计算原理&#xff0c;经常出错&#xff0c;且不同的波特率有不同的采样点的要求。浪费了不少时间。这次一次搞明白can波特率的计算公式。 can波特率计算 在ISO 11898-1-2015 标准…

音视频基础概念(2)——音频

目录 1. 基本知识 2.采样率和采样位数 3.音频编码 4. 声道数 5. 码率 6. 音频格式 日常生活中&#xff0c;音视频随处可见&#xff0c;包括视频、音频、编解码、封装容器、音视频等概念。 1. 基本知识 音频数据的承载方式最常用的是脉冲编码调制&#xff0c;即PCM。于…

JAVA面试(2022年Java常见面试问题)

1、谈谈你对Spring中IOC和AOP的理解。 答案&#xff1a; 2、谈谈Spring的bean的创建过程和生命周期。 答案&#xff1a; 3、谈一下JVM的内存分配和垃圾回收机制。 答案&#xff1a; 4、谈一下你使用比较多的设计模式和场景。 答案&#xff1a; 5、谈一些mysql的事务隔离。 …

什么是文件系统?

【推荐阅读】 一文了解Linux上TCP的几个内核参数调优 一文剖析Linux内核中内存管理 分析linux启动内核源码 文件系统是操作系统用于明确存储设备&#xff08;常见的是磁盘&#xff0c;也有基于NAND Flash的固态硬盘&#xff09;或分区上的文件的方法和数据结构&#xff0c;…

传奇列表上传登录器公告小窗口怎么修改

传奇列表上传登录器公告小窗口怎么修改 很多小伙伴不会上传列表&#xff0c;我是艾西今天给大家分享下怎么上传列表 我们开始实操&#xff08;纯教学分享&#xff09; 在我们的网站文件夹里创建一个列表.txt 在浏览器里找一个列表模板例&#xff1a;www.pkp123.cn:88&#xff…

1570_AURIX_TC275_SCU_ERU

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 从系统的逻辑图看&#xff0c;能够很清楚看到这个模块的功能处理过程&#xff1a;首先是边沿信号的识别&#xff0c;接着是根据判断进行置位处理&#xff0c;最后进行工作触发。如果设置的…

使用Nordic的nRF52840 Dongle配合Wireshark对蓝牙设备抓包(BLE)

硬件准备&#xff1a; 1&#xff09;nRF52840 Dongle 2&#xff09;待抓包的蓝牙设备 软件准备&#xff1a; 1&#xff09;Python 2&#xff09;Wireshark 3&#xff09;nRF Sniffer for Bluetooth LE Python安装 需要注意的是下载的nRF Sniffer for Bluetooth LE版本是否…

K8s 之 Deployment 应用案例

目录一、YAML 配置文件二、运行服务三、更新 Deployment3.1 动态伸缩容3.2 触发上线四、故障自动转移五、指定节点运行 Pod六、删除 deployment一、YAML 配置文件 我们要清楚&#xff0c;在 K8s 中有两种创建资源的方式&#xff1a; &#xff08;1&#xff09;命令行方式&…

【GO】 K8s 管理系统项目[API部分--Pod]

K8s 管理系统项目[API部分–Pod] 前端: Vueelement plus 后端: gogin 1. 功能设计 2. 初始化 2.1创建项目 2.2 配置goproxy GOPROXYhttps://goproxy.cn 2.3 添加格式化工具 2.4 安装模块 go get k8s.io/client-go/tools/clientcmd go get k8s.io/api/core/v1 go get k8s.i…

使用 docker buildx 构建跨平台 Go 镜像

目录 前提 docker buildx 启用 Buildx builder 实例 构建驱动 buildx 的跨平台构建策略 一次构建多个架构 Go 镜像实践 源代码和 Dockerfile 执行跨平台构建 验证构建结果 如何交叉编译 Golang 的 CGO 项目 准备交叉编译环境和依赖 交叉编译 CGO 示例 总结 参考链接…

供水设备远程监控客户案例

一、客户介绍 客户积累多年的技术研发和工程运维经验&#xff0c;对传统的恒压供水工程所面临的维护难、维修难、运维效率低和能耗管控弱等诸多问题有深刻的体会&#xff0c;经过广泛调研&#xff0c;客户最终选择使用蓝蜂物联网的云平台和边缘计算产品对恒压供水设备和工程进行…

数据处理指令(一)—— 搬移指令MOV、MVN

数据处理指令指的是和数学运算、逻辑运算相关的指令&#xff0c;比如加减乘、与或非、赋值比较等 目录 1、MOV —— 直接搬移 (1) MOV 指令格式 (2) MOV生成指令的策略&#xff08;MOV的优点&#xff09; (3) MOV 只能搬移“立即数”的原因&#xff08;MOV的缺点&#x…

问卷设计一:问卷题目哪些有类型和注意要点?

问卷法常被人们应用于社会调查中&#xff0c;它能反馈出最真实的社会信息。所以&#xff0c;很多企业为了最大程度地了解市场&#xff0c;也经常使用问卷调查法进行研究。不过&#xff0c;想要发挥出问卷法的最大用处&#xff0c;前提是要将问卷设计规范并且可量化。 想要设计…

用ArkTs在鸿蒙系统上画一个世界杯海报

偶然看到了CSDN关于世界杯的征文活动&#xff1a; 用代码画一个足球&#xff1f; 哈哈很有意思&#xff01; 想了想&#xff0c;画一个自定义View&#xff08;足球&#xff09;&#xff0c;当然是使用Canvas了&#xff0c;但除了Canvas还有没有其它方法呢&#xff1f;那是必须…

c语言算数转换 操作符

【题目名称】下面代码的结果是&#xff1a;( b)#include <stdio.h> int main() {int a, b, c;a 5;c a;b c, c, a, a;//逗号表达式从左向右以此计算 表达式结果是最后一个表达式b a c; //a9 先算加后算加等printf("a %d b %d c %d\n:", a, b, c);retu…

【软件测试】工作瓶颈?测试的出路在哪?

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 3年软件测试经验&am…

【内网安全-隧道技术】SMB、ICMP、DNS隧道、SSH协议

目录 一、基础知识 二、隧道技术 1、简介&#xff1a; 2、SMB隧道 3、ICMP隧道 4、DNS隧道 5、SSH协议 6、控制上线-插件 一、基础知识 【内网安全-基础】基础知识、信息收集、工具https://blog.csdn.net/qq_53079406/article/details/128292587?spm1001.2014.3001.55…

Seata 术语

爬虫组件分析目录概述需求&#xff1a;设计思路实现思路分析1.TC (Transaction Coordinator) - 事务协调者2.TM (Transaction Manager) - 事务管理器3.RM参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&…

[附源码]Nodejs计算机毕业设计基于的防疫隔离服务系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…