C++-在返回int的函数中通过引用传递参数
C++ - passing parameter by reference in a function which returns int
我创建了一个C++程序,以测试通过引用传递函数参数的功能。
#include <iostream>
using namespace std;
int f(int &b) {
b = b + 1;
cout << b << endl;
return b;
}
int main() {
int t = 10;
cout << f(t) << " " << t << endl;
//cout << f(&t) << " " << t << endl;
system("PAUSE");
return 0;
}
你能解释一下为什么这个程序在执行f
函数后不会影响t
的值吗?传递的b
参数是引用,所以我认为它的值会在程序执行后发生变化,因为我使用的是主函数中的实际变量,而不是它的副本。在这种情况下,我希望它是11,但它不受程序执行的影响。
为什么会发生这种情况?
t
的值会递增。如果您将输出语句一分为二,就会看到这一点:
cout << f(t) << endl;
cout << t << endl;
使用您的原始单一输出语句:
cout << f(t) << " " << t << endl;
编译器可以在f(t)
之前自由评估t
,从而生成您所看到的输出。有关更多信息,请参阅cout<lt;调用它打印的函数的顺序?
您的代码有未定义的行为,因为它没有定义在语句中副作用发生的时间点。
它类似于
cout << i++ << ++i;
根据编译器的不同,您可能会得到不同的结果。
该语言没有指定运算符参数的求值顺序,因此未指定cout
表达式是在函数调用之前还是之后取t
的值。
如果你引入一个序列点,你会看到预期的结果,也许可以把它分成两个表达式:
cout << f(t) << " ";
cout << t << endl;
您被输出顺序绊倒了。如前所述,t
确实会递增,但您可能会对输出的顺序感到困惑。
然而,我喜欢回避一些问题,并试图弄清楚如何让人们不仅理解眼前的问题,而且理解他们最初遇到困难的原因,这一点我很清楚
您需要学习调试器
通过使用一个,您可以逐步遍历代码,在任何给定点看到t
的值,也可以看到,几乎不需要您付出任何努力,它确实会增加(包括确切的时间和方式)。通过使用调试器(包括递归等概念)跟踪代码,您还可以更好地了解代码的工作方式。
我建议您立即开始这方面的工作,因为这将让您了解代码的实际工作方式,而无需通过输出语句来猜测。
我想您会遇到涉及序列点的问题。您正在同一表达式中修改和打印t
的值。
编译器决定评估t
的顺序和决定评估f(t)
的顺序是未定义的。因此,函数可能不会像您想象的那样首先被调用。
如果您将打印分解为两个语句,那么您将看到t
实际上发生了更改。例如:
cout << f(t) << " ";
cout << t << endl;
将具有您期望的输出。
- 将const引用参数初始化为默认参数会导致悬空引用吗
- 具有常量引用参数的函数模板专用化
- C++:常量引用参数
- 字符串引用参数的效率C++
- 通过非常量引用参数修改常量引用参数
- 如何将指针变量作为引用参数传递?
- C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
- 移动类的成员作为常量引用参数传递
- C++带有适用于左值和右值的引用参数的函数
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- 如何使用类型特征将函数的通用引用参数限制为 r 值引用?
- 委托构造函数和引用参数
- 对 const 引用参数使用默认值会导致崩溃
- 为什么我们不允许将纯引用参数传递给 std::thread,但允许传递原始指针?
- 为什么我需要将默认引用参数定义为 const 以便为其分配一个左值?
- 将非左值作为常量引用参数传递.临时是在本地作用域还是在调用方作用域中创建的?
- 如何强制函数仅接受左值引用参数
- 模板引用参数推断失败C++
- 非类型引用参数可以在运行时修改,这是否意味着模板可以在运行时实例化?
- 将unique_ptr作为引用参数或常量传递unique_ptr引用