0

動的な 2 次元配列を関数に渡そうとしていますが、エラーが発生します。配列の次元を明示的に提供しようとしましたが、機能しましたが、動的は機能していません。ポインターはありません(しゃれは意図されていません)

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

ここで詳しく説明した 3 つの方法をすべて試しました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 に答える