Почему длина строки пустого массива отличается от размера массива? - PullRequest
0 голосов
/ 30 октября 2019

При возврате длины и размера пустой строки в C значения различаются. Почему это так?

char b[7];

printf("String Length: %d", strlen(b)); // Returns 22
printf("String Size: %d", sizeof(b));   // Returns 7

Ответы [ 4 ]

3 голосов
/ 30 октября 2019

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

Даже если вы инициализировали массив (например, char b[7] = "a";), функция strlen выдаст результат, отличный от оператора sizeof.

Естьпросто невозможно заставить оба дать один и тот же результат без неопределенного поведения тем или иным образом.


Теперь, что касается того, почему strlen возвращает 22 в вашем случае, это потому, что неинициализированные локальные переменные,даже массивы, действительно , неинициализированы. Их значения и содержимое не определены и могут рассматриваться как случайные или мусорные. В вашем массиве нет случайного нулевого терминатора.

Когда вы передаете указатель на первый элемент массива в функцию strlen, он продолжит искать нулевой терминатордаже если это выходит за пределы. А в вашем конкретном случае просто случается, что байт, соответствующий нулевому терминатору, после того, как strlen насчитали 22 "случайных" или "мусорных" символа.

3 голосов
/ 30 октября 2019

Это связано с тем, что выделенное пространство вашего массива не очищается. Таким образом, в стеке, где вы размещены char b[7];, есть случайные данные. Функция strlen () запускает вас в ячейке памяти b [0] для поиска конечного символа '\ 0'.

В вашем случае первый символ '\ 0' найден, а 23-е место имеет длину 22. Это число 22 является неопределенным поведением и может отличаться при каждом запуске кода.

Если вы инициализируете свой массив с '\ 0' на b [0], он вернет длину 0.

0 голосов
/ 30 октября 2019

Один массив [фиксированного размера] может содержать строки различной длины (конечно, в разное время)

char t[10]; x = sizeof t; /* 10 */
x = strlen(t); /* BANG: t  is not valid */
t[0] = '\0'; x = strlen(t); /* 0 */
strcpy(t, "1"); x = strlen(t); /* 1 */
strcpy(t, "12345678"); x = strlen(t); /* 8 */
strcpy(t, "123456789"); x = strlen(t); /* 9 */
strcpy(t, "1234567890"); /* BANG */
0 голосов
/ 30 октября 2019

При возврате длины и размера пустой строки в C значения различаются. Почему это так?

Если массив не имеет статической длительности хранения, он не содержит даже пустую строку. Он просто неинициализирован и имеет неопределенную ценность. Поэтому использование функции strlen приводит к неопределенному поведению.

Обратите внимание на то, что эти вызовы

printf("String Length: %d", strlen(b));
printf("String Size: %d", sizeof(b));

имеют неопределенное поведение, поскольку используются неверные спецификаторы преобразования. Вы должны использовать %zu вместо %d.

Вы можете объявить массив как

char b[7] = "";

или как

char b[7] = { '\0' };

или даже как

char b[7] = { [6] = '\0' };

В этих случаях массив действительно содержит пустую строку, и функция strlen вернет 0.

В любом случае функция strlen и оператор sizeof возвращают разные значенияпоскольку функция strlen не считает конечный ноль строки, хранящейся в массиве.

Рассмотрим следующую демонстрационную программу

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char s[] = "Hello";

    printf( "strlen( s ) = %zu\n", strlen( s ) );
    printf( "sizeof( s ) = %zu\n", sizeof( s ) );

    return 0;
}

Ее вывод

strlen( s ) = 5
sizeof( s ) = 6
...