Отправляет email-рассылки с помощью сервиса Sendsay

Delphi - проблемы и решения

  Все выпуски  

Проблемы и решения в Delphi


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Проблемы и решения в Delphi

Проблемы и решения в Delphi - выпуск 6 от 23.02.2001.

Полуправда хуже лжи...

Всех подписчиков, имеющих отношение к защите нашего отечества, поздравляю
с праздником и желаю всего самого хорошего, доброго и приятного.


Доброго Вам времени суток уважаемый читатель.

Выпуск шестой. О чем это я? Ах да - полуправда. В прошлом выпуске мы
начали искать интересности в программировании на Паскале. Так вот - есть
там такая возможность, как передача параметров в процедуры и функции
разными способами. Ни в одной из прочитанных книжек я не обнаружил полной
"правды" по этому поводу. Но все по порядку.
Итак существует несколько вариантов передачи параметров в процедуры и
функции. Это передача по значению, по ссылке, как константы и как выходного
параметра. Те, кто никогда не слышал о такой возможности просто пользовался
передачей по значению. Выглядит это до смешного привычно :

'Procedure Pr1(p1 : Integer,p2 : Boolean);' .

Передать по ссылке :

'Procedure Pr2(var p1 : Integer,p2 : Boolean);' .

Да, да все очень просто - просто добавили 'var'. И теперь p1 передается
по ссылке(только p1).
Зачем это разнообразие? Смотрите сами - в первом случае, изменяя значения
переменных внутри процедуры в основной программе они не меняются. Т.е.
действие происходит с копиями переменных, а не с их оригиналами. А вот во
втором случае как раз происходит работа с самой переменной, так как в
процедуру передаются(реально) лишь ссылки на значения этих переменных.
Смею Вас заверить всё работает просто изумительно - абсолютно никакаих
проблем. Но!!! Это до тех пор пока Вы не используете внутри процедуры
функции из user32.lib перекодировки строк(CharToOem например). В этом
случае появляется проблемка.

- (прб.5) Если внутри процедуры Вы собираетесь перекодировать строки(неважно
PChar или String) и при этом желаете оставить в основном модуле их без
изменений, а это не получается, то откажитесь от использования функций из
user32.lib. Либо напишите свои, либо перед завершением процедуры перекодируйте
обратно(не забывайте о затратах).

Вот такие бывают коллизии(ну не говорят нам всего). Не смотря на это считаю
данную возможность очень важной. И если Вы не относите себя к программистам
которые считают, что если на их машине все "летает", значит сойдет, то отмечу
для Вас еще один существенный момент. При передаче параметров по значению
происходит копирование переменной в новую - для процедуры, а это - затраченное
время. И если при передаче одной, двух переменных это покажется незначительными
потерями, то представьте себе передачу, например, переменной типа TStrigList c
cотней записей. Каково?

- (с.6) Старайтесь строить такой алгоритм программы, в котором по максимуму бы
использовались вызовы процедур с передачей параметров по ссылке.

У нас осталось еще два варианта. Рассмотрим их.

Передать как константу :

'Procedure Pr2(const p1 : Integer,p2 : Boolean);' .

Я бы назвал этот вариант страховочным. Дело в том, что при такой передаче все
происходит как при передаче по значению(с копированием), но плюс к этому еще на
этапе компиляции будет произведена проверка - а не меняете ли Вы значение
переданной переменной? Если - да, то компилятор на Вас поругается и Вы
воскликните - 'Ё~!@#$% ! Я же сам этого хотел!'.

Передать как выходной параметр :

'Procedure Pr2(out p1 : Integer,p2 : Boolean);'

Иногда очень полезная возможность. Опять же, все происходит анологично передаче по
ссылке(никаких копирований), однако плюс ко всему передаваемая переменная чистится.
Удобно, например, когда Вы передаете структуру на перезаполнение. Хотя ведь и для
чистки необходимо произвести определенную работу, а значит загрузить машинку.
Поэтому этот вариант я бы назвал вариантом для очень совестливых. Так сказать,
почистимся для очистки совести.

Естественно, для функций все абсолютно анологично.
Пожалуй с этим все.


К сожалению новых вопросов пока не поступало(как и ответов на уже имеющиеся).


--------------------------------------------------------------------------------------------
Вопросы и ответы(тут можно помочь самим). Пока будут все вопросы, а
далее только не отвеченные или не полностью отвеченные.
--------------------------------------------------------------------------------------------

Вопрос:1 - Как быстро считать в строку файл, если это к примеру
                  *.exe? Если использовать TStringList.LoadFromFile,
                  то попадает туда не всё - почему?

Ответить.

ОТВЕТ:1(от автора рассылки) -

Могу предложить такой вариант -

function FileToStr(ImFile:String):String;
var S:TFileStream;
str : String;
Buf: array [1..10000] of Char;

begin
str := '';
S:=TFileStream.Create(ImFile,fmOpenRead);
while s.Position < s.Size do
begin
s.Read(buf,10000);
str := str+String(buf);
// Application.ProcessMessages; // Это, если файл огромный.
end;
Delete(str,s.size+1,10000);
s.Free;
Result := str;
end;


--------------------------------------------------------------------------------------------
Вопрос:2 - Как сделать индекс по 2-м полям в локальной базе, например
                  Paradox, если я хочу скажем, сортировать по условию - кусок
                  того поля + кусок другого? BDE использую.

Ответить.

___________________________________________________________________________

Если Вы хотите как можно скорее получить ответ на свой вопрос, то
укажите в теме письма - 'delphiV' , иначе письмо будет прочитано значительно
позже. Если же у вас есть предложения то в теме письма укажите пожалуйста -
'delphiP'.

Спросить Предложить Архивы Сколько нас

Автор рассылки - Дмитрий.
ICQ(1.00 - 12.00мск.) - 89533941.


http://subscribe.ru/
E-mail: ask@subscribe.ru
Поиск

В избранное