Нуль-терминированная строка: различия между версиями
[отпатрулированная версия] | [отпатрулированная версия] |
V1adis1av (обсуждение | вклад) |
A5b (обсуждение | вклад) https://www.opennet.ru/docs/RUS/gas/gas-7.html http://queue.acm.org/detail.cfm?id=2010365 !!!! |
||
Строка 1: | Строка 1: | ||
'''Нуль-терминированная строка''' или '''C-строка''' (от названия [[Си (язык программирования)|языка Си]]) или ASCIZ-строка (от названия директивы ассемблера <code>.asciz</code>) — способ представления [[строковый тип|строк]] в языках программирования, при котором вместо введения специального строкового типа используется массив символов, а концом строки считается первый встретившийся специальный ''нуль-символ'' (код [[ASCII]] 0x00). Например, в ''строковом буфере'' (области памяти, выделенной для хранения строки) размером 11 байт нуль-терминированная строка «СТРОКА» в кодировке [[Windows-1251]] может представляться следующим образом: |
'''Нуль-терминированная строка''' или '''C-строка''' (от названия [[Си (язык программирования)|языка Си]]) или ASCIZ-строка (от названия директивы ассемблера <code>.asciz</code><ref>https://www.opennet.ru/docs/RUS/gas/gas-7.html</ref><ref>http://web.mit.edu/rhel-doc/3/rhel-as-en-3/asciz.html</ref>) — способ представления [[строковый тип|строк]] в языках программирования, при котором вместо введения специального строкового типа используется массив символов, а концом строки считается первый встретившийся специальный ''нуль-символ'' (код [[ASCII]] 0x00). Например, в ''строковом буфере'' (области памяти, выделенной для хранения строки) размером 11 байт нуль-терминированная строка «СТРОКА» в кодировке [[Windows-1251]] может представляться следующим образом: |
||
{| class="standard" |
{| class="standard" |
||
Строка 9: | Строка 9: | ||
Символы после нуль-символа называются ''мусором'' — это данные, которые могли остаться в буфере от предыдущих строк или от других использований памяти. Среди них также могут находиться нулевые символы. |
Символы после нуль-символа называются ''мусором'' — это данные, которые могли остаться в буфере от предыдущих строк или от других использований памяти. Среди них также могут находиться нулевые символы. |
||
При использовании [[байт|однобайтных]] [[кодовая страница|кодировок]] ([[ASCII]]) объём памяти, требуемый для представления строки из N символов, равен {{s|N + 1}} байт. В том случае, когда для кодирования символов применяется [[Юникод]], длина строки зависит от используемого представления Юникода (например, {{s|2N + 2}} байта для UCS-2). |
При использовании [[байт|однобайтных]] [[кодовая страница|кодировок]] ([[ASCII]]) объём памяти, требуемый для представления строки из N символов, равен {{s|N + 1}} байт. В том случае, когда для кодирования символов применяется [[Юникод]], длина строки зависит от используемого представления Юникода (например, {{s|2N + 2}} байта для [[UCS-2]]). |
||
Такие строки являются стандартом в [[Си (язык программирования)|Си]] и некоторых других языках программирования. Поскольку они используются для передачи строковых аргументов в стандартные функции во многих [[операционная система|операционных системах]], операции для работы с нуль-терминированными строками появились в [[Паскаль (язык программирования)|Паскале]] и других языках. |
Такие строки являются стандартом в [[Си (язык программирования)|Си]] и некоторых других языках программирования. Поскольку они используются для передачи строковых аргументов в стандартные функции во многих [[операционная система|операционных системах]], операции для работы с нуль-терминированными строками появились в [[Паскаль (язык программирования)|Паскале]] и других языках. |
||
Для ссылки на нуль-терминированную строку применяется [[Указатель (тип данных)|указатель]] на первый её символ. Это простой, быстрый и гибкий подход, но чреватый ошибками. Программист постоянно должен следить за своим кодом, а именно: |
Для ссылки на нуль-терминированную строку применяется [[Указатель (тип данных)|указатель]] на первый её символ. Это простой, быстрый и гибкий подход, но чреватый ошибками<ref>http://russian.joelonsoftware.com/Articles/BacktoBasics.html</ref><ref>http://queue.acm.org/detail.cfm?id=2010365</ref>. Программист постоянно должен следить за своим кодом, а именно: |
||
* быть уверенным, что не случаются [[переполнение буфера|переполнения буфера]]; |
* быть уверенным, что не случаются [[переполнение буфера|переполнения буфера]]; |
||
* аккуратно проводить [[Утечка памяти|управление памятью]], выделяемой под строки; |
* аккуратно проводить [[Утечка памяти|управление памятью]], выделяемой под строки; |
||
Строка 20: | Строка 20: | ||
Кроме того, некоторые операции со строками, например, [[конкатенация]], для нуль-терминированных строк выполняются медленнее, чем для других типов строк. |
Кроме того, некоторые операции со строками, например, [[конкатенация]], для нуль-терминированных строк выполняются медленнее, чем для других типов строк. |
||
= Сравнение с альтернативами = |
== Сравнение с альтернативами == |
||
Альтернативой нуль-терминированным строкам являются способы, принятые в Паскале и современных ООП-языках. В Паскале строка начинается с первого элемента массива, а в нулевом элементе хранится длина строки. В этом случае не требуется специального терминатора для обозначения конца строки. С другой стороны, здесь на длину строки накладывается ограничение, связанное с вместимостью нулевого элемента массива, то есть в случае с однобайтовыми элементами длина строки не может превышать 255 символов. Нуль-терминированные строки такому ограничению не подвержены и теоретически могут хранить строки любой длины. В объектно-ориентированных языках применяется хранение записи с длиной строки и ссылкой (или указателем) на массив символов. Эти способы не подвержены недостатку нуль-терминированных строк: они могут хранить в себе нуль-символы без искажений и специального кодирования. |
Альтернативой нуль-терминированным строкам являются способы, принятые в Паскале и современных ООП-языках. В Паскале строка начинается с первого элемента массива, а в нулевом элементе хранится длина строки. В этом случае не требуется специального терминатора для обозначения конца строки. С другой стороны, здесь на длину строки накладывается ограничение, связанное с вместимостью нулевого элемента массива, то есть в случае с однобайтовыми элементами длина строки не может превышать 255 символов. Нуль-терминированные строки такому ограничению не подвержены и теоретически могут хранить строки любой длины. В объектно-ориентированных языках применяется хранение записи с длиной строки и ссылкой (или указателем) на массив символов. Эти способы не подвержены недостатку нуль-терминированных строк: они могут хранить в себе нуль-символы без искажений и специального кодирования. |
||
В ряде проприетарных интерфейсов применяются дважды-нуль-терминированные строки, признаком завершения которых является два последовательных нуль-терминатора<ref>[https://blogs.msdn.microsoft.com/oldnewthing/20091008-00/?p=16443/ What is the format of a double-null-terminated string with no strings?] / MSDN, 2009</ref>. Также двойной нуль может использоваться для обозначения |
|||
== В языке Си == |
== В языке Си == |
||
Строка 34: | Строка 36: | ||
== См. также == |
== См. также == |
||
* [[Строковый тип]] |
* [[Строковый тип]] |
||
== Примечания == |
|||
{{примечания}} |
|||
== Литература == |
|||
* Poul-Henning Kamp, [http://queue.acm.org/detail.cfm?id=2010365 The Most Expensive One-byte Mistake. Did Ken, Dennis, and Brian choose wrong with NUL-terminated text strings?] / ACM Queue, Volume 9, issue 7, July 25, 2011 |
|||
* [http://russian.joelonsoftware.com/Articles/BacktoBasics.html Назад, к основам] - [http://www.joelonsoftware.com/articles/fog0000000319.html Back to Basics by Joel Spolsky], December 11, 2001 |
|||
{{Язык программирования Си}} |
{{Язык программирования Си}} |
||
Версия от 08:06, 17 сентября 2016
Нуль-терминированная строка или C-строка (от названия языка Си) или ASCIZ-строка (от названия директивы ассемблера .asciz
[1][2]) — способ представления строк в языках программирования, при котором вместо введения специального строкового типа используется массив символов, а концом строки считается первый встретившийся специальный нуль-символ (код ASCII 0x00). Например, в строковом буфере (области памяти, выделенной для хранения строки) размером 11 байт нуль-терминированная строка «СТРОКА» в кодировке Windows-1251 может представляться следующим образом:
С | Т | Р | О | К | А | NULL | F | % | NULL | 4 |
0xD1 | 0xD2 | 0xD0 | 0xCE | 0xCA | 0xC0 | 0x00 | 0x46 | 0x25 | 0x00 | 0x34 |
Символы после нуль-символа называются мусором — это данные, которые могли остаться в буфере от предыдущих строк или от других использований памяти. Среди них также могут находиться нулевые символы.
При использовании однобайтных кодировок (ASCII) объём памяти, требуемый для представления строки из N символов, равен N + 1 байт. В том случае, когда для кодирования символов применяется Юникод, длина строки зависит от используемого представления Юникода (например, 2N + 2 байта для UCS-2).
Такие строки являются стандартом в Си и некоторых других языках программирования. Поскольку они используются для передачи строковых аргументов в стандартные функции во многих операционных системах, операции для работы с нуль-терминированными строками появились в Паскале и других языках.
Для ссылки на нуль-терминированную строку применяется указатель на первый её символ. Это простой, быстрый и гибкий подход, но чреватый ошибками[3][4]. Программист постоянно должен следить за своим кодом, а именно:
- быть уверенным, что не случаются переполнения буфера;
- аккуратно проводить управление памятью, выделяемой под строки;
- следить за корректной нуль-терминацией строк при использовании функций, которые её не гарантируют (например, strncpy);
- в редких случаях, когда размер строки может быть очень велик, следить, что не происходит переполнение целого при подсчёте длины и прочих связанных с длиной вычислениях.
Кроме того, некоторые операции со строками, например, конкатенация, для нуль-терминированных строк выполняются медленнее, чем для других типов строк.
Сравнение с альтернативами
Альтернативой нуль-терминированным строкам являются способы, принятые в Паскале и современных ООП-языках. В Паскале строка начинается с первого элемента массива, а в нулевом элементе хранится длина строки. В этом случае не требуется специального терминатора для обозначения конца строки. С другой стороны, здесь на длину строки накладывается ограничение, связанное с вместимостью нулевого элемента массива, то есть в случае с однобайтовыми элементами длина строки не может превышать 255 символов. Нуль-терминированные строки такому ограничению не подвержены и теоретически могут хранить строки любой длины. В объектно-ориентированных языках применяется хранение записи с длиной строки и ссылкой (или указателем) на массив символов. Эти способы не подвержены недостатку нуль-терминированных строк: они могут хранить в себе нуль-символы без искажений и специального кодирования.
В ряде проприетарных интерфейсов применяются дважды-нуль-терминированные строки, признаком завершения которых является два последовательных нуль-терминатора[5]. Также двойной нуль может использоваться для обозначения
В языке Си
Для работы с нуль-терминированными строками в языке программирования Си используется ряд функций:
- strcpy, wcscpy — копирование строк;
- strlen, wcslen — вычисление длины строки;
- strchr — поиск символа в строке;
- strdup — дублирование строк;
- strstr — поиск подстроки.
См. также
Примечания
Литература
- Poul-Henning Kamp, The Most Expensive One-byte Mistake. Did Ken, Dennis, and Brian choose wrong with NUL-terminated text strings? / ACM Queue, Volume 9, issue 7, July 25, 2011
- Назад, к основам - Back to Basics by Joel Spolsky, December 11, 2001