CODESYS:我可以分配并数组到另一个数组吗?

问题描述 投票:0回答:1

我可以在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]

arrays variable-assignment assign codesys
1个回答
0
投票

我们可以通过运行做一个简单的实验:

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
    值。
  • 它假设数组是一维的,或者如果是多维的,则每个维度的边界必须匹配,否则结果的顺序将是错误的。
  • 它假设数组元素具有相同类型。
  • 它假设数组元素是值类型,换句话说,不是指针/引用。如果使用指针数组,指针将被复制,但指针指向的底层值将保持不变,所以要小心。
© www.soinside.com 2019 - 2024. All rights reserved.