代码1:
var
a, b: Integer;
begin
a := 1;
b := a;
end;提问:在这里是否把b的指针指向a的地址?
代码2:
type
TMyArray = array of string;var
aA, bA: TMyArray;
begin
SetLength(aA, 2);
aA[0] := 'hi';
aA[1] := 'hello';
bA := aA;
end;提问:这里当bA数组改变数值时,是否aA的数值也跟着改变,除非bA的长度改变才会另外复制一份新数据来自己使用?
var
a, b: Integer;
begin
a := 1;
b := a;
end;提问:在这里是否把b的指针指向a的地址?
代码2:
type
TMyArray = array of string;var
aA, bA: TMyArray;
begin
SetLength(aA, 2);
aA[0] := 'hi';
aA[1] := 'hello';
bA := aA;
end;提问:这里当bA数组改变数值时,是否aA的数值也跟着改变,除非bA的长度改变才会另外复制一份新数据来自己使用?
2。aA,bA都可以理解为指针,aA分配了空间,bA指向aA,一切问题都解决了!
1, 不是
2, 應該是
这里当bA数组改变数值时,是否aA的数值也跟着改变:不会,除非bA的长度改变才会另外复制一份新数据来自己使用,不会
简单类型按值传递
引用类型按指针传递
除非用VAR或Const修饰符
//尽管是汇编,但应该并不难看懂.
system单元procedure _DynArrayAsg;
asm
{ ->EAX Pointer to destination (pointer to pointer to heap object }
{ EDX source (pointer to heap object }
{ ECX Pointer to rtti describing dynamic array } PUSH EBX
MOV EBX,[EAX] { Increment ref count of source if non-nil } TEST EDX,EDX
JE @@skipInc
LOCK INC dword ptr [EDX-8]
@@skipInc:
{ Dec ref count of destination - if it becomes 0, clear dest }
TEST EBX,EBX
JE @@skipClear
LOCK DEC dword ptr[EBX-8]
JNZ @@skipClear
PUSH EAX
PUSH EDX
MOV EDX,ECX
INC dword ptr[EBX-8]
CALL _DynArrayClear
POP EDX
POP EAX
@@skipClear:
{ Finally store source into destination }
MOV [EAX],EDX POP EBX
end;
引用类型包括类类型、接口类型、委托类型和数组类型。
在Delphi中应该是一样的。
同意aiirii(ari-爱的眼睛) 的意见
如果aA,bA数组定义为静态数组,那么bA改变,aA不会变。(预先都分配了内存)
如果aA,bA数组定义为动态数组,那么bA改变,aA会变。
我做了例子的没有错。如果aA,bA数组定义为静态数组
那么bA:=aA是赋值
如果aA,bA数组定义为动态数组
那么bA:=aA是引用。
为什么是这样呢?
如果是类的话,是不是也这样呢?
唉
Clone就是引用拷贝(浅表拷贝)。Copy就是值拷贝(深层拷贝),数组必须预先分配数组元素的空间。
在Delphi中用=虽然不区分那种拷贝,但是在编译器中根据对象是否已经分配了数组元素的空间
来决定是否是Clone或Copy。不知道我说的对不对。
我感觉还是觉得学习C#好些。好些似是而非的东西在C#中讲的明白些。也许我说错了。呵呵。
另外,String类型同动态CHAR数组有点相似...但它们赋值也有点区别.
String赋值差不多就是用的这个函数吧..同动态数组赋值比较下异同...procedure _LStrLAsg(var dest; const source);
var
P: Pointer;
begin
P := Pointer(source);
_LStrAddRef(P);
P := Pointer(dest);
Pointer(dest) := Pointer(source);
_LStrClr(P);
end;
也就是要定义成同样的typetype
Arraychar =array[0..100] of char;var
a:arraychar;
b:arraychar;
begin
b:=a;
move ecx 25
rep movsd //COPY 25*4=100字节.
编译器处理成rep movsd 指针,把整块内存COPY一下.