通过引用传递的指针随每次循环迭代更新:(完整性检查 - 第2部分)

时间:2016-04-24 17:49:10

标签: c++ pointers pass-by-reference

我正在努力掌握与指针和引用相关的概念。在下面的代码片段中,我在迭代链表时从for循环中多次调用函数shifting()。每次迭代时, int * ptr int count 都会更改并传递给函数shifting()。此外,一些其他指针和整数变量通过引用传递

疑惑:

  1. 我可以指定如shift()函数中所示的指针引用吗?整数val引用的问题相同。

  2. 后台发生了什么?我读到无法重新分配引用。每次调用shift()时都不是这种情况吗?

  3. 请注意,* ptr和count不会通过引用传递。它们只是被阅读。

    void shifting(int const * ptr, int const * &ptr6, int const * &ptr7, int const * &ptr8,
                  int count, int &val6, int &val7, int &val8)
    {
        ptr8 = ptr7;    val8 = val7;
        ptr7 = ptr6;    val7 = val6;
        ptr6 = ptr;     val6 = count;
    }
    
    int main()
    {
        int const *ptr6 = NULL;     int val6 = 0;
        int const *ptr7 = NULL;     int val7 = 0;
        int const *ptr8 = NULL;     int val8 = 0;
    
        int count = 0;
    
        // myList: a linked-list
        // front(): gives first element of list
        // back(): gives last element of list
        // nextElement(): gives next element of list
    
        for (int *ptr = myList.front(); ptr != myList.back(); ptr = nextElement();)
        {
            count++;
            shifting(ptr, ptr6, ptr7, ptr8, count, val6, val7, val8);
        }
    }
    

    编辑:我尝试了上面的示例(在此处发布后),只有整数部分,如下所示:

    #include <iostream>
    using namespace std;
    
    void shifting( int i, int &val6, int &val7, int &val8 )
    {
        val8 = val7;
        val7 = val6;
        val6 = i;
    }
    
    int main()
    {
        int val6 = 0;
        int val7 = 0;
        int val8 = 0;
    
        for (int i = 1; i <= 10; i++)
        {
            shifting(i, val6, val7, val8);
            cout <<"i: "<<i<<"  val6: "<<val6<<"  val7: "<<val7<<"  val8: "<<val8<<endl;
        }
    
        return 0;
    }
    

    我得到了如下输出。如何重新分配引用?我读过他们不应该重新分配。

    i: 1  val6: 1  val7: 0  val8: 0
    i: 2  val6: 2  val7: 1  val8: 0
    i: 3  val6: 3  val7: 2  val8: 1
    i: 4  val6: 4  val7: 3  val8: 2
    i: 5  val6: 5  val7: 4  val8: 3
    i: 6  val6: 6  val7: 5  val8: 4
    i: 7  val6: 7  val7: 6  val8: 5
    i: 8  val6: 8  val7: 7  val8: 6
    i: 9  val6: 9  val7: 8  val8: 7
    i: 10  val6: 10  val7: 9  val8: 8
    

2 个答案:

答案 0 :(得分:1)

  
      
  1. 我可以指定shift()函数中显示的指针引用吗?整数val引用的问题相同。
  2.   

是。但是当你这样做时,你要分配给指示物而不是参考物。

  

后台发生了什么?

这是(有效地)在后台进行的。也就是说,如果你想在没有引用的情况下达到相同的效果,你可以这样做:

void shifting(int const * ptr, int const ** ptr6, int const ** ptr7, int const ** ptr8,
              int count, int* val6, int *val7, int *val8)
{
    *ptr8 = *ptr7;    *val8 = *val7;
    *ptr7 = *ptr6;    *val7 = *val6;
    *ptr6 = ptr;      *val6 = count;
}

在你称之为的地方:

shifting(ptr, &ptr6, &ptr7, &ptr8, count, &val6, &val7, &val8);
  

我读到无法重新分配引用。

这是正确的。虽然我更喜欢重新绑定这个词。您可以执行看起来像是对引用的赋值。但这实际上是指称对象。实际上,在创建引用之后,其名称充当引用对象的别名。对引用的任何操作(decltype除外)就像在指示对象上完成一样。

  

每次调用shift()时,情况都不是这样吗?

没有。在引用上使用赋值运算符时,实际上是指定了引用,而不是引用。

你的例子非常复杂,也许更简单的事情会让事情变得清晰。

int a = 0;
int b = 77;
int& ra = a; // ra is a reference to a, and always will be
int& rb = b; // rb is a reference to b, and always will be
ra = b;      // ra is still a reference to a, but now a == 77
ra = 999;    // now a == 999
rb = ra;     // rb is still a reference to b, but now b == 999

为进一步澄清,上述例子与此完全相同:

int a = 0;
int b = 77;
a = b;
a = 999;
b = a;

或者这个例子使用指针:

int a = 0;
int b = 77;
int* pa = &a; // pa is a pointer to a, this can change, but won't in this example
int* pb = &b; // pb is a pointer to b, this can change, but won't in this example
*pa = b;      // pa is still a pointer to a, but now a == 77
*pa = 999;    // now a == 999
*pb = *pa;    // pb is still a pointer to b, but now b == 999

答案 1 :(得分:1)

我认为通过在函数和调用者之间重用变量名称可能会让你自己感到困惑:例如,在移位val6中是一个局部变量,绑定到调用它的任何东西,这恰好发生了是一个同名的外部变量。

#include <iostream>

void test(int& i) {
    std::cout << "test/i = " << i << '\n';
}

int main() {
    int i = 1;
    int j = 42;

    test(i);
    test(j);
}

此输出(参见http://ideone.com/lRNINP

test/i = 1
test/i = 42

作为本地引用的重要性在于它在函数迭代结束时消失,并在下一次迭代时使用新参数进行重组。

  

我得到了如下输出。如何重新分配引用?

他们不是,价值只是随着你的功能似乎正在改变:(见http://ideone.com/oCmOPk

#include <iostream>

int main() {
    int i = 0;
    int& ir = i;  // not an assignment, a binding
    ir = 1;  // pass '1' thru 'ir' to 'i'.

    std::cout << "ir " << ir << ", i " << i << "\n";

    int j = 0;
    int& jr = j;
    jr = 42;  // pass '42' thru 'jr' to 'j'

    std::cout << "jr " << jr << ", j " << j << "\n";

    ir = jr;  // pass the *value* of 'jr' thru 'ir' to 'i'
    j = 99;

    // if ir is rebound to jr, both of these will be 99.
    std::cout << "ir " << ir << ", i " << i << "\n";
    std::cout << "jr " << jr << ", j " << j << "\n";
}

输出:

ir 1, i 1
jr 42, j 42
ir 42, i 42
jr 99, j 99