![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
const в параметрах [D7]
махс © (2008-03-02 11:23:00)Загадка для меня. В каких случаях в процедуру или функцию передают значение константой;
Я понимаю, что это означает. Но вот когда именно это применяют не пойму. Бывает выжу чужой исходник, в функцию передают пять параметров - не один внутри функции не изменяют, а с констнтой идет только самый первый.
Поясните?
Спасибо.
oxffff (2008-03-02 20:38:00) [61]У меня
Вариант 1
1094 abc
1141 abcEX
Вариант 2
1094 abcEX
1140 abc
oxffff (2008-03-02 20:37:00) [62]
> {RASkov} © (02.03.08 20:16) [25]
Поменяй вызов.
цикл abc(5);
цикл abcEx(5);
цикл abcEx(5);
цикл abc(5);
{RASkov} (2008-03-02 20:16:00) [63]> [24] oxffff © (02.03.08 20:09)
> Этот код исполняется идентично.
Как же идентично, а по времени выполнения - поразному?
oxffff (2008-03-02 20:09:00) [64]
> как же понять [7]?
procedure abc(i: integer);
begin
end;
procedure abcEx(const i: integer);
begin
end;
Этот код исполняется идентично.
oxffff (2008-03-02 20:05:00) [65]
> procedure abcEx(const i: integer);
> begin
> //по ссылки
> end;
Увы. Это не по ссылке. см. Delphi help
{RASkov} (2008-03-02 19:48:00) [66]Дайте поймаю мысль...
> Разница есть.
С таким кодом:
procedure abc(i: integer);
begin
//по значению
end;
procedure abcEx(const i: integer);
begin
//по ссылки
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
Tick1,Tick2:DWORD;
begin
Tick1:=GetTickCount;
for i:=0 to 100000000 do abc(5);
Tick1:=GetTickCount-Tick1;
Tick2:=GetTickCount;
for i:=0 to 100000000 do abcEx(5);
Tick2:=GetTickCount-Tick2;
showmessage(inttostr(Tick1)+' '+inttostr(Tick2));
end;
Тоже есть.... в 3 раза... с конст итегер быстрее.... как же понять [7]?
oxffff (2008-03-02 19:39:00) [67]
> Loginov Dmitry © (02.03.08 19:05) [19]
> > Почему бы тут не передать Default, как const?
>
>
> 1) это ничего не даст. Просто нельзя будет изменять значение
> переменной в процедуре, вот и все.
Опять заблуждение, хочешь пример?
TypeA=record
A,B,C,D:integer;
end;
procedure abc(s:TypeA);
begin
end;
procedure abcEx(const s:TypeA);
begin
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
Tick1,Tick2:DWORD;
A:TypeA;
begin
Tick1:=GetTickCount;
for i:=0 to 1000000000 do abc(A);
Tick1:=GetTickCount-Tick1;
Tick2:=GetTickCount;
for i:=0 to 1000000000 do abcEx(A);
Tick2:=GetTickCount-Tick2;
showmessage(inttostr(Tick1)+' '+inttostr(Tick2));
end;
Учти пример еще без Managed типов.
oxffff (2008-03-02 19:30:00) [68]
> Loginov Dmitry © (02.03.08 19:05) [19]
Разница есть.
procedure abc(s:string);
begin
end;
procedure abcEx(const s:string);
begin
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
Tick1,Tick2:DWORD;
begin
Tick1:=GetTickCount;
for i:=0 to 100000000 do abc('123');
Tick1:=GetTickCount-Tick1;
Tick2:=GetTickCount;
for i:=0 to 100000000 do abcEx('123');
Tick2:=GetTickCount-Tick2;
showmessage(inttostr(Tick1)+' '+inttostr(Tick2));
end;
Loginov Dmitry (2008-03-02 19:05:00) [69]> Почему бы тут не передать Default, как const?
1) это ничего не даст. Просто нельзя будет изменять значение переменной в процедуре, вот и все.
2) const и var при передаче глобальных переменных является потенциальной проблемой в многопоточном приложении.
А переменные String передавать с Const - это скорее правило хорошего тона. Именно в примере [2] оптимизации от этого никакой нет, т.к. нет обращения к отдельным символам строки. В других же случаях наличие Const может заметно улучшить производительность приложения по сравнению с его отсутствием.
oxffff (2008-03-02 16:24:00) [70]
> {RASkov} © (02.03.08 16:19) [17]
Пример надуман, однако такая ситуация имеет место быть.
Такая ситуация может неявно возникнуть в многопоточном приложении.
{RASkov} (2008-03-02 16:19:00) [71]> [15] oxffff © (02.03.08 16:10)
> Однако оные выкрутасы могут приводить к проблемам, например
> вот одна из них выдуманная на ходу
Помоему это нужно специально так придумать, да и не каждому дано так придумать :) я про код)
oxffff (2008-03-02 16:12:00) [72]
> (это подавляет вызовы addref/release при assign op, и finalize
> при scope exit )
Подавляет вызов addref при передачи параметра.
oxffff (2008-03-02 16:10:00) [73]
> махс (02.03.08 13:08) [2]
> Ну вот пример из боландовских исходников:
>
> function StrToIntDef(const S: string; Default: Integer):
> Integer;
В данном случае при const имеет смысл для S, по скольку S является managed типом (не в терминах .NET естествено), const означает, что локальная переменая является синонимом
(это подавляет вызовы addref/release при assign op, и finalize при scope exit )
переданного параметра с ораниченным временем жизни
Однако оные выкрутасы могут приводить к проблемам, например вот одна из них выдуманная на ходу
var GlobalA:string;
implementation
{$R *.dfm}
procedure HarmfulProc(const a:string);
var b:string;
begin
GlobalA:=''; //Освобождает память
b:=a; //Копируем invalid ref //
end; //Освобождает память снова //AV
procedure TForm1.Button1Click(Sender: TObject);
begin
GlobalA:='SomeText';
GlobalA:=GlobalA+GlobalA;
HarmfulProc(GlobalA);
end;
{RASkov} (2008-03-02 15:50:00) [74]> [12] Anatoly Podgoretsky © (02.03.08 14:53)
> Не путай передачу по значению, с передачей по ссылке.
А где я что напутал?
> И смотри окно CPU
А вот туда я не умею смотреть, т.е. смотреть-то туда умею, но там ничего не понимаю :(
> [13] Игорь Шевченко © (02.03.08 15:12)
> В которой сказано, что параметры передаются по значению,
> если не указано слово var
или const... еще out ...
>
Ладно.... фик с ними :) Что-то мы тут запутались..... т.е. я запутался и вас путаю... )
Игорь Шевченко (2008-03-02 15:12:00) [75]{RASkov} © (02.03.08 14:49) [11]
> > С точки зрения передачи параметров, быстродействия и прочих
>
> > аспектов времени выполнения абсолютно одинаковые.
>
> Что-то опять не то.... См [7] :(
А что смотреть на 7 ? Лучше смотреть на грамматику языка. В которой сказано, что параметры передаются по значению, если не указано слово var.
Anatoly Podgoretsky (2008-03-02 14:53:00) [76]
> Что-то опять не то.... См [7] :(
Не путай передачу по значению, с передачей по ссылке.
И смотри окно CPU что бы определить как передается интегер при const, var и без модификатора.
{RASkov} (2008-03-02 14:49:00) [77]> [10] Игорь Шевченко © (02.03.08 14:35)
> Давно бы откомпилировал и посмотрел
Мне известно что будет с "const" и без нее...
Я именно про саму передачу параметра.... с const(var) - у нас одна "переменная", без - две. (утрировано)
> С точки зрения передачи параметров, быстродействияи прочих
> аспектов времени выполнения абсолютно одинаковые.
Что-то опять не то.... См [7] :(
> С точки зрения компиляции компилятор....
Ну его точка зрения мне понятна...:)
Игорь Шевченко (2008-03-02 14:35:00) [78]
> procedure M(const I: Integer);
> и
> procedure M1(I: Integer);
> одинаковые что ли?
С точки зрения передачи параметров, быстродействия и прочих аспектов времени выполнения абсолютно одинаковые.
С точки зрения компиляции компилятор будет ругаться, если внутри процедуры параметру будет что-то присваиваться.
Давно бы откомпилировал и посмотрел
{RASkov} (2008-03-02 14:30:00) [79]> [7] Anatoly Podgoretsky © (02.03.08 14:28)
Ясно.... спасибо)
{RASkov} (2008-03-02 14:29:00) [80]Почему появилось [6].
Я пробегся по нескольким местам в VCL и нигде не встретил (const xx: Integer) или (const xx: Cardinal).....
Var - были, а конст нигде.... только по значению..... Странно все это :)
В прочем я не так и много мест просмотрел....