3.3.1. Виды строк в Delphi
3.3.1. Виды строк в Delphi
Для работы с кодировкой ANSI в Delphi существует три вида строк: AnsiString, ShortString и PChar. Различие между ними заключается в способе хранения строки, а также выделения и освобождения памяти для нее. Зарезервированное слово string по умолчанию означает тип AnsiString, но если после нее следует число в квадратных скобках, то это означает тип ShortString, а число — ограничение по длине. Кроме того, существует опция компилятора Huge strings (управляется также директивами компилятора {$H+/-} и {$LONGSTRINGS ON/OFF}, которая по умолчанию включена, но если ее выключить, то слово string станет эквивалентно ShortString; или, что то же самое, string[255]. Эта опция введена для обратной совместимости с Turbo Pascal, в новых программах отключать ее нет нужды. Внутреннее устройство этих типов данных иллюстрирует рис. 3.2.
Рис. 3.2. Устройство различных строковых типов Delphi
Наиболее просто устроен тип ShortString. Это массив символов с индексами от 0 до N, где N — число символов, указанное при объявлении переменной (в случае использования идентификатора ShortString N явно не указывается и равно 255). Нулевой элемент массива хранит текущую длину строки, которая может быть меньше или равна объявленной (эту длину мы будем далее обозначать M), элементы с индексами от 1 до M — это символы, составляющие строку. Значения элементов с индексами M+1..N не определены. Все стандартные функции для работы со строками игнорируют эти символы. В памяти такая переменная всегда занимает N+1 байтов.
Ограничения типа ShortString очевидны: на хранение длины отводится только один байт, поэтому такая строка не может содержать больше 255 символов. Кроме того, такой способ записи длины не совпадает с принятым в Windows, поэтому ShortString несовместим с системными строками.
В системе приняты так называемые нуль-терминированные строки: строка передается указателем на ее первый символ, длина строки отдельно нигде не хранится, признаком конца строки считается встретившийся в цепочке символов #0. Длина таких строк ограничена только доступной памятью и способом адресации (т. е. в Windows теоретически это 4 294 967 295 символов). Для работы с такими строками предусмотрен тип PChar. Переменная такого типа является указателем на начало строки. В литературе нередко можно встретить утверждение, что PChar = ^Сhar, однако это неверно: тип PChar встроен в компилятор и не выводится из других типов. Это позволяет выполнять с ним операции, недопустимые для других указателей. Во-первых, если P — переменная типа PChar, то допустимо обращение к отдельным символам строки с помощью конструкции P[N], где N — целочисленное выражение, определяющее номер символа (в отличие от типа ShortString, здесь символы нумеруются с 0, а не с 1). Во-вторых, к указателям типа PChar разрешено добавлять и вычитать целые числа, смещая указатель на соответствующее число байтов вверх или вниз (здесь речь идет только об операторах "+" и "-"; адресная арифметика с помощью процедур Inc и Dec доступна для любых типизированных указателей, а не только для PChar).
При работе с PChar программист целиком и полностью отвечает за выделение памяти для строки и за ее освобождение. Именно это и служит основным источником ошибок у новичков: они пытаются работать с такими строками так же, как и с AnsiString, надеясь, что операции с памятью будут выполнены автоматически. Это очень грубая ошибка, способная привести к самым непредсказуемым последствиям.
Хотя программист имеет полную свободу выбора в том, как именно выделять и освобождать память для нуль-терминированных строк, в большинстве случаев самыми удобными оказываются специально предназначенные для этого функции StrNew, StrDispose и т. п. Их преимущество заключается в том, что менеджер памяти выделяет чуть больше места, чем требуется для хранения строки, и в эту дополнительную память записывается, сколько байтов было выделено. Благодаря этому функция StrDispose удаляет ровно столько памяти, сколько было выделено, даже если в середину выделенного блока был записан символ #0, уменьшающий длину строки.
Компилятор также позволяет рассматривать статические массивы типа Char, начинающиеся с нулевого индекса, как нуль-терминированные строки. Такие массивы совместимы с типом PChar, что позволяет обойтись без использования динамической памяти при работе со строками.
Тип AnsiString объединяет достоинства типов ShortString и PChar: строки имеют фактически неограниченную длину, заботиться о выделении памяти для них не нужно, в их конец автоматически добавляется символ #0, что делает их совместимыми с системными строками (впрочем, эта совместимость не абсолютная; как и когда можно использовать AnsiString в функциях API, мы рассматривали в разд. 1.1.13.).
Переменная типа AnsiString — это указатель на первый символ строки, как и в случае PChar. Разница в том, что перед этой строкой в память записывается дополнительная информация: длина строки и счетчик ссылок. Это позволяет компилятору генерировать код, автоматически выделяющий, перераспределявший и освобождающий память, выделяемую для строки. Работа с памятью происходит совершенно прозрачно для программиста, в большинстве случаев со строками AnsiString можно работать, вообще не задумываясь об их внутреннем устройстве. Символы в таких строках нумеруются с единицы, чтобы облегчить перенос старых программ, использовавших строки типа ShortString.
Счетчик ссылок позволяет реализовать то, что называется copy-on-demand, копирование по необходимости. Если у нас есть две переменные S1, S2 типа AnsiString, присваивание вида S1:= S2 не приводит к копированию всей строки. Вместо этого в указатель S1 копируется значение указателя S2, а счетчик ссылок строки увеличивается на единицу. В дальнейшем, если одну из этих строк потребуется модифицировать, она сначала будет скопирована (а счетчик ссылок оригинала, естественно, уменьшен) и только потом изменена, чтобы это не затрагивало остальные переменные.
Далее мы рассмотрим, какие проблемы могут возникнуть при использовании строк разного вида.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
1.3.3. Delphi и CGI
1.3.3. Delphi и CGI В данной главе я расскажу, как написать простое Дельфи CGI приложение, без использования Web Modules или других Client/Server модулей.Во первых аббревиатура CGI означает Common Gateway Interface, и это только имя для передачи информации от клиента серверу. На клиентской стороне это
2.1.1. Delphi и HTML
2.1.1. Delphi и HTML Мой главный инструмент разработчики это Дельфи, и мы напишем Delphi Database HTML Expert в данной главе. Дельфи позволяет подсоединяться практически к базе данных любого формата. С помощью BDE к Парадоксу и dBASE, с помощью ODBC например к Access, и с помощью SQL Links к большим DBMS типа
Вопросы по Delphi 2.0
Вопросы по Delphi 2.0 Что нового в Delphi 2.0 по сравнения с Delphi 1.0? Выпущенная в феврале 1995 года версия Delphi 1.0 стала первым инструментом для Windows, комбинирующим оптимизирующий компилятор, механизмы визуальной разработки Two-Way-Tools и масштабируемую архитектуру обработки баз данных.
Что нового в Delphi 2.0 по сравнения с Delphi 1.0?
Что нового в Delphi 2.0 по сравнения с Delphi 1.0? Выпущенная в феврале 1995 года версия Delphi 1.0 стала первым инструментом для Windows, комбинирующим оптимизирующий компилятор, механизмы визуальной разработки Two-Way-Tools и масштабируемую архитектуру обработки баз данных. Сегодня сотни
Глава 1 Windows API и Delphi
Глава 1 Windows API и Delphi Библиотека VCL, делающая создание приложений в Delphi таким быстрым и удобным, все же не позволяет разработчику задействовать все возможности операционной системы. Полный доступ к ним дает API (Application Programming Interface) — интерфейс, который система предоставляет
3.2.2. Вещественные типы Delphi
3.2.2. Вещественные типы Delphi В Delphi существует четыре вещественных типа: Single, Double, Extended и Real. Их общий формат одинаков (рис. 3.1, а).Знак — это всегда один бит. Он равен нулю для положительных чисел и единице для отрицательных. Что же касается размеров мантиссы и экспоненты, то
Глава 1. Что нового в Delphi 4
Глава 1. Что нового в Delphi 4 Delphi 4 представляет следующие новые свойства и усовершенствования:Новые расширения языка.Delphi 4 в язык Object Pascal включены динамические массивы, методы обработки переполнения, установка значения параметров по умолчанию, и многое другое.Менеджер
Разработчик Delphi
Разработчик Delphi Русскоязычные N Сервер Описание 1 http://www.inprise.ru Российское представительство Inprise Фирма – разработчик
9.3. Использование OLE в Delphi
9.3. Использование OLE в Delphi Как и многие современные среды программирования, Delphi поддерживает возможность автоматизированной разработки приложений, работающих с различными СОМ-сервисами или серверами. Для более глубокого понимания принципов работы приложений,