我想将数组传递给构造函数,但只传递第一个值 - 其余的看起来像垃圾。
以下是我正在处理的简化版本:
#include <iostream>
class board
{
public:
int state[64];
board(int arr[])
{
*state = *arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
有人可以解释为什么这不起作用以及如何正确传递数组?另外,我不想复制数组。 (我是否真的必须将每行代码缩进4个代码?这非常繁琐。)
答案 0 :(得分:9)
在这种情况下,最好使用对数组的引用:
class board
{
int (&state)[64];
public:
board(int (&arr)[64])
: state(arr)
{}
// initialize use a pointer to an array
board(int (*p)[64])
: state(*p)
{}
void print();
};
一些优点 - 不复制数组,编译器会强制传入正确的大小数组。
缺点是初始化board
对象的数组需要至少与对象一样长,并且对象外部的数组所做的任何更改都会“反映”到对象的状态。但是如果你使用指向原始数组的指针也会出现这些缺点(基本上,只复制数组会消除这些缺点)。
另外一个缺点是你不能使用指向数组元素的指针来创建对象(如果未在数组元素中提供数组大小,那么这就是数组函数参数'衰减'参数的声明)。例如,如果数组通过一个实际上是指针的函数参数传递,并且您希望该函数能够创建引用该数组的board
对象。
答案 1 :(得分:5)
尝试将数组传递给函数会导致将指针传递给数组的第一个元素。
您无法分配数组,而T[]
等参数与T*
相同。所以
*state = *arr;
取消引用指向state
和arr
的指针,并将arr
的第一个元素指定给state
的第一个元素。
如果您要执行的操作是将值从一个数组复制到另一个数组,则可以使用std::copy
:
std::copy(arr, arr + 64, state); // this assumes that the array size will
// ALWAYS be 64
或者,您应该查看std::array<int>
,其行为与您假设数组的行为完全相同:
#include <array>
#include <algorithm>
#include <iostream>
class board
{
public:
std::array<int, 64> state;
board(const std::array<int, 64> arr) // or initialiser list : state(arr)
{
state = arr; // we can assign std::arrays
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
// using this array to initialise the std::array 'test' below
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
std::array<int, 64> test(std::begin(arr), std::end(arr));
board b(test);
b.print();
std::cin.get();
return 0;
}
答案 2 :(得分:1)
#include <iostream>
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << *(state + x + y*8) << " "; //changed here
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
或者您可以将其用作:
class board
{
public:
int state[64];
board(int arr[])
{
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
编辑1: 稳定的解决方案
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = new int[64];
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
答案 3 :(得分:0)
*state = *arr;
正在使用dereferencing,它返回指针地址处的值。
这与state[0] = *arr;
相同,因为*arr
是int
。
有关指针的信息,请参阅this article。请参阅参考部分。
要解决此问题,您需要执行此操作:
for (int i = 0; i < 64; i++) state[i] = arr[i]
答案 4 :(得分:0)
数组的名称是其中第一个元素的地址。
因此,行*state = *arr
会将state[0]
设置为arr[0]
。
由于您现在已将state
定义为int state[64];
,state
为const pointer
类型int
,其地址无法更改。
您可以将其更改为int *state;
,然后state = arr
即可。
答案 5 :(得分:0)
* arr给出存储在arr [0]的值。在c ++中,数组的名称是指向数组中第一个元素的指针。
因此当你执行* state = * arr时,将值存储在变量状态的arr [0]中。
现在,如果你想传递数组而不必显式复制每个元素,我建议你在你调用的方法中创建另一个相同大小的数组,然后从调用者传递数组的名称,本质上:
methodWhereArrayisPassed(int *arrayName)
{
int arrCopy[64];
arrCopy = arrayName;
// Do more stuff here
}
methodWhichPassesArray()
{
// do stuff here
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
methodWhereArrayisPassed(arr);
// do stuff here
}