Как изменить и передать указатель массива в качестве аргумента функции, которая требует массив в качестве аргумента?

0

Это, вероятно, новичок. Скажем, например, в следующем методе мы используем массивы alpha и theta, которые передаются как аргумент функции gsl_ran_dirichlet, а функция вычисляет новые значения theta и обновляет один и тот же массив theta.

Теперь проблема в том, что я не смогу инициализировать тету в классе, как указано в следующем фрагменте кода. Скорее мне придется использовать указатели для массивов тета и альфа. Как передать эти указатели массива в качестве аргумента в метод gsl_ran_dirichlet?

Я знаю, что невозможно передать указатель в качестве аргумента в метод, который требует массива в качестве аргумента. Но каков наилучший способ сделать это (предположим, что мы не можем изменить gsl_ran_dirichlet)?

void test (){
    double alpha[2] = { 1, 1};
    double theta[2] = { 1, 1};

    const gsl_rng_type * T;
    gsl_rng * r;

    gsl_rng_env_setup();

    T = gsl_rng_default;
    r = gsl_rng_alloc(T);

    gsl_ran_dirichlet(r, 2, alpha, theta);
    cout << theta[0] << "," << theta[1] << endl;

    gsl_rng_free(r);
}

Результат:

0.4,0.6

Теперь я также добавляю функцию и ошибку, которую я получаю в следующем коде, где массивы загружаются динамически:

void test() {
    double *alpha, *theta;

    alpha = new double[3];
    theta = new double[3];

    for(int i=0; i<3; ++i){
        alpha = 1;
        theta = 1;
    }

    const gsl_rng_type * T;
    gsl_rng * r;

    gsl_rng_env_setup();

    T = gsl_rng_default;
    r = gsl_rng_alloc(T);

    gsl_ran_dirichlet(r, 3, alpha, theta);
    cout << theta[0] << "," << theta[1] << "," << theta[2] << ":";

    gsl_rng_free(r);
}

Ошибка:

../test.cpp:56:11: error: invalid conversion from ‘int to ‘double* [-fpermissive]
../test.cpp:57:11: error: invalid conversion from ‘int to ‘double* [-fpermissive]
make: *** [test.o] Error 1
  • 0
    Я полностью не смог увидеть проблему. Скомпилировано и запущено?
  • 0
    Функция, предоставленная выше с массивами, работает, но, скажем, мы объявили как double * alpha; двойная * тета; и загружать значения в эти массивы динамически, я не могу передать эти указатели в качестве аргументов функции gsl_ran_dirichlet.
Показать ещё 2 комментария
Теги:
arrays
pointers
function

6 ответов

1
Лучший ответ

Попробуйте изменить назначения в цикле for for

alpha[i] = 1;
theta[i] = 1;
  • 0
    Это моя глупая ошибка. Большое спасибо! :-)
2

Генеральная:

  • Переменная для указателя: &variable.
  • Указатель на переменную: *pointer.

Конкретный:

Имя массива и указатель на массив можно использовать таким же образом, т. pointer_to_theta[0] theta[0] и pointer_to_theta[0] эквивалентны.

int foo[2] = { 1, 2 };

int * pointer_to_foo = foo;

assert( foo[1] == pointer_to_foo[1] );
2

Ваша проблема не в вызове функции.

просто

for(int i=0; i<3; ++i){
    alpha = 1;
    theta = 1;
}

неправильно.

alpha - это double* который вы не можете присвоить ему int (1).

То, что вы пытаетесь сделать, это

alpha[i] = 1;

или

*(alpha + i) = 1

А также! прочитайте сообщение об ошибке. В сообщении об ошибке есть номер строки, и он указывает вам, где эта проблема. Вы должны найти его самостоятельно, если заглянете в свою линию 56 и 57

  • 0
    Спасибо Адриан, я понял.
0

Ошибка компиляции проста: вы присваиваете int указателю-a- double.

for( int i=0; i < 3; ++i ) {
   alpha[i] = i; // dereference before assignment
}

"Как-передать-массив" функции несколько сложнее. Обычно для старого и C-совместимого кода передается указатель на массив вместе с его размером (foo( int* values, size_t size)).

Если у вас есть свобода выбора, вы предпочтете использовать стандартные коллекции (например, std::vector<double>) (и такие алгоритмы, как iota):

std::vector<double> alpha, theta;
std::iota(begin(alpha), end(alpha));
std::iota(begin(theta), end(theta));

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

void gsl_ran_dirichlet(
       std::vector<double> &r, // though I prefer output args to come last
       int i, 
       const std::vector<double> &alpha, 
       const std::vector<double> &theta);
0

Проблема в вашем коде не имеет никакого отношения к передаче массива в функцию.

В вашем For-loop вы пытаетесь] установить указатель (double *) в Integer (1), который является причиной компиляции ошибки.

Вы должны задать позицию своего массива с помощью [], чтобы установить значение.

for(int i=0; i<3; ++i){
    alpha[i] = 1.0;
    theta[i] = 1.0;
}

Это идентично обычным указателям. Чтобы установить значение указателя, вы должны разыменовать адрес.

int* x = new int();
*x = 5;
0
double* alpha;
double* tetha;

void foo()
{
   double (&refToAlpha)[2] = reinterpret_cast<double(&)[2]> (alpha);
   double (&refToTetha)[2] = reinterpret_cast<double(&)[2]> (tetha);
   ...
   gsl_ran_dirichlet(r, 2, refToAlpha, refToTetha);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню