Delphi2005 study notes 3 - an array parameters

xiaoxiao2021-03-06  61

There is the following code: Procedure change (A: array of int32); procedure change0 (var A: array of int32); type ta = array [0..10] of int32; procedure change2 (A: Ta); Procedure Change3 (Var A: ta);

Var aa: ta; bb: array of int32;

IMPLEMENTATION

{$ Autobox on}

Procedure Change (A: Array of Int32); Begin A [0]: = 123; A: = BB; END;

Procedure Change0 (VAR A: Array Of Int32); Begin A [0]: = 123; A: = BB; END;

Procedure Change2 (A: Ta); Begin A [0]: = 123; A: = BB; END;

Procedure change3 (var A: ta); begin a [0]: = 123; A: = BB; END; then perform the following statement setLength (BB, 11); bb [0]: = 5678;

AA: = TA (& Array.createInstance); AA [0]: = 0; Change (aa); MessageBox.show (aa [0] .tostring ()); if & object (aa) = & Object (bb) Then MessageBox.show ('=');

AA: = TA (& Array.createInstance); AA [0]: = 0; Change0 (AA); MessageBox.show (AA [0] .tostring ()); if & object (aa) = & Object (bb) Then MessageBox.show ('=');

AA: = TA (& Array.createInstance (TypeOf (INT32), 11)); AA [0]: = 0; Change2 (AA); MessageBox.show (aa [0] .tostring ()); if & object (aa) = & Object (bb) Then MessageBox.show ('=');

AA: = Ta (& Array.createInstance); AA [0]: = 0; Change3 (AA); MessageBox.show (AA [0] .tostring ()); if & object (aa) = & Object (bb) Then MessageBox.show ('='); the result discovers that the Array Of INT32 method can change the value of the array element, but can not change the number of group-in-array forms stored in the array variable, and output 123Var Array Of INT32 can change array. The value, but also change the number of groups stored in the array variable, output 5678, and = TA mode, and cannot change the value of the array element, but it is very strange, AA and BB point to the same array, output 0 and = var TA mode Change the value of the array element, but not 5678 but 123; but AA and BB points to the same array, output 123 and = anti-assembly results Method public static void change (int32 [] a) Cil Managed {// code size: 13 byte (s) .maxstack 3 l_0000: ldarg.0 l_0001: ldc.i4.0 l_0002: ldc.i4.s 123 l_0004: STELEM.I4 L_0005: ldsfld int32 [] Winform.Units.winform :: bb l_000a: starg . SA L_000c: Ret} .method public static void change0 (int32 [] & a) CIL Managed

{

// Code Size: 14 byte (s)

.MAXSTACK 3

L_0000: ldarg.0

L_0001: ldind.ref

L_0002: ldc.i4.0

L_0003: ldc.i4.s 123

L_0005: STELEM.I4

L_0006: ldarg.0

L_0007: ldsfld int32 [] Winform.Units.winform :: bb

L_000c: stind.ref

L_000d: Ret

}

.method public static void change2 (INT32 [] a) CIL Managed

{

// Code Size: 42 byte (s)

.MAXSTACK 4

.locals

INT32 NUM1)

L_0000: ldarg.0

L_0001: Callvirt Instance Object [Mscorlib] System.Array :: Clone ()

L_0006: CastClass Int32 []

L_000b: starg.s a

L_000d: ldarg.0

L_000e: ldc.i4.0

L_000f: ldc.i4.s 123

L_0011: STELEM.I4

L_0012: ldsfld int32 [] winform.Units.winform :: bb

L_0017: DUP

L_0018: ldlen

L_0019: STLOC.0

L_001a: ldarg.0

L_001b: ldloc.0

L_001c: ldc.i4.s 11

L_001e: ble.s l_0023

L_0020: ldc.i4.s 11

L_0022: STLOC.0

L_0023: LDLOC.0

L_0024: Call void [mscorlib] System.Array :: copy ([mscorlib] system.Array, [mscorlib] system.Array, int32) L_0029: Ret

}

.method public static void change3 (int32 [] & a) CIL MANAGED

{

// Code Size: 31 byte (s)

.MAXSTACK 4

.locals

INT32 NUM1)

L_0000: ldarg.0

L_0001: ldind.ref

L_0002: ldc.i4.0

L_0003: ldc.i4.s 123

L_0005: STELEM.I4

L_0006: ldsfld int32 [] winform.Units.winform :: bb

L_000b: DUP

L_000c: ldlen

L_000d: STLOC.0

L_000e: ldarg.0

L_000f: ldind.ref

L_0010: ldloc.0

L_0011: ldc.i4.s 11

L_0013: ble.s l_0018

L_0015: ldc.i4.s 11

L_0017: STLOC.0

L_0018: LDLOC.0

L_0019: Call void [mscorlib] System.Array :: copy ([mscorlib] system.Array, [mscorlib] system.Array, int32)

L_001e: Ret

}

Conclusion: Use the Array Of Int32 mode, actually correspond to the variable number of parameters of the C #, that is, params INT32 [], this parameter method is the first address of the array (ie, the value of the parameter), not the first address of the group The address of the variable plus VAR modifications, i.e., joining the REF modification, transmitting the address of the number of variables that store the number of groups (ie, the address of the parameter variable itself) uses the TA mode, and the value of the array is cloned in the function inside the function, neither change The first address of the array does not change the value of the original array to the VAR modification, which seems to be delivered to the address of the variable itself. It still doesn't understand why. Corresponding C # code is public static void change (params int [] a)

{

a [0] = 0x7b;

A = WinForm.bb;

}

Public static void change0 (params ref int [] a)

{

a [0] = 0x7b;

A = WinForm.bb;

}

Public static void change2 (int [] a)

{

A = (int []) a.clone ();

a [0] = 0x7b;

INT Num1 = Winform.bb.Length;

IF (Num1> 11)

{

Num1 = 11;

}

Array.copy (WinForm.bb, A, Num1);

}

Public Static Void Change3 (Ref Int [] a)

{

a [0] = 0x7b;

INT Num1 = Winform.bb.Length;

IF (Num1> 11)

{

Num1 = 11;

}

Array.copy (WinForm.bb, A, Num1);

}

转载请注明原文地址:https://www.9cbs.com/read-84899.html

New Post(0)