Когда вы передаете массивы функциям в C, они распадаются на указатель на первый элемент в массиве, , даже если вы указываете тип массива в прототипе функции (а) . Следовательно, sizeof
даст вам размер указателя, , а не размера массива.
Обычная практика - передавать размер массива вместе с массивом (вероятно, в видеsize_t
) и используйте , что , чтобы сплести свою магию, что-то вроде:
int zeroArray(void *address, size_t sz) { // void* makes it clear
memset(address, 0, sz); // but int thing[][] would be same.
}
:
int xyzzy[42][7];
zeroArray(xyzzy, sizeof(xyzzy));
Однако, вы уже передаете достаточно информации вашей текущей функции, чтобы сделатьэто, в частности, n
. Вы должны просто использовать это для формирования типа для оператора sizeof
(который может принимать переменную или тип), и он будет делать то, что вам нужно:
memset(magic_square, 0, sizeof(int[n][n]));
(a) Покрыт по последнему стандарту C11
в разделе 6.3.2.1 Lvalues, arrays, and function designators /3
:
За исключением случаев, когда он является операндом оператора sizeof
, оператор _Alignof
, или унарный оператор &
, или строковый литерал, используемый для инициализации массива, выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», которое указываетк начальному элементу объекта массива и не является lvalue.
Я ссылался на последний итерацию стандарта, несмотря на ваш тег c99
, единственное отличие состоит в том, чточто стандарт C99 не упоминает Alignof
, так как он не существовал в этой итерации. Кроме этого, цитата идентична.
Это идет путь назад, даже в первое издание K & R, 5.3 Pointers and arrays
:
На самом деле, ссылкав массив преобразуется компилятором в указатель на начало массива.