Передача мульти-массивов в функции через указатель - PullRequest
1 голос
/ 01 августа 2010

как я могу передать multiarray в функцию через указатель с c ++.Я могу сделать это с помощью простых массивов

void Foo(int *arr) { }
int someArr[10];
Foo(someArr);

А как насчет двухмерного массива?

Ответы [ 3 ]

2 голосов
/ 01 августа 2010

Вы можете достичь того, чего хотите, таким образом:

void foo(int *array) { }

int column_size = 5;

int main() {
   int array[column_size][2];

   foo(&array[0][0]);

   return 0; 
}

хотя вы должны позаботиться о том, как вы читаете элементы из функции foo. Чтобы прочитать элемент array[c][r], необходимо выполнить:

int element = *(array + c * column_size + r);

Общая функция элемента get:

int get_element(int *array, int row, int column, int column_size)   {
  int element = *(array + row * column_size + column);
  return element;
}

Итак, если у вас есть, скажем, двумерный массив типа int array[M][N] и вы хотите получить элемент array[i][j], просто вызовите функцию следующим образом:

getElement(&array[0][0], i, j, N)

Почему это работает?

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

int a[3][3] = {{1, 2, 4}, {5, 6, 7}, {8, 9, 10}};

давайте предположим, что целое число составляет 4 байта, а & a [0] [0] соответствует адресу памяти 0x10. Затем 1 сохраняется в 0x10 адрес памяти, 2 сохраняется в 0x14, ..., 7 сохраняется в 0x24 адрес памяти, ... и 10 сохраняется в 0x30 адрес памяти (см. Следующую таблицу).

*Memory*

Memory address => Value => Pointer pointing at this memory address

   0x10        =>   1   => &a[0][0]
   0x14        =>   2   => (&a[0][0] + 1) or (&a[0][1])
   0x18        =>   4   => (&a[0][0] + 2) or (&a[0][2])
   0x1c        =>   5   => (&a[0][0] + 3 * 1 + 0) or (&a[1][0])
   0x20        =>   6   => (&a[0][0] + 3 * 1 + 1) or (&a[1][1])
   0x24        =>   7   => (&a[0][0] + 3 * 1 + 1) or (&a[1][2])
   0x28        =>   8   => (&a[0][0] + 3 * 2 + 0) or (&a[2][0])
   0x2c        =>   9   => (&a[0][0] + 3 * 2 + 1) or (&a[2][1])
   0x30        =>   10  => (&a[0][0] + 3 * 2 + 2) or (&a[2][2])

Теперь, когда у вас есть следующий указатель:

int *pt = (&a[0][0] + 2);

указатель pt будет указывать на 2 элемента после a[0][0]. Так что pt указывает на [0] [2]. *pt будет равно 4.

Теперь предположим, что вы хотите получить элемент a[i][j]. Для того, чтобы получить этот элемент вам нужно отодвинуть i * COLUMN_SIZE элементов, чтобы попасть в правильную строку, где находится элемент (каждая строка имеет COLUMN_SIZE элементов), а затем вам нужно добавить j, чтобы попасть в правильный столбец.

Если вы хотите получить a[2][1] (где COLUMN_SIZE = 3), то 2 * COLUMN_SIZE = 6 + 1 = 7. Таким образом, чтобы получить элемент a[2][1], вы делаете *(&a[0][0] + 2 * 3 + 1) или *(&a[0][0] + 7).

Для некоторых великолепных обучающих программ по указателям, посмотрите здесь: Библиотека Stanford CS Ed .

2 голосов
/ 01 августа 2010

Это более или менее одно и то же - за исключением, конечно, разных битов.

#include <stdio.h>

enum { DIM = 6 };

static void Bar(int arr[][DIM], int n)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < DIM; j++)
            printf("  %2d", arr[i][j]);
        putchar('\n');
    }
}

int anotherArr[][DIM] =
{
    {  1,  2,  3,  4,  5,  6 },
    {  6,  5,  4,  3,  2,  1 },
    {  0,  0,  0,  0,  0,  0 },
    { -1, -2, -3, -4, -5, -6 },
};

int main(void)
{
    Bar(anotherArr, 4);
    return(0);
}
0 голосов
/ 01 августа 2010
void Foo(int **arr) { }
int someArr[10][10];
Foo(someArr);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...