![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему изменяются поля в глобальной переменной [D7]
Михаил © (2012-02-26 20:19:00)Есть небольшая программка:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
// Некая структура исходных данных
type
TinData = record
id : Integer;
a : array of Integer;
end;
// Процедура с параметром ссылкой
procedure Proc1(inData: TinData); forward;
var
inData: TinData;
procedure Proc1(inData: TinData);
begin
inData.id := 30;
inData.a[0] := 1;
inData.a[1] := 2;
end;
begin
// Задаем начальные параметры структуры исходных данных
inData.id := 25;
SetLength(inData.a, 2);
inData.a[0] := 110;
inData.a[1] := 115;
// Передаем копию переменной inData в процедуру
// и изменяем значения ее полей
Proc1(inData);
// Выводим результат
writeln('id = ', inData.id);
writeln('a[0] = ', inData.a[0]);
writeln('a[1] = ', inData.a[1]);
readln;
end.
На выходе получаю такой результат:
id = 25
a[0] = 1
a[1] = 2
Вопрос: Почему значение поля id не изменилось, а значения массива изменились в глобальной переменной inData.
По идее если я передаю параметр по ссылке, программа должна сделать копию переменной и не влиять на значение глобальной.
Или я не прав?
Заранее благодарен!!!
Dimka Maslov (2012-02-27 18:42:00) [1]
> поэтому все массивы (строки в том числе) лучше передавать
> с модификаторами var или const
Строки даже без модификатора передаются по ссылке. Просто при первой же попытке изменить строку неявно делается новая копия. Кроме того, если нам надо передать строку, творчески с ней поработать в рамках подпрограммы, но чтобы наружу изменения не вылезли. с var - вылезут, с const - заругается компилятор.
Дмитрий Белькевич (2012-02-27 17:32:00) [2]
> По ссылке - это с var. По значению - без var.
По ссылке - с var или с const. Без var/const - массивам при входе в процедуру делается копия, указатели (в том числе на инстансы классов - объекты) передаются как есть.
> Блин в Delphi термины по ссылке и по значению такие запутанные((
Не путай себя. Достаточно знать, что переменные, переданные как var могут быть изменены внутри процедуры и возвращены наружу процедуры измененными. Без var - могут быть изменены, но наружу процедуры эти изменения не видны, так как меняется внутренняя копия данных.
По ссылке или по значению имеет значение для скорости. Понятно, что любое копирование данных уменьшает скорость выполнения, поэтому все массивы (строки в том числе) лучше передавать с модификаторами var или const.
icWasya (2012-02-27 14:15:00) [3]Varдля динмассива означает, что внутри процедуры мы можем изменить его размер.
Anatoly Podgoretsky (2012-02-27 08:37:00) [4]> Михаил (27.02.2012 06:09:05) [5]
дин. массивы и указатели не передаются, передается ссылка
MBo (2012-02-27 06:33:00) [5]Нет, не всё понял...
По ссылке - это с var. По значению - без var.
При передаче по значению считай, что создается копия параметра, и работа происходит с ней. Однако для указательных переменных можно изменить то, на что указывает указатель, и это отразится на внешних данных. Саму же указательную переменную не изменишь.
При передаче по ссылке (с var) можно изменить и саму переменную, в том числе для указательных - изменить адрес.
Михаил (2012-02-27 06:09:00) [6]Спасибо! Все понял. Получается если я передаю в процедуру параметр, который является указателем, то это уже в любом случае приведет к изменениям в глобальной переменной, даже если я передаю его по ссылке (без слова var).
Выходит что слово varпри передаче параметров касается только статичных переменных. А дин. массивы и указатели всегда передаются по значению (что и приводит к изменению в глобальной переменной).
Блин в Delphi термины по ссылкеи по значениютакие запутанные((
Благодарю всех за ответы!
oxffff (2012-02-26 21:36:00) [7]
> По идее если я передаю параметр по ссылке, программа должна
> сделать копию переменной и не влиять на значение глобальной.
>
> Или я не прав?
> Заранее благодарен!!!
>
Для динамических массивов в Delphi используется ссылочная семантика копирования,в отличии от семантики по значению.
Dimka Maslov (2012-02-26 21:17:00) [8]
> По идее если я передаю параметр по ссылке
Передача параметра по ссылке подразумевает использование ключевого слова var перед именем параметра в описании аргументов функции.
Amoeba_ (2012-02-26 20:56:00) [9]
> Сергей М. © (26.02.12 20:33) [1]
>
> поле inData.a есть копия указателя на управл.структуру одного
> и того же дин.массива, а не копия этого массива
что как раз очень хорошо видно под отладчиком
Сергей М. (2012-02-26 20:33:00) [10]поле inData.a есть копия указателяна управл.структуру одного и того же дин.массива, а не копия этого массива