Подтвердить что ты не робот

Что означает символ \0 в строке C?

Рассмотрим следующий код:

char str[]= "Hello\0";

Какова длина массива str и с каким количеством окон заканчивается?

4b9b3361

Ответ 1

sizeof str - 7 - пять байтов для текста "Hello", плюс явный терминатор NUL плюс неявный терминатор NUL.

strlen(str) - 5 - только пять байтов "Hello".

Ключевым моментом здесь является то, что неявный терминатор nul всегда добавляется, даже если строковый литерал заканчивается на \0. Конечно, strlen просто останавливается при первом \0 - он не может отличить разницу.

Есть одно исключение из неявного правила терминатора NUL - если вы явно указываете размер массива, строка будет усечена, чтобы соответствовать:

char str[6] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 6 (with one NUL)
char str[7] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 7 (with two NULs)
char str[8] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 8 (with three NULs per C99 6.7.8.21)

Это, однако, редко полезно и склонно просчитывать длину строки и заканчиваться неисчерпаемой строкой. Это также запрещено в С++.

Ответ 2

Длина массива равна 7, символ NUL \0 по-прежнему считается символом, а строка все равно заканчивается неявным \0

Смотрите эту ссылку, чтобы увидеть рабочий пример

Обратите внимание, что если бы вы объявили str как char str[6]= "Hello\0";, длина была бы 6, потому что неявный NUL добавляется только в том случае, если он может поместиться (чего не может быть в этом примере.)

& раздел; 6.7.8/p14
Массив тип символа может быть инициализирован символьный строковый литерал, необязательно заключенные в фигурные скобки. Sucessive символы символьной строки буквальный (включая завершающий null character , если есть место, или если массив неизвестного размера) инициализируйте элементы массива.

Примеры

char str[] = "Hello\0"; /* sizeof == 7, Explicit + Implicit NUL */
char str[5]= "Hello\0"; /* sizeof == 5, str is "Hello" with no NUL (no longer a C-string, just an array of char). This may trigger compiler warning */
char str[6]= "Hello\0"; /* sizeof == 6, Explicit NUL only */
char str[7]= "Hello\0"; /* sizeof == 7, Explicit + Implicit NUL */
char str[8]= "Hello\0"; /* sizeof == 8, Explicit + two Implicit NUL */

Ответ 3

Разбивая свое обычное барабанное соло JUST TRY IT, вот как вы можете ответить на такие вопросы в будущем:

$ cat junk.c
#include <stdio.h>

char* string = "Hello\0";

int main(int argv, char** argc)
{
    printf("-->%s<--\n", string);
}
$ gcc -S junk.c
$ cat junk.s

... устраняя ненужные части...

.LC0:
    .string "Hello"
    .string ""

...

.LC1:
    .string "-->%s<--\n"

...

Обратите внимание на то, как строка, которую я использовал для printf, просто "-->%s<---\n", а глобальная строка состоит из двух частей: "Hello" и "". Ассемблер GNU также завершает строки с неявным символом NUL, поэтому тот факт, что первая строка (.LC0) находится в этих двух частях, указывает на наличие двух NUL s. Таким образом, строка имеет длину 7 байтов. Как правило, если вы действительно хотите знать, что делает ваш компилятор с определенным куском кода, изолируйте его в таком фиктивном примере, как это, и посмотрите, что он делает, используя -S (для GNU - MSVC имеет флаг также для вывода ассемблера, но Я не знаю, что это за руку). Вы узнаете много о том, как работает ваш код (или не работает в зависимости от обстоятельств), и вы получите ответ быстро, который на 100% гарантированно соответствует инструментам и среде, в которой вы работаете.

Ответ 4

Какова длина массива str и с каким количеством окон заканчивается?

Позвольте узнать:

int main() {
  char str[] = "Hello\0";
  int length = sizeof str / sizeof str[0];
  // "sizeof array" is the bytes for the whole array (must use a real array, not
  // a pointer), divide by "sizeof array[0]" (sometimes sizeof *array is used)
  // to get the number of items in the array
  printf("array length: %d\n", length);
  printf("last 3 bytes: %02x %02x %02x\n",
         str[length - 3], str[length - 2], str[length - 1]);
  return 0;
}

Ответ 5

В частности, я хочу упомянуть одну ситуацию, с помощью которой вы можете смутить.

В чем разница между "\ 0" и ""?

Ответ заключается в том, что "\0" представляет в массиве {0 0} и "" is {0}.

Потому что "\0" по-прежнему является строковым литералом, и он также добавит "\0" в конец. И "" пуст, но также добавляет "\0".

Понимание этого поможет вам глубоко понять "\0".