深蓝学院C++基础与深度解析笔记 第 4 章 表达式
第 4 章 表达式
一、表达式基础
A、表达式: 由一到多个操作数组成,可以求值并 ( 通常会 ) 返回求值结果:
#include <iostream>
int main(){int x;x = 3;
}
- 最基本的表达式:变量、字面值
- 通常来说,表达式会包含操作符(运算符), 且可以嵌套
- 操作符的特性
● 接收几个操作数:一元、二元、三元 ?:
● 操作数的类型 - 类型转换
● 操作数是左值还是右值
● 结果的类型
● 结果是左值还是右值
● 优先级与结合性 (cpp-reference) ,可以通过小括号来改变运算顺序,和数学上一样,相同的优先级的结合性相同
● 操作符的重载 不改变接收操作数的个数、优先级与结合性 - 操作数求值顺序的不确定性
最终的顺序:
括号 -> 优先级 -> 结合性
PS: 函数调用也是表达式:
#include<iostream>
void fun(int p12, int p2)
{std::cout<< p1 << ' ' << p2 << '\n';
}
int main(){int x=0;fun(x=x+1,x=x+1);
}
函数参数计算顺序可能不同
B、左值和右值
传统的左值与右值划分
– 来源于 C 语言:左值可能放在等号左边;右值只能放在等号右边
– 在 C++ 中,左值也不一定能放在等号左边;右值也可能放在等号左边
● 所有的划分都是针对表达式的,不是针对对象或数值,针对表达式结果
– glvalue :泛左值:标识一个对象、位或函数
– prvalue :纯右值:用于初始化对象或作为操作数
– xvalue : 将亡值:表示其资源可以被重新使用,在内存销毁前把内容保留下来
decltype(实体/表达式)
● 左值与右值的转换
– 左值转换为右值( lvalue to rvalue conversion )
– 临时具体化( Temporary Materialization )
● 再论 decltype
– prvalue → type
– lvalue → type&
– xvalue → type&&
std::move()可以构造亡值
C、类型转换
一些操作符要求其操作数具有特定的类型,或者具有相同的类型,此时可能产生类型转换
1、 隐式类型转换
– 自动发生
– 实际上是一个(有限长度的)转型序列
– https://en.cppreference.com/w/cpp/language/implicit_conversion
– 并非所有类型之间都可以任意转换
数值提升:精度、内存空间提升;数值之间的转换可以导致精度缺失,更改值
2、显示类型转换
使用的时候小心谨慎些,容易出错,风险较大;尽量写长些,容易识别
– 显式引入的转换 可以使用括号和类型结合转换
– static_cast
– const_cast
– dynamic_cast
– reinterpret_cast
– C 形式的类型转换
关于类型转换的补充:
静态转换(Static Cast):
静态转换是最常用的类型转换方式之一,用于显式转换一种类型为另一种类型,但在转换时没有进行运行时检查。静态转换可以用于类层次结构中的上下转换(派生类向基类转换),以及非相关类型之间的转换。使用静态转换时,需要注意类型转换的安全性,因为它没有运行时检查。示例:
int x = 10;
double y = static_cast<double>(x); // 将整数转换为浮点数
动态转换(Dynamic Cast):
动态转换用于在类层次结构中进行安全的上下转换(派生类向基类转换),并提供运行时类型检查。如果转换无效,即源指针指向的对象不是目标类型的一个有效派生类对象,动态转换将返回空指针(对于指针类型)或引发 std::bad_cast 异常(对于引用类型)。示例:
Base* basePtr = new Derived(); // 派生类指针赋值给基类指针
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 动态转换
if (derivedPtr != nullptr) {// 转换成功,可以安全使用 derivedPtrderivedPtr->doSomething();
}
重新解释转换(Reinterpret Cast):
重新解释转换是一种较为低级别的转换方式,用于将一个指针或引用转换为不同类型的指针或引用,甚至可以将整数类型转换为指针类型或反之。它的行为比较危险,需要谨慎使用,因为它不会进行任何类型检查和转换。示例:
int x = 10;
double* ptr = reinterpret_cast<double*>(&x); // 将整数指针转换为双精度浮点数指针
常量转换(Const Cast):
常量转换用于移除表达式的常量性(const)或将常量性添加到表达式。它主要用于处理函数重载或操作函数返回类型为常量的情况。常量转换不能用于修改实际的常量对象。示例:
const int x = 10;
int* ptr = const_cast<int*>(&x); // 移除常量性以获取非常量指针
*ptr = 20; // 修改通过常量指针获取的值
使用Boost将数字型对象的值转换为字符文本格式:boost::lexical_cast
在进行类型转换时,应谨慎考虑类型安全性和潜在的运行时错误
二、表达式详述
A、算术操作符
● 共分为三个优先级
– + , - (一元,正负号),可以让数组变成指针,类型提升
– * , / , % (%只接受整数)
– + , - (二元,加减号)
● 均为左结合的
● 通常来说,操作数与结果均为算数类型的右值;但加减法与一元 + 可接收指针
● 一元 + 操作符会产生 integral promotion
● 整数相除会产生整数,向 0 取整
● 求余只能接收整数类型操作数,结果符号与第一个操作数相同
● 满足 (m / n) * n + m % n == m
B、逻辑与关系操作符
● 关系操作符接收算术或指针类型操作数;逻辑操作符接收可转换为 bool 值的操作数
● 操作数与结果均为右值(结果类型为 bool )
● 除逻辑非外,其它操作符都是左结合的
● 逻辑与、逻辑或具有短路特性
● 逻辑与的优先级高于逻辑或,建议使用括号!
● 通常来说,不能将多个关系操作符串连 例子:c>b>a ×
● 不要写出 val == true 这样的代码
● Spaceship operator: <=>用于比较复杂的对象的对比(C++20)
– strong_ordering
– weak_ordering
– partial_ordering nan:not a number 非正常数字
c、位操作符
~:按位取反
● 接收右值,进行位运算,返回右值
● 除取反外,其它运算符均为左结合的
● 注意计算过程中可能会涉及到整形提升 integral promotion
● 注意这里** **
● 移位操作在一定情况下等价于乘(移位 :左移<< 1(乘2的1次)、右移>>1(除2)) 2 的幂,但速度更快
<<n : 乘2的n次 >>n : 除2的n次
● 注意整数的符号与位操作符的相关影响
– integral promotion 会根据整数的符号影响其结果
– 右移保持符号,但左移不能保证
D、赋值操作符
● 左操作数为可修改左值;右操作数为右值,可以转换为左操作数的类型
● 赋值操作符是右结合的:先处理右侧的
● 求值结果为左操作数
● 可以引入大括号(初始化列表)以防止收缩转换( narrowing conversion )
● 小心区分 = 与 ==
● 复合赋值运算符
交换x,y:
E、自增与自减运算符
● ++; –
● 分前缀与后缀两种情况
- 操作数为左值;前缀时返回左值操作完之后的;后缀时返回操作之前的右值
● 建议使用前缀形式
F、其它操作符
● 成员访问操作符: . 与 ->
– -> 等价于 (*).
– . 的左操作数是左值(或右值),返回左值(或右值 xvalue ),和返回类型相同
– -> 的左操作数指针,返回左值
● 条件操作符
– 唯一的三元操作符: ?:
,可以嵌套
– 接收一个可转换为 bool 的表达式与两个类型相同的表达式,只有一个表达式会被求值
– 如果表达式均是左值,那么就返回左值,否则返回右值
– 右结合,嵌套多层的?:
会先转换成 单个的 ?:
G:其他操作符:
逗号操作符
– 确保操作数会被从左向右求值
– 求值结果为右操作数
– 左结合
●sizeof 操作符
– 操作数可以是一个类型(需要加括号)或一个表达式
– 并不会实际求值,而是返回相应的字节尺寸
● 其它操作符
– 域解析操作符 ::
– 函数调用操作符 ()
– 索引操作符 []
– 抛出异常操作符 throw
– …
在 C++17 中,可以确保 e1 会先于 e2 被求值
– e1[e2]
– e1.e2
– e1.e2
– e1→e2
– e1<<e2
– e1>>e2
– e2 = e1 / e2 += e1 / e2 *= e1… (赋值及赋值相关的复合运算)
● new Type(e) 会确保 e 会在分配内存之后求值
相关文章:

