我可以在codesys上执行以下操作吗?
声明
VAR
abVariable_A 字节数组[0...15] := [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
abVariable_B ARRAY[1...16] OF BYTE := [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
END_VAR
节目:
abVariable_B := abVariable_A;
abVariable_B 的输出是什么? 我可以期待吗?
ab变量_B
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
或者我会得到?
ab变量_B
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
请注意数组的维度,虽然两者的维度都是 16,但索引并不从同一点开始。这会影响数组的分配吗?
我期待
ab变量_B
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
我们可以通过运行做一个简单的实验:
PROGRAM Test
VAR
abVariable_A: ARRAY[0..15] OF BYTE := [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
abVariable_B: ARRAY[1..16] OF BYTE := [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
pA_before: POINTER TO BYTE;
pB_before: POINTER TO BYTE;
pA_after: POINTER TO BYTE;
pB_after: POINTER TO BYTE;
END_VAR
pA_before := ADR(abVariable_A);
pB_before := ADR(abVariable_B);
abVariable_B := abVariable_A;
pA_after := ADR(abVariable_A);
pB_after := ADR(abVariable_B);
END_PROGRAM
观察结果:
正如我们所看到的,两个数组中的值是相同的,并且数组地址没有改变(这意味着所有值都被复制,而不是像许多其他语言那样仅复制数组引用/指针)。
我们可以通过修改一个数组中的值之一来仔细检查这些值是否已复制并且数组没有指向同一个数组:
abVariable_B := abVariable_A;
abVariable_B[3] := 255;
观察结果:
这个实验表明,codesys 将数组分配视为所有值的内存副本(至少在 CODESYS 3.5.16 中,尚未在旧版本上测试过这一点)。
初始索引对于数组的底层内存布局绝对不重要,它只是为了程序员的方便。然而,对于不同长度的数组却不能这样说:
abVariable_A: ARRAY[0..15] OF BYTE := [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
abVariable_B: ARRAY[1..18] OF BYTE := [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
当我们尝试将
C0032: Cannot convert type 'ARRAY [0..15] OF BYTE' to type 'ARRAY [1..18] OF BYTE'
分配给 abVariable_A
时,会导致 abVariable_B
错误。
如果
abVariable_A
大于 abVariable_B
,则会显示类似的错误。
如果不信任内置数组分配,或者想要处理上述情况,其中数组具有不同的长度,您可以创建一个自定义函数,例如:
FUNCTION ArrayCopy
VAR_INPUT
destination: ANY;
source: ANY;
END_VAR
MEMUtils.MemCpy(pbyDest := destination.pValue, pbySrc := source.pValue, MIN(destination.diSize, source.diSize));
END_FUNCTION
如果我们用它代替赋值:
ArrayCopy(abVariable_B, abVariable_A);
abVariable_B[3] := 255;
结果符合预期:
但请记住,上面的函数需要 MemoryUtils 库,并且只是一个示例。尽管它适用于任何类型的数组,但它也有缺点:
TypeClass
值。