2.4 C语言之运算符
2.4 C语言之运算符
- 一、算术运算符
- 二、关系运算符
- 三、逻辑运算符
- 四、自增自减运算符
- 五、按位运算符
- 六、赋值运算符
- 七、条件表达式
- 八、运算符优先级与求值次序
一、算术运算符
二元算术运算符包括:+(加)、-(减)、*(乘)、/(除)、%(取模)
- 整数除法会截断结果中的小数部分
- 表达式x
%y的结果是x除以y的余数,当x能被y整除时,其值为0。 - 取模运算符不能应用于float和double类型。
- 在有负操作数的情况下,整数除法截取的方向以及取模运算结果的符号取决于具体机器的实现,这和处理上溢和下溢的情况是一样的
- 二元运算符
+和-具有相同的优先级,它们的优先级比*、/和%的优先级低 - 而二元运算符
*、/和%的优先级低于一元运算符+和- - 算术运算符采用从左到右的结合规律
二、关系运算符
关系运算符包括:>、 >=、 <、<=
- 关系运算符优先级相同
- 关系运算符优先级低于算术优先级,因此 i
<lim - 1 等价于 i<(lim - 1) - 关系运算符优先级高于相等性运算符(
==、!=),因此0!=a<=1 等价于 0!=(a<=1)
三、逻辑运算符
逻辑运算符包括:&&(与) 、||(或) 、!(非)
- 由
&&或||连接的表达式按从左到右的顺序进行求值,并且,在知道结果值为真或假后立即停止计算(短路)。 &&优先级高于||,但是两者都比关系运算符和相等性运算符的优先级低- 在关系表达式或逻辑表达式中,如果关系为真,则表达式的结果值为数值1,如果为假,则结果值为数值0
- 逻辑运算符!的作用是将非0操作数转换为0,将操作数0转换为1。一般这样用 if(!valid),一般不采用 if(valid==0)
四、自增自减运算符
C语言提供了两个用于变量递增与递减的特殊运算符。自增运算符++使其操作数递增1,自减运算符--使其操作数递减1。
++与--这两个运算符特殊的地方在于:它们既可以用作前缀运算符(++n),也可以用作后缀运算符(n++)。在这两种情况下,其效果都是将变量n的值加1。但是,它们之间有一点不同。表达式++n先将n的值递增1,然后再使用变量n的值;而表达式n++则是先使用n的值,然后再将n的值递增1。- 如果n的值为5,那么 x = n++; 执行后的结果是将x置为5,而 x = ++n; 执行后的结果是将x置为6,这两条语句执行完成后,变量n的值都是6。
- 自增自减运算符只能作用于变量,类似于表达式(i+j)++是非法的
五、按位运算符
C语言提供了6个位操作运算符。这些运算符只能作用于整型操作数,即只能作用于带符号或无符号char、short、int、long类型:
| 运算符 | 说明 | 运算规则 |
|---|---|---|
| & | 按位与(AND) | 参与运算的两个二进位都为1,结果位才为1;1&1=1, 1&0=0,0&1=0,0&0=0 |
| | | 按位或(OR) | 参与运算的两个二进位只要有一个为1,结果位就为1;1|1=1, 1|0=1, 0|1=1, 0|0=0 |
| ^ | 按位异或(XOR) | 参与运算的两个二进位不同,结果位为1,相同,结果位为0;1^1=0, 1^0=1, 0^1=1, 0^0=0 |
| << | 左移 | m<<n,将二进制位左移n位 |
| >> | 右移 | m>>n, 将二进制位右移n位 |
| ~ | 按位求反(一元运算符) | 0变1,1变0 |
- 按位与运算符
&经常用于屏蔽某些二进制位(x&1=x; x&0=0,其中x取值0或者1),比如:
n = n & 0177; 该语句将n中除7个低二进制位外的其它各位均置为0
0177八进制–>十进制127–>二进制 01111111
可以看出,0177对应的二进制的7个低位都是1,那么不管n的7个低位是1还是0,与0177进行&运算之后这7位的结果总是保持不变;而除了这7个低位,n的其它位都将&0,其结果显然也是0 - 按位或运算符
|经常用于将某些二进制位置为1(x|1=1; x&0=x,其中x取值0或者1),比如:
n = n|SET_ON; 该语句将n中对应于SET_ON中为1的那些二进制位置为1。 - 按位异或运算符^当两个操作数的对应位不相同时,将该位设置为1,否则,将该位设置为0
- 注意区分按位运算符
&、|与逻辑运算符&&、||,比如:
int x = 1, y = 2;
printf(“%d”, x & y); // 0
printf(“%d”, x && y); // 1 - 移位运算符<<和>>分别用于将运算的左操作数左移和右移,移动的位数则由右操作数指定(右操作数的值必须是非负值)。表达式x<<2表示将x的值左移两位,右边空出的两位用0填补,该表达式等价于对左操作数乘以4;在对unsigned类型的值右移时,左边空出的部分用0填补;在对signed类型的值右移时,某些机器将对左边空出部分用符号位填补(即算术移位),而另一些机器则对左边空出部分用0填补(即逻辑移位)
#include <stdio.h>main()
{int x = 5; // 0000 0101 printf("%d\n", x << 2); // 0001 0100 20=x*4printf("%d\n", x >> 2); // 0000 0001 1=x/4unsigned int y = 5; // 0000 0101 printf("%d\n", y >> 2); // 0000 0001 1=x/4signed int z = -5; // 1000 0101原码 --> 1111 1010 反码(原码取反) --> 1111 1011 补码(反码加1)printf("%d\n", z >> 2); // 1111 1011(-5补码) -->右移2位,左边空位补符号位 1111 1110补码 --> 1111 1101反码 --> 1000 0010原码 -2return 0;
}
关于负数的二进制可以参考我的另一篇博客:负数的二进制
- 一元运算符~用于求整数的二进制反码,即1变0,0变1,比如:
int a = 64 + 16 + 1;// 077八进制-->十进制63-->二进制 011 1111 -->取反 0100 0000// 0101 0001 a//&0100 0000 ~077//=0100 0000a = a & ~077; // 将把a的最后六位设置为0printf("%d\n", a);
- 看一个例子
printf("%d\n", ~0); // -1 1000 0001 -> 1111 1111(补)printf("%d\n", ~0 << 2); // 1111 1111(补) << 2 --> 1111 1100(补) 1111 1011(反) 1000 0100(原) -4printf("%d\n", ~(~0 << 2)); // 1111 1100 -->取反 0000 0011printf("%d\n", getbits(13, 2, 2));// 返回整数x从第p位(从右边数,假定最右边是第0位)开始,往右数n位的值,也即除了这n位,其左边位都置0
unsigned getbits(unsigned int x, int p, int n) {// 0000 1101 x=13 p=2 n=2// 0000 0110 //&0000 0011 // 0000 0010 2return (x >> (p + 1 - n)) & ~(~0 << n);
}
x >> (p + 1 - n) 将要求的n位数移到最右端,其中p+1-n就是要求的n位数的右端的没用的位数;
~0所有位都为1;
~0<<n左移n位,右端的n位置0;
~(~0<<n)右端的n位置1;
做&运算,将n位左边位都置0
六、赋值运算符
在赋值表达式中,如果表达式左边的变量重复出现在表达式的右边,如:
i = i + 2,
则可以将这种表达式缩写为下列形式:
i += 2,其中的+=属于赋值运算符
大多数二元运算符都有相应的赋值运算符op=,其中op可以是下面这些运算符之一:
+ - * / & << >> & ^ |
七、条件表达式
下面这组语句:
if (a > b)z = a;elsez = b;
用于求a和b中的最大值,并将结果保存到z中。条件表达式(使用三元运算符" ? : ")提供了另外一种方法编写这段程序及类似的代码段。在表达式
expr1 ? expr2 : expr3
中,首先计算expr1,如果其值不等于0(为真),则计算expr2的值,并以该值作为条件表达式的值,否则计算expr3的值,并以该值作为条件表达式的值。expr2和expr3中只能有一个表达式被计算。因此,以上语句可以改写为:
z = (a>b) ? a : b; /* z = max(a,b) */
八、运算符优先级与求值次序
下表总结了所有运算符的优先级与结合性,同一行中的各运算符具有相同的优先级,各行间从上往下优先级逐行降低。
| 运算符 | 结合性 |
|---|---|
| () [ ] -> . | 从左至右 |
| ! ~ ++ – + - * (type) sizeof | 从右至左 |
| * / % | 从左至右 |
| + - | 从左至右 |
| << >> | 从左至右 |
| < <= > >= | 从左至右 |
| == != | 从左至右 |
| & | 从左至右 |
| ^ | 从左至右 |
| | | 从左至右 |
| && | 从左至右 |
| || | 从左至右 |
| ? : | 从左至右 |
= += -= *= /= %= &= ^= |= <<= >>= | 从右至左 |
| , | 从左至右 |
- 运算符-> .用于访问结构成员,sizeof 对象长度,后续讨论
- 一元运算符*(通过指针间接访问),一元运算符&(对象地址),后续讨论
- 注意:一元运算符+、-、*、&优先级高于二元运算符+、-、*、&
- C语言没有指定同一运算符中多个操作数的计算顺序(&& || ?: ,运算符除外)。例如:
x = f() + g();
在上面的语句中,f()可以在g()之后计算,也可以在g()之前计算。因此,如果f或g改变了另一个函数所使用的变量,那么x的结果可能会依赖这两个函数的计算顺序。解决办法是把中间结果保存在临时变量中。 - 类似地,C语言也没有指定函数各参数的求值顺序。例如:
printf(“%d %d\n”, ++n, power(2, n)); 在不同的编译器中的输出结果可能不同,这取决于先执行n的自增还是先执行power函数,解决的办法是
++n;
printf(“%d %d\n”, n, power(2, n)); - 函数调用、嵌套赋值语句、自增、自减都可能产生副作用(在对表达式求值的同时,修改了某些变量的值)。在有副作用影响的表达式中,其执行结果同表达式中的变量被修改的顺序之间存在着微妙的依赖关系,比如:
a[i] = i++;
数组下标i是引用旧值还是新值?编译器不同,结果可能不同。C语言标准对大多数这类问题有意未作具体规定。表达式何时会产生这种副作用(对变量赋值),将由编译器决定,因为最佳的求值顺序同机器结构有很大关系。(ANSI C标准明确规定了所有对参数的副作用都必须在函数调用之前生效,但这对前面介绍的那种printf函数调用没有什么帮助) - 在任何一种编程语言中,如果代码的执行结果与求值顺序有关,则都是不好的程序设计风格。如果不知道这些问题在各种机器上是如何解决的,就不要尝试使用某种特殊的实现方式。
相关文章:
2.4 C语言之运算符
2.4 C语言之运算符 一、算术运算符二、关系运算符三、逻辑运算符四、自增自减运算符五、按位运算符六、赋值运算符七、条件表达式八、运算符优先级与求值次序 一、算术运算符 二元算术运算符包括:(加)、-(减)、*(乘)、/(除)、%(取模) 整数除法会截断结果中的小数部…...
做题笔记:SQL Sever 方式做牛客SQL的题目--SQL157
----SQL157 平均播放进度大于60%的视频类别 计算各类视频的平均播放进度,将进度大于60%的类别输出。 注: 播放进度播放时长视频时长*100%,当播放时长大于视频时长时,播放进度均记为100%。 结果保留两位小数,并按播放进…...
微信小程序map视野发生改变时切换定位点
<!--地图--> <view><map id"myMap" style"width: 100%; height: 300px;" latitude"{{latitude}}" longitude"{{longitude}}"scale"{{scale}}" markers"{{markers}}" controls"{{controls}}&q…...
javaweb搭配ajax和json
ajax一般用来前端界面与后端界面交互使用。数据格式一般使用json,优点是便于对象与字符串的转化。 1.不适用json对象封装。 jsp: <script>$.ajax({url: "/LoginServlet",data: {"name":name, "pwd":password},dataType: &qu…...
VS2022 将项目打包,导出为exe运行
我有一个在 VS2022 上开发的程序,基于.net 6框架, 想打包成 .exe程序,以在另一个没有安装VS的机器上运行,另一个机器是Win7系统,上面安装了.net 6框架。 虽然网上很多教程,需要安装Project Installer,配置A…...
【Py/Java/C++三种语言OD2023C卷真题】20天拿下华为OD笔试【DP】2023C-分班【欧弟算法】全网注释最详细分类最全的华为OD真题题解
文章目录 题目描述与示例题目描述输入描述输出描述示例一输入输出 示例二输入输出 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前…...
pr模板哪个网站好?免费Pr模板视频素材下载网站 Prmuban.com
pr模板哪个网站好?哪里可以下载免费的pr模板视频素材,PR模板网(Prmuban.com)影视后期制作模板视频剪辑素材资源网站。 包含PR模板、PR插件、PR预设、MOGRT、LUT、转场特效、音乐素材、音效素材等,更好的剪辑师必备资源…...
【论文阅读】LoRA: Low-Rank Adaptation of Large Language Models
code:GitHub - microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Models" 做法: 把预训练LLMs里面的参数权重给冻结;向transformer架构中的每一层,注入可训练的…...
MybatisPlus的分页插件
PaginationInnerInterceptor 此插件是核心插件,目前代理了 Executor#query 和 Executor#update 和 StatementHandler#prepare 方法。 在SpringBoot环境中配置方式如下: /*** author giserDev* description 配置分页插件、方言、mapper包扫描等* date 2023-12-13 …...
保障网络安全:了解威胁检测和风险评分的重要性
在当今数字时代,网络安全问题变得愈发突出,而及时发现和迅速应对潜在威胁成为保障组织信息安全的首要任务。令人震惊的是,根据2023年的数据,平均而言,检测到一次网络入侵的时间竟然长达207天。这引起了对安全策略和技术…...
3D摄影棚布光:Set A Light 3D Studio
Set A Light 3D Studio是一款专业的灯光模拟软件,旨在帮助摄影师和电影制片人在电脑上进行虚拟灯光布置和场景模拟,以实现更加精准和高质量的拍摄效果。该软件提供了丰富的灯光和场景模型,支持灵活调整光源位置、强度、颜色和效果等参数&…...
#HarmonyOS:应用的包名配置--应用图标和标签配置--配置链接
配置相关 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/application-component-configuration-stage-0000001478340869-V2 应用的包名配置 应用需要在工程的AppScope目录下的app.json5配置文件中配置bundleName标签,该标签用于标识应用的唯…...
docker小白第三天
docker小白第三天 docker为什么会比虚拟机快 1、docker有着比虚拟机更少的抽象层。不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上docker将会在效率上有明显优势。 2、dock…...
FFmpegd的AVBSF
本章主要介绍AVBSF 文章目录 结构体定义对外函数常见的过滤器 从名字我们可以知道这是个码流过滤器,我们最常用的是一个叫做h264_mp4toannexb_bsf的东东 这个过滤器的作用是把h264以MP4格式的NALU转换为annexb(0x000001) const AVBitStreamF…...
深圳三男子写字楼内吸烟被罚,快用富维AI神器,实时监控防火灾
最近,在深圳,一专项控烟督查组在福田区新华保险大厦发现三名男子在写字楼内楼道违法吸烟,并对其进行了现场处罚。根据《控烟条例》,这类室内区域严禁吸烟,但人们往往忽视这一规定,从而引发潜在的安全风险。…...
有哪些已经上线的vue商城项目?
前言 下面是一些商城的项目,需要练手的同学可以挑选一些来练,废话少说,让我们直接开始正题~~ 1、newbee-mall-vue3-app 是一个基于 Vue 3 和 TypeScript 的电商前端项目,它是 newbee-mall 项目的升级版。该项目包含了商品列表、…...
Nginx服务器配置SSL证书
本文将全面介绍如何在Nginx或Tengine服务器配置SSL证书,具体包括下载和上传证书文件,在Nginx上配置证书文件、证书链和证书密钥等参数,以及安装证书后结果的验证。成功配置SSL证书后,您将能够通过HTTPS加密通道安全访问Nginx服务器…...
【JVM从入门到实战】(六)类加载器的双亲委派机制
一、双亲委派机制 在Java中如何使用代码的方式去主动加载一个类呢? 方式1:使用Class.forName方法,使用当前类的类加载器去加载指定的类。 方式2:获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。 …...
SpringCloud面试题及答案(最新50道大厂版,持续更新)
在Java开发中,Spring Cloud作为微服务架构的关键组成部分,为了帮助广大Java技术爱好者和专业开发人员深入理解Spring Cloud,本文《SpringCloud面试题及答案(最新50道大厂版,持续更新)》提供了最前沿、最实用…...
Next.js 的设计理念
Next.js 的设计理念:简洁、强大与高效 Next.js 是一个流行的 React 框架,由 Vercel 公司开发。它的设计理念是简洁、强大和高效,这种理念贯穿于 Next.js 的所有功能中。下面我们将深入探讨这三个设计理念。 简洁 Next.js 的一个核心设计理…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
