Нужно ли умножать 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
?
Ответы
Ответ 1
В то время как это не обязательно, я считаю хорошей практикой оставить в sizeof (char), потому что он делает код более читаемым и позволяет избежать использования магического числа. Кроме того, если код нужно изменить позже, чтобы вместо char он перераспределял размер чего-то в указатель для этого объекта, проще изменить код, чем если бы у вас было только "1".
Ответ 2
По определению 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);
потому что он работает независимо от типа указателя.
Ответ 3
sizeof(char)
всегда 1 независимо от того, какой тип манипуляции с памятью вы делаете.
Однако sizeof(TCHAR)
может меняться в зависимости от ваших параметров компилятора.
Ответ 4
Я рассматриваю это как anti-pattern. Это сигнализирует, что программист не совсем знал, что он/она делает, что сразу бросает остальную часть кода в сомнительный свет.
Конечно, это не (цитирование Википедии) "неэффективно", но я считаю его "далек от оптимального". Это не стоит ничего во время выполнения, но он загромождает код ненужным барахлом, все время сигнализируя, что кто-то считает это необходимым.
Также обратите внимание, что выражение не анализируется как функция-вызов: sizeof
не является функцией. Вы не вызываете функцию, передавая ей магический символ char
. Вы применяете встроенный оператор унарного префикса sizeof
к выражению, и ваше выражение в этом случае относится к типу char
, который в C записывается как (char)
.
Совершенно возможно и настоятельно рекомендуется, когда это возможно, использовать sizeof
для других выражений, тогда он даст размер значения выражения:
char a;
printf("A char size is %u\n", (unsigned int) sizeof a);
Это будет печатать 1
, всегда, во всех соответствующих реализациях C.
Я также очень согласен с Дэвидом Курнерау и считаю, что повторять имя типа в malloc()
-call также является своего рода анти-шаблоном.
Вместо
char *str;
str = malloc(N * sizeof (char));
что многие напишут для выделения буфера строк с емкостью N-символа, я бы пошел с
char *str;
str = malloc(N * sizeof *str);
Или (только для строк) опустить sizeof
в соответствии с приведенным выше, но это, конечно, более общее и работает точно также для любого типа указателя.
Ответ 5
Это не обязательно. См. здесь (например).
sizeof(char)
определяется стандартом C, всегда равным 1 (байт). Обратите внимание, что поскольку sizeof
возвращает количество байтов, количество бит на байт не имеет значения (и в практическом смысле это 8 в любом случае).
Ответ 6
Что-то еще нужно иметь в виду, так это то, что компилятор статически знает значение sizeof (char) равным 1, и он также знает, что умножение числа на статический 1 означает, что умножение не нужно делать; компилятор оптимизирует его. Озабоченность выступления не должна входить в рассмотрение на этих основаниях.
Ответ 7
Из "Нового стандарта C. Экономический и культурный комментарий".
- Статистика: 2,0% от размераof взяты из
char
и 1,5% - от unsigned char
. Страница 1033 в версии 1.2.
- стр. 1037.
Число бит в представлении типа символа равно не имеет значения. По определению число байтов в байте, тип символа равен один.
Рекомендации по кодированию Разработчики иногда ассоциировать байт, как всегда содержащий восемь бит. На хостах, где тип символа - 16 бит, это может приводят к ошибочному предположению, что применение sizeof к типу символа вернет значение 2. Эти вопросы обсуждаются в других местах.
Ответ 8
Использование sizeof (char) делает ваш код более читабельным и портативным.
На x86 мы все знаем, что символ 1 байт. Но прямое его изложение помогает сделать ваши намерения более ясными, что всегда хорошо.
Кроме того, что, если ваш код будет помещен на другую платформу, где символ не является 1 байтом. Что, если вместо символа было всего 4 бита?
Согласовано, это не обязательно, но это не замедляет ваше время работы, и оно будет окупиться в этом редком случае, вам нужно перенести свой код в другую архитектуру.