Как отправить 2-D массив в качестве ссылки в C ++ и обратно? - PullRequest
0 голосов
/ 25 сентября 2011

еще один вопрос от начального до среднего уровня.Я пытаюсь передать 2-D массив функции в C ++.Я знаю, что массив не может быть отправлен непосредственно в функцию, поэтому я сначала создал указатель (имена отредактированы, но вы поймете, что идея):

double input[a][b] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
Class.calculate (*(input), a, b);

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

for (int x=0; x<=a; x++){
    for (int y=0; y<=b; y++){
        tmpInput[x][y]= (*input)[x][y];
    }
}

Компилятор жалуется на ошибку, а именно invalid types ‘double[int]’ for array subscript, но я все еще не могу выяснить проблему.Лучше всего, что я не разыменовал двумерный массив должным образом, но другой вариант заключается в том, что C ++ не может разыменовать двумерные массивы напрямую, вместо этого полагаясь на преобразование массива в 1-D перед отправкой.Есть идеи?

Ответы [ 5 ]

3 голосов
/ 25 сентября 2011

Почему массив нельзя отправить напрямую в функцию?

Call Class.calculate (*(input), a, b); пытается разыменовать input, что вы не можете сделать, так как это не указатель.

Если calculate определяется как:

Class::calculate(double *input[], size a, size b)

Вы можете просто позвонить Class.calculate(input, a, b).

2 голосов
/ 25 сентября 2011

Никто еще ничего не сказал о шаблонах? Я разочарован!


Вы можете фактически передать его как реальную ссылку без необходимости передавать размер в качестве дополнительных параметров в C ++:

class Class{
public:
  // ...
  template<unsigned N, unsigned M>
  void calculate(double (&arr)[N][M]){
    // use it like normal, arr[x][y]
    // ...
  }
  // ...
};

Пример на Ideone.

Даже если это не отвечает на тот вопрос, который вы задали, всегда хорошо знать такие вещи. :) В конце концов, шаблоны являются важной частью C ++, независимо от того, начинающий вы, средний или профессиональный. Вы используете их, хотя, возможно, не осознанно, с первого дня.

2 голосов
/ 25 сентября 2011

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

Неправильно. Вы можете передать это. Просто укажите первый аргумент функции-члена calculate как указатель на указатель.

calculate( double **ptr, int rows, int columns ){

   // Now access the array via ptr as usual with the [] operator. 
   // like ptr[0][1]
}

И назовите это как - Class.calculate (input, a, b);

0 голосов
/ 25 сентября 2011

Трудно сказать наверняка, не увидев объявление calculate(), но я думаю, это несоответствие типов аргументов. Вы можете отправить свой массив как double*, но не как double** - он является массивом значений типа double (они расположены линейно в памяти, даже если компилятор позволяет вам рассматривать их как многомерный массив). Но это , а не массив указателей на двойники, что на самом деле означает тип double**: разыменуйте double** и вы получите double*.

Если вы знаете, что второй нижний индекс является константой (в вашем случае, 2), вы можете определить calculate(), чтобы ожидать массив чисел с двойным числом N * 2:

void calculate(double array[][2], int a)
{
    //Whatever
}

Или, если оба измерения могут измениться, просто возьмите прямую double* и указатель на математику самостоятельно (вам, вероятно, придется привести ваш массив к double* при вызове этого, но это будет работать):

void calculate(double* array, int a, int b)
{
    //To get array[i][j]:
    array[i * b + j];
}

Надеюсь, это поможет!

0 голосов
/ 25 сентября 2011

Используйте Boost.MultiArray:

http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html

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

, если вы хотите узнать о сырых указателях (или вы пишете встроенное приложение, которое должно умещаться в 64 КБ памяти или что-то в этом роде),хорошая идея написать код, который использует их.Если вы хотите написать поддерживаемый производственный код, то лучше использовать STL / Boost и избегать необработанных указателей, за исключением кода, который вряд ли придется читать очень много.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...