#c #pointers #syntax #types #casting
#c #указатели #синтаксис #типы #Кастинг
Вопрос:
Большинство существующих функций памяти во время выполнения принимают или возвращают void*, что позволяет передавать аргументы без явного приведения типов указателей. Должен ли этот шаблон реплицироваться при создании пользовательских функций памяти?
Другими словами, что из следующего является более правильным и почему:
int read_bytes( void * dest, size_t count );
или
int read_bytes( uint8_t * dest, size_t count );
?
Ответ №1:
Я бы рекомендовал использовать void*
. В противном случае каждый вызов функции будет выглядеть как:
int n = read_bytes((uint8_t*)amp;myVar, sizeof(myVar));
вместо того, чтобы просто
int n = read_bytes(amp;myVar, sizeof(myVar));
Ответ №2:
void* — это указатель общего назначения в C / C . Он используется в тех случаях, когда вы не хотите, чтобы определенный тип указывался с данными, и позволяет избежать необходимости приведения указателя. Это также указатель, который вы хотите использовать с необработанными адресами.
Вы бы использовали uint_t, где вы хотите указать, что вы действительно имеете дело с целыми числами без знака.
Ответ №3:
Если вы обрабатываете память только как необработанную, непрозрачную память, а не как последовательность байтов, то void *
это подходящий тип. Это может быть идиоматическим, например, при использовании placement-new для создания объекта в памяти. Существуют также некоторые традиционные API-интерфейсы C, которые используют указатели void для ссылок на память, например memcpy
or memchr
, поэтому иногда может быть удобно использовать один и тот же тип.
С другой стороны, если вы думаете о памяти как о массиве байтов, и особенно если вы хотите получить доступ к случайным байтам в памяти (т. Е. Выполнить арифметику указателя или итератора), вам обязательно следует использовать тип указателя char . Существует определенная дискуссия о том, какой из них лучше; как правило, для ввода-вывода вам нужен простой char
как «тип данных системного ввода-вывода» (например, ввод-вывод чтения / записи). С другой стороны, если вы хотите оперировать арифметическими байтовыми значениями, unsigned char
это более уместно. Однако эти два типа совместимы с макетом, так что не стесняйтесь относиться к одному как к другому, если это необходимо.