PDA

View Full Version : سوال: تبادل مقادیر بین دو متغیر Variant



mbshareat
دوشنبه 20 آبان 1387, 11:12 صبح
من قبلا با VB کار می کردم و حالا در دلفی به چیزی شبیه Swap در بیسیک نیاز دارم.
فکر کنم اشکالی که به آن برخورد کردم این بود که پارامتر از نوع خروجی (Out) وقتی برای نوع
Variant تعریف شود دیگر نمی تواند هر نوعی را به عنوان پارامتر قبول کند.:اشتباه:
مثلا اگر بخواهم یک متغیر از نوع داده Integer را به تابع یا رویه ارسال کنم اشکال عدم تطابق نوع می گرفت.:گیج:
درضمن من نمی دانم آیا در دلفی پارامتر از نوع ورودی/خروجی هم داریم یا نه؟لطفا من رو راهنمایی کنین.:کف:

vcldeveloper
دوشنبه 20 آبان 1387, 16:24 عصر
فکر کنم اشکالی که به آن برخورد کردم این بود که پارامتر از نوع خروجی (Out) وقتی برای نوع
Variant تعریف شود دیگر نمی تواند هر نوعی را به عنوان پارامتر قبول کند.

وقتی پارامتری را بصورت var یا out تعریف می کنید، باید نوع داده ایی که به تابع میدید، دقیقا برابر نوع داده تعریف شده باشه. کد تابعی که نوشتید، و چگونگی استفاده از آن را بزارید شاید راه حل بهتری بشه براش در نظر گرفت، مثلا یکی از راههاش میتونه استفاده از untyped parameters باشه.


درضمن من نمی دانم آیا در دلفی پارامتر از نوع ورودی/خروجی هم داریم یا نه؟
بجای out از var استفاده کنید.

mbshareat
دوشنبه 20 آبان 1387, 22:00 عصر
:خجالت::تمام كد يونيت را می گذارم


unit Unit1;

interface

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

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
Procedure Swapx(var a,b:Variant);
var
Form1: TForm1;

implementation

{$R *.dfm}

Procedure Swapx(var a,b:Variant);
Var
C:Variant;
Begin
C:=a;
a:=b;
B:=c;
End;
procedure TForm1.FormCreate(Sender: TObject);
Var
A,B:Integer;
begin
A:=1;
B:=2;
SwapX(A,B);
Label1.Caption:=Format('%d',[a]);
end;

end.

vcldeveloper
سه شنبه 21 آبان 1387, 03:07 صبح
دلفی یک زبان به اصطلاح Strongly-typed هست. برای همین هم روی نوع داده ها سخت گیری میکنه. در دلفی کار بالا در صورتی انجام پذیر هست که مقادیر پاس داده شده به تابع Swap هم Variant باشند. البته چون Variant هستند، می توانند حاوی هر نوع داده ایی (غیر از Pointer و Class) باشند، ولی نوع آنها باید Variant باشه، پس مثلا کد بالا به این شکل تغییر میکنه:


var
A,B: Variant;
begin
A:=1;
B:=2;
SwapX(A,B);
Label1.Caption:= A;
end;


راه دیگه اینه که از untyped parameter، با مشخص کردن اندازه پارمترها، کار کنید:


procedure Swap(var X, Y; Size: Word);
var
Z : TBytes;
begin
SetLength(Z,Size);
Move(X,Z[0],Size);
Move(Y,X,Size);
Move(Z[0],Y,Size);
end;
این کد مقادیر X و Y را با هم تعویض می کند، ولی نیاز دارد که طول داده های X و Y از قبل برای آن مشخص شود:


var
X, Y : integer;
begin
X := 10;
Y := 15;
Swap(X,Y, SizeOf(X));
ShowMessage(IntToStr(X));
end;
البته کد بالا با داده هایی که بطور خودکار مدیریت میشند (مثل string) هم بدون مشکل کار میکنه، و نیازی به مشخص کردن سایز نداره:


var
X, Y : string;
begin
X := ' This is X';
Y := 'And this is Y';
Swap(X,Y,1);
ShowMessage(X);
end;



آیا ممکنه پارامتری مانند Out V:Variant به روتین یا تابعی ارسال کرد و بعد با تعریف مثلا
Var PI:PVariant مقدار V را دستكاری كرد؟
بله، ولی این کار توصیه نمیشه، چون نوع داده Variant بطور خودکار توسط دلفی مدیریت میشه، و ایجاد تغییر در داده های آن باعث ایجاد اخلال در مدیریت دلفی بر روی این نوع داده میشه، غیر از اینکه دقیقا با ساختار آن آشنا باشید، و بدونید چه کار می کنید، و کار شما چه تاثیراتی دارد.