Читаем О чём не пишут в книгах по Delphi полностью

Этот код выдаст Равно. Как мы знаем из предыдущих примеров (см. листинг 3.22), значения указателей не будут равны, следовательно, производится сравнение по содержанию, т. е. именно то, что к требуется. Если исследовать код, который генерирует компилятор, то можно увидеть, что сначала неявно создается строка AnsiString, в которую копируется содержимое строки PChar, а потом сравниваются две строки AnsiString. Сравниваются, естественно, по значению.

Для строк ShortString сравнение указателей невозможно, две таких строки всегда сравниваются по значению. Правила хранения литералов и сравнения с другими типами следующие:

1. Литералы типа ShortString размещаются в сегменте кода только один раз на одну функцию, сколько бы раз они ни повторялись в ее тексте.

2. При сравнении строк ShortString и AnsiString первая сначала конвертируется в тип AnsiString, а потом выполняется сравнение.

3. При сравнении строк ShortString и PChar строка PChar конвертируется в ShortString, затем эти строки сравниваются.

Последнее правило таит в себе «подводный камень», который иллюстрируется следующим примером (листинг 3.26).

Листинг 3.26. Ошибка при сравнении переменных типа ShortString и PChar

procedure TForm1.Button8Click(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 S = P then Label1.Caption:= 'Равно'

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

 StrDispose(Р);

end;

Здесь формируется строка типа PChar, состоящая из 299 символов "A". Затем формируется строка ShortString, состоящая из 255 символов "А". Очевидно, что эти строки не равны, потому что имеют разную длину. Тем не менее на экране появится надпись Равно.

Происходит это вот почему: строка 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.Button1 °Click(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;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных