sizeof для константного символа с нулевым символом в конце * - PullRequest
19 голосов
/ 29 октября 2010
const char* a;

как мне убедиться, что строка 'a' оканчивается нулем? когда a = "abcd", и я делаю sizeof (a), я получаю 4. Означает ли это, что он не заканчивается нулем? если бы это было так, я бы получил 5?

Ответы [ 6 ]

31 голосов
/ 29 октября 2010

sizeof(a) дает вам размер указателя, а не массива символов, на который указывает указатель. Это так же, как если бы вы сказали sizeof(char*).

Вам необходимо использовать strlen() для вычисления длины строки с нулевым символом в конце (обратите внимание, что возвращаемая длина не включает нулевой терминатор, поэтому strlen("abcd") равно 4, а не 5). Или вы можете инициализировать массив строковым литералом:

char a[] = "abcd";
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer

Строковый литерал "abcd" завершен нулем; все строковые литералы заканчиваются нулем.

12 голосов
/ 29 октября 2010

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

6 голосов
/ 29 октября 2010

Проблема здесь в том, что вы путаете sizeof(), который является операцией времени компиляции, с длиной строки, которая является операцией времени выполнения. Причина возврата 4 при запуске sizeof(a) состоит в том, что a является указателем, а типичный типичный указатель указателя в C составляет 4 байта. Чтобы получить длину строки, используйте strlen.

Что касается второго вопроса, как убедиться, что строка завершена нулем. Единственный способ сделать это - завершить строку самостоятельно. Учитывая только char*, нет никакой возможности гарантировать 100%, что оно будет правильно завершено. Необходимо быть очень внимательным, чтобы в договоре между производителем и потребителем char* понималось, кто завершает строку.

5 голосов
/ 29 октября 2010

Если вам передают массив символов, в котором могут быть или не быть данные с нулевым символом в конце, на самом деле нет хорошего способа проверки.Лучшее, что вы можете сделать, - это найти нулевой символ до определенной длины (не бесконечно!).Но 0 - это не совсем необычный байт данных, который можно найти в неинициализированной области памяти.

Это одна из многих особенностей стандартного строкового стандарта Си, которая не нравится многим.Поиск длины строки, которую клиент передает вам, - это в лучшем случае операция поиска O (n), а в худшем случае ошибка сегментации.

Другая проблема, конечно, заключается в том, что массивы и указатели являются взаимозаменяемыми.Это означает, что array_name + 2 соответствует &(array_name[2]), а sizeof(a) равно sizeof(char*), а не длине массива.

4 голосов
/ 29 октября 2010

sizeof(a) равно sizeof(const char*), размер указателя.На него не влияет содержание a.Для этого вам нужно strlen.

Кроме того, все строковые литералы в двойных кавычках, такие как ваш "abcd" в исходном коде, автоматически обнуляются.

1 голос
/ 29 октября 2010

sizeof (a) возвращает размер const char *a ... не тот размер, на который он указывает.Вы можете использовать strlen(a) для определения длины строки с нулевым символом в конце, и нет, результат strlen не включает в себя нулевой терминатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...