Нужно ли умножать sizeof (char) при манипулировании памятью?

При использовании malloc и выполнении подобной манипуляции с памятью я могу полагаться на sizeof (char), который всегда равен 1?

Например, мне нужно выделить память для N элементов типа char . Требуется умножить на sizeof( char ) :

 char* buffer = malloc( N * sizeof( char ) ); 

или я могу полагаться на sizeof (char), всегда равным 1, и просто пропустить умножение

 char* buffer = malloc( N ); 

Я полностью понимаю, что sizeof оценивается во время компиляции, а затем компилятор может даже скомпилировать умножение, и поэтому штраф за производительность будет минимальным и, скорее всего, нулевым.

Я прошу в основном о ясности кода и переносимости. Является ли это умножение когда-либо необходимым для типа char ?

Хотя это и не обязательно, я считаю хорошей практикой уйти в sizeof (char), потому что он делает код более читаемым и позволяет избежать использования магического номера. Кроме того, если код нужно изменить позже, чтобы вместо символа он выделял размер чего-то в указатель для этого объекта, проще изменить код, чем если бы у вас было только «1».

По определению sizeof (char) всегда равен 1. Один байт – это размер символа на C, независимо от количества бит в байте (8 на общем настольном процессоре).

Типичным примером, когда один байт не является 8 бит, является PDP-10 и другие старые мини-компьютерные архитектуры с 9/36 бит байтами. Но байты, которые не являются 2 ^ N, становятся чрезвычайно необычными, я считаю

Кроме того, я думаю, что это лучший стиль:

 char* buf1; double* buf2; buf1 = malloc(sizeof(*buf1) * N); buf2 = malloc(sizeof(*buf2) * N); 

потому что он работает независимо от типа указателя.

sizeof(char) всегда 1 независимо от того, какой тип манипуляции с памятью вы делаете.

Однако sizeof(TCHAR) может меняться в зависимости от ваших параметров компилятора.

Я считаю это своего рода анти-шаблон . Это сигнализирует о том, что программист не совсем знал, что он / она делает, что сразу бросает остальную часть кода в сомнительный свет.

Конечно, это не (цитирование Википедии) «неэффективно», но я считаю, что это «далеко не оптимально». Это не стоит ничего во время выполнения, но он загромождает код ненужным барахлом, все время сигнализируя, что кто-то считает это необходимым.

Также обратите внимание, что выражение не анализируется как вызов функции: sizeof не является функцией. Вы не вызываете функцию, передавая ей магический символ char . Вы применяете встроенный оператор унарного префикса sizeof к выражению, а ваше выражение в данном случае относится к типу char , который в C записывается как (char) .

Вполне возможно, и, по возможности, настоятельно рекомендуется использовать sizeof для других выражений, тогда он даст размер значения выражения:

 char a; printf("A char's size is %u\n", (unsigned int) sizeof a); 

Это будет печатать 1 , всегда, на всех соответствующих реализациях C.

Я также сильно согласен с Дэвидом Курнерау и считаю, что повторять имя типа в malloc() -телефоне также является своего рода анти-шаблоном.

Вместо

 char *str; str = malloc(N * sizeof (char)); 

что многие будут писать для выделения буфера строк с пропускной способностью N-символа, я бы пошел с

 char *str; str = malloc(N * sizeof *str); 

Или (только для строк) опустить sizeof как указано выше, но это, конечно, более общее и работает точно также для любого типа указателя.

Это не обязательно. См. Здесь (например).

sizeof(char) определяется стандартом C, всегда равным 1 (байт). Обратите внимание, что поскольку sizeof возвращает количество байтов, количество бит на байт не имеет значения (и в практическом смысле это 8 в любом случае).

Что-то еще следует иметь в виду, так это то, что компилятор статически знает значение sizeof (char) равным 1, и он также знает, что умножение числа на статичное 1 означает, что умножение не нужно делать; компилятор оптимизирует его. Озабоченность исполнения не должна входить в рассмотрение на этих основаниях.

Из «Нового стандарта C. Экономический и культурный комментарий».

  1. Статистика: 2,0% от sizeof берутся из char и 1,5% – от unsigned char . Страница 1033 в версии 1.2.
  2. страница 1037.

Количество битов в представлении символьного типа не имеет значения. По определению количество байтов в байтах типа символа равно единице.

Рекомендации по кодированию Разработчики иногда связывают байты, как всегда, содержащие восемь бит. На хостах, где тип символа – 16 бит, это может привести к неверному предположению о том, что применение sizeof к типу символа вернет значение 2. Эти проблемы обсуждаются в другом месте.

Использование sizeof (char) делает ваш код более читабельным и портативным.

На x86 мы все знаем, что символ 1 байт. Но прямое изложение его помогает сделать ваши намерения более ясными, что всегда хорошо.

Кроме того, что, если ваш код будет помещен на другую платформу, где символ не является 1 байтом. Что, если у персонажа было всего 4 бита?

Согласитесь, это не обязательно, но это не замедляет ваше время работы, и оно будет окупиться в этом редком случае, вам нужно перенести свой код на другую архитектуру.