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

这篇具有很好参考价值的文章主要介绍了深蓝学院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 : 将亡值:表示其资源可以被重新使用,在内存销毁前把内容保留下来
深蓝学院C++基础与深度解析笔记 第 4 章 表达式
decltype(实体/表达式)
深蓝学院C++基础与深度解析笔记 第 4 章 表达式
● 左值与右值的转换
– 左值转换为右值( 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、位操作符
~:按位取反
深蓝学院C++基础与深度解析笔记 第 4 章 表达式
深蓝学院C++基础与深度解析笔记 第 4 章 表达式

接收右值,进行位运算,返回右值
● 除取反外,其它运算符均为左结合的
● 注意计算过程中可能会涉及到整形提升 integral promotion
● 注意这里** **
● 移位操作在一定情况下等价于乘(移位 :左移<< 1(乘2的1次)、右移>>1(除2)) 2 的幂,但速度更快
<<n : 乘2的n次 >>n : 除2的n次
● 注意整数的符号与位操作符的相关影响
– integral promotion 会根据整数的符号影响其结果
– 右移保持符号,但左移不能保证

D、赋值操作符
● 左操作数为可修改左值;右操作数为右值,可以转换为左操作数的类型
● 赋值操作符是右结合的:先处理右侧的
● 求值结果为左操作数
● 可以引入大括号(初始化列表)以防止收缩转换( narrowing conversion )
● 小心区分 = 与 ==
● 复合赋值运算符
交换x,y:
深蓝学院C++基础与深度解析笔记 第 4 章 表达式

E、自增与自减运算符
● ++; –
● 分前缀与后缀两种情况

  • 操作数为左值;前缀时返回左值操作完之后的;后缀时返回操作之前的右值

● 建议使用前缀形式

F、其它操作符
● 成员访问操作符: . 与 ->
– -> 等价于 (*).
– . 的左操作数是左值(或右值),返回左值(或右值 xvalue ),和返回类型相同
– -> 的左操作数指针,返回左值
● 条件操作符
– 唯一的三元操作符: ?:,可以嵌套
深蓝学院C++基础与深度解析笔记 第 4 章 表达式

– 接收一个可转换为 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 会在分配内存之后求值文章来源地址https://www.toymoban.com/news/detail-490248.html

到了这里,关于深蓝学院C++基础与深度解析笔记 第 4 章 表达式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【深蓝学院】移动机器人运动规划--第2章 基于搜索的路径规划--笔记

    Configuration Space等概念 机器人配置: 指机器人位置和所有点的表示。 DOF: 指用于表示机器人配置所需的最小的实数坐标的数量n。 C-space: 包含机器人n维所有配置的空间。 在C-space中机器人的pose是一个点。 机器人在C-space中被表示为一个点,pose包含为R,t 空间中的障碍物也需要映

    2024年01月22日
    浏览(49)
  • Go语句与表达式深度解析:全案例手册

    关注公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。 语句是Go编程

    2024年02月09日
    浏览(41)
  • 深度解析Cron表达式:精确控制任务调度的艺术

    深度解析Cron表达式:精确控制任务调度的艺术 希望我们都可以满怀期待的路过每一个转角 去遇见 那个属于自己故事的开始 去追寻那个最真实的自己 去放下 去拿起 安然,自得,不受世俗牵绊… 导言 在计算机科学领域,任务调度是一项关键的工作。而Cron表达式就是一种强

    2024年02月02日
    浏览(41)
  • 【C++】lambda表达式语法详细解读(代码演示,要点解析)

    前言 大家好吖,欢迎来到 YY 滴C++系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初学者易

    2024年02月03日
    浏览(49)
  • C++复习笔记--Lambda表达式

    ① [] 用于捕获变量,一般用于使用和修改外部的变量,可以为空; ② (int a, int b) 表示参数列表,可以省略; ③ - int 定义返回类型,一般可以省略,让编译器自动推断; ④ auto f 表示将定义的 lambda 表达式赋值给对象 f,auto 用于自动推断类型; 基本用法如下: ① 使用和修

    2024年02月16日
    浏览(61)
  • 【23JavaScript 正则表达式】深入解析JavaScript正则表达式:基础概念、常用方法和实例详解,轻松掌握强大的文本模式匹配工具

    正则表达式是一种强大的文本模式匹配工具,用于在字符串中搜索和操作特定的文本模式。在JavaScript中,正则表达式提供了一种灵活的方式来处理字符串操作。 在JavaScript中,可以通过使用字面量表示法或RegExp对象来创建正则表达式。 字面量表示法 RegExp对象 JavaScript中的正则

    2024年02月08日
    浏览(64)
  • 【自学笔记】01Java基础-08Java常用API:05正则表达式与Lambda表达式

    记录Java基础-常用API-正则表达式与Lambda表达式的内容。 正则表达式在线练习网站 正则表达式是一种强大的文本处理工具,它使用特殊的字符和模式来匹配、查找、替换或提取字符串中的特定内容。 在Java中,正则表达式的功能主要通过 java.util.regex 包中的 Pattern 和 Matcher 类实

    2024年01月19日
    浏览(70)
  • Python学习笔记_基础篇(八)_正则表达式

    1.1. 简单介绍 正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只

    2024年02月12日
    浏览(57)
  • Golang通过栈实现表达式运算(中缀表达式转后缀表达式解析语法)

    需求背景:将string表达式数组 [title == AUSU ( header == Wecome || brand != AC68U )] 解析并使用ES查询得到运算结果。 分析:带有括号的表达式,需要根据优先级解析,可将中缀表达式转换为后缀表达式,去除括号

    2024年02月14日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包