Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > procedure и её пораметры (const var);


Автор: ivan219 30.10.2006, 00:38
Скажите какой из вареанто верный.

procedure(var a,b: Integer; c: String);

1. var относится только к a,b
2. var относится к a,b,c

Также и с Const если написать procedure(const a,b: Integer; c:String);
Будетли Const относится к a,b,c

А то я что-то не разобрался???????

Автор: digs 30.10.2006, 00:40
и const и var радотают до точки с запятой

Автор: ivan219 30.10.2006, 00:42
И ещё какая разница меду записями:

Procedure(const A: Integer);

Procedure(A: Integer);

Т.е. как они будут выглядеть в EXE файле и как будут работать (быстрее) так как я вкниге читал что используя const можно оптимизировать прцедуру.

Автор: Snowy 30.10.2006, 00:58
Если const, то физически в процедуру передаётся не значение A, а указатель на исходную переменную. 
То же самое происходит и в случае var, но в var переменную разрешено менять. 
Соответственно только в случае var исходная переменная изменится. 
Без var можно менять A, как угодно - на исходную переменную не повлияет. 
С const вообще нельзя менять A.
Никакого ускорения от этого быть не может. 
С точки зрения скорости, не имеет никакого значения, что именно класть в стек - значение или указатель.
Извлекаем мы всё равно всё те же 4 байта. А дальше всё равно по какому адресу брать значение - скорость та же.

Автор: Fedia 30.10.2006, 01:05
Параметр const нельзя изменять в вызываемой процедуре.
Параметр же переданный без атрибута (модификатора) можно менять в вызванной процедуре, но при выходе из процедуры переданный параметр останется неизменным.

Автор: ivan219 30.10.2006, 01:40
Понятно smile 

Автор: digs 30.10.2006, 03:43
Цитата(Snowy @  30.10.2006,  02:58 Найти цитируемый пост)
Извлекаем мы всё равно всё те же 4 байта. А дальше всё равно по какому адресу брать значение - скорость та же.

А если Integer извлекаем? При const сначала берем адрес, а по нему берем Integer. Без const берем Integer сразу. Быстрее без const.
Хотя надо еще проверить, может в целях оптимизации const на такие вещи не действует: все равно передается значение.

Автор: bems 30.10.2006, 04:03
Цитата(Snowy @  30.10.2006,  00:58 Найти цитируемый пост)
Если const, то физически в процедуру передаётся не значение A, а указатель на исходную переменную
только если тип аргумента не влизает в 4 байта. Иначе передается по значению, но менять все равно нельзя.

Цитата(Snowy @  30.10.2006,  00:58 Найти цитируемый пост)
С точки зрения скорости, не имеет никакого значения, что именно класть в стек - значение или указатель.
А если значение очень длинное?

Автор: Snowy 30.10.2006, 09:46
Цитата(digs @  30.10.2006,  04:43 Найти цитируемый пост)
 При const сначала берем адрес, а по нему берем Integer
А где хранится Integer? В регистрах? Нет. В памяти - по определённому адресу.
Тут ассемблер нужно знать, чтобы понять smile
Код не работает с переменными - он работает со значениями по адресу в памяти.
Значение: достали из стека - записали по адресу.
Адрес - достали из стека - записали адрес.
Работаем в любом случае с адресом в памяти.
Если процедура на чистом асме - то выбираем как нам удобнее.

Цитата(bems @  30.10.2006,  05:03 Найти цитируемый пост)
только если тип аргумента не влизает в 4 байта. Иначе передается по значению, но менять все равно нельзя.
const всегда передаёт адрес. А указанное тобой поведение - это без указания const.

Цитата(bems @  30.10.2006,  05:03 Найти цитируемый пост)
А если значение очень длинное?
Какое такое "очень длинное?"

Добавлено @ 09:48 
Если под длинным, подразумевается, что не помещается в 4 байта, то передаётся указатель.
Тогда вообще нет разницы.

