Помогите, пожалуйста, с передачей многомерных массивов.

Я пишу простую тестовую программу для передачи многомерных массивов. Я изо всех сил пытался получить подпись вызываемой функции.

Код у меня есть:

void p(int (*s)[100], int n) { ... }

...

{
  int s1[10][100], s2[10][1000];
  p(s1, 100);
}

Этот код работает, но это не то, что я хотел. Я хочу, чтобы функция p не обращала внимания на то, является ли диапазон значений 100 или 1000, но должна знать, что существует 10 указателей (с помощью сигнатуры функции).

В качестве первой попытки:

void p(int (*s)[10], int n) // n = # elements in the range of the array

и в качестве второго:

void p(int **s, int n) // n = # of elements in the range of the array

Но безрезультатно я могу заставить их работать правильно. Я не хочу жестко кодировать 100 или 1000 в подписи, а вместо этого передаю их, имея в виду, что всегда будет 10 массивов.

Очевидно, я хочу избежать объявления функции:

void p(int *s1, int *s2, int *s3, ..., int *s10, int n) 

К вашему сведению, я смотрю ответы на похожий вопрос, но все еще запутался .


person snap    schedule 05.04.2010    source источник


Ответы (2)


Вам нужно транспонировать ваши массивы, чтобы это работало. Объявить

int s1[100][10];
int s2[1000][10];

Теперь вы можете передать их в такую ​​функцию:

void foo(int (*s)[10], int n) {
    /* various declarations */
    for (i = 0; i < n; i++)
        for (j = 0; j < 10; j++)
            s[i][j] += 1
}

Из-за того, как работает система типов C, аргумент массива может быть «гибким» только в том смысле, в котором вы хотите, в его крайнем левом индексе.

person Dale Hagglund    schedule 05.04.2010
comment
В качестве альтернативы void p(int s[][10], int n) - person outis; 05.04.2010
comment
@outis: Совершенно верно. Я использовал int (*s)[10] отчасти потому, что имитировал исходный вопрос, а также потому, что лично я стараюсь избегать объявлений аргументов, таких как int s[][10], поскольку они вводят читателя в заблуждение относительно того, что на самом деле передается функции. - person Dale Hagglund; 05.04.2010
comment
Спасибо, Дейл. Похоже, это правильный метод для обеспечения того, что я изначально хотел. Единственная проблема заключается в том, что транспонированная структура мешает моему коду. Похоже, что другой ответ, который предлагает динамическое построение многомерного массива и передачу диапазона, был бы более подходящим и понятным для понимания. - person snap; 05.04.2010
comment
Пожалуйста. Если транспонированные массивы делают ваш код слишком громоздким, то, безусловно, стоит попробовать идею, описанную @shakov. - person Dale Hagglund; 05.04.2010

Вы также можете создать struct для матрицы и передать ее функции p

struct Matrix{
     int **array;
     int n;
     int m;
};


void p(Matrix *k){
     length=k->m;
     width=k->n;
     firstElement=k->array[0][0];
}
person zoli2k    schedule 05.04.2010
comment
Этот подход работает и является более общим, поскольку он обеспечивает гибкость в обоих измерениях массива. Однако необходимо пояснить, что array — это единый массив из n указателей на целые числа, каждый из которых указывает на массив из m целых чисел. Несмотря на синтаксическое сходство, это сильно отличается от простого объявления int array[N][M] для некоторых констант N и M. - person Dale Hagglund; 05.04.2010