【问题标题】:passing 1d and 2d arrays by reference in c++在 C++ 中通过引用传递 1d 和 2d 数组
【发布时间】:2014-05-26 22:56:24
【问题描述】:

我是 C++ 新手,并且有几个关于通过引用函数传递数组的问题(以便函数修改数组)。我意识到已经有人问过类似的问题,但是我认为之前的问题中没有涉及到几点(至少从我所看到的来看)。根据我目前收集到的信息,可以通过执行以下操作通过引用传递数组:

#include<iostream>
using namespace std;

void modify_array(int* a);

int main()
{
  int array[10];

  modify_array(&array[0]);

  for(int i=0;i<10;i++)
  {
    cout<<array[i]<<endl;
  }
}

void modify_array(int* a)
{
  int i;
  for(i=0;i<10;i++)
  {
    *(a+i)=i;
  }
}

这对我来说很有意义,但如果我将函数更改为:

void modify_array(int* a)
{
  int i;
  for(i=0;i<10;i++)
  {
    a[i]=i;  //line changed
  }
}

这也有效。有区别吗?还是第二个只是捷径?同样在传递二维数组的情况下,我猜想下面的代码会起作用:

#include<iostream>
using namespace std;

void modify_array(int* a);

int main()
{
  int array[10][10];

  modify_array(&array[0][0]);

}

void modify_array(int* a)
{
  int i,j;
  for(i=0;i<10;i++)
  {
    for(j=0;j<10;j++)
    {
      a[i][j]=i*j;
    }
  }
}

但事实并非如此。根据我在其他相关问题中看到的情况,您会执行以下操作:

void modify_array(int (*a)[10])
{ 
  int i,j;
  //a[i][j]= blah blah blah;
}

或者,

void modify_array(int (&a)[10][10])
{ 
  int i,j;
  //a[i][j]= blah blah blah;
}

后两个函数定义有什么区别?有经验的 c++ 程序员建议使用什么:(*a)[10][10] 表示法或 (&a)[10][10] 表示法?

【问题讨论】:

  • void modify_array(int* a); 采用指向整数块的指针或指向单个 int 的指针。可以堆栈或动态分配。 modify_array(int (&amp;a)[10]) 通过引用获取 10 个整数的数组。必须堆栈分配,大小不会丢失。可以使用 sizeof 运算符。
  • @CantChooseUsernames ok 那么a[i]=i 的使用是*(a+i)=i 的快捷方式吗?在主程序的这两种情况下,我们都通过modify_array(&amp;array[0]) 调用函数,因此我们将内存引用传递给数组的第一个元素,所以看起来a[i]=i 将更改内存位置而不是实际值。谢谢。
  • @FredOverflow 谢谢我实际上没有看到这个(正在查看其他一些问题)。不确定它是否回答了我的所有问题,但我会看看。

标签: c++ arrays pass-by-reference pass-by-value


【解决方案1】:

*(a+i)=i;a[i]=i; 是等价的。第一个被视为应用于指向数组的指针的偏移量并将值分配给指针对象,而第二个是将值分配给数组的元素。

但是,当传递一个指向函数modify_array(int* a) 的指针时,它不能推断出指针对象是一个二维数组,并且不知道要偏移多少大小来寻址数组的其他行,a[i][j]=i*j;。对于编译器来说,它只能访问数组的第一维。

做你需要的正确方法是这样

#include<iostream>
using namespace std;

void modify_array(int (&a)[10][10]);

int main()
{
  int array[10][10];

  modify_array(array);

  for(int i=0;i<10;i++)
  {
    for(int j=0;j<10;j++)
    {
      cout<<array[i][j]<<endl;
    }
  }
}

void modify_array(int (&a)[10][10])
{
  int i;
  for(i=0;i<10;i++)
  {
    for(int j=0;j<10;j++)
    {
      a[i][j]=i*j;
    }
  }
}

Live example

该函数需要一个 10x10 的 int 数组,通过引用传递。

【讨论】:

  • 好的,所以当我们通过modify_array(array) 调用程序主体中的函数时,我们通过引用发送这个 10×10 数组。那么程序实际上是否仍然只发送第一个元素 &array[0] 的内存地址?还是发送数组中所有元素的内存地址(即 100 个地址)?如果我们在函数中添加cout&lt;&lt;&amp;a&lt;&lt;endl; 行,它应该只显示一个地址(即&a[0] 的地址)对吧?
  • 引用在许多方面与指针不同,但请理解在您的示例中通过引用传递不会复制整个数组。它的编译方式取决于编译器,并且肯定会涉及指针。是的,cout&lt;&lt;&amp;a&lt;&lt;endl; 应该给你相同的地址,并且参数是对数组的引用,而不是对 100 个地址的引用。查看stackoverflow.com/questions/57483/…
  • 不完全正确:“对数组的引用”只是一个加糖的指针。 cplusplus.com/doc/tutorial/pointers
  • 有关指针与引用的更多信息,请参见此处:www3.ntu.edu.sg/home/ehchua/programming/cpp/…
  • 不错的答案,但是,虽然*(a + b) 在 C 中等同于 a[b],但在 C++ 中并非如此:在 C++ 中,operator[] 可能在用户定义的类型中被重载,这可能使其行为不同于用户定义的operator+operator* 的组合。
猜你喜欢
  • 2012-04-20
  • 2020-10-18
  • 2013-11-07
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2012-04-17
相关资源
最近更新 更多