Всегда ли размер sizeof (char) всегда эквивалентен sizeof (буквальному)? - PullRequest
2 голосов
/ 23 апреля 2019

Всегда ли верно следующее для любой реализации?

(strlen("some string with weird characters") + 1) * sizeof(char) 
    == sizeof("some string with weird characters");

Я спрашиваю, могу ли я надежно использовать (strlen(my_string) + 1) * sizeof(char) для вычисления двоичного размера любой строки.Также, пожалуйста, дайте мне знать, если есть лучший способ сделать это.

Ответы [ 4 ]

8 голосов
/ 23 апреля 2019

Нет.Единственная ситуация, в которой он отличается, - это встроенные нули:

(strlen("strlen can see this\0strlen cannot see this") + 1) * sizeof(char) 
    != sizeof("strlen can see this\0strlen cannot see this");

Кроме того, sizeof(char) всегда 1, так что нет никакого смысла в этом.


Так какстроковые литералы - это массивы типа char[N] (для некоторого положительного размера N), метод sizeof является правильным способом получения их размера (но / sizeof(char) не требуется, поскольку он 1).

2 голосов
/ 23 апреля 2019

Нет!

char str[20] = "abc";

имеет размер 20 и длину строки 3.


Редактировать: Два способа дают один и тот же результат (для этих конкретных данных), но следует отметить два момента:

sizeof(char) всегда 1 по определению. Как правило, лучше использовать размер именованной переменной, и тогда код легче поддерживать. Например

char *ptr = malloc(100 * sizeof(char));

лучше как

char *ptr = malloc(100 * sizeof *ptr);

и затем, если вам нужно изменить тип, вам не нужно менять размер.

Другой момент заключается в том, что sizeof вычисляется компилятором, но strlen не вычисляется до времени выполнения (кроме оптимизации компилятора). Но для строкового литерала, если это требуемый размер, тогда sizeof, как правило, будет более эффективным, поскольку строковый литерал не может измениться во время выполнения.

0 голосов
/ 24 апреля 2019

В большинстве случаев равенство будет иметь место и его можно упростить, поскольку sizeof(char) по определению равно 1.

Обратите внимание, однако, что если строковый литерал содержит внедренные нулевые байты, strlen() будет меньше, чем размер литерала минус 1.

Вот самый короткий контрпример:

strlen("\0") + 1 != sizeof("\0")   // strlen("\0") is 0 but sizeof("\0") is 2
0 голосов
/ 23 апреля 2019

Нет, оба значения

(strlen(myString) + 1) * sizeof(char)

и

sizeof(myString)

не всегда равны.Если массив char myString содержит количество элементов и отличается от упомянутого индекса массива, то strlen(myString) и sizeof(myString) будут отличаться.Например, в следующем случае

char myString[10];

и (strlen(myString) + 1) * sizeof(char), и sizeof(myString) приведут к одинаковому результату.Но если другой случай, например

char myString[10] = "Hello";

, результаты будут другими.

Также я бы предпочел это

(strlen(myString) + 1) * sizeof( *myString)

, а не

(strlen(myString) + 1) * sizeof(char)

как sizeof( *myString) выглядит обобщенно.

Примечание , если myString имеет тип char*, то есть тип указателя как

char *myString = "some string with weird characters";

или используется в качестве аргументов функции удерживается как

void myTestFunc(char *myString) { }

, тогда sizeof(myString) не будет работать, strlen(myString) + 1) * sizeof( *myString) предпочтительнее.

...