Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];

Вниз

Var и const параметры   Найти похожие ветки 

 
Asteroid   (2003-05-02 20:39) [0]

Есть примерно такой код:

type TMatrix = array [ 0..15 ] of Single;

procedure MatrixMult( var q: TMatrix; const a, b: TMatrix );
begin
...
q[ i ] = q[ i ] + a[ j ] + b[ k ];
...
end;

procedure Call()
begin
...
MatrixMult( M, M, M2 ); // т.е. q = a
...
end;

Вопросы такие:
1) значения в массиве q изменяются - будут ли меняться значения в массиве a?
2) что будет, если вместо var использовать out?
3) имеет ли вообще смысл использовать var, out и const для массивов?


 
jack128   (2003-05-02 21:50) [1]


> 1) значения в массиве q изменяются - будут ли меняться значения
> в массиве a?

А проверить самому?
Сделал тест на строках, все нормально в q изменились занчения, а в а остались те же

> 2) что будет, если вместо var использовать out?

при out переменная обнуляется

> 3) имеет ли вообще смысл использовать var, out и const для
> массивов?
Имеет


 
Asteroid   (2003-05-02 23:06) [2]

1) Сделал тест на массивах. Как и предполагал, изменились и в q, и в a :( Заодно нашел выход - достаточно убрать const :)

2) не обнуляется (по крайней мере, массив)

3) thanks


 
jack128   (2003-05-02 23:47) [3]

Странно все это... У тя какая дельфя?


 
Aleks1   (2003-05-03 02:42) [4]

2 jack128 © (02.05.03 23:47)
"Странно все это... "

А странно ли? Насколько помню, утверждение const в списке параметров функции(процедуры) лишь означает обязательство программиста не изменять значение данного параметра внутри функции, посему компиллятор считает себя в праве передать данный параметр по ссылке, а не по значению.


 
Morfein   (2003-05-03 09:06) [5]

>> Aleks1:
Хм, как ты представляешь себе передачу массива по значению? :))
ЗаPUSHить в стэк все элементы? :) Или по регистрам сопроцессора распихать? :))


 
Aldor   (2003-05-03 09:40) [6]

Когда ты передаешь не переменные, а структуры, будь то классы или массивы, ты передаешь только их указатели (сами массивы в стек не пишуться), поэтому const и var влияют только на то, что ты можешь изменить указатель, а менять данные по ссылке можешь как угодно.

P.S. var и out отличаются тем, что аргумент var ты можешь и читать и изменять, а out - только изменять. Удачи.


 
Morfein   (2003-05-03 10:50) [7]

>> Aldor:
Я-то это знаю...


 
Набережных С.   (2003-05-03 14:29) [8]

>Aldor © (03.05.03 09:40)
>var и out отличаются тем, что аргумент var ты можешь и читать и изменять, а out - только изменять

Неужели?


 
evvcom   (2003-05-03 23:57) [9]


> Morfein © (03.05.03 09:06)
> >> Aleks1:
> Хм, как ты представляешь себе передачу массива по значению?
> :))
> ЗаPUSHить в стэк все элементы? :) Или по регистрам сопроцессора
> распихать? :))


В этом есть доля истины. В любом случае в стек пихается указатель на массив, но! Если идет передача массива без const, то в вызываемой процедуре/функции во время инициализации отводится в стеке место под такой же массив и копируется туда все содержимое исходного массива, и дальнейшая работа идет с копией, которая впоследствии уничтожается. Если же массив передается как const, то компилятор считает, что массив действительно меняться не будет, и никакой локальной копии этого массива не делается, поэтому ничего странного в том, что массив A изменялся одновременно с Q.
Если кому это кажется неправдоподобным, смотрите CPU Window. Это разрешит все Ваши сомнения.


 
default   (2003-05-04 00:29) [10]

параметры-константы - это тоже самое что и параметры-значения разве что
нельзя редактировать их стековые копии(явно)
вот код который по-моему это доказывает

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMas = Array[1..3] of Byte;

var
Form1: TForm1;
Mas: TMas = (1, 2, 3);

implementation

{$R *.dfm}

procedure Test(const M: TMas);
begin

PByte(Integer(@M[1]) + 1)^ := 19;
Form1.Caption := IntToStr(M[2]) // Form1.Caption = "19" (меняется значение в стеке)

end;

procedure TForm1.Button1Click(Sender: TObject);
begin

Test(Mas);
Caption := Caption + " : " + IntToStr(Mas[2]) // Mas[2] = 2 (глобальный массив не изменился)

end;

end.

если я не прав то скажите(
всякое бывает







 
evvcom   (2003-05-04 02:06) [11]


> default © (04.05.03 00:29)


Браво! Я оказался немного неправ, заявив "В любом случае в стек пихается указатель на массив". Я никогда не использовал ранее массив общим размером до 4 байт. Посмотрел вышеприведенный пример в D5, и действительно выводится результат "19 : 2". Причина: если массив до 4 байт включительно, то (5 дельфи во всяком случае) компилятор все же передает в функцию/процедуру не указатель, а сами данные (смотрел через CPU Window). Увеличьте размер массива хотя бы до 5 байт и получите результат "19 : 19".
Вывод: используйте данные правильно, чтобы избежать кривотолков. Вполне вероятно, что в последующих версиях какие-либо недокументированные возможности/способности утратятся, а на замену появятся (а может и не появятся) другие. Если есть желание изменить переменную, то объявляйте параметр как var, если она точно постоянная, то const. И не надо слишком много мудрить!


 
default   (2003-05-04 12:49) [12]

to evvcom
Отличная работа!
так даже не подумаешь что для разных размеров переменных компилятор
действует по разному! Теперь будем знать!



 
Нуу   (2003-05-05 01:37) [13]

А если попробовать массив размером 3 байта? Он вроде бы меньше 4-х!
Уже начиная с TurboPascal стандартными размерами являются 1 aka byte, 2 aka word(integer), 4 aka Long.


 
evvcom   (2003-05-05 08:20) [14]


> Нуу (05.05.03 01:37)
> А если попробовать массив размером 3 байта?


Смотри пример default © (04.05.03 00:29)

> TMas = Array[1..3] of Byte;

Это и есть массив в 3 байта. С этого все и началось.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.009 c
1-46806
Chlavik
2003-05-02 13:42
2003.05.15
А как мне найти компонента по его свойтсву Tag ?


1-46725
qqqqq0001
2003-05-04 20:30
2003.05.15
Tfinddialog


1-46773
Pliajnik
2003-04-30 23:55
2003.05.15
Функция перевода чисел из 10-ой системы в 16-ю


3-46606
Rol
2003-04-22 11:08
2003.05.15
TIBDataSet.UpdateRecordTypes


3-46571
Alexis
2003-04-22 18:45
2003.05.15
CachedUpdates, ApplyUpdates & exceptions





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский