Большое предупреждение: я бы не стал так обрабатывать многомерные массивы.
Я пытался это просто проверить, но это:
#include <stdio.h>
int foo(char b[][7])
{
printf("%d\n", b[3][4]);
return 0;
}
int main(int argc, char** argv)
{
char multi_d_arr[20][7];
multi_d_arr[3][4] = 42;
foo(multi_d_arr);
return 0;
}
Компилируется и запускается без каких-либо проблем, используя gcc -Wall
. Я не уверен, честно, как второй аргумент можно считать несовместимым типом указателя. Работает нормально.
Однако, как вы спросите, как бы я справился с 2-D массивами? Лучше всего использовать указатели так:
char** array2d = malloc((MAX_i+1)*sizeof(char*));
for ( i = 0; i < (MAX_i+1); i++ )
{
array2d[i] = malloc((MAX_j+1)*sizeof(char));
}
Теперь, для ясности, самый большой элемент, к которому вы можете получить доступ, - array2d[MAX_i][MAX_j]
.
Не забудьте инвертировать процесс, когда закончите:
for ( i = 0; i < (MAX_i+1); i++ )
{
free(array2d[i]);
}
free(array2d);
Теперь, используя этот метод, индексная запись остается действительной, поэтому array2d[x][y]
по-прежнему обращается к нужному значению. В буквальном смысле, array2d
- это массив указателей, как и каждый array2d[i]
.
Почему это лучший метод? Ну, вы можете иметь подмассивы переменного размера, если вам так нравится. Все, что вам нужно сделать, это изменить цикл for. Эта техника часто используется для массивов строк, особенно в int main(int argc, char** argv)
подписи приложения. argv
- это массив массивов строк переменной длины. Используйте strlen()
, чтобы определить их длину.
Можете ли вы передать это? Конечно. Вы только что получили его в main, для начала, но вы также можете написать свою подпись функции следующим образом:
int foo(char** ar2d, const unsigned int size);
и назовите его:
char** somearray;
/* initialisation of the above */
foo(ar2d, thesizeofar2d);
/* when done, free somearray appropriately */
Просто чтобы прояснить, ваш метод включения параметров размера (например, const unsigned int size
) является очень хорошей практикой, и вам следует придерживаться его.