Передача трехмерных массивов в функции в C? - PullRequest
2 голосов
/ 17 ноября 2009

Каков наилучший способ передачи трехмерных массивов в функции в C?

Ответы [ 4 ]

5 голосов
/ 17 ноября 2009

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

#define DIM 5

void do_something(float array[][DIM][DIM])
{
    array[0][0][0] = 0;
    ...
}
5 голосов
/ 17 ноября 2009

typedef твой друг.

#include <stdio.h>
typedef int dimension1[20]; /* define dimension1 as array of 20
                               elements of type int */
typedef dimension1 dimension2[10]; /* define dimension2 as array of 10
                                      elements of type dimension1 */

int foo(dimension2 arr[], size_t siz);

int main(void) {
  dimension2 dimension3[7] = {0}; /* declare dimension3 as an array of 7
                                     elements of type dimension2 */
  dimension3[4][3][2] = 9999;
  dimension3[4][0][12] = 1;
  dimension3[3][8][18] = 42;

  printf("%d\n", foo(dimension3, 7));

  return 0;
}

int foo(dimension2 arr[], size_t siz) {
  int d1, d2, d3;
  int retval = 0;
  for (d3=0; d3<siz; d3++) {
    for (d2=0; d2<sizeof *arr / sizeof **arr; d2++) {
      for (d1=0; d1<sizeof **arr / sizeof ***arr; d1++) {
        retval += arr[d3][d2][d1];
      }
    }
    /* edit: previous answer used definite types for the sizeof argument */
    //for (d2=0; d2<sizeof (dimension2) / sizeof (dimension1); d2++) {
    //  for (d1=0; d1<sizeof (dimension1) / sizeof (int); d1++) {
    //    retval += arr[d3][d2][d1];
    //  }
    //}
  }
  return retval;
}

Редактировать

Мне не нравится использование определенных типов в качестве аргумента sizeof.
Я добавил способ получения размеров (под) массивов без непосредственного указания их типов, но вместо этого позволил компилятору выводить правильный тип из определений объектов.


2-е редактирование

Как отмечает В соответствии с замечаниями Экмана, определение типа "голые" массивы может быть опасным . Обратите внимание, что в приведенном выше коде я не передаю сами массивы функции foo. Я передаю указатель на массив «более низкого уровня».

foo() в приведенном выше коде принимает указатель на объект типа dimension2. Объект dimension3 - это массив элементов типа dimension2 , а не объект типа dimension3 (который даже не определен).

Но помните записку Пера Экмана.

4 голосов
/ 17 ноября 2009

Передайте их как указатели.

Пример

int a[N][M][P];

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

где foo

void foo( int*)

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

void foo( int*, int D1, int D2, int D3)

и звоните

foo( &a[0][0][0], N, M, P);
3 голосов
/ 17 ноября 2009

определение типа «голые» массивы может быть опасным.

Попробуйте это

#include <stdio.h>

typedef char t1[10];

void foo(t1 a) {
        t1 b;

        printf("%d %d\n", sizeof a, sizeof b);
}

int main(void) {
        t1 a;
        foo(a);
        return 0;
}

Можно подумать, что размер двух переменных одного типа вернет одинаковый размер но не в этом случае. По этой причине рекомендуется оборачивать массивы typedef-ed. в структуре.

typedef struct {
        char x[10];
} t1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...