Если нравится наш проект, пожалуйста, поддержите любой приемлимой суммой чтобы помочь оплачивать хостинг. Спасибо!
Навигация  🇷🇺RU | 🇬🇧EN

Новые комментарии

Последние файлы

Пожертвования
[ Через Yoo.Money ]
(бывшие Яндекс.Деньги) 410011494554572

Contact us if you wish
PayPal or BitCoin donation

Наши друзья

Статьи

(0D|NG


.:ВХОД:.

Эта страничка посвящена программированию на Delphi (под Windows) и Pascal (под DOS). Всё, чего тут касается только следующих языков (версии):

Delphi 7 и Turbo Pascal 7.1. Может работать (должно) и в младших версиях - но не ручаюсь за все команды.


.:DOS -> Windows:.

Я столкнулся со следующими проблемами при переходе из под DOS'овского Pascal'я в Delphi под Windows:

• Функции для работы с файлами поменяли свои имена:

Pascal (DOS) - Delphi (Windows):

Assign(Fl, 'filename.ext') - AssignFile(Fl, 'filename.ext')

Close(Fl) - CloseFile(Fl)

• Размер памяти, выделяемой процедурой GetMem, больше не ограничен максимальным размером сегмента в 64K (65535 байт).

• Тип Integer стал размером в 32-бита, и равнозначен использованию типа LongInt (который, кстати, не изменился).

• Появились новые типы:

Имя типа = Диапазон = Формат

SmallInt = -32768..32767 = со знаком 16-бит (это "старый" Integer)

Cardinal = 0..4294967295 = беззнаковый 32-бита

LongWord = 0..4294967295 = беззнаковый 32-бита

Int64 = -2^63..2^63-1 = со знаком 64-бита

• С дробными типами дело обстоит так:

Имя типа = Диапазон = Значащие цифры = Размер в байтах

Real48 = 2.9 x 10^-39 .. 1.7 x 10^38 = 11-12 = 6 (это "старый" Real)

Real = 5.0 x 10^-324 .. 1.7 x 10^308 = 15-16 = 8

• Длину строки больше нельзя указать как S[0]:=#4, для этого используется процедура: SetLength(S,4).

• ВНИМАНИЕ!!! Под строки больше не выделяется 256 байт памяти!!! Память выделяется автоматически, в зависимости от изменения длинны строки.

Так что НЕЛЬЗЯ писать что-то после последнего символа строки - там может быть область других переменных!!!

• Появился тип AnsiString - это строка длинной, не поверите, в 2 Гб (!!!). Старый тип называется ShortString.

• Если в программе какая-то переменная типа String, то, в зависимости от переключателя {$H+} (по умолчанию) или {$H-} эта переменная будет либо AnsiString, либо ShortString.

• Ну и, само собой, в Delphi ПОЛНОСТЬЮ отсутствуют модули CRT, Graph, DOS (хотя кое-какие функции из модуля DOS перекочевали в модуль SysUtils, например FindFirst / FindNext, GetTime и что-то ещё).

• Также изменились имена используемых констант. Если раньше для атрибута файла "только чтение" надо было писать ReadOnly, то теперь нужно faReadOnly (File Attribute Read Only). Просто посмотрите, что требуется и добавьте первые буквы необходимого сокращения.

Delphi в отличие от Pascal может разбирать сложные выражения. Например, вот это выражение Delphi обработает правильно:


{ из программа EAUnpacker - см. раздел "Программы" и "Статьи -> Распакуй файло"}

Var

  K, Bl: Byte;

  L: LongInt;

...

L:=0;

For K:=3 DownTo 0 Do

  Begin

    BlockRead(F, Bl, 1);

    L:=L+(Bl Shl (8*K)); { < - обратите внимание на эту строку! }

  End;

...


В данном случае Pascal её скомпилирует (ошибки нет) - но БУДЕТ НЕПРАВИЛЬНО СЧИТАТЬ ЭТУ СТРОКУ!!! У меня есть подозрение, что он просто пропускает какие-то сложные вложенные операторы... А вот Delphi - тот считает правильно.

Вычитал в Интернете недавно, что если написать:

L:=L+LongInt(Bl Shl (8*K));

то всё будет работать. Т.е. сделать явное приведение типов. Т.к. оказывается, что в Pascal и Delphi результат операции зависит только от типа входящих в неё переменных, но не от типа результата.


.:Разбор полётов:.

Если начали писать под Delphi - то не надо стараться поддерживать принцип "сверху - в низ", т.е. если читаете что-то в память, не заботьтесь об этих 64Кб, используйте SetLength и прочее. Я, например, пишу под Delphi, когда мне нужно чтобы программа поддерживала длинные имена, или чтобы работать с графикой было проще (TBitmap). Несколько советов:

• Во многих случаях, если в этом нет острой необходимости (например пишите распаковщик) - делайте консольное приложение (File -> New -> Other... -> [New] -> Console Application). Так как GUI приложение со всеми формами (даже если она одна) жрёт много места (имеется ввиду .EXE файл).

• Небольшой пример, для извращенцев как я, которые пытаются запихнуть элемент на форму во время выполнения:

Procedure CreateTextEdit;

Var TextEdit: TEdit;

Begin

  TextEdit:=TEdit.Create(TextEdit);

  TextEdit.Parent:=Form1; { имя формы, которой будет принадлежать элемент }

  TextEdit.Name:='TextEdit1';

End;

{ Свойство Name неплохо задать, чтобы можно было "забить" на указатель TextEdit и найти нужный элемент через:

TextEdit:=TEdit(Form1.FindComponent('TextEdit1'));

после чего делаете с TextEdit, что душе угодно...}

• Хорошо бы, как и в Pascal, не забывать и "чистить" память. Речь идёт не только о FreeMem, Dispose и прочих, а об объектах:

  Picture:=TBitmap.Create; { создаём объект }

  Picture.LoadFromFile('image.bmp'); { что-нибудь с объектом делаем }

  Picture.Width:=10;

  Picture.Height:=10;

  Picture.Canvas.Pixels[0,0]:=RGB(255,0,0);

  Picture.Free; { <- чистим память из-под созданного объекта }

Хороший тон, всё же...

• Чтобы прочитать из файла строчку фиксированной длинны (например сигнатуру) не обязательно читать её посимвольно в цикле n раз. Можно сделать так:

  SetLength(S,4); { указываем размер строки !!! иначе в Delphi будете писать в память, которой нет !!! В Pascal напишите: S[0]:=#4 }

  BlockRead(Fl, S[1], 4); { S[1] - адрес ПЕРВОГО элемента строки, т.е. адрес

начиная с которого нужно считывать. НЕ ПИШИТЕ ПРОСТО S или S[0] - ЗАТРЁТЕ длину строки!!! }

Подобным же макаром можно обращаться и с массивами.

• В Delphi есть такая штука как динамические массивы. Вот пример их использования:

Procedure Example;

Var

    Arry: Array Of Integer; { массив элементов типа Integer }

    I: LongInt;

Begin

  SetLength(Arry, 10); { выделяем память под 10 элементов массива }

{ чего-нибудь с массивом делаем; например, зануляем все элементы; функция Length работает так же как и для строк - возвращает количество элементов }

  For I:=0 To Length(Arry)-1 Do { индексация массива начинается с нуля !!! }

    Arry[I]:=0;

  ... { чего-нибудь там ещё делаем }

  SetLength(Arry, 0); { в конце уничтожаем массив }

End;


.:ВыХОД:.

Ваши пожелания - ответы тут...


2006-04-15 11:26
-=CHE@TER=-
    © CTPAX-X 2006-2024 | engine version 2.5
Based on original site design by Blade

 

 

 
При копировании материалов ссылка на сайт WWW.CTPAX-X.ORG обязательна!
Использование материалов влечёт безоговорочное принятие правил сайта.
Количество запросов к БД: 7 | Страница сгенерирована за 0.007884 сек.