2

我正在尝试分配两个初始化数组evenNumbersoddNumbers数组数组integers

PROGRAM ArrayInit
VAR
    evenNumbers : ARRAY[1..3] OF INT := [2, 4, 6];
    oddNumbers: ARRAY[1..3] OF INT := [1, 3, 5];
    
    integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];
END_VAR

这段代码给了我一个编译器错误

预期数组初始化

当然,我可以integers像这样直接用我想要的数字进行初始化:

PROGRAM ArrayInit
VAR
    integers: ARRAY[1..2] OF ARRAY[1..3] OF INT := [
        [2, 4, 6], [1, 3, 5]
    ];
END_VAR

或者像谢尔盖提到的

PROGRAM ArrayInit
VAR
    integers: ARRAY[1..2, 1..3] OF INT := [
        2, 4, 6, 1, 3, 5
    ];
END_VAR

但是,如果原始数组非常大和/或我想记录这些不同的数组是什么,一个描述性的名称会很好。即integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];很好地表明integers有两个列表,一个是偶数,一个是奇数。

我也尝试过初始化integersintegers: ARRAY[1..2] OF ARRAY[1..3] OF INT := [[evenNumbers], [oddNumbers]];,但这给了我编译器错误:

无法将类型“ARRAY [1..3] OF INT”转换为类型“INT”

现在我想知道这是否可能?如果是这样,有人知道我该怎么做吗?

4

2 回答 2

3

要分配多级数组,您可以在一行中完成。

combinedSet : ARRAY[1..2, 1..2] OF INT := [1,2,3,4];

将导致数组

[
  1 => [
     1 => 1, 
     2 => 2
  ],
  2 => [
     1 => 2, 
     2 => 4
  ]
]

所以首先它分配第一个元素的所有元素[1, 1], [1, 2], [1, 3]... 然后嵌套一个[2, 1], [2, 2], [2, 3]...

附加信息

将 2 个数组合并为一个多维的最简单方法是:

PROGRAM PLC_PRG
    VAR
        arr1 : ARRAY[1..3] OF INT := [1,3,5];
        arr2 : ARRAY[1..3] OF INT := [2,4,6];
        combinedSet : ARRAY[1..2] OF ARRAY[1..3] OF INT;
    END_VAR
    
    combinedSet[1] := arr1;
    combinedSet[2] := arr2;
END_PROGRAM

这不起作用的原因

integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];

因为在使用的时候evenNumbersoddNumbers没有初始化。如果您在其中声明它们VAR CONSTANT可能会起作用,但是您将无法在程序中更改这些数组的内容。

于 2021-11-05T14:46:58.187 回答
2

我认为您不能在初始化第三个数组时加入数组(请参阅下面的编辑)。然而,你可以做的是在程序开始时调用一个函数,一旦加入这两个数组:

PROGRAM PLC_PRG
VAR
    arr1: ARRAY [0..2] OF INT := [1, 2, 3];
    arr2: ARRAY [0..2] OF INT := [4, 5, 6];
    arr3: ARRAY [0..5] OF INT;
    initialized: BOOL := FALSE;
END_VAR

IF (NOT initialized) THEN
    initialized := TRUE;
    JOIN_INT_ARRAYS(arr1 := arr1, arr2 := arr2, dest_arr := arr3);
END_IF
// Assume that:
//      - the destination ARRAY size can fit all source ARRAYs
//      - all ARRAYs store INTs
FUNCTION JOIN_INT_ARRAYS
VAR CONSTANT
    size_of_int: DWORD := SIZEOF(INT);
END_VAR
VAR_IN_OUT
    arr1: ARRAY [*] OF INT;
    arr2: ARRAY [*] OF INT;
    dest_arr: ARRAY [*] OF INT;
END_VAR
VAR
    arr1_len: DWORD := DINT_TO_DWORD(UPPER_BOUND(arr1, 1) - LOWER_BOUND(arr1, 1) + 1) * size_of_int;
END_VAR

MEMUtils.MemCpy(pbySrc := arr1, pbyDest := dest_arr, dwSize := arr1_len);
MEMUtils.MemCpy(pbySrc := arr2, pbyDest := dest_arr + arr1_len, dwSize := DINT_TO_DWORD(UPPER_BOUND(arr2, 1) - LOWER_BOUND(arr2, 1) + 1) * size_of_int);

结果:

结果.png

需要注意的几点:

  • 我使用MemCpyMEMUtils库中的函数。如果您没有它,或者不想将它添加到您的项目中,您可以使用FOR循环手动将值从一个数组复制到另一个数组。
  • 我省略了范围检查,这可能非常危险。如果您想要额外的保护,请自行添加。
  • 避免arr_dest作为arr1or传递arr2。尝试从数组复制到自身可能会导致问题。

编辑:

实际上,这似乎有效:

integers: ARRAY [0..1] OF ARRAY [0..2] OF INT := [[2, 4, 6], [1, 3, 5]];
evenNumbers: ARRAY [0..2] OF INT := integers[0];
oddNumbers: ARRAY [0..2] OF INT := integers[1];

结果:

结果1.png

但我不知道这是否是你想要的结果。如果你想要一个连续数组作为组合数组,那么你可以试试这个:

// in Program
evenNumbers: ARRAY [0..2] OF INT := [2, 4, 6];
oddNumbers: ARRAY [0..2] OF INT := [1, 3, 5];
integers: ARRAY [0..5] OF INT := JOIN_INT_ARRAYS_3_3_6(arr1 := evenNumbers, arr2 := oddNumbers);
// (left)3 + (right)3 = (result)6
FUNCTION JOIN_INT_ARRAYS_3_3_6 : ARRAY [0..5] OF INT
VAR_IN_OUT
    arr1: ARRAY [0..2] OF INT;
    arr2: ARRAY [0..2] OF INT;
END_VAR
VAR
    i: USINT;
END_VAR

FOR i := 0 TO 2 DO
    JOIN_INT_ARRAYS_3_3_6[i] := arr1[i];
END_FOR
FOR i := 0 TO 2 DO
    JOIN_INT_ARRAYS_3_3_6[i + 3] := arr2[i];
END_FOR

结果:

结果2.png

但是,这种方法不能通用,所以每次条件变化都得修改它的输入输出数组大小,如果你想在多个地方使用它,就创建很多,这样不优雅,而且我个人会避免它,但如果这对你有用,那么就在这里。

此外,这似乎给了我一个C0441: Access to uninitialized VAR_IN_OUT variable警告,所以另一个尝试避免它的理由。

于 2021-11-05T15:52:09.380 回答