Я вхожу в C/C++, и много условий открывается незнакомое мне. Один из них является переменной или указателем, который завершается нулем. Что означает для пространства в памяти, которая будет завершена нулем?
Возьмите строку Hi
в ASCII. Его простейшее представление в памяти - два байта:
0x48
0x69
Но где заканчивается этот кусок памяти? Если вы также не готовы передать количество байтов в строке, вы не знаете - фрагменты памяти по сути не имеют длины.
Итак, в C есть стандарт, согласно которому строки заканчиваются нулевым байтом, также известным как символ NUL
:
0x48
0x69
0x00
Теперь строка однозначно состоит из двух символов, потому что есть два символа перед ] NUL
.
Есть два распространенных способа обработки массивов, которые могут иметь содержимое переменной длины (например, строки). Первый - отдельно хранить длину данных, хранящихся в массиве. Это делают такие языки, как Fortran и Ada, а также std :: string в C ++. Недостатком этого является то, что вам каким-то образом нужно передать эту дополнительную информацию всему, что имеет дело с вашим массивом.
Другой способ - зарезервировать дополнительный элемент, не связанный с данными, в конце массива, чтобы он служил дозорным. Для дозорного вы используете значение, которое никогда не должно появляться в реальных данных. Для строк 0 (или «NUL») - хороший выбор, так как он не печатается и не служит другой цели в ASCII. Итак, что делает C (и многие языки, скопированные с C) - это предположение, что все строки заканчиваются (или «заканчиваются») на 0.
У этого есть несколько недостатков. Во-первых, это медленно. Каждый раз, когда подпрограмме требуется знать длину строки, это операция O (n) (поиск по всей строке в поисках 0).Другая проблема заключается в том, что однажды вы можете по какой-то причине захотеть поместить 0 в свою строку, поэтому теперь вам понадобится целый второй набор строковых подпрограмм, которые игнорируют нуль и в любом случае используют отдельную длину (например: strnlen ()). Третья большая проблема заключается в том, что если кто-то забудет поставить этот 0 в конце (или он каким-то образом будет уничтожен), следующая строковая операция для выполнения проверки lenth будет весело проходить через память, пока она не случайно найдет другой 0, вылетает, или пользователь теряет терпение и убивает его. Такие ошибки могут стать серьезной проблемой для отслеживания PITA.
По всем этим причинам к подходу на языке C обычно относятся с неодобрением.
Это зарезервированное значение для обозначения конца последовательности (например) символов в строке.
Более правильное название завершено с нулевым (или NUL) завершением . Это связано с тем, что используемое значение равно нулю, а не является кодом символа для «0». Чтобы уточнить различие, посмотрите таблицу набора символов ASCII .
Это необходимо, поскольку такие языки, как C, имеют тип данных char
, но не имеют типа данных string
. Следовательно, разработчику остается решать, как управлять строками в своем приложении. Обычный способ сделать это - иметь массив из char
s с нулевым значением, используемым для завершения (т. Е. Обозначения конца) строки.
Обратите внимание, что существует различие между длиной строки и длиной изначально объявленного массива символов.
char name[50];
Объявляет массив из 50 символов. Однако эти значения не инициализируются. Поэтому, если я хочу сохранить строку «Hello»
(длиной 5 символов), я действительно не хочу утруждать себя установкой оставшихся 45 символов на пробелы (или какое-то другое значение). Вместо этого я сохраняю значение NUL после последнего символа в моей строке.
В более поздних языках, таких как Pascal, Java и C #, определен конкретный строковый
тип. У них есть значение заголовка, указывающее количество символов в строке. У этого есть несколько преимуществ; во-первых, вам не нужно идти до конца строки, чтобы узнать ее длину, во-вторых, ваша строка может содержать нулевые символы .
В Википедии есть дополнительная информация в разделе String (информатика) .
Это относится к тому, как строки C хранятся в памяти. Символ NUL, представленный \ 0 в строковых итерациях, присутствует в конце строки C в памяти. Нет других метаданных, связанных, например, со строкой C, такой как длина. Обратите внимание на различное написание между символом NUL и указателем NULL.
Строки в стиле C заканчиваются символом NUL ('\ 0'). Это обеспечивает маркер для функций, которые работают со строками (например, strlen, strcpy), чтобы использовать их для определения конца строки.
Массивы и строка в C - это просто указатели на ячейку памяти. По указателю можно найти начало массива. Конец массива не определен. Конец символьного массива (который представляет собой строку) - нулевой байт.
Итак, в памяти строка hello записывается как:
68 65 6c 6c 6f 00 |hello|
Завершается нулем
Это когда ваш остроконечный босс увольняет вас.