Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Что делает VAR в процедуре


Автор: StepRu 15.8.2007, 14:09
Подскажите пожалуйста

Код

procedure MyProc(var M:TMemoryStream)


и

Код

procedure MyProc(M:TMemoryStream)


В чём у них разница? Ведь M:TMemoryStream уже является указателем на объект, но если поставить VAR - что измениться? Пожалуйста, дайте обоснованный ответ! с указанием на источник.

Автор: MetalFan 15.8.2007, 14:15
Цитата(StepRu @  15.8.2007,  14:09 Найти цитируемый пост)
дайте обоснованный ответ! с указанием на источник. 

чем то это напоминает кусок экзаменационного билета ;)
источник - любой учебник по паскалю с объяснением передачи параметров.
в первом случае параметр передается по ссылке и его значение можно изменить внутри процедуры.
во втором - по значению. т.е. изменение его внутри процедуры не приведет к изменению вне ее.

Автор: StepRu 15.8.2007, 14:45
Цитата(MetalFan @  15.8.2007,  14:15 Найти цитируемый пост)

в первом случае параметр передается по ссылке и его значение можно изменить внутри процедуры.
во втором - по значению. т.е. изменение его внутри процедуры не приведет к изменению вне ее.

Неа, это относиться не к классам =( Вот если бы там был не TMemoryStream а Integer, то вопросов бы не возникло. 

Код

procedure m(t:TButton);
begin
  t.Height:=10;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
m(Button1);
end;

процедура m без проблем меняет внешний объект как с Var, так и без него.

Автор: ivashkanet 15.8.2007, 14:49
StepRu, изменяет части объекта, но не весь объект!

Попробуй
Код

procedure m(t:TButton);
begin
  t = anOtherButton;
end;

Автор: StepRu 15.8.2007, 15:04
ivashkanet  А по какому принципу он эти части определяет? Например когда я юзал TMemoryStream и писал из процедуры во внешний объект методом WriteBuffer, то во внешнем объекте в начале всё было ок, но 40 байт он недописывал. Вар конечно усё исправил, но первые байты он почему то записал без Var =|

Автор: ivashkanet 15.8.2007, 15:23
StepRu, ничего не понял.
Дельфи я не знаю. Просто это межъязыковой вопрос (в C# все точно так же).
Суть в том, что при передаче  по "ссылке" (val) мы можем модифицировать объект на который эта "ссылка" ссылается.
Код
procedure m(var i:Integer, var t:TButton);
begin
  i := 5;
  t := Button123;
end;

Если же мы передаём "по значению" (без var), то модифицировать ссылку на объект нельзя, зато можно модифицировать сам объект
Код
procedure m(var i:SuperInteger, var t:TButton);
begin
  i.Value := 5;
  t := Button123; -- не прокатит
  t.Height:=10; -- прокатит
end;

Автор: Yanis 15.8.2007, 15:28
Цитата(StepRu @  15.8.2007,  15:45 Найти цитируемый пост)
процедура m без проблем меняет

Она не меняет. Она тока вызывает пропертю Height, а уже она меняет.

Автор: bems 15.8.2007, 15:33
с варом можно переписать ссылку ссылкой на другой объект

Автор: StepRu 15.8.2007, 16:04
Млин =) Народ, я наверное плохо объясняю, но мне надо модифицировать внешний объект из процедуры, передав в неё ссылку на этот объект!

Код

procedure m(t:TMemoryStream);
var
  i:Word;
begin
for I := 1 to 10 do
  t.WriteBuffer(I,SizeOf(I));
ShowMessage(IntToStr(t.Size));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  value,i:Word;
begin
MemStr:=TMemoryStream.Create;
m(MemStr);
MemStr.Position:=0;
for I := 1 to 10 do
begin
  MemStr.ReadBuffer(value,SizeOf(value));
  if value<>I then
    ShowMessage('Ошибка в записи №'+IntToStr(I)+'где value = '+IntToStr(value));
end;
ShowMessage(IntToStr(MemStr.Size));
end;

 как вы видите, я внутри функции m никакой другой объект не присваиваю t. Кстати, фукция нормально пашет как с Var, так и без него, изменяя данные в  памяти с помощью объекта MemStr, переданного в функцию. Так вот у меня вопрос в чём - что этот VAr делает, когда в качестве типа параметра указан класс? Он лишь позволяет ссылаться на другой объект внутри функции? Просто например если тип был бы Integer, то без Var он бы не изменился вне функции, а с классом он меняется! Так вот, как влияет VAR на внешний объект? из примера понял - что никак =/

PS. Был более сложный код, где записывались данные не однотипные, так вот там если не указать VAR, memStr не досчитался бы нескольких записей.

PS 2. Кстати, если указать VAR, то взятие адреса @

Код

procedure TForm1.m(var t:TMemoryStream);
var
  i:Word;
begin
if @t=@memStr

вернёт естественно True. А вот если я Var не укажу, то ссылка на объект просто копируется? Но это никак не будет влиять на обращение к внешнему объекту и работу с его методами, свойствами, конструктором и деструктором? Просто реально был случай, когда без Var исчезало несколько байт в потоке памяти.

Автор: bems 15.8.2007, 16:25
var нужен чтобы записать в переменную ссылку на новый объект. При изменении значений полей объекта сама ссылка остается неизменной и var не нужен но и не мешает.
Цитата(StepRu @  15.8.2007,  16:04 Найти цитируемый пост)
как вы видите, я внутри функции m никакой другой объект не присваиваю t. 
значит вар тебе никчему

Цитата(StepRu @  15.8.2007,  16:04 Найти цитируемый пост)
Просто например если тип был бы Integer, то без Var он бы не изменился вне функции, а с классом он меняется! 
с классом значение переменной тоже не меняется, а меняется содержимое памяти где-то начиная с адреса на который _указывает_ переменная. Поэтому в принципе все то же самое

Добавлено через 48 секунд
Цитата(StepRu @  15.8.2007,  16:04 Найти цитируемый пост)
PS. Был более сложный код, где записывались данные не однотипные, так вот там если не указать VAR, memStr не досчитался бы нескольких записей.

давай этот код, там и посмотрим

Добавлено через 9 минут и 2 секунды
Цитата(StepRu @  15.8.2007,  16:04 Найти цитируемый пост)
Просто реально был случай, когда без Var исчезало несколько байт в потоке памяти.

 smile  smile 

Автор: StepRu 15.8.2007, 16:56
bems
Спасибо огромное. Я понял в чём была ошибка - исправил усё. реально ступил в адресации, т.к. очень запутан проект и там действительно указатель  передавать надо в главную программу smile 

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