深蓝学院C++基础与深度解析笔记 第 4 章 表达式

news2024/11/18 12:35:29

第 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_castconst_castdynamic_castreinterpret_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) {
    // 转换成功,可以安全使用 derivedPtr
    derivedPtr->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 会在分配内存之后求值

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

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

相关文章

Vue3项目中引入ElementUI使用详解

目录 Vue3项目中引入 ElementUI1.安装2.引入2.1 全局引入2.2 按需引入viteWebpack 3.使用 Vue3项目中引入 ElementUI ElementUI是一个强大的PC端UI组件框架&#xff0c;它不依赖于vue&#xff0c;但是却是当前和vue配合做项目开发的一个比较好的ui框架&#xff0c;其包含了布局…

TensorFlow详细配置(Python版本)

文章目录 TensorFlow详细配置(Python版本)安装Python环境&#xff08;Python全家桶 Anaconda3&#xff09;环境配置TensorFlow官网对照表CUDA安装cuDNN 安装TensorFlow安装Jupyter Notebook使用方法其他问题 TensorFlow详细配置(Python版本) 安装Python环境&#xff08;Python…

51 最佳实践-安全最佳实践-qemu-ga

文章目录 51 最佳实践-安全最佳实践-qemu-ga51.1 概述51.2 操作方法 51 最佳实践-安全最佳实践-qemu-ga 51.1 概述 qemu-ga&#xff08;Qemu Guest Agent&#xff09;它是运行在虚拟机内部的守护进程&#xff0c;它允许用户在host OS上通过QEMU提供带外通道实现对guest OS的多…

【面试】线上Java程序占用 CPU 过高请说一下排查方法?

文章目录 前言模拟一个高 CPU 场景排查步骤第一步&#xff0c;使用 top 找到占用 CPU 最高的 Java 进程第二步&#xff0c;用 top -Hp 命令查看占用 CPU 最高的线程第三步&#xff0c;保存线程栈信息第四步&#xff0c;在线程栈中查找最贵祸首的线程 前言 这个问题可以说是 Ja…

【java】JDK21 要来了

文章目录 前言更丝滑的并发编程模式虚拟线程&#xff08;Virtual Threads&#xff09;结构化并发&#xff08;Structured Concurrency&#xff09;作用域值&#xff08;Scoped Values&#xff09; 试验一下虚拟线程的例子结构化编程的例子Scoped Values 的例子 前言 不过多久&…

算法与数据结构——递归算法+回溯算法——八皇后问题

八皇后问题 八皇后问题是一个经典的回溯算法问题&#xff0c;目的是在88的国际象棋棋盘上放置八个皇后&#xff0c;使得没有皇后可以互相攻击&#xff08;即没有两个皇后在同一行、同一列或同一对角线上&#xff09;。 回溯算法是一种解决问题的算法&#xff0c;它通过尝试所有…

软件质量保障QA

软件质量保障 目录概述需求&#xff1a; 设计思路实现思路分析1.alibaba guileline2.ckeckstyle3.findBugs4.PMD5.SourceMononiot 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness…

2014年全国硕士研究生入学统一考试管理类专业学位联考英语(二)试题

2014年全国硕士研究生入学考试英语(二)试题 Section I Use of English Directions:   Read the following text. Choose the best word(s) for each numbered blank and mark A, B, C or D on ANSWER SHEET. (10 points)   Thinner isn’t always better. A number of st…

软考A计划-网络工程师-交换机与路由器的配置

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

MyBatis­-Plus入门

目录 1.特性&#xff1a; 2.mybatis-plus 快速使用 3.mybatis与mybatis-plus实现方式对比 4.BaseMapper接口介绍 5.mybatis-plus中常用的注解 7.全局ID生成策略 8.逻辑删除&#xff08;1&#xff1a;局部逻辑删除&#xff1b;2&#xff1a;全局逻辑删除&#xff09; 8.…

Java代码质量分析Sonar

目录 1. sonar安装1.1 简介1.1.1 客户端1.1.2 sonar 版本区分1.1.2.1 社区版1.1.2.2 开发者版1.1.2.3 企业版 1.2 安装部署1.2.1 修改文件句柄数1.2.2 创建挂载目录1.2.3 创建docker-compose.yml1.2.4 启动1.2.4.1 访问测试 1.2.5 安装插件1.2.5.1 汉化插件 1.3 静态分析插件介…

新手快速搭建springboot项目

一、创建项目 1.1、创建项目 1.2、配置编码 1.3、取消无用提示 1.4、取消无用参数提示 二、添加POM父依赖 <!-- 两种方式添加父依赖或者import方式 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-p…

redis-conf

1 大小写不敏感 2 包含文件 3 网络 4 通用配置 5 快照 6 复制 -----待补充 7 安全 security 8 限制 clients 9 APPEND ONLY MODE aof模式

OpenCV项目开发实战-- 将一个三角形变形为另一个三角形 ( C++ / Python )代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:左图中蓝色三角形内的所有像素都已转换为右图中的蓝色三角形。 在本教程中,我们将看到如何将图像中的单个三角形变形为不同图像中的另一个三角形。 在计算机图形学中,人们一直在处理扭曲三角形,因为任何 3D 表…

hadoop集群三之hive安装

这里记录下自己使用虚拟机详细安装hive的过程&#xff0c;在安装hive之前需要保证咋们已经安装好了hadoop&#xff0c;没有的话可以参考我之前的安装的流程 安装mysql # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022# 安装Mysql yum库 rpm -Uvh http…

初识 Linux 进程

问题 strace 输出中的 execve(...) 究竟是什么&#xff1f; 进程生命周期 操作系统内部定义了进程的不同状态 Linux 进程基本概念 进程是 Linux 任务的执行单元&#xff0c;也是 Linux 系统资源的分配单元 每个 Linux 应用程序运行后由一个或多个进程构成 每个 Linux 进程可…

对称密钥【密码学】(四)

一、前言 在使用单向散列函数校验数据完整性时&#xff0c;需要保证原始的散列值不能被更改。 因此&#xff0c;在很多场景下&#xff0c;我们并不能仅仅通过单向散列函数来解决完整性问题&#xff0c;还需要其他技术来解决这个问题&#xff0c;如加密技术。 本篇博客就来介绍…

CloudFlare系列--使用第三方来自定义CSDN的IP(蓝精灵)

原文网址&#xff1a;CloudFlare系列--使用第三方来自定义CSDN的IP(蓝精灵)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍CloudFlare的CDN如何自定义第三方IP。 概述 CloudFlare官网接入域名的方式只能是 NS 接入&#xff0c;这样默认DNS服务器只能改为CloudFlare的DNS服…

从零开始Vue项目中使用MapboxGL开发三维地图教程(七)创建一个自动旋转的地球、添加一个3D模型、实现在两个地图之间滑动和同步来比较两个地图

目录 1、创建一个自动旋转的地球地图2、添加一个3D模型3、一个页面创建两个底图之间滑动 1、创建一个自动旋转的地球地图 实现功能&#xff1a;地球仪和camera动画结合在一起&#xff0c;创建旋转行星效果。 实现思路&#xff1a;通过在动画结束时调用easeTo&#xff0c;旋转…

软考A计划-网络工程师-IP,TCP,UDP,ICMP报头

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…