按值传递2D数组并不起作用

时间:2014-08-11 08:48:31

标签: c++ c arrays function-calls function-call

我正在尝试将2d数组传递给函数。我不希望修改实际的数组。所以按价值传递它。但我的实际2darray正在修改。(当我修改myArray时,x正在被修改)。为什么会这样?

int main(int argc, const char* argv[])
{
    int x[3][3];
    x[0][0]=2;
    x[0][1]=2;
    x[0][2]=2;
    x[1][0]=2;
    x[1][1]=2;
    x[1][2]=2;
    x[2][0]=2;
    x[2][1]=2;
    x[2][2]=2;
    func1(x);
}

void func1(int myArray[][3])
{
    int i, j;
    int ROWS=3;
    int COLS=3;

     for (i=0; i<ROWS; i++)
     {
         for (j=0; j<COLS; j++)
         {
             myArray[i][j] =3;
         }
     }
}

如果我们不知道这两个维度,是否可以按值传递2D数组?

4 个答案:

答案 0 :(得分:1)

您可以利用以下事实:在复制或分配该类型的实例时,会复制和分配用户定义类型中的数组,例如

template <size_t N, size_t M>
struct Foo
{
  int data[N][M];
};

template <size_t N, size_t M>
void func1(Foo<N, M> foo)
{
  foo.data[1][2] = 42;
}

int main()
{
  Foo<3, 3> f;
  f.data[0][0]=2;
  ...
  func1(f);
}

此处,func1具有foo的本地副本,该副本具有自己的数组副本。我已经使用模板推广到任意大小。

请注意,C ++提供了std::array模板,您可以使用该模板而不是Foo,因此在实际代码中您可以执行以下操作:

#include <array>

template <typename T, size_t N, size_t M>
void func1(std::array<std::array<T, N>, M> arr)
{
  arr[1][2] = 42;
}

int main()
{
  std::array<std::array<int, 3>, 3> a;
  a[0][0]=2;
  ...
  func1(a);
}

如果你坚持使用pre-C ++ 11实现,你可以使用boost库中的std::tr1::array(标题<tr1/array>boost::array。这也是一个不错的练习。推出自己的。

答案 1 :(得分:0)

数组作为指针传递,并且将2d数组作为指针传递给它并不是很简单。 你应该用一个类封装数组并传递对该类的引用。

这样&#34;用户&#34;我们也不知道你的数组的底层实现,你可以在不影响以后的功能的情况下进行更改。 当然,将const引用传递给类实例将与传递指针一样轻量级,因此不会对性能产生影响。

答案 2 :(得分:0)

在标准C ++中, 8.3.5函数第5节解释了:

  

确定每个参数的类型后,任何类型的参数   “T的数组”或“返回的函数T”被调整为“指向的指针”   分别为T“或”指向函数返回T的指针。

这就是为什么你的函数实际上使用指针并修改原始值。

第8点进一步解释:

  

如果参数的类型包含“数组”的类型   运行时绑定的T“,”指向未知绑定T“的数组,或   “引用T的未知界限数组”,该程序格式不正确。

所以,你必须提前知道尺寸。

替代方案:

如果您想按价值工作,最好使用标准容器,例如矢量(此处为vector<vector<int>>)。然后你的x将在main()中用:

声明
vector<vector<int>> x(3, vector<int>(3));  // initialised vector of 3 vector of 3 ints

甚至更好,去掉你对同一个常数的长长的作业列表:

vector<vector<int>> x(3, vector<int>(3, 2));  // vector of 3 vector of 3 ints with value 2

您的功能定义为:

void func1(vector<vector<int>> myArray)
{   // resets all existing values to 3.  
    for (size_t i = 0; i<myArray.size(); i++)
        for (size_t j = 0; j<myArray[i].size(); j++)
            myArray[i][j] = 3;
}  

答案 3 :(得分:0)

防止func1被更改,将其更改为const指针。

void func1(const int (*myArray)[3])
{
    int i, j;
    int ROWS=3;
    int COLS=3;

     for (i=0; i<ROWS; i++)
     {
         for (j=0; j<COLS; j++)
         {
            // myArray[i][j] =3; //compilation error, is now const
            cout <<" "<<myArray[i][j];  
         }
     }
}