深蓝学院C++基础与深度解析笔记 第 4 章 表达式
第 4 章 表达式 一、表达式基础 A、表达式: 由一到多个操作数组成,可以求值并 ( 通常会 ) 返回求值结果: #include <iostream> int main(){int x;x 3; }最基本的表达式:变量、字面值通常来说,表达式会包含操作符(运算符…...
CLION开发STM32之W5500系列(一)
开篇说明 本系列适用于需要使单片机通过网口进行通信的开发。针对的是刚入门的同学们,也是个人的经验分享。本次使用到的芯片为stm32f103vet6(其他的也可以)本次使用的网口模块为W5500,其网关有示例程序均可以参考.本次使用Clion+OpenOCD+ARM-GCC 进行开发、烧录、编译.建议熟…...

Web3通过ganache运行起一个本地虚拟区块链
通过文章 Web3开发准备工作 手把手带你创建自己的 MetaMask 账号大家简单的对网络 有了个比较模糊的概念 不同的网络连接这不同的区块链 那么 我们就要搞清楚 我们切换不同的网络 我们的数字资产是不一样的 在这里 我们需要先安装一个插件工具 ganache 我们先在本地创建一个文…...
01 背包问题解析与代码 python 实现
01 背包问题解析与代码 问题定义 给定一堆具有不同重量 { w 1 , w 2 , ⋯ , w n } \{ w_1,w_2, \cdots,w_n \} {w1,w2,⋯,wn}与价值 { v 1 , v 2 , ⋯ , v n } \{ v_1,v_2, \cdots,v_n \} {v1,v2,⋯,vn}的背包(knapsack),在总重…...
Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能
Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能 在前端展示上传的视频列表时,我们可以使用Element-UI中的Card组件来实现。同时,我们还可以添加一些功能,如缓存播放的视频、选择视频文本特征提取处理、写笔记、删除视频、组…...

