<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF</id>
	<title>Строковый тип - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF"/>
	<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF&amp;action=history"/>
	<updated>2026-07-16T17:38:04Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF&amp;diff=7274&amp;oldid=prev</id>
		<title>imported&gt;DenisKrivosheev: /* Представление символов строки */ исправление</title>
		<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF&amp;diff=7274&amp;oldid=prev"/>
		<updated>2025-11-30T11:56:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Представление символов строки: &lt;/span&gt; исправление&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В [[информатика|информатике]], &amp;#039;&amp;#039;&amp;#039;строковый тип&amp;#039;&amp;#039;&amp;#039; ({{lang-en|string type}}) — [[тип данных]], значениями которого является произвольная последовательность (строка) символов [[Алфавит (информатика)|алфавита]]. Каждая переменная такого типа (&amp;#039;&amp;#039;&amp;#039;строковая переменная&amp;#039;&amp;#039;&amp;#039;) может быть представлена фиксированным количеством [[байт]]ов либо иметь произвольную длину.&lt;br /&gt;
&lt;br /&gt;
== Представление в памяти ==&lt;br /&gt;
Некоторые [[язык программирования|языки программирования]] накладывают ограничения на максимальную длину строки, но в большинстве языков подобные ограничения отсутствуют. При использовании [[Unicode]] каждый символ строкового типа может требовать двух или даже четырёх байтов для своего представления.&lt;br /&gt;
&lt;br /&gt;
Основные проблемы в машинном представлении строкового типа:&lt;br /&gt;
* строки могут иметь достаточно существенный размер (до нескольких десятков мегабайтов);&lt;br /&gt;
* изменяющийся со временем размер — возникают трудности с добавлением и удалением символов.&lt;br /&gt;
&lt;br /&gt;
В представлении строк в памяти компьютера существует два принципиально разных подхода.&lt;br /&gt;
&lt;br /&gt;
=== Представление массивом символов ===&lt;br /&gt;
В этом подходе строки представляются &amp;#039;&amp;#039;[[Массив (программирование)|массивом]] символов&amp;#039;&amp;#039;; при этом размер массива хранится в отдельной (служебной) области. От названия языка [[Pascal]], где этот метод был впервые реализован, данный метод получил название &amp;#039;&amp;#039;Pascal strings&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Слегка оптимизированным вариантом этого метода является т. н. формат &amp;#039;&amp;#039;c-addr u&amp;#039;&amp;#039; (от {{lang-en|character-aligned address + unsigned number}}), применяемый в [[Форт (язык программирования)|Форте]]. В отличие от Pascal strings, здесь размер массива хранится не совместно со строковыми данными, а является частью [[Указатель (тип данных)|указателя]] на строку.&lt;br /&gt;
&lt;br /&gt;
==== Преимущества ====&lt;br /&gt;
* программа в каждый момент времени содержит сведения о размере строки, поэтому операции добавления символов в конец, копирования строки и собственно получения размера строки выполняются достаточно быстро;&lt;br /&gt;
* строка может содержать любые данные;&lt;br /&gt;
* возможно на программном уровне следить за выходом за границы строки при её обработке;&lt;br /&gt;
* возможно быстрое выполнение операции вида «взятие N-ого символа с конца строки».&lt;br /&gt;
&lt;br /&gt;
==== Недостатки ====&lt;br /&gt;
* проблемы с хранением и обработкой символов произвольной длины;&lt;br /&gt;
* увеличение затрат на хранение строк — значение «длина строки» также занимает место и в случае большого количества строк маленького размера может существенно увеличить требования алгоритма к оперативной памяти;&lt;br /&gt;
* ограничение максимального размера строки. В современных языках программирования это ограничение скорее теоретическое, так как обычно размер строки хранится в 32-битовом поле, что даёт максимальный размер строки в 4 294 967 295 байт (4 гигабайта);&lt;br /&gt;
* при использовании [[алфавит]]а с переменным размером символа (например, [[UTF-8]]), в размере хранится не количество символов, а именно размер строки в байтах, поэтому количество символов необходимо считать отдельно.&lt;br /&gt;
&lt;br /&gt;
=== Метод «завершающего байта» ===&lt;br /&gt;
{{main|Нуль-терминированная строка}}&lt;br /&gt;
&lt;br /&gt;
Второй метод заключается в использовании &amp;#039;&amp;#039;«завершающего байта»&amp;#039;&amp;#039;&amp;lt;ref&amp;gt;{{Cite web |url=http://queue.acm.org/detail.cfm?id=2010365 |title=The Most Expensive One-byte Mistake — ACM Queue&amp;lt;!-- Заголовок добавлен ботом --&amp;gt; |access-date=2016-09-17 |archive-date=2016-09-19 |archive-url=https://web.archive.org/web/20160919163315/http://queue.acm.org/detail.cfm?id=2010365 |url-status=live }}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{Cite web |url=http://local.joelonsoftware.com/wiki/%D0%9D%D0%B0%D0%B7%D0%B0%D0%B4,_%D0%BA_%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B0%D0%BC |title=Joel on Software - Назад, к основам |access-date=2016-09-17 |archive-date=2016-09-16 |archive-url=https://web.archive.org/web/20160916212518/http://local.joelonsoftware.com/wiki/%D0%9D%D0%B0%D0%B7%D0%B0%D0%B4,_%D0%BA_%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B0%D0%BC |url-status=live }}&amp;lt;/ref&amp;gt;. Одно из возможных значений символов алфавита (как правило, это символ с кодом 0) выбирается в качестве признака конца строки, и строка хранится как последовательность байтов от начала до конца. Есть системы, в которых в качестве признака конца строки используется не символ 0, а байт 0xFF (255) или код символа «$».&lt;br /&gt;
&lt;br /&gt;
Метод имеет три названия — &amp;#039;&amp;#039;ASCIIZ&amp;#039;&amp;#039; (или asciz, символы в кодировке [[ASCII]] с нулевым завершающим байтом), &amp;#039;&amp;#039;C-strings&amp;#039;&amp;#039; (наибольшее распространение метод получил именно в языке [[Си (язык программирования)|Си]]) и метод [[нуль-терминированная строка|нуль-терминированных строк]].&lt;br /&gt;
&lt;br /&gt;
==== Преимущества ====&lt;br /&gt;
* отсутствие дополнительной служебной информации о строке (кроме завершающего байта);&lt;br /&gt;
* возможность представления строки без создания отдельного типа данных;&lt;br /&gt;
* отсутствие ограничения на максимальный размер строки;&lt;br /&gt;
* экономное использование памяти;&lt;br /&gt;
* простота получения суффикса строки;&lt;br /&gt;
* простота передачи строк в функции (передаётся указатель на первый символ);&lt;br /&gt;
&lt;br /&gt;
==== Недостатки ====&lt;br /&gt;
* долгое выполнение операций получения длины и [[конкатенация|конкатенации]] строк;&lt;br /&gt;
* отсутствие средств контроля за выходом за пределы строки, в случае повреждения завершающего байта возможность повреждения больших областей памяти, что может привести к непредсказуемым последствиям — потере данных, краху программы и даже всей системы;&lt;br /&gt;
* невозможность использовать символ завершающего байта в качестве элемента строки.&lt;br /&gt;
* невозможность использовать некоторые кодировки с размером символа в несколько байт (например, UTF-16), так как во многих таких символах, например Ā (0x0100), один из байтов равен нулю (в то же время, кодировка UTF-8 свободна от этого недостатка).&lt;br /&gt;
&lt;br /&gt;
=== Использование обоих методов ===&lt;br /&gt;
В таких языках, как, например, [[Оберон (язык программирования)|Оберон]], строка размещается в массиве символов определённой длины, причём её конец обозначается нулевым символом. По умолчанию, весь массив заполнен нулевыми символами. Такой способ позволяет объединить многие преимущества обоих подходов, а также избежать большинство их недостатков.&lt;br /&gt;
&lt;br /&gt;
=== Представление в виде списка ===&lt;br /&gt;
Языки [[Erlang]]&amp;lt;ref&amp;gt;{{книга&lt;br /&gt;
| автор = Simon St. Laurent&lt;br /&gt;
| заглавие = Introducing Erlang&lt;br /&gt;
| ссылка = https://archive.org/details/introducingerlan00laur&lt;br /&gt;
| издательство = O’Reilly Media, Inc.&lt;br /&gt;
| год = 2013&lt;br /&gt;
| allpages = 185&lt;br /&gt;
| pages = [https://archive.org/details/introducingerlan00laur/page/n77 62]&lt;br /&gt;
| isbn = 978-1-449-33176-4&lt;br /&gt;
| ref = Simon St. Laurent&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;, [[Haskell]]&amp;lt;ref&amp;gt;Bryan O’Sullivan, Don Stewart, John Goerzen, Real World Haskell. [http://book.realworldhaskell.org/read/characters-strings-and-escaping-rules.html  Appendix B. Characters, strings, and escaping rules] {{Wayback|url=http://book.realworldhaskell.org/read/characters-strings-and-escaping-rules.html |date=20120126041437 }}&amp;lt;/ref&amp;gt;, [[Пролог (язык программирования)|Пролог]]&amp;lt;ref&amp;gt;SWI-Prolog Manual: [http://www.swi-prolog.org/pldoc/man?section=text-representation 5.2.2 Representing text: strings, atoms and code lists] {{Wayback|url=http://www.swi-prolog.org/pldoc/man?section=text-representation |date=20140717093340 }}&amp;lt;/ref&amp;gt; используют для строкового типа [[Связный список|список]] символов. Этот метод делает язык более «теоретически элегантным» за счёт соблюдения [[ортогональность|ортогональности]] в [[система типов|системе типов]], но приносит существенные потери быстродействия.&lt;br /&gt;
&lt;br /&gt;
== Реализация в языках программирования ==&lt;br /&gt;
* В первых языках программирования вообще не было строкового типа; программист должен был сам строить функции для работы со строками того или другого типа.&lt;br /&gt;
* В [[Си (язык программирования)|Си]] используются [[нуль-терминированная строка|нуль-терминированные строки]] с полным ручным контролем со стороны программиста.&lt;br /&gt;
* В стандартном [[Паскаль (язык программирования)|Паскале]] строка выглядит как массив из 256 байтов; первый байт хранил длину строки, в остальных хранится её тело. Таким образом, длина строки не может превышать 255 символов. В [[Borland Pascal]] 7.0 также появились строки «а-ля Си» — очевидно, из-за того, что в число поддерживаемых платформ вошла [[Windows]].&lt;br /&gt;
* В [[Object Pascal]] и C++ [[Стандартная библиотека шаблонов|STL]] строка является «чёрным ящиком», в котором выделение/высвобождение памяти происходит автоматически — без участия [[программист]]а. При создании строки память выделяется автоматически; как только на строку не останется ни одной ссылки, память возвращается системе. Преимущество этого метода в том, что программист не задумывается над работой строк. С другой стороны, программист имеет недостаточный контроль над работой программы в критичных к скорости участках; также трудно реализуется передача таких строк в качестве параметра в [[DLL]]. Также Object Pascal автоматически следит, чтобы в конце строки был символ с кодом 0. Поэтому если функция требует на входе [[нуль-терминированная строка|нуль-терминированную строку]], для конвертации надо просто написать &amp;lt;code&amp;gt;PAnsiChar(&amp;#039;&amp;#039;строковая_переменная&amp;#039;&amp;#039;)&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;PWideChar(&amp;#039;&amp;#039;строковая_переменная&amp;#039;&amp;#039;)&amp;lt;/code&amp;gt; (для Pascal), &amp;lt;code&amp;gt;&amp;#039;&amp;#039;переменная&amp;#039;&amp;#039;.c_str()&amp;lt;/code&amp;gt; (для Builder/STL).&lt;br /&gt;
* В [[C Sharp|C#]] и других языках со [[сборка мусора (программирование)|сборкой мусора]] строка является неизменяемым объектом; если строку нужно модифицировать, создаётся другой объект. Этот метод медленный и расходует немало временной памяти, но хорошо сочетается с [[концепция|концепцией]] сборки мусора. Преимущество этого метода в том, что [[присваивание]] происходит быстро и без дублирования строк. Также имеется некоторый ручной контроль над конструированием строк (в [[Java]], например, через классы &amp;lt;code&amp;gt;StringBuffer и StringBuilder&amp;lt;/code&amp;gt;) — это позволяет уменьшить количество выделений и высвобождений памяти и, соответственно, увеличить скорость.&lt;br /&gt;
** В некоторых языках (например, [[Standard ML]]) кроме этого, есть дополнительный модуль для обеспечения ещё большей эффективности — «подстрока» (SubString). Его использование позволяет выполнять операции над строками без копирования их тел посредством манипулирования индексами начала и конца подстроки; физическое копирование происходит лишь при необходимости преобразовании подстрок в строки.&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Простейшие операции со строками:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* получение символа по номеру позиции (индексу) — в большинстве языков это тривиальная операция;&lt;br /&gt;
* [[конкатенация]] (соединение) строк.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Производные операции:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* получение [[подстрока|подстроки]] по индексам начала и конца;&lt;br /&gt;
* проверка вхождения одной строки в другую ([[поиск подстроки]] в строке);&lt;br /&gt;
* проверка на совпадение строк ([[Чувствительность к регистру символов|с учётом или без учёта регистра символов]]);&lt;br /&gt;
* получение длины строки;&lt;br /&gt;
* замена подстроки в строке.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Операции при трактовке строк как [[Список (информатика)|списков]]:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* [[Свёртка списка|свёртка]];&lt;br /&gt;
* отображение одного списка на другой;&lt;br /&gt;
* фильтрация списка по критерию.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Более сложные операции:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* нахождение минимальной [[надстрока|надстроки]], содержащей все указанные строки;&lt;br /&gt;
* поиск в двух массивах строк совпадающих последовательностей &amp;#039;&amp;#039;([[задача о плагиате]])&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Возможные задачи для строк на [[естественный язык|естественном языке]]:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* сравнение на близость указанных строк по заданному критерию;&lt;br /&gt;
* определение языка и [[кодировка|кодировки]] текста на основании вероятностей символов и слогов.&lt;br /&gt;
&lt;br /&gt;
== Представление символов строки ==&lt;br /&gt;
До появления стандарта Юникод в 1991 году, один символ обычно кодировался одним байтом из 8 двоичных битов или меньше — [[КОИ-7|7-битные]], [[Шестибитные кодировки|6--битные]]. 8-битные кодировки позволяли представлять 256 возможных значений. Однако для полноценного представления символов алфавитов нескольких языков (многоязыковых документов, [[типографика|типографских]] символов — несколько видов [[кавычка|кавычек]], [[тире]], нескольких видов [[пробел]]ов и для написания текстов на [[иероглиф]]ических языках — [[китайский язык|китайском]], [[японский язык|японском]] и [[корейский язык|корейском]]) 256 символов недостаточно. Для решения этой проблемы применялись разные подходы:&lt;br /&gt;
&lt;br /&gt;
* Переключение языка управляющими кодами. Метод не стандартизирован и лишает текст самостоятельности (то есть последовательность символов без управляющего кода в начале теряет смысл); использовался в некоторых ранних русификациях [[ZX-Spectrum]] и [[БК (семейство компьютеров)|БК]].&lt;br /&gt;
* Использование двух или более байт для представления каждого символа ([[UTF-16]], [[UTF-32]]). Главным недостатком этого метода является потеря совместимости с предыдущими библиотеками для работы с текстом при представлении строки как ASCIIZ. Например, концом строки должен считаться уже не байт со значением 0, а два или четыре подряд идущих нулевых байта, в то время как одиночный байт «0» может встречаться в середине строки, что сбивает библиотеку «с толку».&lt;br /&gt;
* Использование кодировки с переменным размером символа. Например, в [[UTF-8]] часть символов представляется одним байтом, часть двумя, тремя или четырьмя. Этот метод позволяет сохранить частичную совместимость со старыми библиотеками (нет символов 0 внутри строки и поэтому 0 можно использовать как признак конца строки), но приводит к невозможности прямой адресации символа в памяти по номеру его позиции в строке.&lt;br /&gt;
&lt;br /&gt;
== Лексический анализ ==&lt;br /&gt;
Для проверки соответствия всех словоформ при лексическом (семантическом) анализе используются меры схожести лексем:&lt;br /&gt;
* [[Расстояние Дамерау — Левенштейна]]&lt;br /&gt;
* [[Расстояние Левенштейна]]&lt;br /&gt;
* [[Расстояние Хэмминга]]&lt;br /&gt;
* [[Сходство Джаро — Винклера]]&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Нуль-терминированная строка]]&lt;br /&gt;
* [[Пустая строка]]&lt;br /&gt;
* [[Текстовые данные]]&lt;br /&gt;
* [[Свободная полугруппа]]&lt;br /&gt;
* [[Лексикографический порядок]]&lt;br /&gt;
* [[Список алгоритмов#Алгоритмы на строках|Алгоритмы на строках]]&lt;br /&gt;
* [[Слово (математика)]]&lt;br /&gt;
* [[Теория последовательностей]]&lt;br /&gt;
* [[Широкий символ]]&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{примечания}}&lt;br /&gt;
&amp;lt;!-- == Ссылки ==--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Типы данных}}&lt;br /&gt;
{{Строки}}&lt;br /&gt;
{{Нет источников |дата=2009-11-29}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Типы данных]]&lt;br /&gt;
[[Категория:Строковые алгоритмы|*]]&lt;br /&gt;
[[Категория:Примитивные типы данных]]&lt;/div&gt;</summary>
		<author><name>imported&gt;DenisKrivosheev</name></author>
	</entry>
</feed>