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

Интервал:

Закладка:

Сделать

Из этого следует правило, которое должен помнить разработчик: функция, возвращающая строковое значение, не должна делать никаких предположений о первоначальном значении переменной Result, т.к. оно может оказаться любым.

Следует заметить, что аналогичным образом компилятор обходится и с другими сложными типами: если функция возвращает такой тип, то Resultстановится не локальной переменной, а неявным параметром-переменной. Просто с другими типами это не так заметно, потому что от них никто не ожидает автоматической инициализации в прологе функции, и обращаются с переменной Resultтак, будто она содержит случайный мусор.

3.3.8. Строки в записях

Поля в записях могут иметь любой строковый тип без дополнительных ограничений. Однако следует учитывать, что, в отличие от полей простых типов, значения полей типа PCharи AnsiStringлежат вне пределов структуры, причем в случае AnsiStringэто не так бросается в глаза, т.к вручную выделять и освобождать память не приходится. Это может привести к неприятному сюрпризу, если работать со структурой как с цельным блоком данных. Чаще всего проблема появляется при записи структуры в поток, файл и т.п. В этом случае записывается только значение указателя, которое не имеет никакого смысла для того, кто потом эти данные читает, такой указатель указывает либо в никуда, либо на данные, никакого отношения к строке не имеющие.

Для иллюстрации этой проблемы, а также методов её решения нам понадобятся два проекта: RecordRead и RecordWrite (на компакт-диске они оба находятся в папке RecordReadWrite). Обойтись одним проектом здесь нельзя — указатель, переданный в пределах проекта, остается корректным, поэтому проблема маскируется. В проекте RecordWrite три кнопки, соответствующие трем методам сохранения записи в поток TFileStream(в файлы Method1.stm, Method2.stm и Method3.stm соответственно). В три целочисленных поля заносятся текущие час, минута, секунда и сотая доля секунды, строка — произвольная, введенная пользователем в поле ввода Edit1. Файлы пишутся в текущую папку, из-за этого программы нельзя запускать непосредственно с компакт-диска. В проекте RecordRead три кнопки соответствуют трем методам чтения (каждый из своего файла). Сначала рассмотрим первый метод — как делать ни в коем случае нельзя.

В проекте RecordWrite имеем следующий код (листинг 3.35).

Листинг 3.35. Неправильный метод записи структуры со строкой в файл

type

TMethod1Record = packed record

Hour: Word;

Minute: Word;

Second: Word;

MSec: Word;

Msg: string;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

Rec: TMethod1Record;

Stream: TFileStream;

begin

DecodeTime(Now, Rec.Hour, Rec.Minute, Rec.Second, Rec.MSec);

Rec.Msg := Edit1.Text;

Stream := TFileStream.Create('Method1.stm', fmCreate);

Stream.WriteBuffer(Rec, SizeOf(Rec));

Stream.Free;

end;

В проекте RecordRead соответствующий код (листинг 3.36).

Листинг 3.36. Неправильный метод чтения структуры со строкой из файла

procedure TForm1.Button1Click(Sender: TObject);

var

Rec: TMethod1Record;

Stream: TFileStream;

begin

Stream := TFileStream.Create('Method1.stm', fmOpenRead);

Stream.ReadBuffer(Rec, SizeOf(Rec));

Stream.Free;

Label1.Caption :=

TimeToStr(EncodeTime(Rec.Hour, Rec.Minute, Rec.Second, Rec.MSec));

Label2.Caption := Rec.Msg; { * }

end;

Примечание

В проекте RecordRead объявлена такая же запись TMethod1Record, описание которой во втором случае для краткости опущено.

Запись в файл происходит нормально, но при чтении в строке, отмеченной звездочкой, скорее всего, возникает исключение Access violation (в некоторых случаях исключения может не быть, но вместо сообщения будет выведен мусор). Причину этого мы уже обсудили ранее — указатель Msg, действительный в контексте процесса RecordWrite, не имеет смысла в процессе RecordRead, а сама строка передана не была. Без ошибок этим методом можно передать только пустую строку, потому что ей соответствует указатель nil, имеющий одинаковый смысл во всех процессах. Однако метод передачи строк, умеющий передавать только пустые строки, имеет весьма сомнительную ценность с практической точки зрения.

Самый простой способ исправить ситуацию— изменить тип поля Msgна ShortString. Больше ничего в приведенном коде менять не придется. Однако использование ShortStringимеет два недостатка. Во-первых, длина строки в этом случае ограничена 255 символами. Во-вторых, если длина строки меньше максимально возможной, часть памяти, выделенной для структуры, останется незаполненной. Если средняя длина строки существенно меньше максимальной, то таких неиспользуемых кусков в потоке будет много, т.е. файл окажется неоправданно раздутым. Это всегда плохо, а в некоторых случаях — вообще недопустимо, поэтому ShortStringможно посоветовать только в тех случаях, когда строки имеют примерно одинаковую длину (напомним, что ShortStringпозволяет ограничить длину строки меньшим, чем 255, числом символов — в этом случае поле будет занимать меньше места).

С одним из этих недостатков можно бороться: если заменить в записи ShortStringстатическим массивом типа Char, то можно передавать строки большей, чем 255 символов, длины. Второй метод демонстрирует этот способ.

В проекте RecordWrite этому соответствует код (листинг 3.37).

Листинг 3.37. Запись в файл структуры с массивом символов

const

MsgLen = 15;

type

TMethod2Record = packed record

Hour: Word;

Minute: Word;

Second: Word;

MSec: Word;

Msg: array[0..MsgLen - 1] of Char;

end;

procedure TForm1.Button2Click(Sender: TObject);

var

Rес: TMethod2Record;

Stream: TFileStream;

begin

DecodeTime(Now, Rec.Hour, Rec.Minute, Rес.Second, Rec.MSec);

StrPLCopy(Rec.Msg, Edit1.Text, MsgLen - 1);

Stream := TFileStream.Create('Method2.stm', fmCreate);

Stream.WriteBuffer(Rec, SizeOf(Rec));

Stream.Free;

end;

В проекте RecordRead это следующий код (листинг 3.38).

Листинг 3.38. Чтение из файла структуры с массивом символов

procedure TForm1.Button2Click(Sender: TObject);

var

Rес: TMethod2Record;

Stream: TFileStream;

begin

Stream := TFileStream.Create('Method2.stm', fmOpenRead);

Stream.ReadBuffer(Rec, SizeOf(Rec));

Stream.Free;

Label1.Caption :=

TimeToStr(EncodeTime(Rec.Hour, Rec.Minute, Rec.Second, Rec.MSec));

Label2.Caption := Rec.Msg;

end;

Константа MsgLenзадаёт максимальную (вместе с завершающим нулём) длину строки. В приведенном примере она взята достаточно маленькой, чтобы наглядно продемонстрировать, что данный метод имеет ограничения на длину строки. Переделки по сравнению с кодом предыдущего метода минимальны: при записи для копирования значения Edit1.Textвместо присваивания нужно вызывать функцию StrPLCopy. В коде RecordReadизменений (за исключением описания самой структуры) вообще нет — это достигается за счёт того, что массив Charсчитается компилятором совместимым с PChar, а выражения типа PCharмогут быть присвоены переменным типа AnsiString — конвертирование выполнится автоматически.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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