Я немного озадачен тем, что передавать в качестве первого параметра в memset, когда вам нужно установить элементы статического массива. Я искал, но я не мог найти ответы на некоторые мои конкретные вопросы.
Если у меня есть массив, объявленный как:
char arr[10];
Я видел, что эти два вызова действительны и дают одинаковый эффект:
memset( arr, 0, 10);
memset( &arr, 0, 10);
Мои конкретные вопросы:
1- Почему они одинаково влияют на обр?
2- Чем отличаются эти звонки?
3- Какой из них будет считаться правильным?
Спасибо!
Срок хранения не имеет к этому никакого отношения; массив — это массив. Это выражение:
&arr
производит char (*)[10]
указатель на массив char
с 10 элементами. Однако когда arr
передается функции следующим образом:
memset(arr, 0, 10);
он ухудшается до указателя на первый элемент, т.е. char*
, Это не одно и то же. «Правильный» (идиоматический) вызов:
memset(arr, 0, 10);
Однако в этом случае они оба преобразуются в void*
когда перешел к memset
и интерпретируется в функции как unsigned char*
, Так как они оба указывают на одно и то же место, это дает одинаковый результат.
Однако важно понимать, что при работе с истинно соответствующими типами (т. Е. Не void*
) указатель на массив не такой же как указатель на первый элемент массива.
Например, увеличение char (*)[10]
увеличит указатель sizeof(char[10])
байт при увеличении char*
будет увеличивать только один байт.
Почему они одинаково влияют на обр? Чем отличаются эти звонки?
Поскольку адрес массива совпадает с адресом его первого элемента (массивы распадаются на указатели на их первый элемент при передаче в функцию), просто они имеют другой тип. arr
имеет тип char[10]
, который разлагается в char *
когда передается в функцию. По сравнению, &arr
имеет тип char (*)[10]
который не изменяется при передаче в качестве аргумента функции.
Какой из них будет считаться правильным?
Пока функция не ожидает определенного типа, т.е. е. он принимает void *
Либо один хорош. Однако если вызываемая функция ожидает, что один из типов будет указан, то другой использовать не следует, поскольку в этом случае ваша программа будет деформирована и вызовет неопределенное поведение.
1- Почему они одинаково влияют на обр?
Они оба содержат одно и то же значение, которое является адресом начала массива.
2- Чем отличаются эти звонки?
arr
распадается на указатель на символ, т.е. char*
(это преобразование происходит, когда вы передаете имя массива функции) и &arr
это указатель на массив символа, то есть char (*)[]
,
3- Какой из них будет считаться правильным?
я хотел бы использовать arr
, memset
принимает void*
что является причиной того, что обе работы.
Также обратите внимание, что char arr[10] = {};
может использоваться для обнуления инициализации массива.