Нуль-терминированная строка

Нуль-термини́рованная или нуль-термина́льная строка́, также C-строка́ (от названия языка Си) или ASCIIZ-строка́ (от англ. ASCII zero-terminated string) — способ представления строк в языках программирования, при котором вместо введения специального строкового типа используется массив символов, а концом строки считается первый встретившийся специальный нуль-символ (управляющий символ NUL с кодом 0x00).

Описание

Например, в строковом буфере (области памяти, выделенной для хранения строки) размером 11 байтов нуль-терминированная строка «СТРОКА» в кодировке Windows-1251 может представляться следующим образом:

СТРОКАNULF%NUL4
0xD10xD20xD00xCE0xCA0xC00x000x460x250x000x34

В данном примере представлена область памяти из 11 байтов, хотя на самом деле строка занимает всего 7. Символы после нуль-символа (8—11 байты) называются мусором — это данные, которые могли остаться в буфере от предыдущих строк или от других использований памяти. Среди них также могут находиться нулевые символы.

При использовании однобайтовых кодировок (кодовых страниц), например расширенного ASCII, объём памяти, требуемый для представления строки из N символов, равен N + 1 байт. В случае, когда для кодирования символов применяется Юникод, длина строки зависит от используемого представления Юникода (например, 4N + 4 байта для UTF-32) и (для UTF-8 и UTF-16) от кодируемого текста (от N + 1 до 4N + 1 байта для UTF-8, от 2N + 2 до 4N + 2 байтов для UTF-16).

Такие строки являются стандартом в Си и некоторых других языках программирования. Поскольку они используются для передачи строковых аргументов в стандартные функции во многих операционных системах, операции для работы с нуль-терминированными строками появились в Паскале и других языках.

Для работы с нуль-терминированной строкой используется указатель на её начало (символ с индексом 0). Это простой, быстрый и гибкий подход, но он чреват ошибками[1][2]. Программист постоянно должен следить за своим кодом, а именно:

  • быть уверенным, что не случаются переполнения буфера;
  • аккуратно проводить управление памятью, выделяемой под строки;
  • выполнять принудительное нуль-терминирование строк при использовании функций, которые его не гарантируют (например, strncpy);
  • в редких случаях, когда размер строки может быть очень велик, следить, что не происходит переполнение целого при подсчёте длины и прочих связанных с длиной вычислениях.

Кроме того, некоторые операции со строками, например конкатенация, для нуль-терминированных строк выполняются медленнее, чем для других типов строк.

Сравнение с альтернативами

Альтернативой нуль-терминированным строкам являются способы, принятые в Паскале и современных объектно-ориентированных языках. В Паскале строка начинается с первого элемента массива, а в нулевом элементе хранится длина строки. В этом случае не требуется использовать специальный терминатор для обозначения конца строки. С другой стороны, здесь на длину строки накладывается ограничение, связанное с вместимостью нулевого элемента массива, то есть в случае с однобайтовыми символами длина строки не может превышать 255 символов. Нуль-терминированные строки такому ограничению не подвержены и теоретически могут иметь любую длину. В ОО-языках применяется хранение записи с длиной строки и ссылкой (или указателем) на массив символов. Эти способы лишены недостатка нуль-терминированных строк: они могут хранить в себе нуль-символы без искажений и специального кодирования.

В ряде интерфейсов применяются дважды-нуль-терминированные строки, признаком завершения которых является последовательность из двух нуль-символов[3].

В языке Си

Для работы с нуль-терминированными строками в языке программирования Си используется ряд функций:

  • strcpy, wcscpy — копирование строк;
  • strlen, wcslen — вычисление длины строки;
  • strchr — поиск символа в строке;
  • strdup — дублирование строк;
  • strstr — поиск подстроки;
  • strtok — разделение строки через разделители на подстроки;
  • strbrk — поиск первого вхождения в строку одного из символов другой строки.

В языке ассемблера

В некоторых разновидностях языка ассемблера для определения нуль-терминированных строк используется специальная директива. Так, в GNU Assembler для этого есть директива .asciz[4][5].

См. также

Примечания

  1. Joel on Software - Назад, к основам. Дата обращения: 17 сентября 2016. Архивировано из оригинала 25 сентября 2016 года.
  2. The Most Expensive One-byte Mistake - ACM Queue (англ.). Дата обращения: 17 сентября 2016. Архивировано 19 сентября 2016 года.
  3. What is the format of a double-null-terminated string with no strings? (англ.) Архивная копия от 13 февраля 2019 на Wayback Machine / MSDN, 2009
  4. Использование GNU ассемблера as.: Ассемблерные директивы. Дата обращения: 17 сентября 2016. Архивировано 17 сентября 2016 года.
  5. .asciz "string"… (англ.). Дата обращения: 17 сентября 2016. Архивировано из оригинала 17 сентября 2016 года.

Литература

Ссылки