Строковый тип

Материал из Википедии — свободной энциклопедии

В

алфавита. Каждая переменная такого типа (строковая переменная) может быть представлена фиксированным количеством байтов
либо иметь произвольную длину.

Представление в памяти

Некоторые

Unicode
каждый символ строкового типа может требовать двух или даже четырёх байтов для своего представления.

Основные проблемы в машинном представлении строкового типа:

  • строки могут иметь достаточно существенный размер (до нескольких десятков мегабайтов);
  • изменяющийся со временем размер — возникают трудности с добавлением и удалением символов.

В представлении строк в памяти компьютера существует два принципиально разных подхода.

Представление массивом символов

В этом подходе строки представляются

Pascal
, где этот метод был впервые реализован, данный метод получил название Pascal strings.

Слегка оптимизированным вариантом этого метода является т. н. формат c-addr u (от англ. character-aligned address + unsigned number), применяемый в Форте. В отличие от Pascal strings, здесь размер массива хранится не совместно со строковыми данными, а является частью указателя на строку.

Преимущества

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

Недостатки

  • проблемы с хранением и обработкой символов произвольной длины;
  • увеличение затрат на хранение строк — значение «длина строки» также занимает место и в случае большого количества строк маленького размера может существенно увеличить требования алгоритма к оперативной памяти;
  • ограничение максимального размера строки. В современных языках программирования это ограничение скорее теоретическое, так как обычно размер строки хранится в 32-битовом поле, что даёт максимальный размер строки в 4 294 967 295 байт (4 гигабайта);
  • при использовании алфавита с переменным размером символа (например, UTF-8), в размере хранится не количество символов, а именно размер строки в байтах, поэтому количество символов необходимо считать отдельно.

Метод «завершающего байта»

Второй метод заключается в использовании «завершающего байта»[1][2]. Одно из возможных значений символов алфавита (как правило, это символ с кодом 0) выбирается в качестве признака конца строки, и строка хранится как последовательность байтов от начала до конца. Есть системы, в которых в качестве признака конца строки используется не символ 0, а байт 0xFF (255) или код символа «$».

Метод имеет три названия — ASCIIZ (или asciz, символы в кодировке ASCII с нулевым завершающим байтом), C-strings (наибольшее распространение метод получил именно в языке Си) и метод нуль-терминированных строк.

Преимущества

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

Недостатки

  • долгое выполнение операций получения длины и конкатенации строк;
  • отсутствие средств контроля за выходом за пределы строки, в случае повреждения завершающего байта возможность повреждения больших областей памяти, что может привести к непредсказуемым последствиям — потере данных, краху программы и даже всей системы;
  • невозможность использовать символ завершающего байта в качестве элемента строки.
  • невозможность использовать некоторые кодировки с размером символа в несколько байт (например, UTF-16), так как во многих таких символах, например Ā (0x0100), один из байтов равен нулю (в то же время, кодировка UTF-8 свободна от этого недостатка).

Использование обоих методов

В таких языках, как, например, Оберон, строка размещается в массиве символов определённой длины, причём её конец обозначается нулевым символом. По умолчанию, весь массив заполнен нулевыми символами. Такой способ позволяет объединить многие преимущества обоих подходов, а также избежать большинство их недостатков.

Представление в виде списка

Языки Erlang[3], Haskell[4], Пролог[5] используют для строкового типа список символов. Этот метод делает язык более «теоретически элегантным» за счёт соблюдения ортогональности в системе типов, но приносит существенные потери быстродействия.

Реализация в языках программирования

Операции

Простейшие операции со строками
  • получение символа по номеру позиции (индексу) — в большинстве языков это тривиальная операция;
  • конкатенация (соединение) строк.
Производные операции
Операции при трактовке строк как списков
  • свёртка;
  • отображение одного списка на другой;
  • фильтрация списка по критерию.
Более сложные операции
  • нахождение минимальной надстроки, содержащей все указанные строки;
  • поиск в двух массивах строк совпадающих последовательностей (задача о плагиате).
Возможные задачи для строк на естественном языке
  • сравнение на близость указанных строк по заданному критерию;
  • определение языка и
    кодировки
    текста на основании вероятностей символов и слогов.

Представление символов строки

До появления стандарта Юникод в 1991 году, один символ обычно кодировался одним байтом из 8 двоичных битов или меньше —

кавычек, тире, нескольких видов пробелов и для написания текстов на иероглифических языках — китайском, японском и корейском
) 256 символов недостаточно. Для решения этой проблемы применялись разные подходы:

Лексический анализ

Для проверки соответствия всех словоформ при лексическом (семантическом) анализе используются меры схожести лексем:

См. также

Примечания

  1. The Most Expensive One-byte Mistake — ACM Queue. Дата обращения: 17 сентября 2016. Архивировано 19 сентября 2016 года.
  2. Joel on Software - Назад, к основам. Дата обращения: 17 сентября 2016. Архивировано 16 сентября 2016 года.
  3. Simon St. Laurent. Introducing Erlang. — O’Reilly Media, Inc., 2013. — P. 62. — 185 p. — ISBN 978-1-449-33176-4.
  4. Bryan O’Sullivan, Don Stewart, John Goerzen, Real World Haskell. Appendix B. Characters, strings, and escaping rules Архивная копия от 26 января 2012 на Wayback Machine
  5. SWI-Prolog Manual: 5.2.2 Representing text: strings, atoms and code lists Архивная копия от 17 июля 2014 на Wayback Machine