将动态数组/矩阵传递给函数进行初始化

Posted

技术标签:

【中文标题】将动态数组/矩阵传递给函数进行初始化【英文标题】:Pass dynamic arrays/matrices to functions for initialization 【发布时间】:2019-09-30 16:25:12 【问题描述】:

我的问题基本上是这个问题Proper way to pass dynamic arrays to other functions的后续问题。这里询问将动态数组传递给函数的正确方法。给出了三个选项:

void test(bool arr[])
void test(bool *arr)
void test(bool *&arr)

前两个通过值传递(数组的)指针,第二个通过引用传递指针。 All 可用于更改数组的内容,如alestanis 的回答所示。

现在我的问题是,如果您想在函数内动态分配数组,那么正确的方法是什么。所以是这样的:

void init(double ?arr?, int n)
    arr = new double[n];


void main()
    double * array;
    init(array,15);

我相信它只适用于最后一种语法,但我不确定。

此外,如果您有一个矩阵,我想知道最后一种语法会是什么样子。你有两个& 吗?还是根本不可能?

附:我有不同的大向量和矩阵,所以我宁愿使用常规数组而不是标准的东西。向量和矩阵的大小是用户的输入值,向量和矩阵仅在输入完成后创建,因此我无需调整向量/矩阵的大小。

【问题讨论】:

开箱即用:使用std::vectorstd::vector 将为您处理内存分配和释放。它具有与数组相同的访问运算符。如果你想修改它,你甚至可以通过引用传递。 我有不同的大向量和矩阵,所以我宁愿使用常规数组而不是 std 的东西 - 如果这是与性能相关的,你不会失去任何东西切换到 std::vector 如果你正确使用它。另一方面,您在安全等方面获得了很多。 写有std的东西,没有。然后编译、分析和比较结果。 vector 应该留下的只是初始化期间的一个小插曲。这是否重要取决于要求。 @user4581301 -- 有时向量会提高代码的速度,尤其是如果原始非向量代码一遍又一遍地使用new[]delete[] 而不是一个向量并做一个简单的@ 987654332@. 我更喜欢double* array = make_double_array(15); 而不是输出参数。 (但更好的是std::vector 或至少std::unique_ptr)。 【参考方案1】:

如果您将按值传递指针,则指针随函数的变化不会影响原始参数。该函数将处理原始指针值的副本。

所以你有两种方法。 C++ 方法是

void test(bool *&arr);

C 方法是

void test(bool **arr)

这是一个演示程序。

#include <iostream>
#include <iterator>
#include <numeric>

void init( double * &a, size_t n )

    a = new double[n];

    std::iota( a, a + n, 0.0 );


void init( double **a, size_t n )

    *a = new double[n];

    std::iota( std::reverse_iterator<double *>( *a + n ), std::reverse_iterator<double *>( *a ), 0.0 );


int main() 

    size_t n = 10;
    double *a = nullptr;

    init( a, n );

    for ( const double *p = a; p != a + n; ++p )
    
        std::cout << *p << ' ';
    

    std::cout << '\n';

    delete []a;
    a = nullptr;

    init( &a, n );

    for ( const double *p = a; p != a + n; ++p )
    
        std::cout << *p << ' ';
    

    std::cout << '\n';

    delete []a;
    a = nullptr;

    return 0;

它的输出是

0 1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 0

如果您想动态分配具有固定列数的二维数组,那么例如函数声明可以如下所示。

#include <iostream>
#include <iterator>
#include <numeric>

const size_t N = 5;

void init( double ( * &a )[N], size_t n )

    a = new double[n][N];

    for ( size_t i = 0; i < n; i++ )
    
        std::iota( std::begin( a[i] ), std::end( a[i] ), i + i / 10.0 ); 
            


void init( double ( **a )[N], size_t n )

    *a = new double[n][N];

    for ( size_t i = 0; i < n; i++ )
    
        std::iota( std::begin( ( *a )[i] ), std::end( ( *a )[i] ), i + i / 10.0 ); 
            


int main()

    double ( *a )[N] = nullptr;

    init( a, N );

    for ( size_t i = 0; i < N; i++ )
    
        for ( const auto &item : a[i] )
        
            std::cout << item << ' ';
        

        std::cout << '\n';
    

    std::cout << '\n';

    delete []a;
    a = nullptr;

    init( a, N );

    for ( size_t i = 0; i < N; i++ )
    
        for ( const auto &item : a[i] )
        
            std::cout << item << ' ';
        

        std::cout << '\n';
    

    std::cout << '\n';

    delete []a;
    a = nullptr;

    return 0;

程序输出是

0 1 2 3 4 
1.1 2.1 3.1 4.1 5.1 
2.2 3.2 4.2 5.2 6.2 
3.3 4.3 5.3 6.3 7.3 
4.4 5.4 6.4 7.4 8.4 

0 1 2 3 4 
1.1 2.1 3.1 4.1 5.1 
2.2 3.2 4.2 5.2 6.2 
3.3 4.3 5.3 6.3 7.3 
4.4 5.4 6.4 7.4 8.4

【讨论】:

谢谢!你能把你的答案扩展到一个大小为 (n,3) 的矩阵,一个 2D 向量吗?

以上是关于将动态数组/矩阵传递给函数进行初始化的主要内容,如果未能解决你的问题,请参考以下文章

如何将函数中使用的数组传递给动态分配的main数组?

这是查找动态分配数组长度的好方法吗?

C语言如何给用函数二维数组动态赋值

C中动态初始化数组时出错[复制]

C语言 写个给二维数组初始化的函数

如何将字符串数组动态传递给Java中的SQL“IN”子句? [复制]