Во вводном курсе C я узнал, что при хранении строки хранятся с нулевым символом \0
в конце. Но что, если я хочу напечатать строку, скажем, printf("hello")
хотя я обнаружил, что это не заканчивается \0
следующим утверждением
printf("%d", printf("hello"));
Output: 5
но это кажется противоречивым, насколько я знаю, что переменные, такие как строки, хранятся в основной памяти, и я предполагаю, что при печати чего-то это также может быть сохранено в основной памяти, тогда почему разница?
);
, что вы намереваетесь показать этим кодом? Как вы доказали, что это не заканчивается\0
?Ответы:
Нулевой байт отмечает конец строки. Он не учитывается по длине строки и не печатается, когда строка печатается с помощью
printf
. По сути, нулевой байт сообщает функциям, которые выполняют манипуляции со строками, когда останавливаться.Вы увидите разницу, если создадите
char
массив, инициализированный строкой. Использованиеsizeof
оператора будет отражать размер массива, включая нулевой байт. Например:источник
printf()
. TBH Я понятия не имею, какprintf()
работает.printf
возвращает количество напечатанных символов.'\0'
не печатается - это просто сигнал о том, что в этой строке больше нет символов. Также не учитывается длина строкиhttps://godbolt.org/z/wYn33e
источник
Ваше предположение неверно. Ваша строка действительно заканчивается на
\0
.Он содержит 5 символов
h
,e
,l
,l
,o
и символ 0.«Внутренний»
print()
вывод выводит количество напечатанных символов, и это 5.источник
В Си все литеральные строки на самом деле являются массивами символов, которые включают в себя нулевой терминатор.
Однако нулевой терминатор не учитывается в длине строки (литеральной или нет) и не печатается. Печать останавливается, когда нулевой терминатор найден.
источник
printf
выходило бы за пределы строки, печатать «случайные» или «мусорные» символы и возвращать число отличается от длины строки. Если вы уже знаете длину строки, вы также можете проверить, соответствует ли символ в этом индексе'\0'
, что будет работать, но технически неопределенное поведение, если размер массива не включает терминатор (какchar arr[5] = "hello";
, например, который не будет добавлять терминатор в массив).char * p = "Hello"; int i = 0; while (p[i] != '\0') { printf("%d: %c", i, p[i]); i++; }
посмотреть и посмотреть, как он работает: он показывает строки с индексами и содержимое в этой строке. После индекса 4 он находит символ 0 и прерывает цикл while. Там вы видите, что есть символ 0.Все ответы действительно хороши, но я хотел бы добавить еще один пример, чтобы завершить все эти
Для тех, кто не хочет попробовать это на онлайн GDB, вывод:
https://linux.die.net/man/3/printf
Полезно ли понимать, что делает escape-терминатор? Это не граница для массива символов или строки. Это персонаж, который скажет парню, который разбирает -STOP, (печатает), разбирает, пока здесь.
PS: А если разбирать и печатать как массив символов
ты получаешь:
где, пробел после двойного l, является нулевым терминатором, однако, анализируя массив char, будет просто значение char каждого байта. Если вы выполните другой анализ и напечатаете значение int каждого байта ("% d%, char_array [i]), вы увидите, что (вы получаете представление ASCII code-int), пробел имеет значение 0.
источник
В
C
функцииprintf()
возвращает количество напечатанных символов,\0
являетсяnull
терминатором, который используется для обозначения конца строки на языке c, и встроенногоstring
типа на данный момент не существуетc++
, однако размер вашего массива должен быть как минимум больше числа, котороеchar
вы хотите хранить.Вот ссылка: cpp ref printf ()
источник
Вы неправы. Это утверждение не подтверждает, что строковый литерал
"hello"
не заканчивается завершающим нулевым символом'\0'
. Это утверждение подтвердило, что функцияprintf
выводит элементы строки, пока не встретится завершающий нулевой символ.Когда вы используете строковый литерал, как в приведенном выше заявлении, компилятор создает массив символов со статической продолжительностью хранения, который содержит элементы строкового литерала.
Так на самом деле это выражение
обрабатывается компилятором что-то вроде следующего
Действие функции printf при этом можно представить следующим образом
Чтобы получить количество символов, хранящихся в строковом литерале "hello", вы можете запустить следующую программу
Выход программы
источник
Сначала вы должны очистить свою концепцию. Поскольку она будет очищена при работе с массивом, используемая вами команда печати просто подсчитывает символы, помещенные в парантез. В строке массива необходимо, чтобы она заканчивалась на \ 0
источник
Строка - это вектор символов. Содержит последовательность символов, образующих строку, за которой следует специальная конечная строка символов: '\ 0'
Пример: char str [10] = {'H', 'e', 'l', 'l', 'o', '\ 0'};
Пример: следующий символьный вектор не является одной строкой, потому что он не заканчивается на «\ 0»
char str [2] = {'h', 'e'};
источник