首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++17 新的求值顺序规则:小白友好版指南

C++17 新的求值顺序规则:小白友好版指南

原创
作者头像
码事漫谈
发布2025-01-21 19:07:31
发布2025-01-21 19:07:31
24100
代码可运行
举报
文章被收录于专栏:C++C++
运行总次数:0
代码可运行
生成动漫图片.png
生成动漫图片.png

嘿,C++ 小白们!今天,我们要聊一个听起来有点枯燥,但实际上超重要的话题——C++17 中的求值顺序规则。别急,我会用最通俗易懂的方式,带你一步步搞懂这个知识点,让你在编程路上少走弯路,写出更安全、更可靠的代码。别看这些规则好像很抽象,它们可是能实实在在帮到我们这些初学者的呢!

一、求值顺序:编程中的“先后顺序”

想象一下,你同时在做几件事情,比如一边听歌一边写作业。你可能会先打开音乐播放器,再拿出作业本开始写。在编程的世界里,计算机执行代码也是一样,它需要知道先做什么、后做什么,这就涉及到“求值顺序”这个概念。

在 C++ 中,求值顺序就是指表达式中各个子表达式(你可以把它们想象成一个个小任务)的计算顺序。就好比你先穿袜子再穿鞋,而不是反过来,这样才不会出错。在 C++17 之前,很多复杂表达式的子表达式求值顺序是未定义的,这就像是在做事情时顺序混乱,可能会导致程序行为的不确定性,尤其是在涉及到函数参数传递时,很容易让人头大。

二、C++17 中的求值顺序大变革

好消息是,C++17 对求值顺序的规则进行了明确,这就好比给我们提供了一份清晰的“做事指南”,让代码的行为更加可预测。这些变化主要集中在以下几个方面:

(一)函数参数的求值顺序:从左到右

在 C++17 之前,函数参数的求值顺序是未指定的。这就像是你和朋友约好一起去吃饭,但没说好是先去你家拿东西还是直接去餐厅,结果每次都不一样,很容易让人困惑。但现在,C++17 明确规定,函数参数的求值顺序是从左到右。这就像是约定好了先去你家,再去餐厅,顺序固定了,就不会再出现混乱的情况了。

举个栗子:

代码语言:cpp
代码运行次数:0
运行
复制
int func(int, int);

int a = 1;
int b = func(a++, a); // 在 C++17 中,a++ 先求值,然后是 a

在 C++17 之前,这段代码中 a++ 和 a 的求值顺序是不确定的,可能会导致 func 接收到的参数是 (1, 1) 或 (2, 1),让人摸不着头脑。但在 C++17 中,a++ 会先于 a 被求值,因此 func 接收的参数将是 (1, 2),这就清晰多了!

(二)赋值表达式的求值顺序:先左后右

赋值表达式就像是你把一样东西从一个地方搬到另一个地方。在 C++17 中,赋值符号左侧的操作数(接收值的部分)总是在右侧的操作数(赋值的值)之前被求值。这就像是你先确定好要放东西的位置,再去拿东西,而不是反过来。

例如:

代码语言:cpp
代码运行次数:0
运行
复制
int x = 1;
int y = 2;
int z = 3;

z = x++ + y; // 先求 x++,然后是 y,最后赋值给 z

在这个例子中,x++ 的求值结果是 1(因为 x 的值先被使用,然后才加 1),然后 y 的值是 2,所以 z 被赋值为 3。这就像是你先确定好 z 的位置,然后从 x 和 y 那里“搬”来值,最后放到 z 的位置上。

(三)初始化列表的求值顺序:从左到右

初始化列表就像是你准备的一份清单,上面列出了要做的事情或要准备的东西。在 C++17 中,初始化列表中的表达式现在保证按照它们在列表中出现的顺序从左到右求值。这就像是你按照清单上的顺序一项项准备,不会出现遗漏或混乱的情况。

例如:

代码语言:cpp
代码运行次数:0
运行
复制
class MyClass {
public:
    MyClass(int, int, int);
};

MyClass obj(1, 2, 3); // 初始化列表中的值按从左到右的顺序求值

在这个例子中,MyClass 的构造函数接收三个参数,初始化列表中的值 1、2、3 会按照从左到右的顺序依次传递给构造函数,这就保证了参数的顺序和预期一致。

三、实际应用示例:用新规则写出安全代码

(一)函数参数求值顺序的应用

我们再来看一个函数参数求值顺序的例子,这次我们用一个稍微复杂点的例子来说明:

代码语言:cpp
代码运行次数:0
运行
复制
#include <iostream>

int increment(int& x) {
    return ++x;
}

void printValues(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}

int main() {
    int x = 1;
    printValues(increment(x), increment(x), increment(x));
}

在 C++17 之前,这段代码中 increment(x) 的求值顺序是不确定的,可能会导致输出结果混乱。但在 C++17 中,由于函数参数的求值顺序是从左到右,所以 increment(x) 会依次被求值,输出结果将是:

代码语言:cpp
代码运行次数:0
运行
复制
a: 2, b: 3, c: 4

这就清晰地展示了 x 的值是如何依次增加并传递给 printValues 函数的。

(二)赋值表达式求值顺序的应用

再来看一个赋值表达式求值顺序的例子:

代码语言:cpp
代码运行次数:0
运行
复制
int a = 1;
int b = 2;
a = b = 3; // 先求 b = 3,然后将结果赋值给 a

在这个例子中,赋值表达式 b = 3 先被求值,b 的值变为 3,然后 a 被赋值为 b 的值,也就是 3。这就像是你先给 b 准备了一份礼物(值 3),然后再把这份礼物转送给 a,顺序非常清晰。

四、结论:新规则让编程更简单

C++17 的求值顺序规则的更新,就像是给我们这些编程新手提供了一份详细的“操作手册”,让我们在写代码时不再迷茫。这些改变有助于避免一些常见的编程错误,特别是在涉及复杂表达式和多线程环境下。作为一个 C++ 开发者,理解并正确应用这些新规则是非常重要的,它将帮助你提高代码的质量和性能。

希望这篇文章能够帮助你理解 C++17 中求值顺序的新规则,并在你的编程实践中得到应用。别忘了,编程就像是一场冒险,而这些规则就是我们的指南针,帮助我们在编程的海洋中找到正确的方向。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、求值顺序:编程中的“先后顺序”
  • 二、C++17 中的求值顺序大变革
    • (一)函数参数的求值顺序:从左到右
    • (二)赋值表达式的求值顺序:先左后右
    • (三)初始化列表的求值顺序:从左到右
  • 三、实际应用示例:用新规则写出安全代码
    • (一)函数参数求值顺序的应用
    • (二)赋值表达式求值顺序的应用
  • 四、结论:新规则让编程更简单
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档