Автор: Yanis 30.10.2006, 11:21
И всё таки, значение вмещающееся в двойное слово передаётся в функцию непосредственно. Переменная размер которой больше чем двойное слово - передаётся по указателю smile
Я согласен с высказываением bems: 
Цитата(bems @  30.10.2006,  05:03 Найти цитируемый пост)
только если тип аргумента не влизает в 4 байта.


А вот, что касаетсяименения аргумента, то тут нужно уточнить дабы не допустить путаницы у менее опытных. Как таковое, значение переданное const нельзя изменять, но это легко обходится, т.к. Delphi "защищает" значение на уровне типов. Следственно получив указатель мы можем делать с значением переданным нам в функции всё что угодно.

Код

type
  TX = record
    x, y: DWORD;
  end;

{ ... }

procedure p(const P: TX);
var
  pOnTX: ^TX;
begin
  pOnTX := @P;
  pOnTX^.x := 11;
  ShowMessage('p: ' + IntToStr(pOnTX^.x));
end;

var
  x1: TX;
begin
  x1.x := 10;
  p(x1);
end;

Автор: Snowy 30.10.2006, 11:41
Цитата(Yanis @  30.10.2006,  12:21 Найти цитируемый пост)
Я согласен с высказываением bems
А я нет.
При указании const всегда будет передаваться по указателю.
Даже если это Integer или byte.

Автор: Fedia 30.10.2006, 12:05
Цитата(Yanis @  30.10.2006,  11:21 Найти цитируемый пост)
Как таковое, значение переданное const нельзя изменять, но это легко обходится

Не знал о такой возможности, но зачем может понадобиться сначала накладывать ограничения, объявляя параметр функции с атрибутом const, а затем обходить свое же ограничение с использованием указателей ?

Автор: Snowy 30.10.2006, 12:22
Ну так указатели - это способ уйти от стандартов, сделать недоступное доступным, а код более запутанным и неочевидным, чреватым побочными эффектами.
Даже компилятор вам скажет, что использование указателей небезопасно smile
Но, если очень хочется, то можно smile Если конечно ты единственный автор проекта... 
Иначе твои коллеги тебя точно не похвалят за то, что константная процедура меняет данные, которые её не доверяли менять.

Автор: vlgr 30.10.2006, 12:55
Цитата(Snowy @ 30.10.2006,  11:41)
Цитата(Yanis @  30.10.2006,  12:21 Найти цитируемый пост)
Я согласен с высказываением bems
А я нет.
При указании const всегда будет передаваться по указателю.
Даже если это Integer или byte.


Неверно. 
При указании var всегда будет передаваться по указателю.
При указании const если аргумент до 4 байт значение, иначе по указателю. 

Автор: Yanis 30.10.2006, 13:45
Цитата(Fedia @  30.10.2006,  13:05 Найти цитируемый пост)
Не знал о такой возможности, но зачем может понадобиться сначала накладывать ограничения, объявляя параметр функции с атрибутом const, а затем обходить свое же ограничение с использованием указателей ? 

Скажу так: это иногда требуется! Так как иногда требуется воспользоваться закрытым виртуальным методом чужого класса smile

Впечатлило? smile Вот тебе ещё интересный снип smile
Код
const
  x: DWORD = 0;
begin
  PDWORD(Pointer(@X))^ := 1;
  ShowMessage(IntToStr(X));
end;


Добавлено @ 13:47 
Snowy
А ты для какой версии компилятора говоришь? Delphi какая?

Автор: bems 30.10.2006, 16:38
Цитата(Snowy @  30.10.2006,  09:46 Найти цитируемый пост)
Какое такое "очень длинное?"

Добавлено @ 09:48 
Если под длинным, подразумевается, что не помещается в 4 байта, то передаётся указатель.

именно это и имееется ввиду.
Цитата(Snowy @  30.10.2006,  11:41 Найти цитируемый пост)
При указании const всегда будет передаваться по указателю.
Даже если это Integer или byte. 

Глянь первую ссылку внизу страницы - люди видели гараздо более разнообразное поведение

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)