多传感器时频信号处理:多通道非平稳数据的分析工具(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

数据结构算法 -分而治之算法
引言 坤坤是一个养鸡场的员工,他非常热爱他的工作,并且总是努力提高他的专业技能。有一天,养鸡场接到了一项任务:在短时间内处理一批大量的鸡。 这批鸡数量非常大,比普通的数量要多得多,坤坤意识到他们需…...
涉密信息系统口令管理制度
第一条 口令是涉密信息系统身份认证的基本防护措施,为保障 涉密信息系统的安全运行,规范网络用户及系统口令,特制定本制度。 第二条 具有口令功能的计算机、网络设备等计算机信息系统设 备,必须使用口令对用户的身份进行验证…...
UML与流程图
UML简介 UML(Unified Modeling Language,统一建模语言)是一种用于软件系统分析与设计的标准化建模语言。它提供了一套丰富的图形符号和规则,可用于描述系统的结构、行为和交互,帮助开发人员、设计师和利益相关者之间进…...

音视频开发Level0: 入门级20~25k的工作
今天给大家分享一个音视频开发领域,入门级别的工作,要求不高。 主要做什么呢,行车记录仪,运动相机,各种拍摄器材包括医疗领域的喉镜啊,等等。 这种产品,招人的公司深圳最多,因为深…...

Git第一章、Git的原理与使用
目录 一、Git安装 1.1Linux Centos安装 二、Git基本操作 2.1创建 Git 本地仓库 2.2配置Git 三、认识工作区、暂存区、版本库 3.1添加文件(场景一) 3.2修改文件 3.3版本回退 四、撤销修改 4.1情况一:对于工作区的代码,还…...

软件开发流程
目录 软件软件开发流程的演变 瀑布模型敏捷模型 XPSCRUMDevOps 1.软件 与计算机系统操作有关的计算机程序、可能有的文件、文档及数据。 软件可以分为两种主要类型: 独立软件:独立软件是一种完整的应用程序,可以直接在计算机或移动设备上…...

编程语言的优劣评选标准与未来发展趋势——探索最佳编程语言选择
编程语言的优劣评选标准与未来发展趋势——探索最佳编程语言选择 评判标准不同编程语言的优点与缺点分析对编程语言未来发展的猜测和未来趋势 💕 💕 💕 博主个人主页: 汴京城下君–野生程序员💕 💕 &#x…...

axios 发送请求请求头信息不包含Cookie信息
问题 axios 发送请求请求头信息不包含Cookie信息 详细问题 使用VueSpringBoot进行项目开发,axios进行网络请求,发送请求,请求头信息不包含Cookie信息 具体如下 实际效果 预期效果 解决方案 作用域 Vue项目全局配置 打开Vue项目的入口…...
正则表达式笔记
/你的正则表达式写在这里/ 1? 1出现0次或1次 1* 1出现0次或多次 1 1出现1次或多次 1{2} 1出现了2次 1{2,3} 1出现了2到3次 1{2,} 1出现了2次及以上 (5555){1} 5555出现了1次 (dog|cat) dog或者cat [a-zA-Z] a…...

数据结构链表(C语言实现)
绪论 机遇对于有准备的头脑有特别的亲和力。本章将讲写到链表其中主要将写到单链表和带头双向循环链表的如何实现。 话不多说安全带系好,发车啦(建议电脑观看)。 附:红色,部分为重点部分;蓝颜色为需要记忆的…...

Springboot实现接口传输加解密
前言 先给大家看下效果,原本我们的请求是这样子的 加密后的数据传输是这样子的 加解密步骤: 1.前端请求前进行加密,然后发送到后端 2.后端收到请求后解密 3.后端返回数据前进行加密 4.前端拿到加密串后,解密数据 加解密算法&…...
TypeScript类型系统:强类型的优势和使用方式
目录 引言强类型的优势更好的代码可读性更好的代码可维护性更好的代码重构能力更好的代码可靠性更好的代码重用能力 使用方式声明变量类型函数参数和返回值类型类型别名泛型类型(了解) 总结 引言 在上一篇文章《TypeScript入门指南:从JS到TS的…...
有没有可以代替风铃系统的专业问卷工具?
风铃系统问卷是一种流行的调查和数据分析工具,已广泛应用于学术研究、市场营销和社会科学。然而,有几种替代产品提供了与风铃系统类似的特性和功能,可以被企业用来进行调查和分析数据。在这篇文章中,我们将介绍风铃系统的十大替代…...

【数字调制】数字调制技术FSK与PSK分析与研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...