0

我正在尝试将动态二维数组传递给函数,但它给出了错误。我尝试显式提供数组尺寸并且它工作但动态不起作用,任何指针(双关语不是故意的)

#include <iostream>
#include <vector>

using namespace std;

void print_2d_array(int arr_size, int (*arr)[5]){
    for(int i = 0; i < arr_size; ++i){
        for(int j = 0; j < arr_size; ++j)
            cout << arr[i][j] << "\t";
        cout << endl;
    }
}

int main(){
    vector<int> x{10,15,20,30,40};
    int arr[x.size()][x.size()];

    for(int i = 0; i < x.size(); ++i)
        arr[i][i] = 0;

    print_2d_array(5, arr);
    return 0;
}

我尝试了此处详细介绍的所有三种方法Passing 2D array in C

如果不是如上所示实例化数组,我使用类似的东西

arr[5][5];

它按预期工作。我收到以下错误

error: cannot convert ‘int (*)[(<anonymous> + 1)]’ to ‘int (*)[5]’ for argument ‘2’ 
to ‘void print_2d_array(int, int (*)[5])’

print_2d_array(5, arr);

4

2 回答 2

1

Variable Length Array (VLA) is not part of C++ standard. It is part of C99 standard, and typically implemented as an extension for C++ in various compilers.

It is typically ok to use a VLA in a C++ program when you allocates an array. But you are going to have problems when you need to pass the array around, because there is no argument type that is VLA so that you can pass it as arguments to functions in C++. (That's why when you manually inline the function, the code runs ok, which avoids passing the array into a function.) You have to pass the array as a pointer to the function, and maybe use reinterpret_cast before and inside the function to convert the VLA to a pointer, and convert it back. It is simply terrible code.

When coding in C++, just use the C++ idiomatic way. Since you already use vector, you can just use vector<vector<int>> (vector<vector<int> > if not using C++11, but from the way you initialize x, you are using C++11) as a 2-D array. Your code should be modified as below:

#include <iostream>
#include <vector>

using namespace std;

void print_2d_array(int arr_size, vector<vector<int>> &arr){
    for(int i = 0; i < arr_size; ++i){
        for(int j = 0; j < arr_size; ++j)
            cout << arr[i][j] << "\t";
        cout << endl;
    }
}

int main(){
    vector<int> x{10,15,20,30,40};
    vector<vector<int>> arr(x.size(), vector<int>(x.size()));

    // No need to use this to initialize:
    // for(int i = 0; i < sizeof(x); ++i)
    //     arr[i][i] = 0;

    print_2d_array(5, arr);
    return 0;
}

Note that this also fixed your problem that your arr was not properly initialized.

If you are going to use C, then VLA is totally ok, and it will be like this (and not that I didn't fix your initialization, which only initialized the diagonal elements. You have to use a C, not C++ compiler to compile this.):

#include <stdio.h>

void print_2d_array(int arr_size, int arr[][arr_size]){
    for(int i = 0; i < arr_size; ++i){
        for(int j = 0; j < arr_size; ++j)
            printf("%d\t", arr[i][j]);
        printf("\n");
    }
}

int main(){
    int x[] = {10,15,20,30,40};
    int arr[sizeof(x)][sizeof(x)];

    // bad initialization:
    for(int i = 0; i < sizeof(x); ++i)
        arr[i][i] = 0;

    print_2d_array(5, arr);
    return 0;
}

Ok, if you decide to use C++ but don't like vector, the next simplest thing is to use primitive pointers, which is not recommended.

#include <iostream>
#include <vector>

using namespace std;

void print_2d_array(int arr_size, int **arr){
    for(int i = 0; i < arr_size; ++i){
        for(int j = 0; j < arr_size; ++j)
            cout << arr[i][j] << "\t";
        cout << endl;
    }
}

int main(){
    vector<int> x {10,15,20,30,40};
    int **arr = new int*[x.size()];
    for (int i = 0; i < x.size(); ++i) {
        arr[i] = new int[x.size()];
        for (int j = 0; j < x.size(); ++j) {
            arr[i][j] = 0;
        }
    }

    print_2d_array(5, arr);

    for (int i = 0; i < x.size(); ++i) {
        delete[] arr[i];
    }
    return 0;
}

Save your trouble and use containers. You are using modern C++.

(The answer assumes you couldn't determine the size of the array before running. Although this is not the case in your example--the size must be 5 and there is no reason to use VLA.)

于 2015-04-13T07:25:05.277 回答
0

首先,

int arr[x.size()][x.size()];

不是有效的 C++。数组的维度必须在编译时知道。

如果您使用支持可变长度数组作为扩展的编译器,则可以使用该语句。但是,变量的类型不是int (*)[5],这正是 所期望的print_2d_array

std::array如果您在编译时知道尺寸,则 可以使用嵌套。

std::vector如果需要在运行时计算尺寸,您可以使用嵌套。

更新,以回应OP的评论

采用该程序的简化版本。

#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> x{10,15,20,30,40};
    int arr[x.size()][x.size()];
    return 0;
}

编译命令:

g++ -Wall -std=c++11    socc.cc   -o socc -pedantic

错误/警告:

socc.cc: In function ‘int main()’:
socc.cc:8:31: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
     int arr[x.size()][x.size()];
                               ^
socc.cc:8:31: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
socc.cc:8:9: warning: unused variable ‘arr’ [-Wunused-variable]
     int arr[x.size()][x.size()
于 2015-04-13T04:26:12.633 回答