如何将数组传递给构造函数?

时间:2023-02-02 19:10:18

I want to pass an array to a constructor, but only the first value is passed--the rest looks like garbage.

我想将一个数组传递给构造函数,但只传递第一个值——其余的看起来像垃圾。

Here's a simplified version of what I'm working on:

这是我正在做的一个简化版本:

#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;
}

Can someone explain why this doesn't work and how to properly pass an array? Also, I don't want to copy the array. (And do I really have to indent every line by 4 spaces for code? That's pretty tedious.)

有人能解释为什么它不能工作以及如何正确地传递一个数组吗?另外,我不想复制数组。(我真的需要把每一行缩进4个空格来写代码吗?)这很乏味。)

6 个解决方案

#1


9  

In this case it might be best to use a reference to the array:

在这种情况下,最好使用对数组的引用:

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();
};

A couple of advantages - no copying of the array, and the compiler will enforce that the correct size array is passed in.

有两个优点——不复制数组,编译器将强制传入正确的大小数组。

The drawbacks are that the array you initialize the board object with needs to live at least as long as the object and any changes made to the array outside of the object are 'reflected' into the object's state. but those drawbacks occur if you use a pointer to the original array as well (basically, only copying the array will eliminate those drawbacks).

缺点是,初始化board对象的数组需要至少存活一段时间,只要对象和对象外部数组的任何更改都“反映”到对象的状态。但是,如果您也使用一个指向原始数组的指针(基本上,只有复制数组才能消除这些缺陷),就会出现这些缺陷。

One additional drawback is that you can't create the object using a pointer to an array element (which is what array function parameters 'decay' to if the array size isn't provided in the parameter's declaration). For example, if the array is passed through a function parameter that's really a pointer, and you want that function to be able to create a board object referring to that array.

另一个缺点是不能使用指向数组元素的指针来创建对象(如果参数的声明中没有提供数组大小,那么数组函数参数就会“衰减”)。例如,如果数组通过一个函数参数传递,而这个函数实际上是一个指针,那么您希望该函数能够创建一个引用该数组的board对象。

#2


5  

Attempting to pass an array to a function results in passing a pointer to the first element of the array.

尝试将数组传递给函数会导致将指针传递到数组的第一个元素。

You can't assign arrays, and taking a parameter like T[] is the same as T*. So

你不能赋值数组,取一个像T[]这样的参数就等于T*。所以

*state = *arr;

Is dereferencing the pointers to state and arr and assigning the first element of arr to the first element of state.

是取消指向状态和arr的指针,并将arr的第一个元素分配到状态的第一个元素。

If what you want to do is copy the values from one array to another, you can use std::copy:

如果您要做的是将值从一个数组复制到另一个数组,您可以使用std:::copy:

std::copy(arr, arr + 64, state); // this assumes that the array size will
                                 // ALWAYS be 64

Alternatively, you should look at std::array<int>, which behaves exactly like you were assuming arrays behave:

或者,您应该查看std::array ,它的行为与假设数组的行为完全相同:

#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;
}

#3


0  

*arr gives the value that is stored at arr[0] . In c++ , the name of the array is a pointer to the first element in the array.

*arr给出存储在arr[0]中的值。在c++中,数组的名称是指向数组中第一个元素的指针。

So when you do *state = *arr , you store the value at arr[0] in the variable state.

所以当你做*state = *arr时,你将值存储在arr[0]的变量状态。

Now , if you want to pass the array without having to copy each element explicitly , I suggest that you make another array of the same size in the method which you are calling and then pass the name of the array from the caller , in essence :

现在,如果您想传递数组而不需要显式地复制每个元素,我建议您在正在调用的方法中创建另一个相同大小的数组,然后从调用者那里传递数组的名称,本质上:

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
}

#4


0  

The name of an array is the address of the first element in it.

数组的名称是其中第一个元素的地址。

Hence the line *state = *arr will set state[0] to arr[0].

因此,line *state = *arr将状态[0]设置为arr[0]。

Since right now you have defined state as int state[64];, state is const pointer of type int whose address cannot be changed.

因为现在您已经将状态定义为int状态[64];,state是类型int的const指针,它的地址不能更改。

You can change it to int *state; and then state = arr will work.

你可以把它改成int *state;状态= arr可以。

#5


0  

*state = *arr; is using dereferencing, which returns the value at the address of the pointer.

* = * arr状态;使用去引用,它返回指针地址处的值。

This is the same as state[0] = *arr; because *arr is an int.

它等于状态[0]= *arr;因为*arr是整数。

See this article for info on pointers. See the deference section.

有关指针的信息,请参阅本文。请尊重部分。

To solve this problem you want to do this:

要解决这个问题,你需要这样做:

