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

Интервал:

Закладка:

Сделать

Все проблемы при присваивании сводятся к одному из этих случаев или к их комбинации.

Все эти ситуации при выключенной опции Range checkingприводят к ошибкам, которые бывает очень трудно обнаружить. Из-за этого рекомендуется включать эту опцию хотя бы на этапе отладки.

В некоторых случаях возможность присваивания значений, выходящих за пределы диапазона переменной, может быть необходимой (например, для реализации "хитрых" алгоритмов или при сопряжении сторонних библиотек, одна из которых использует знаковые типы, другая — беззнаковые). Чтобы включение ERangeErrorне возникало, следует предусмотреть явное приведение типа. Например, следующий код работает без исключений при включенной опции Range checking(листинг 3.3).

Листинг 3.3. Явное приведение типа для подавления исключений

procedure TForm1.Button1Click(Sender: TObject);

var

X: Byte;

Y: ShortInt;

begin

Y := -1;

X := Byte(Y);

Label1.Caption := IntToStr(X)

end;

В результате его выполнения переменная Xполучает значение 255.

3.1.3. Переполнение при арифметических операциях

Переполнением принято называть ситуацию, когда при операциях над переменной результат выходит за пределы ее диапазона. Рассмотрим следующий пример (листинг 3.4, проект Overflow1 на компакт-диске).

Листинг 3.4. Переполнение при вычитании

procedure TForm1.Button1Click(Sender: TObject);

var X: Byte;

begin

X := 0;

X := X - 1;

Label1.Caption := IntToStr(X)

end;

Переменная Xполучит значение 255, поскольку при вычитании получается -1, что в беззнаковом формате соответствует 255. В принципе, этот пример практически эквивалентен примеру Assignment1, за исключением того, что значение -1 появляется в результате арифметических операций.

Немного изменим этот пример — заменим оператор вычитания функцией Dec(листинг 3.5, пример Overflow2 на компакт-диске).

Листинг 3.5. Переполнение при декременте

{$R+}

procedure TForm1.Button1Click(Sender: TObject);

var X: Byte;

begin

X := 0;

Dec(X);

Label1.Caption := IntToStr(X);

end;

Результат получается тот же (X получает значение 255), но обратите внимание: несмотря на то, что опция Range checkingвключена, исключение не возникает. Этим пример Overflow2 отличается от Overflow1 — там исключение возникнет. Связано это с тем, что переполнение при использовании Decи подобных ей функций контролируется другой опцией — Overflow checking(в коде программы включается директивой {$Q+}или {$OVERFLOWCHECKS ON}). Эта опция по умолчанию тоже отключена и ее также рекомендуется включать при отладке. При ее включении в данном примере возникнет исключение EIntOverflow.

3.1.4. Сравнение знакового и беззнакового числа

Посмотрим, что произойдет, если мы попытаемся сравнить знаковое и беззнаковое число (листинг 3.6, пример Compare1 на компакт-диске).

Листинг 3.6. Сравнение "одинаковых" знакового и беззнакового числа

procedure TForm1.Button1Click(Sender: TObject);

var

X: Byte;

Y: ShortInt;

begin

Y := -1;

X := Y;

if X = Y then Label1.Caption := 'Равно';

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

end;

В окне появится надпись Не равно, хотя последовательность битов в переменных Xи Yбудет, как мы уже знаем, одинаковая. Надпись соответствует действительности — X(255) действительно не равно Y(-1). Разберемся, почему так происходит.

Те, кто успел самостоятельно откомпилировать пример Compare1, могли заметить предупреждение компилятора на строке со сравнением: "Comparing signed and unsigned types — widened both operands". Это предупреждение все объясняет: компилятор, зная, что совпадение наборов битов не гарантирует равенство знакового и беззнакового выражения, сначала "расширяет" типы выражений до того типа, чей диапазон целиком вмещает оба требуемых диапазона и лишь затем выполняет сравнение. Это обеспечивает правильный результат сравнения, но требует дополнительных ресурсов, поэтому компилятор выдает предупреждение.

Аналогичные действия компилятор выполнит при сравнении выражений типов Wordи SmallInt, а также LongIntи LongWord. Тип Int64 не имеет беззнакового аналога, поэтому операнды этого типа при сравнении компилятор не "расширяет".

Явное приведение типов позволяет избавиться от операций по расширению типа и ограничиться побитовым сравнением (листинг 3.7. пример Compare2 на компакт-диске).

Листинг 3.7. Явное приведение типов при сравнении

procedure TForm1.Button1Click(Sender: TObject);

var

X: Byte;

Y: ShortInt;

begin

Y := -1;

X := Y;

if X = Byte(Y) then Label1.Caption := 'Равно'

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

end;

При компиляции такого кода не выдается никаких предупреждений, но и результат сравнения будет неверным: Равно.

Примечание

Операции >, <, >= и <= тоже работают по-разному для знаковых и беззнаковых чисел. Пусть, например, сравниваются числа 01000000 и 11000000. В беззнаковом формате это 64 и 192, поэтому первое число меньше второго. А в знаковом это 64 и -64, т. е. первое число больше. Из-за этого для операций сравнения для знаковых и беззнаковых чисел в системе команд процессора существуют разные команды. В литературе, чтобы подчеркнуть это, часто используются различные названия операций в зависимости от формата: для знаковых чисел — "больше" и "меньше", для беззнаковых — "выше" и "ниже".

3.1.5. Неявное преобразование в цикле for

Рассмотрим программу (пример ForRange на компакт-диске), на форме которой находятся кнопка и панель, причем кнопка (это важно!) — не на панели, а на форме, а на панели нет никаких компонентов. Обработчик нажатия на кнопку выглядит следующим образом (листинг 3.8).

Листинг 3.8. Обработчик нажатия кнопки

procedure TForm1.Button1Click(Sender: TObject);

var

I: Cardinal;

begin

for I := 0 to Panel1.ControlCount - 1 do

Panel1.Controls[I].Tag := 1;

end;

На первый взгляд кажется, что при нажатии на кнопку ничего не должно происходить, т.к. на панели никаких визуальных компонентов нет, и цикл forне должен выполниться ни разу. Тем не менее нажатие на кнопку вызывает исключение Access violation.

При нулевом количестве компонентов на панели выражение Panel1.ControlCount - 1должно давать значение -1. Но поскольку переменная цикла имеет тип Сardinal, эта комбинация битов интерпретируется как 4 294 967 295, верхняя граница оказывается больше нижней, и цикл начинает выполняться, обращаясь к несуществующим элементам управления. Отсюда и ошибка.

Ошибка исчезнет, если тип переменной Iизменить на Integer— в этом случае верхняя граница цикла получит корректное значение -1, и цикл действительно не выполнится ни разу. Если на панели будет находиться хотя бы один компонент, ошибки тоже не будет, потому что верхняя граница цикла не выйдет из диапазона неотрицательных чисел.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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