В этом коде есть концептуальная ошибка - выражение массива не может быть целью назначения. Если вы пытались написать
void func1(void)
{
mat bbb;
bbb = aaa;
bbb[1][2] = 3;
}
компилятор выдаст диагностику для выражения bbb = aaa
(gcc дает диагностику "несовместимые типы в присваивании", поскольку aaa
преобразуется в тип указателя; подробнее об этом ниже). То, что вы пытаетесь сделать, передав bbb
в func2
, фактически одно и то же, и в конечном итоге не сработает.
Давайте избавимся от typedefs, чтобы мы могли видеть действительные типы
double aaa[MAX_SIZE][MAX_SIZE];
...
void func2(double (*ccc)[MAX_SIZE])
{
ccc = aaa;
}
void func1()
{
double bbb[MAX_SIZE][MAX_SIZE];
func2(bbb);
bbb[1][2] = 3;
}
Если это не операнд операторов sizeof
или унарных &
или строковый литерал, используемый для инициализации другого массива в объявлении, выражение типа "массив N-элементов из T
" будет быть заменено выражением типа «указатель на T
», значением которого является адрес первого элемента массива. Когда вы вызываете func2
, выражение bbb
преобразуется из типа "MAX_SIZE
массив из MAX_SIZE
массив из double
" в "указатель на MAX_SIZE
массив из double
"; следовательно, объявление ccc
как double (*ccc)[MAX_SIZE]
.
Аналогично, в строке ccc = aaa
в func2
выражение aaa
преобразуется из типа double [MAX_SIZE][MAX_SIZE]
в double (*)[MAX_SIZE]
.
Пока что func2
является кошерным, потому что ccc
является выражением-указателем, а не выражением массива, поэтому присваивание разрешено. ccc
также оказывается совершенно отличным от bbb
(получает копию значения указателя, которое оценивается bbb
), поэтому запись в ccc
не влияет на bbb
. Если вы попытались обойти это, передав указатель на bbb
, например:
void func2(double (*ccc)[MAX_SIZE][MAX_SIZE])
{
*ccc = aaa;
}
void func1(void)
{
double bbb[MAX_SIZE][MAX_SIZE];
func2(&bbb);
bbb[1][2] = 3;
}
компилятор выдаст диагностику на *ccc = aaa
, либо потому, что *ccc
имеет тип массива, либо потому что типы *ccc
и aaa
несовместимы (помните, aaa
преобразуется в указатель выражение).