Как передать многомерный массив в функцию в C и C ++ - PullRequest
40 голосов
/ 13 мая 2010
#include<stdio.h>
void print(int *arr[], int s1, int s2) {
    int i, j;
    for(i = 0; i<s1; i++)
        for(j = 0; j<s2; j++)
            printf("%d, ", *((arr+i)+j));
}

int main() {
    int a[4][4] = {{0}};
    print(a,4,4);
}

Это работает в C, но не в C ++.

ошибка:

cannot convert `int (*)[4]' to `int**' for argument `1' to 
`void print(int**, int, int)'

Почему это не работает в C ++? Какие изменения необходимо внести?

Ответы [ 12 ]

0 голосов
/ 13 мая 2010

Первое, что нужно сделать, это правильно подобрать типы. Если правила C ++ такие же, как и C, в отношении типов массивов (я почти уверен, что они есть), тогда с учетом объявления

int a[4][4];

выражение a имеет тип int [4][4], который неявно преобразуется ("распадается") в тип указателя int (*)[4] (указатель на массив из 4 элементов типа int) при передаче в print, поэтому вы нужно изменить print на

void print(int (*arr)[4], int s1, int s2)
{
  int i, j;        
  for(i = 0; i<s1; i++)        
    for(j = 0; j<s2; j++)        
      printf("%d, ", arr[i][j]);        
}        

Выражение arr[i] неявно разыменовывается arr, поэтому вам не нужно возиться с явным разыменованием.

Недостатком является то, что print может обрабатывать только массивы Nx4 типа int; если вы хотите обрабатывать массивы других размеров, вам нужно использовать другой подход.

Одна вещь, которую вы можете сделать, это вместо передачи массива, передачи адреса первого элемента и print вручную вычислить смещения, например:

int main() {                    
  int a[4][4] = {{0}};                    
  print(&a[0][0],4,4);  // note how a is being passed                  
}  

void print(int *arr, int s1, int s2)  // note that arr is a simple int *
{
  int i, j;
  for (i = 0; i < s1; i++)
    for (j = 0; j < s2; j++)
      printf("%d, ", arr[i * s2 + j]);
}
0 голосов
/ 13 мая 2010

Краткий ответ, вы можете изменить программу следующим образом

void print(int arr[], int s1, int s2) {
...
printf("%d,", *(a+i + s2*j));
...
print((int*)a,4,4);

Для этого потребуется лучший ответ, объясняющий различия между указателем и арифметикой указателя и массивами в C и C ++. Я не буду начинать это сейчас. Может быть, кто-то еще?

Я явно не шокирован тем же, что и другие постеры в вашем коде. Что беспокоит меня больше всего в заголовке функции печати, так это то, что вы используете двойное косвенное обращение для массива, в котором вы не намерены возвращать исходный указатель обратно (на самом деле это невозможно сделать, так как это константа). Ответ @ | V | lad исправит это, установив одно или два измерения в фиксированную константу, но затем передача s1 и s2 станет бесполезной.

Все зависит от того, что вы действительно хотите сделать. Является ли функция печати массивом общего назначения или специализированной для некоторых типов массивов?

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