for (int i = 0; i < 64; i++) state[i] = arr[i]

#6


0  

#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;
}

or you can use it as:

或者你可以这样使用:

class board
{
    public:
        int state[64];
        board(int arr[])
        {
            for(int i=0;i<64;++i)
               state[i] = arr[i];
        }
        void print();
};

EDIT 1: stable solution

编辑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();
    };

#1


9  

In this case it might be best to use a reference to the array:

在这种情况下,最好使用对数组的引用:

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();
};

A couple of advantages - no copying of the array, and the compiler will enforce that the correct size array is passed in.

有两个优点——不复制数组,编译器将强制传入正确的大小数组。

The drawbacks are that the array you initialize the board object with needs to live at least as long as the object and any changes made to the array outside of the object are 'reflected' into the object's state. but those drawbacks occur if you use a pointer to the original array as well (basically, only copying the array will eliminate those drawbacks).

缺点是,初始化board对象的数组需要至少存活一段时间,只要对象和对象外部数组的任何更改都“反映”到对象的状态。但是,如果您也使用一个指向原始数组的指针(基本上,只有复制数组才能消除这些缺陷),就会出现这些缺陷。

One additional drawback is that you can't create the object using a pointer to an array element (which is what array function parameters 'decay' to if the array size isn't provided in the parameter's declaration). For example, if the array is passed through a function parameter that's really a pointer, and you want that function to be able to create a board object referring to that array.

另一个缺点是不能使用指向数组元素的指针来创建对象(如果参数的声明中没有提供数组大小,那么数组函数参数就会“衰减”)。例如,如果数组通过一个函数参数传递,而这个函数实际上是一个指针,那么您希望该函数能够创建一个引用该数组的board对象。

#2


5  

Attempting to pass an array to a function results in passing a pointer to the first element of the array.

尝试将数组传递给函数会导致将指针传递到数组的第一个元素。

You can't assign arrays, and taking a parameter like T[] is the same as T*. So

你不能赋值数组,取一个像T[]这样的参数就等于T*。所以

*state = *arr;

Is dereferencing the pointers to state and arr and assigning the first element of arr to the first element of state.

是取消指向状态和arr的指针,并将arr的第一个元素分配到状态的第一个元素。

If what you want to do is copy the values from one array to another, you can use std::copy:

如果您要做的是将值从一个数组复制到另一个数组,您可以使用std:::copy:

std::copy(arr, arr + 64, state); // this assumes that the array size will
                                 // ALWAYS be 64

Alternatively, you should look at std::array<int>, which behaves exactly like you were assuming arrays behave:

或者,您应该查看std::array ,它的行为与假设数组的行为完全相同:

#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;
}

#3


0  

*arr gives the value that is stored at arr[0] . In c++ , the name of the array is a pointer to the first element in the array.

*arr给出存储在arr[0]中的值。在c++中,数组的名称是指向数组中第一个元素的指针。

So when you do *state = *arr , you store the value at arr[0] in the variable state.

所以当你做*state = *arr时,你将值存储在arr[0]的变量状态。

Now , if you want to pass the array without having to copy each element explicitly , I suggest that you make another array of the same size in the method which you are calling and then pass the name of the array from the caller , in essence :

现在,如果您想传递数组而不需要显式地复制每个元素,我建议您在正在调用的方法中创建另一个相同大小的数组,然后从调用者那里传递数组的名称,本质上:

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
}

#4


0  

The name of an array is the address of the first element in it.

数组的名称是其中第一个元素的地址。

Hence the line *state = *arr will set state[0] to arr[0].

因此,line *state = *arr将状态[0]设置为arr[0]。

Since right now you have defined state as int state[64];, state is const pointer of type int whose address cannot be changed.

因为现在您已经将状态定义为int状态[64];,state是类型int的const指针,它的地址不能更改。

You can change it to int *state; and then state = arr will work.

你可以把它改成int *state;状态= arr可以。

#5


0  

*state = *arr; is using dereferencing, which returns the value at the address of the pointer.

* = * arr状态;使用去引用,它返回指针地址处的值。

This is the same as state[0] = *arr; because *arr is an int.

它等于状态[0]= *arr;因为*arr是整数。

See this article for info on pointers. See the deference section.

有关指针的信息,请参阅本文。请尊重部分。

To solve this problem you want to do this:

要解决这个问题,你需要这样做:

for (int i = 0; i < 64; i++) state[i] = arr[i]

#6


0  

#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;
}

or you can use it as:

或者你可以这样使用:

class board
{
    public:
        int state[64];
        board(int arr[])
        {
            for(int i=0;i<64;++i)
               state[i] = arr[i];
        }
        void print();
};

EDIT 1: stable solution

编辑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();
    };