Передача динамических массивов / матриц в функции для инициализации - PullRequest
0 голосов
/ 30 сентября 2019

Мой вопрос в основном является последующим вопросом по этому вопросу Правильный способ передачи динамических массивов другим функциям . Здесь задается правильный способ передачи динамического массива в функцию. Даны три варианта:

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

Первые два передают указатель (из массива) по значению, а второй передает указатель по ссылке. Все можно использовать для изменения содержимого массива, как показано в ответе Алестаниса.

Теперь мой вопрос заключается в том, каким будет правильный путь, если вы хотите динамически размещать массив внутри функции. Итак, что-то вроде этого:

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

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

Я считаю, что это работает только с последним синтаксисом, но я не уверен.

Кроме того, я хотел бы знать, как будет выглядеть последний синтаксисесли у вас есть матрица. Будете ли вы иметь два &? Или это просто невозможно?

PS У меня есть разные большие векторы и матрицы, поэтому я бы предпочел использовать обычный массив вместо std. Размер векторов и матриц является своего рода входными значениями для пользователя, а векторы и матрицы создаются только после завершения ввода, поэтому мне никогда не нужно изменять размер вектора / матрицы.

1 Ответ

2 голосов
/ 30 сентября 2019

Если вы передадите указатель по значению, то его изменение указателя с помощью функции не повлияет на исходный аргумент. Функция будет иметь дело с копией значения исходного указателя.

Итак, у вас есть два подхода. Подход 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...