Помогите склеротику: передача параметра-записи по зна

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Ответить
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Помогите склеротику: передача параметра-записи по зна

Сообщение Cheb »

Не использовал этот изврат со времён Турбо Паскаля, сейчас понадобилось - и понял, что напрочь забыл синтаксис! А в гугле что-то "крокодил не ловится". Помогите слабоумному, подскажите что надо писать в таком случае:

Код: Выделить всё

type TMyRecord = record 
  b: TSomeEnum;
  c: TSomeOtherEnum;
  d: integer;
end;

procedure proc(v: TMyRecord);
....
//вызов:
proc(????);

:cry:
Аватара пользователя
FedeX
постоялец
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение FedeX »

Я наверно немного не понял вопрос...
но если совсем просто, то:
1.обьявить переменную
var rec:TMyRecord;
2. передать в процедуру:
proc(rec);

или (чтоб не переполнять стёк например):
procedure proc(const[var] v: TMyRecord);
....
//вызов:
proc(rec);

или ещё так:
procedure proc(v: PMyRecord);// PMyRecord=^TMyRecord;
....
//вызов:
proc(@rec);
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Короче, я изменил архитектуру и обошёлся без извращения.
Но вопрос остаётся открытым. Вроде бы, можно было как-то передавать записи по значению без создания промежуточной переменной.
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

При работе с объектами (в частности с классами), можно передавать только ссылку на сам объект - см 2 пример вышеизложенного поста
Может имелся в виду рекурсивный вызов процедуры?
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Нет, имелась в виду именно передача записи, и именно по значению.
То есть, я должен так понимать, что ОП мудрит, и вместо передачи по значению втихую устраивает передачу по ссылке?
Тогда понятно, почему об этом нигде нет.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Передача чего бы то ни было по значению - это создание копии, т.к. подразумевает возможность изменения переданного значения, не затрагивая оригинал. В случае записи копирование может быть как путем запихивания в стек на вызывающей стороне, так и путем создания локальной переменной на вызываемой. Первый вариант, возможно, применялся во времена TurboPascal, и до сих пор применяется в ABI некоторых систем (пример - Darwin), но с ним все становится очень интересно, когда в записи появляются всякие ansistring. Кроме того, второй вариант короче в байтах, т.к. код копирования находится только в начале вызываемой ф-ции.
Михаил Крамер
новенький
Сообщения: 73
Зарегистрирован: 08.02.2008 13:26:40

Сообщение Михаил Крамер »

Не догнал, в чём проблема

Код: Выделить всё

type
   rt = record
     a,b: Integer;
   end;
var
  rv: rt;
procedure v(pr: rt);
begin
  pr.a:= pr.b;
end;
begin
 rv.a:= 15;
 v(rv);
 writeln(rv.a);
end.   


Вывод программы - 15, т.е. всё сработало
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Присвоил поле "а" и его же вывел - естественно, сработало :)
Михаил Крамер
новенький
Сообщения: 73
Зарегистрирован: 08.02.2008 13:26:40

Сообщение Михаил Крамер »

Я имел в виду, что изменения, произведнные внутри процедуры, не повлияли на глобальную переменную, как и должно было произойти при передаче параметра по значению - т. е. записи передавать по значению возможно, и не понятно, о чём собственно вопрос.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Мда, по ходу я сам запутался и других запутал... Я имел в виду промежуточную переменную, создаваемую компилятором для хранения локальной копии записи, и пытался показать, что она так или иначе создается. Cheb, похоже, имел в виду создание записи непосредственно при вызове ф-ции, не объявляя переменную - вроде того, как это можно делать с массивами:

Код: Выделить всё

procedure foo(const a: array of integer);
...
foo([12, 23, 34]);

Этот номер с записями не работает (увы).
Михаил Крамер
новенький
Сообщения: 73
Зарегистрирован: 08.02.2008 13:26:40

Сообщение Михаил Крамер »

Сергей, Ваш то пост я понял. Но тут некоторые писали, что типа записи вообще передаются исключительно по ссылке, а не позначению...
Аватара пользователя
FedeX
постоялец
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение FedeX »

>Первый вариант, возможно, применялся во времена TurboPascal
ну вродь если процедура stdcall то и сейчас параметр запихиваеться в стёк. вроде так..
>Но вопрос остаётся открытым. Вроде бы, можно было как-то передавать записи по значению без создания промежуточной переменной.
вродь никак.

хотя можно наварганить что-то вроде:

Код: Выделить всё

TPoint=record
  x,y:integer;
end;

function Point(x,y):TPoint;
begin result.x:=x;result.y:=y; end;

//и использовать так
SetPoint(Point(10,20));
Ответить