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

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

Для программистов

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

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор А. Григорьев
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Происходит это вот почему: строка PCharоказывается больше, чем максимально допустимый размер строки ShortString. Поэтому при конвертировании лишние символы просто отбрасываются. Получается строка длиной 255 символов, совпадающая со строкой ShortString, с которой мы ее сравниваем. Отсюда вывод: если строка ShortStringсодержит 255 символов, а строка PChar— более 255 символов, и ее первые 255 символов совпадают с символами строки ShortString, операция сравнения ошибочно даст положительный результат, хотя эти строки не равны.

Избежать этой ошибки поможет либо явное сравнение длины перед сравнением строк, либо приведение одной из сравниваемых строк к типу 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 советует сначала обеспечить уникальность копии строки с помощью UniqueStringи только потом работать с ней через PChar, если в этом есть необходимость.

Рассмотрим еще один пример, практически не отличающийся от предыдущего (листинг 3.31).

Листинг 3.31. Отсутствие побочного изменения переменной S2при изменении S1

procedure TForm1.Button2Click(Sender: TObject);

var

S1, S2: string;

P: PChar;

begin

S1 := 'Test';

UniqueString(S1);

S2 := S1;

P := @S1[1];

P[0] := 'F';

Label1.Caption := S2;

end;

В этом случае на экран будет выведено Test, т.е. побочного изменения переменной не произойдёт, хотя переменная S1по прежнему изменяется в обход стандартных механизмов Delphi.

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

Интервал:

Закладка:

Сделать


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x