Как передать многомерные массивы неизвестного размера в функцию, используя указатели в c ++? - PullRequest
1 голос
/ 25 мая 2011

Как говорится в вопросе, я пытаюсь передать многомерные массивы в функцию, чтобы распечатать их в файле для инженерного проекта.Формат, для которого вводятся данные, НЕ МОЖЕТ быть изменен, поэтому, пожалуйста, не предлагайте мне просто вводить его как другой тип данных.

Эта конкретная функция ожидает двухмерный массив (хотя у меня есть другие с тремя измерениямипосле этого), где ничего не известно о размере массива до времени выполнения.Я знаю, что должен использовать указатели, чтобы указывать на каждую строку массива в отдельности, но я понятия не имею, что такое синтаксис для передачи его в функцию.В следующем коде рассматриваемый массив является «блоком».Основная функция - это небольшой пример тестирования, который я сделал, чтобы попытаться заставить его работать:

#include<fstream>
using namespace std;

void of_write_blocks(string filename, string block_type[], int **block,
            int grid[][3], string grade_type[], int grade[][3], int n_blocks, int m[])
{
    ofstream file_out(filename.c_str(),ios::app);
    file_out<<"\nblocks\n(\n";

    for(int i=0;i<n_blocks;++i) {
            file_out<<"   "<<block_type[i]<<" ( ";
                    for(int j=0;j<m[i];++j)
                            file_out<<block[i][j]<<" ";
            file_out<<") ( ";
            file_out<<grid[i][0]<<' '<<grid[i][1]<<' '<<grid[i][2]<<" ) ";
            file_out<<grade_type[i]<<" ( ";
            file_out<<grade[i][0]<<' '<<grade[i][1]<<' '<<grade[i][2]<<" )\n";
    }
    file_out<<");\n";
}


//testing example:
int main()
{       
    int block[6][9];
    for(int i=0; i<6;++i) 
            for(int j=0; i<9;++j)
                    block[i][j] = i*j;

    int grid[6][3];
    for(int i=0; i<6;++i)
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;


    int grade[6][3];
    for(int i=0; i<6;++i) 
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;

    string grade_type[6] = {"simpleGrading"};
    string block_type[6] = {"hex"};
    int m[6] = {8};
    int n_blocks = 6;

    of_write_blocks("name",block_type,block,grid,grade_type,grade,n_blocks,m);
}       

любая помощь приветствуется!

Ответы [ 4 ]

5 голосов
/ 25 мая 2011

Вы не можете.Многомерные массивы являются синтаксическим сахаром и скомпилированы непосредственно в код, который выполняет манипуляции с массивом, который является единым блоком памяти.Измерения не передаются в функцию в качестве параметров или чего-то подобного как часть массива, как это делается, например, в Java или C #.

Если вам нужны измерения массива в вашей функции, выВам нужно будет просто принять указатель на первый элемент массива и размеры, а также умножить и добавить, чтобы получить правильный индекс самостоятельно.

В качестве альтернативы используйте что-то вроде std::vector<std::vector<block>>, котороеразмеры как часть объекта, а не как встроенный массив.

2 голосов
/ 25 мая 2011

Если у вас установлен Boost, посмотрите Boost Multi-Array .

0 голосов
/ 26 мая 2011

Почему нельзя использовать ссылку на массив.Пример ниже:

char c[10];
int i[10][20];
double d[10][20][30];

Напишите функцию wrapper следующим образом:

template<typename T, int SIZE>
void Array (T (&a)[SIZE])
{}
template<typename T, int SIZE1, int SIZE2>
void Array (T (&a)[SIZE1][SIZE2])
{}
template<typename T, int SIZE1, int SIZE2, int SIZE3>
void Array (T (&a)[SIZE1][SIZE2][SIZE3])
{}

Это всего лишь пример, демонстрирующий синтаксис, который будет элегантно получать массивбез какого-либо копирования, а также избегает запутанных указателей.Кроме того, если вы знаете, что собираетесь использовать только для int, просто удалите имя типа и явно упомяните int.т.е.

template<int SIZE>
void Array (int (&a)[SIZE]); // explicitly mention int
0 голосов
/ 26 мая 2011

Для ясности я удалил весь нерелевантный код из вашего примера.

#include <iostream>
#include <fstream>

using namespace std;

void of_write_blocks(int **block, int bh, int bw){

  for(int i = 0; i < bh; ++i)
    for(int j = 0; j < bw; ++j)
      cout << block[i][j] << " ";
  cout << endl;
}

int main(){       

  int bh, bw;
  cin >> bh >> bw;

  int** block;
  block = new int*[bh];
  for(int k = 0; k < bh; k++)
    block[k] = new int[bw];

  // initialize the array
  for(int i = 0; i < bh; i++)
    for(int j = 0; j < bw; j++)
      block[i][j] = (i*bw) + j;

  of_write_blocks( block, bh, bw);
}       

В основном мы создаем 2D-массив и инициализируем его.Затем мы передаем его в of_write_block, который печатает массив.Это то, что вы хотели сделать?

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