Нуль-терминированная строка (Url,-myjbnunjkfguugx vmjktg)
Нуль-терминированная или нуль-терминальная строка, также C-строка (от названия языка Си) или ASCIIZ-строка (от англ. ASCII zero-terminated string) — способ представления строк в языках программирования, при котором вместо введения специального строкового типа используется массив символов, а концом строки считается первый встретившийся специальный нуль-символ (управляющий символ ASCII NUL
с кодом 0x00
).
Описание
[править | править код]Например, в строковом буфере (области памяти, выделенной для хранения строки) размером 11 байт нуль-терминированная строка «СТРОКА» в кодировке Windows-1251 может представляться следующим образом:
С | Т | Р | О | К | А | NUL | F | % | NUL | 4 |
0xD1 |
0xD2 |
0xD0 |
0xCE |
0xCA |
0xC0 |
0x00 |
0x46 |
0x25 |
0x00 |
0x34
|
В данном примере представлена область памяти из 11 байт, хотя на самом деле строка занимает всего 7. Символы после нуль-символа (8—11 байты) называются мусором — это данные, которые могли остаться в буфере от предыдущих строк или от других использований памяти. Среди них также могут находиться нулевые символы.
При использовании однобайтных кодировок (кодовых страниц), например расширенного ASCII[англ.], объём памяти, требуемый для представления строки из N символов, равен N + 1 байт. В том случае, когда для кодирования символов применяется Юникод, длина строки зависит от используемого представления Юникода (например, 2N + 2 байта для UCS-2).
Такие строки являются стандартом в Си и некоторых других языках программирования. Поскольку они используются для передачи строковых аргументов в стандартные функции во многих операционных системах, операции для работы с нуль-терминированными строками появились в Паскале и других языках.
Для работы с нуль-терминированной строкой используется указатель на её начало (символ с индексом 0). Это простой, быстрый и гибкий подход, но он чреват ошибками[1][2]. Программист постоянно должен следить за своим кодом, а именно:
- быть уверенным, что не случаются переполнения буфера;
- аккуратно проводить управление памятью, выделяемой под строки;
- выполнять принудительное нуль-терминирование строк при использовании функций, которые его не гарантируют (например, strncpy);
- в редких случаях, когда размер строки может быть очень велик, следить, что не происходит переполнение целого при подсчёте длины и прочих связанных с длиной вычислениях.
Кроме того, некоторые операции со строками, например конкатенация, для нуль-терминированных строк выполняются медленнее, чем для других типов строк.
Сравнение с альтернативами
[править | править код]Альтернативой нуль-терминированным строкам являются способы, принятые в Паскале и современных ООП-языках. В Паскале строка начинается с первого элемента массива, а в нулевом элементе хранится длина строки. В этом случае не требуется использовать специальный терминатор для обозначения конца строки. С другой стороны, здесь на длину строки накладывается ограничение, связанное с вместимостью нулевого элемента массива, то есть в случае с однобайтовыми символами длина строки не может превышать 255 символов. Нуль-терминированные строки такому ограничению не подвержены и теоретически могут иметь любую длину. В объектно-ориентированных языках применяется хранение записи с длиной строки и ссылкой (или указателем) на массив символов. Эти способы лишены недостатка нуль-терминированных строк: они могут хранить в себе нуль-символы без искажений и специального кодирования.
В ряде интерфейсов применяются дважды-нуль-терминированные строки, признаком завершения которых является последовательность из двух нуль-символов[3].
В языке Си
[править | править код]Для работы с нуль-терминированными строками в языке программирования Си используется ряд функций:
- strcpy, wcscpy — копирование строк;
- strlen, wcslen — вычисление длины строки;
- strchr — поиск символа в строке;
- strdup — дублирование строк;
- strstr — поиск подстроки;
- strtok — разделение строки через разделители на подстроки;
- strbrk — поиск первого вхождения в строку одного из символов другой строки.
В языке ассемблера
[править | править код]В некоторых разновидностях языка ассемблера для определения нуль-терминированных строк используется специальная директива. Так, в GNU Assembler для этого есть директива .asciz
[4][5].
См. также
[править | править код]Примечания
[править | править код]- ↑ Joel on Software - Назад, к основам . Дата обращения: 17 сентября 2016. Архивировано из оригинала 25 сентября 2016 года.
- ↑ The Most Expensive One-byte Mistake - ACM Queue (англ.). Дата обращения: 17 сентября 2016. Архивировано 19 сентября 2016 года.
- ↑ What is the format of a double-null-terminated string with no strings? (англ.) Архивная копия от 13 февраля 2019 на Wayback Machine / MSDN, 2009
- ↑ Использование GNU ассемблера as.: Ассемблерные директивы . Дата обращения: 17 сентября 2016. Архивировано 17 сентября 2016 года.
- ↑ .asciz "string"… (англ.). Дата обращения: 17 сентября 2016. Архивировано из оригинала 17 сентября 2016 года.
Литература
[править | править код]- Poul-Henning Kamp, The Most Expensive One-byte Mistake. Did Ken, Dennis, and Brian choose wrong with NUL-terminated text strings? Архивная копия от 19 сентября 2016 на Wayback Machine / ACM Queue, Volume 9, issue 7, July 25, 2011 (англ.)
- Назад, к основам (рус.) — Back to Basics by Joel Spolsky Архивная копия от 5 сентября 2016 на Wayback Machine, December 11, 2001 (англ.)
Ссылки
[править | править код]- http://c2.com/cgi/wiki?StringWithoutLength (англ.) Архивная копия от 19 июля 2016 на Wayback Machine
- http://c2.com/cgi/wiki?NonNullTerminatedString (англ.) Архивная копия от 20 сентября 2016 на Wayback Machine