А. Григорьев - О чём не пишут в книгах по Delphi

Здесь есть возможность читать онлайн «А. Григорьев - О чём не пишут в книгах по Delphi» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: СПб, Год выпуска: 2008, ISBN: 2008, Издательство: БХВ-Петербург, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

О чём не пишут в книгах по Delphi: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «О чём не пишут в книгах по Delphi»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.
Для программистов

О чём не пишут в книгах по Delphi — читать онлайн ознакомительный отрывок

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

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Избежать этой ошибки поможет либо явное сравнение длины перед сравнением строк, либо приведение одной из сравниваемых строк к типу AnsiString(второй аргумент при этом также будет приведен к этому типу). Следующий пример (листинг 3.27) дает правильный результат Не равно.

Листинг 3.27. Правильное сравнение переменных типа ShortStringи PChar

procedure TForm1.Button9Click(Sender: TObject);

var

P: PChar;

S: ShortString;

begin

P := StrAlloc(300);

FillChar(P^, 299, 'A');

P[299] := #0;

S[0] := #255;

FillChar(S[1], 255, 'A');

if string(S) = P then Label1.Caption := 'Равно'

else Label1.Caption := 'He равно';

StrDispose(P);

end;

Учтите, что конвертирование в AnsiString— операция дорогостоящая в смысле процессорного времени (в этом примере будут выделены, а потом освобождены два блока памяти), поэтому там, где нужна производительность, целесообразнее вручную сравнить длину, а еще лучше вообще по возможности избегать сравнения строк разных типов, т.к. без конвертирования это в любом случае не обходится.

Теперь зададимся глупым, на первый взгляд, вопросом: если мы приведем строку AnsiStringк PChar, будут ли равны указатели? Проверим это (листинг 3.28).

Листинг 3.28. Равенство указателей после приведения AnsiStringк PChar

procedure TForm1.Button10Click(Sender: TObject);

var

S: string;

P: PChar;

begin

S := 'Test';

P := PChar(S);

if Pointer(S) = P then Label1.Caption := 'Равно'

else Label1.Caption := 'Не равно';

end;

Вполне ожидаемый результат — Равно. Можно, например, перенести строку из сегмента кода в динамическую память с помощью UniqueString— результат не изменится. Однако выводы делать рано. Рассмотрим следующий пример (листинг 3.29).

Листинг 3.29. Сравнение указателя после приведения пустой строки к PChar

procedure TForm1.Button11Click(Sender: TObject);

var

S: string;

P: PChar;

begin

S := '';

P := PChar(S);

if Pointer(S) = P then Label1.Caption : = 'Равно'

else Label1.Caption := 'He равно';

end;

От предыдущего он отличается только тем, что строка Sимеет пустое значение. Тем не менее на экране мы увидим Не равно. Связано это с тем, что приведение строки AnsiStringк типу PCharна самом деле не является приведением типов. Это скрытый вызов функции _LStrToPChar, и сделано так для того, чтобы правильно обрабатывать пустые строки.

Значение ''(пустая строка) для строки AnsiStringозначает, что память для нее вообще не выделена, а указатель имеет значение nil. Для типа PCharпустая строка — это ненулевой указатель на символ #0. Нулевой указатель также может рассматриваться как пустая строка, но не всегда — иногда это рассматривается как отсутствие какого бы то ни было значения, даже пустого (аналог NULL в базах данных). Чтобы решить это противоречие, функция _LStrToPCharпроверяет, пустая ли строка хранится в переменной, и, если не пустая, возвращает этот указатель, а если пустая, то возвращает не nil, а указатель на символ #0, который специально для этого размещен в сегменте кода. Таким образом, для пустой строки PChar(S) <> Pointer(S), потому что приведение строки AnsiStringк указателю другого типа — это нормальное приведение типов без дополнительной обработки значения.

3.3.5. Побочное изменение

Из-за того, что две одинаковые строки AnsiStringразделяют одну область памяти, на неожиданные эффекты можно натолкнуться, если модифицировать содержимое строки в обход стандартных механизмов. Следующий код (листинг 3.30, пример SideChange на компакт-диске) иллюстрирует такую ситуацию.

Листинг 3.30. Побочное изменение переменной S2при измененииS1

procedure TForm1.Button1Click(Sender: TObject);

var

S1, S2: string;

P: PChar;

begin

S1 := 'Test';

UniqueString(S1);

S2 := S1;

P := PChar(S1);

P[0] := 'F';

Label1.Caption := S2;

end;

В этом примере требует комментариев процедура UniqueString. Она обеспечивает то, что счетчик ссылок на строку будет равен единице, т.е. для этой строки делается уникальная копия. Здесь это понадобилось для того, чтобы строка S1хранилась в динамической памяти, а не в сегменте кода, иначе мы получили бы Access violation, как и во втором случае рассмотренного ранее примера Constants (см. листинг 2.17).

В результате работы этого примера на экран будет выведено не Test, a Fest, хотя значение S2, казалось бы, не должно меняться, потому что изменения, которые мы делаем, касаются только S1. Но более внимательный анализ подсказывает объяснение: после присваивания S2 := S1счетчик ссылок строки становится равным двум, а сама строка разделяется двумя указателями: S1и S2. Если бы мы попытались изменить непосредственно S2, то сначала была бы создана копия этой строки, а потом сделаны изменения в этой копии, а оригинал, на который указывала бы S2, остался без изменений. Но, использовав PChar, мы обошли механизм копирования, поэтому строка осталась в единственном экземпляре, и изменения затронули не только S1, но и S2.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «О чём не пишут в книгах по Delphi»

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


Отзывы о книге «О чём не пишут в книгах по Delphi»

Обсуждение, отзывы о книге «О чём не пишут в книгах по Delphi» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x