Reputation: 2979
I'm trying to assign two initialized arrays evenNumbers
and oddNumbers
to an array of arrays 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
This code gives me a compiler error
Array initialisation expected
Of course I can directly initialize integers
with the numbers that I want like so:
PROGRAM ArrayInit
VAR
integers: ARRAY[1..2] OF ARRAY[1..3] OF INT := [
[2, 4, 6], [1, 3, 5]
];
END_VAR
or like Sergey mentioned
PROGRAM ArrayInit
VAR
integers: ARRAY[1..2, 1..3] OF INT := [
2, 4, 6, 1, 3, 5
];
END_VAR
However, if the original arrays are very big and/or I want to document what these different arrays are, a descriptive name would be nice. I.e. integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];
nicely shows that the integers
has two lists, one with even and one with odd numbers.
I've also tried to initialize integers
as integers: ARRAY[1..2] OF ARRAY[1..3] OF INT := [[evenNumbers], [oddNumbers]];
, but this gives me the compiler error:
Cannot convert type 'ARRAY [1..3] OF INT' to type 'INT'
Now I wonder if it even possible? If so, does anyone know how I can do it?
Upvotes: 4
Views: 3542
Reputation: 1189
Your line integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];
works fine when evenNumbers
and oddNumbers
are constants. You cannot use non-constant variables to initialize other variables.
In case you need evenNumbers
and oddNumbers
to be changed later, you could create two constants evenNumbersConst
and oddNumbersConst
and use them just for the initialization like so:
VAR
evenNumbers : ARRAY[1..3] OF INT := evenNumbersConst;
oddNumbers : ARRAY[1..3] OF INT := oddNumbersConst;
integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbersConst, oddNumbersConst];
END_VAR
VAR CONSTANT
evenNumbersConst : ARRAY[1..3] OF INT := [2, 4, 6];
oddNumbersConst : ARRAY[1..3] OF INT := [1, 3, 5];
END_VAR
Upvotes: 3
Reputation: 1734
I don't think you can join arrays while initializing a third (see the edit below). What you can do however is call a function at the start of the program once that joins those two arrays:
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);
Result:
A few things to note:
MemCpy
function from the MEMUtils
library. If you don't have it, or don't want to add it into your project, you can manually copy values from one array into another using a FOR
loop.arr_dest
as arr1
or arr2
. Trying to copy from an array into itself may lead into problems.Actually, this seems to work:
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];
result:
But I don't know if this is your desired outcome. If you want a continuous array as the combined array, then you can try this:
// 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
and the result:
However, with this method the function can't be general, so you will have to modify it's input and output array sizes every time the conditions change, and create many if you want to use this in several places, thus it's not elegant, and personally I'd avoid it, but if this works for you, then here it is.
Also, this seems to give me a C0441: Access to uninitialized VAR_IN_OUT variable
warning, so another reason to try to avoid it.
Upvotes: 2
Reputation: 3080
To assign multiple level array you do it in one line.
combinedSet : ARRAY[1..2, 1..2] OF INT := [1,2,3,4];
will result in array
[
1 => [
1 => 1,
2 => 2
],
2 => [
1 => 2,
2 => 4
]
]
SO first it assign all element of first element [1, 1]
, [1, 2]
, [1, 3]
... and then nest one [2, 1]
, [2, 2]
, [2, 3]
...
Additional information
Most simple way to merge 2 arrays into one multi dimensional is:
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
The reason this does not work
integers : ARRAY[1..2] OF ARRAY[1..3] OF INT := [evenNumbers, oddNumbers];
Because evenNumbers
and oddNumbers
are not initialized at the moment of use. If you would declare those in VAR CONSTANT
it would probably work but then you would not be able to change content of those arrays in program.
Upvotes: 4