【问题标题】:Can someone explain me how exactly this code is executed?有人可以解释一下这段代码是如何执行的吗?
【发布时间】:2015-03-31 19:46:25
【问题描述】:

有人能解释一下代码是如何在这里执行的吗?我不明白第二行的输出是 8 7 8,而第三行的输出是 21 20 21。

#include<iostream>
using namespace std;
//Funtion passed by value and by reference
int fn1(int &a, int b, int *c){
   a=b++;
   b+=7;
   *c= ++a;

   return b;
}

int main(){
   int x=4, y=7, z=14;
   cout<< x<< " " << y<< " "<< z<< endl; // output: 4 7 14
   fn1(x,y,&z);
   cout<< x<< " " << y<< " "<< z<< endl; // output: 8 7 8 (I dont get this part!!!)
   x=9, y=12, z=19;

   y=fn1(x,y,&z);
   fn1(x,y,&z);
   cout<< x<< " " << y<< " "<< z<< endl; // output: 21 20 21(I dont get this part!!!)
   return 0;
}  

【问题讨论】:

标签: c++


【解决方案1】:

您正在为传递的 b 和 c 的地址创建引用

a is a reference to x hence any change in value of a is reflected in x
since y is passed by value any change in value of b will not change y
and for z as its address is passed any change to the location will be reflected in z

for a = b++
a gets the value 7 and b is incremented to 8(post increment)
b+=7
*c = ++a
a will become 8 and will get assigned to address pointed by c
hence you get output as 8 7 8 as x will be a y will remain 7 and z will be c

接下来的两次调用相同

【讨论】:

  • 感谢您的解释。你能解释第3行的输出吗?当我们说 y=fn1(x,y,&z) 时发生了什么?
  • b 的值首先在 fn1 中递增,因此变为 13,然后将 7 添加到 b,使其变为 20。现在返回的 b 的值分配给 y。因此在 y=fn1(x ,y,&z) x = 13 y = 20 and z = 13 现在对 fn1(x,y,&z) 的第二次调用有 a = 13 b = 20 和 c = 13 现在在第一行 a=b++ a 变为 20 b 在 b += 7 行中变为 21 b 在 *c = ++a a = 21 和 c = 21 行中变为 21。由于变化是 b 未反映在 y 中,最终值将是 x = 21 y = 20 和 z = 21
【解决方案2】:

虽然我不确定您对输出的期望,但我确实看到了一件事可能不是故意的。

请注意,您的函数 fn1 返回一个 int,但是当您在第 20 行调用它时,它不会用于更新您的任何变量。也许您的意思是更新 y 的值?

此外,您可以通过添加打印语句来查看内部变量如何迭代,从而更好地了解函数的工作原理:

int fn1(int &a, int b, int *c){
   a=b++;
   cout << "a: " << a << " ";
   b+=7;
   cout << "b: " << b << " ";
   *c= ++a;
   cout << "c: " << *c << endl;

   return b;
}

【讨论】:

    【解决方案3】:

    第一个输出非常简单,而在第二个输出中唯一的区别是函数的返回值,即

    b+=7
    

    用于重写Y的原始值。然后使用 Y 的新值再次调用该函数。

    【讨论】:

      【解决方案4】:

      第二行:

      xfn1修改,因为第一个参数是通过引用传递的。

      zfn1 修改,因为指向z 的指针被传递给函数。

      第一行:

      a = b++
      

      7 分配给a,因为b7b++ 是一个后增量函数。

      c = ++a
      

      a 递增到8 并将8 分配给c,因为++a 是一个预递增函数。

      第 3 行也是如此。

      【讨论】:

        【解决方案5】:

        在您的int fn1(int &amp;a, int b, int *c) 函数中:

        a 通过引用传入。
        b 通过值传入。
        c 通过指针传入。

        a = b++; 修改 x,因为 ax 的引用。
        b += 7; 修改 b 但不是 y,因为 b 只是 y 的值。
        *c = ++a; 修改了xz,因为ax 的引用,而c 是指向z 的指针。

        当你使用引用和指针时,你可以直接将值写入它们自己的内存空间。但是,当您按值使用时(想想b),会在当前范围内(fn1 函数内部)创建一个新变量,并且对它的任何更改都与该范围隔离。

        查看此 SO 答案以了解有关 C++ 范围的更多信息。 https://stackoverflow.com/a/11345787/1000437

        希望这会有所帮助。

        【讨论】:

          【解决方案6】:

          我会尽力解释。如果您有足够的耐心,这些指针真的很有趣且功能强大:

          fn1(x,y,&z);
          cout<< x<< " " << y<< " "<< z<< endl; 
          // output: 8 7 8 (I dont get this part!!!)
          

          我们来看看我们的函数fn1

          int fn1(int &a, int b, int *c){
          a=b++;
          b+=7;
          *c= ++a;
          
          return b;
          }
          

          首先,请注意fn1(int &amp;a) 中的变量 a 是通过引用传递的,而不是通过值传递的。这意味着我们将直接使用我们传递给 a 的值进行操作。这基本上意味着如果您在函数内部更改 a 的值,该更改将持续。因此,由于 int x=4, y=7, z=14; 和我们调用 fn1(x, y, &amp;z) ,我们将变量 x 传递给 a(将其视为将其暂时从 x 重命名为 a)。所以a最初是4。b只是一个值,所以y的内容被传递给b,*c是一个指针,只是将z的物理地址作为值(这就是你有fn1(&amp;z)的原因)。

          所以当我们调用函数fn1(x, y, &amp;z) 时,我们会执行:

          a=b++;
          

          所以 a 更改为 7,b 更改为 8。(如果这令人困惑,请阅读有关操作符的介绍 this) 那么:

          b+=7; //same as: b=b+7;
          

          所以 b 取值 8+7=?? (对不起!我没有数学学位!)

          最后:

          *c= ++a;
          

          现在,既然我们有 ++a,首先 a 更改为 a=a+1,现在取值 8,因为它是 7!而 *c 的意思是“指针 c 指向的变量的值”:所以 c 指向的变量的值是z。所以 z 的值变成了 a 的值(即 8)。

          现在是最后一步(这次是真的)。为什么y 没有变化? 因为我们fn1 通过值而不是引用来获取 b,并且当函数结束时, var b 被销毁。

          现在尝试做第二部分:

           y=fn1(x,y,&z);
          

          在这种情况下,y 将接受 fn1 返回的任何内容! 我真的建议你采取一步一步的方法。如果它仍然令人困惑,请分别练习通过 ref、val 和稍后通过指针传递的每种 var 类型的行为。

          【讨论】:

          • 非常感谢您的友好解释。帮了大忙。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-06
          相关资源
          最近更新 更多