2010-07-01 5 views
7

Как передать многомерный массив функции в C/C++?Как передать многомерный массив функции?

Размеры массива не известны во время компиляции

+0

@ GMan- Если массив был динамически распределен с размерами на основе пользовательского ввода, тогда размер не будет известен во время компиляции. – bta

ответ

9

Указатель на начало массива вместе с размерами - то сделайте арифметический массив в функции является наиболее распространенным решением.

Или используйте boost

+0

http://gandalf-library.sourceforge.net/ too – rwong

1

Используйте вектор векторов, вы можете передать вектор.

+0

Это неэффективно, за исключением массива jagged (где каждая строка может иметь разную длину от другой) или когда элементы являются строками и т. Д. Также, если asker ищет переменное количество измерений (которые мы еще не знаем), векторы не решат эту проблему, потому что векторы typedef'ed. – rwong

1

Вы можете передать указатель и размеры или использовать std::vector. Но «реальное» решение с шаблоном:

template <size_t N, size_t M> 
void foo(int (&pArray)[N][M]); 

Этот шаблон функция принимает N на M массив целых чисел, по ссылке. Обратите внимание, что это шаблон функции, а не функция, поэтому вы получаете другую экземплярную функцию для каждого типа массива.

+0

Шаблоны не помогут, когда размеры массива неизвестны во время компиляции. – n0rd

+0

@ n0rd: О, я пропустил эту часть. Хотя вопрос либо предельно тривиальный, либо бессмысленный. – GManNickG

1

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

void foo(int bar[n][m], int n, int m) {...} 
+0

Вам не нужно указывать постоянные значения для n и m во время компиляции? Вы делаете на моем C++ Builder 2010. (В вопросе dim's неизвестны при компиляции. – Tom

1

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

т.е.

int var [x][y][z]; 
func (var, x, y, z); 

функция definintion:

void func (int*, int, int, int); 
3

Передача массива легко, твердая часть доступа массив внутри вашей функции. Как отмечалось в некоторых других ответах, вы можете объявить параметр функции как указатель, а также передать количество элементов для каждого dim массива.

#define xsize 20 
#define ysize 30 
int array[xsize][ysize]; 
void fun(int* arr, int x, int y) 
{ 
// to access element 5,20 
int x = arr[y*5+20]; 
} 

fun(array, xsize, ysize); 

Конечно, я ушел из всего бизнеса выделения массива (так как он не знал, что его размер будет, вы не можете использовать #defines (а некоторые говорят, что они плохо, так или иначе)

0

Я просто суммируя варианты от других сообщений.

Если число измерений (п, как в N-мерном массиве) неизвестно, единственный способ заключается в использовании C++ многомерного массива класс. Существует несколько общедоступных реализаций из Boost или других библиотек. См. Martin Beckett's.

Если количество измерений известно, но размер массива является динамическим, см. Tom's ответ для доступа к элементу массива (преобразование мультииндекса в указатель элемента). Сам массив должен быть выделен с помощью malloc или new.

Если вы пишете многомерный массив, вы должны знать о Row-major-order, Column-major-order и т. Д.

А именно, если dimensios массив (Size1, Size2, Size3, ..., SizeN), то:

  • Количество элементов в массиве является (Size1 * Size2 * Size3 * ... * SizeN)
  • Память Необходима sizeof(value_type) * numOfElements
  • Чтобы получить доступ к элементу (index1, index2, index3, ..., indexN), использовать
    • ptr[ index1 + (Size1 * index2) + (Size1 * Size2 * index3) + ... ] Предполагая, что первым индексом массива является fastest-moving dimension
+0

index1 + (Size1 * index2) + (Size1 * Size2 * index3) + ... лучше написано как i1 + size1 * (i2 + size2 * (...)) ...) –

+0

@Alexandre: Согласен. Я знаю http://en.wikipedia.org/wiki/Horner_scheme. Я просто хочу показать формулу так, чтобы ее можно было записать в цикл и т. Д. – rwong

+0

извините, я имею в виду «математически». – rwong

0

Раздел 3.4 на этой странице адреса ваш вопрос:

http://www.programmersheaven.com/2/Pointers-and-Arrays-page-2

, конечно, массивы переменной длины не присутствовали в C до C99, и, насколько я знаю, они не присутствуют в C++. Кроме того, MSVC не реализует/не поддерживает C99.

0

Простым методом является сглаживание массива и итерация с использованием измерений.

#include <stdio.h> 

void print_array(int *arr,int row,int col) 
{ 
    int i,j; 
    for(i=0;i<row;i++){   
     for(j=0;j<col;j++){ 
      printf("%d ",*(arr+i*col+j)); 
     } 
     printf("\n"); 
    } 
} 

int main() 
{ 
int a[2][3] = {{1,0,2},{-1,3,1}}; 
int b[4] = {1,2,3,34}; 
print_array(a,2,3); 
return 0; 
} 

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