【问题标题】:How do I read this small program?如何阅读这个小程序?
【发布时间】:2020-08-14 14:38:03
【问题描述】:

我一直在努力找出增量运算符与 b、c 的值之间的关系,以及引用符号在写入时更改值的方式。该程序打印出 8,但我不确定该参考在这种特殊情况下的实际作用。这是一个代码:

int fun1(int d) {
 ++d;
 return d++;
}
int fun2(int &d) {
 ++d;
 return d++;
}
int main(void) {
 int a = 1, b, c;
 b = fun1(a);
 c = fun2(b);
 cout << a + b + c << endl;
 return 0;
}

提前谢谢你!

【问题讨论】:

  • 使用调试器逐行遍历代码,查看变量中的值如何变化

标签: c++


【解决方案1】:

问题的症结在于代码的这一部分:

int fun1(int d) { }
int fun2(int &d) { }

第一个函数中的int d 是value semantics。这意味着传递给函数fun1 的变量的值是复制的,并且只知道fun1 的内部。

int &amp;d 是引用语义,这意味着传递给fun2 的变量被d 引用,因此如果您在fun2 内部修改d 实际值传递给fun2 的变量已更改。

在您的情况下,这意味着a 的值被fun1 复制,而fun2 更新b 的值。因为d 在fun2 中用作reference 到存储值的实际变量b。

还有更多关于这个程序打印的8 的值。 ++d 是前自增运算符,d++ 是后自增运算符。含义:

  • 预增量:先增加d,然后使用d的新值
  • 后增量:保留d 的值并使用它来做某事,然后增加d 的值

结合这些东西(值/引用语义和前/后增量的行为),我们得到 fun1 和 fun2 返回 d 的原始值,该值在返回原始值之前递增。所以return d++;相当于这段代码:

int returnvalue = d;
d = d + 1;
return returnvalue;

但是因为 fun2 在 main 中有一个对变量 b 的引用 d,所以 b 中的值加一,因为 d 在 return d++ 中后加。

ISOcpp value and reference semantics.和stackoverflow关于C++中指针和引用的区别。


如果您需要对这些术语及其含义进行更详细的解释,list of book 的建议非常棒。我的选择是 C++ 的创建者的 A Tour of C++。它很好地完成了您现在应该了解的有关 C++ 的所有内容,而且非常便宜。

【讨论】:

    【解决方案2】:

    由于第一个答案没有完全进入手头的示例,我将对此进行详细说明,因为它首先是一个棘手的 IMO 主题。

    int a = 1, b, c;
    

    这声明了三个 int 变量:a、b 和 c。它还使用值 1 初始化 a。b 和 c 接收整数的默认起始值​​,因此为 0。

    正如第一个答案提到的,fun1(int d) 将传递给它的变量的值复制到局部变量中,但不会更改原始变量。不过,++d 和 d++ 是怎么回事?这与执行操作的顺序有关。 ++d 取 d 的值,将其加一,然后将其分配回 d。另一方面,d++ 首先将d 的值赋回d(因此,如果在return 语句中使用,则从函数中返回它),然后再将其增加1。为什么这很重要?

    让我们记住fun1(a) 与局部变量一起工作,因此实际上不会更改变量a。 ++d 将局部变量增加 1,所以现在是 2。然后 d++ 返回 d (2) 的当前值,然后再次将局部变量增加 1——但这不会存储在任何地方在函数fun1() 之外。因此,变量 b 现在的值为 2。

    c = fun2(b);
    

    但情况不同。在这里,我们将变量 b 的引用传递给函数。所以++d 不仅增加了局部变量的值,而且增加了b 的值,现在是3。d++ 将此值返回给c(因此它被赋值为3),但也 将b 再次增加 1 到 4。为什么?因为d 是对b 的引用。

    因此,我们的最终值是:a = 1、b = 4、c = 3 和 1 + 4 + 3 = 8。

    【讨论】:

    • 当我们调用第一个函数 (fun1) 并将 ++d 分配给 b 时,我们得到 2,它增加了 1(结果中为 3),但没有存储 3 的值任何地方,所以结果仍然是2。在调用第二个函数(fun2)之后,经过几步之后b值从2增加到4。所以这意味着这次存储了4的值,因为b是a参考?
    • @Daniel4 差不多。第一个答案也被编辑以详细说明这个主题。但基本上,d++(后递增)首先返回 d 的值,然后递增它。在 fun1(int d) 中,这只增加了责任 d。在 fun2(int &d) 中,它增加了引用变量 b。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 2020-12-16
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    相关资源
    最近更新 更多