Несколько вопросов о строках - PullRequest
0 голосов
/ 13 апреля 2020

Я столкнулся с проблемой. В следующем коде я ожидал, что длина строки p будет равна 3, но фактическая длина равна 6. Это первое место, которое мне интересно. Затем, когда я отлаживаю себя, длина отлаженного p соответствует ожидаемому результату. Это заставляет меня чувствовать себя очень озадаченным. Я не знаю, почему длина p равна 6, и почему длина становится 3 при отладке. , Может кто-нибудь ответить на этот вопрос?

#include <cstring>
#include <cstdio>

int main()
{
    char p[]={'a','b','c'}, q[10] = {'a','b','c'};
    printf("%p  %p\n",&q,&p);
    printf("%d  %d\n",strlen(q),strlen(p));
    return 0;
}

pi c -1 pi c -2

Ответы [ 3 ]

3 голосов
/ 13 апреля 2020

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

Вывод программы, содержащей UB, не может быть оправдан ни при каких обстоятельствах. манера.

Чтобы добавить больше контекста, q завершается нулем, в соответствии с правилом списка инициализаторов, имеющего меньше аргументов, чем размер агрегата, остальные члены инициализируются так, как если бы они имели stati c storage, поэтому в случае типа char они инициализируются с 0 (который является нулевым терминатором, необходимым для строки). Итак, использование q в качестве строки - это нормально.

Решение:

Вы можете либо

  • упомянуть измерение, превышающее это элементов списка инициализатора
  • положить нулевое значение в качестве последнего элемента в списке инициализатора {'a','b','c', '\0'}
  • использовать строку (вместо списка инициализатора) для инициализируйте массив, например "abc", который будет включать нулевой терминатор в массиве.
2 голосов
/ 13 апреля 2020

В C строки должны заканчиваться нулевым байтом, и именно так strlen находит их длину. Объявите ваши строки, как это, и длина будет отображаться правильно:

char p[]={'a','b','c', '\0'}, q[10] = {'a','b','c', '\0'};
1 голос
/ 13 апреля 2020

p не заканчивается нулем; strlen продолжает считать до тех пор, пока не увидит ноль (или ваша программа будет прервана, потому что вы обращаетесь к не принадлежащей вам памяти).

Обратите внимание, что q инициализирован , и любые элементы массива не предусмотрены в инициализаторе, установлены на ноль.

...