|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Помогите разобраться с типизированными ссылками
Всем доброго настроения. Народ! помогите немного разобраться с типизированными ссылками.
Например: Код:
type PPerson = ^TPerson; TPerson = record Name: AnsiString; Age: byte; end; var Per1: TPerson; Per2: PPerson; begin Per1.Name:='Peter'; // первый случай New(Per2); // Второй случай Per2.Name:='Peter'; Despose(Per2); end; В первом случае программа выделяет место в памяти при запуске и обращается непосредственно к переменным (данным). И если надо передать другой похожей переменной передает данные содержщиеся в переменной. Если я правильно понял.?! Во втором случае программа выделяет память для работы и затем соответственно освобождает её (динамическая память). И работает уже не с переменными а с адресом памяти где находятся данные переменной. И если надо передать другой похожей переменной передает адрес памяти где находиться данные.?! Получается что если работать со строками и структурами лучше использовать типизированые ссылки? т.к. передавать данные на обработку выгоднее и быстрее передать адрес где находятся данные. И в чем плюсы и минусы этих ссылок.? Спасибо за внимание. Последний раз редактировалось dmdx, 07.08.2008 в 10:45. |
#2
|
|||
|
|||
Смотря, что понимать под обработкой? Кстати, ANSI строки в случае копирования вовсе не копируются, а у них увеличивается счётчик использования (как у интерфейсов). В случае ОБЪЕКТОВ (class) Delphi предоставляет удобный интерфейс, например, операции со свойствами выглядят как применение переменных, хотя при этом вызываются методы. Сам объект - это не область памяти (структура), а ссылка на неё. А раньше приходилось писать ^ или @. Что делать, если одна функция меняет данные, а другая хочет их удалить? Тут надо делать копии. При передаче массива в подпрограмму, стоит var или нет, весь массив не передаётся, а только адрес первого элемента. В Си дошли до того, что используют двойные указатели, т.е. указатель не на объект, а на адрес, а в Delphi всё выглядит посимпатичнее.
Последний раз редактировалось AlexSku, 07.08.2008 в 12:29. |
#3
|
|||
|
|||
А разве в Delphi есть разница между объявлением переменной String и AnsiString? Нет но я понимаю что это два разных типа. но помойму если в переменную String поместить строку длинной более 255 символов она автоматом становиться AnsiString. Или по крайней мере я точно впихивал строку длинной 1608 символов в переменную String.
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит Прапор: вы не попали ни один раз. Программист: Пули вылетели, проблемы у вас. |
#4
|
|||
|
|||
Ну не совсем так.
В Delphi тип String является псевдонимом, по умолчанию указывающем на AnsiString. Что бы сделать Pascal-строку надо явно указать ее длинну (String[100], например). Теперь по поводу типизированных указателей. Вообще, когда в процедуру передается переменная по var, то ВСЕГДА передается указатель. Это раз. Два. Раньше, до 32-битной ОС, была существенная разница в использовании типа и указателя, т.к. память в случае указателя выделялась в "куче", что позволяло использовать более 64К данных. Сейчас разницы в принципе нет, за исключением того, что используя "грязное" преобразование типов можно рассматривать данные в памяти через различные структуры, что юывает иногда очень нужно (чаще всего в API Windows). Ну и хранить типизпрованные указатели можно в TList (хотя я давно перешел на TObjectList и работаю с объектами, имея не только преимущество использования указателей, но и все прелести ООП). |
#5
|
|||
|
|||
Вроде как немного разобрался.
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит Прапор: вы не попали ни один раз. Программист: Пули вылетели, проблемы у вас. |
#6
|
|||
|
|||
Код:
var: Fl: TextFile; procedure OpenFile(var FilePatch: string); begin try AssignFile(Fl,FilePatch); Reset(Fl); finally end; end; begin OpenFile('c:\log.log'); end; т.е. по логике я передаю функции OpenFile адрес памяти в которой храниться значение c:\log.log !? А если не использовать var Код:
... procedure OpenFile(FilePatch: string); ... то я бы передавал именно значение c:\log.log !? Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит Прапор: вы не попали ни один раз. Программист: Пули вылетели, проблемы у вас. |
#7
|
|||
|
|||
Ну, в общем случае, да.
Можешь проверить такой фокус: Код:
procedure VarTest(var A : String); begin A := 'VarTest'; ShowMessage(A); end; procedure NotVarTest(A : String); begin A := 'NotVarTest'; ShowMessage(A); end; var B : String; begin B := 'Main'; ShowMessage(B); VarTest(B); ShowMessage (B); B := 'Main'; ShowMessage(B); NotVarTest(B) ShowMessage(B); end; И посмотри что выводится. |
#8
|
|||
|
|||
Интересная картина получается. Если использовать var в процедурах то передовать можно только переменные. Прямой текст (данные) передавать нельзя.
Код:
прокатит procedure TForm1.Button1Click(Sender: TObject); procedure GetText(Text: string); begin Edit1.Text:=Text; end; var r: string; begin r:='Welcome'; GetText(r); end; не прокатит procedure TForm1.Button1Click(Sender: TObject); procedure GetText(Text: string); begin Edit1.Text:=Text; end; begin GetText('welcome'); end; и ещё один плюс процедура с использованием var в машинном коде занимает менюше места и соответственно выполняется быстрее. файлик with_out_var без использования var в процедуре Код:
procedure TForm1.Button1Click(Sender: TObject); procedure GetText(Text: string); begin Edit1.Text:=Text; end; var r: string; begin r:='Welcome'; GetText(r); end; файлик with_var c использования var в процедуре Код:
procedure TForm1.Button1Click(Sender: TObject); procedure GetText(var Text: string); begin Edit1.Text:=Text; end; var r: string; begin r:='Welcome'; GetText(r); end; и наглядно видно что asm операторов меньше с использованием var. это наверное обуславливается тем что. при запуске процы без var переменная text создается, а проца с var истолькует в себе глобальную переменную!? Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит Прапор: вы не попали ни один раз. Программист: Пули вылетели, проблемы у вас. |
#9
|
|||
|
|||
Разница в том, что без использования var значение переменной помещается в стек, а при использовании var - нет. Вот и разница. По сути, не заморачивался бы ты этими вопросами, т.к. реальна разница имеет влияние на грани погрешности измерения
Лучше помни одну вещь - при использовании var-параметров у тебя может возникать сторонний эффект, т.е. изменяется значение переданной переменной. Лучше этого избегать. |