Когда вы передаете массив в C, он всегда передается по ссылке, то есть через указатель.Тип этого указателя не указатель на массив , а указатель на первый элемент .Например, генератор кода будет обрабатывать void f(char[][10])
, как если бы он был void f(char*)
.Размеры массива потеряны.Парсер, однако, будет жаловаться, если увидит, что f
объявлен дважды так.
Мотивация C заключалась в том, чтобы иметь мощный и переносимый ассемблер, а не новый язык программирования.Многомерные массивы - это логические конструкции, которых нет в машине.Массивы - это способ мышления.
Чтобы передать размеры массивов в функции, программисты на C традиционно используют struct
s:
typedef struct array_tag {
int count;
char data[1]; /* actually data[count] */
} ARRAY;
typedef struct grid_tag {
int rows, columns;
char grid[1][1]; /* actually grid[rows][columns] */
} GRID;
void f(ARRAY* x)
{
int i;
for (i = 0; i < x->count; ++i) {
char c = x->data[i];
}
}
void g(GRID* x)
{
int i, j;
for (i = 0; i < x->rows; ++i)
for (j = 0; j < x->columns; ++j) {
char c = x->grid[i][j];
}
}
void h()
{
{
const int len = 100;
ARRAY* x = (ARRAY*) malloc(sizeof(ARRAY) + len * sizeof(char));
x->count = len;
f(x);
}
{
const int rows = 2, cols = 3;
GRID* x = (GRID*) malloc(sizeof(GRID) + rows * cols * sizeof(char));
x->rows = rows;
x->columns = cols;
g(x);
}
}
Да, выражение malloc
в этом примере выделяет слишком мало байт.Поэтому GNU-компилятор поддерживает массивы нулевой длины в течение длительного времени , что недопустимо в C90.
C99 продвинулся на один шаг вперед с гибкими массивами.Из ИСО / МЭК 9899: 1999, раздел 6.7.2.1, параграф 16: "В особом случае последний элемент структуры с более чем одним именованным элементом может иметь неполный тип массива; это называется гибким массивомmember. " В C99 типы ARRAY
и GRID
могут быть объявлены как:
typedef struct array_tag {
int count;
char data[]; /* actually data[count] */
} ARRAY;
typedef struct grid_tag {
int rows, columns;
char grid[][1]; /* actually grid[rows][columns] */
} GRID;
, и вы можете
assert(1*sizeof(int) == sizeof(ARRAY));
assert(2*sizeof(int) == sizeof(GRID));
Многие люди думают, что массивы C причудливы,Но они также являются элегантным решением, которое позволяет объявлять бесконечно сложные массивы.Он известен как «уравнение массива K & R».Хорошее объяснение можно найти здесь .
Надеюсь, это поможет.