在我使用 IFM PLC 的一些项目中,我遇到了以下代码:
someArray:ARRAY [6..8] OF BYTE;
Run Code Online (Sandbox Code Playgroud)
当我在断点处检查数组时,我发现它具有三个元素:
someArray[6] = 0
someArray[7] = 0
someArray[8] = 0
Run Code Online (Sandbox Code Playgroud)
我一生都无法理解为什么有人会这样做,或者为什么这是可能的。我从来没有见过这样的事情。我没有进一步的来源可以帮助我理解它的用途(缺少部分),但这就是它的声明和使用方式。我查看了文档,也找不到原因。
为什么这是可能的,在什么情况下你会想要这样的数组?
CODESYS 有一篇文章说
... 结构化文本基于 Pascal 编程语言 ...
Pascal 同样允许任何起始索引,例如:
temperature = array [-10 .. 50] of real;
Run Code Online (Sandbox Code Playgroud)
这就是codesys 允许这样做的原因。
不过,这种功能的存在也是有原因的:
大多数程序员都习惯数组索引从 0 开始,但是这里有一篇文章列出了从 1 开始计算索引的语言。它们中的大多数是供非程序员使用的,例如数学家、工程师等,codesys 也不例外(为什么梯形逻辑存在:P)。
如果开发人员不厌其烦地允许从 0 或 1 开始,不妨将其扩展到用户想要的任何位置。
您可能希望将数组中的索引与实际标识符相关联。例如,假设您有 2 个设备和一个由 2 个布尔值组成的数组(表示设备是否正在运行),并且这些设备放置在容器 #2 和 #3 中,而容器 #1 没有此类设备。您可以创建 2 个单独的变量(例如dev2, dev3),或者您可以创建一个 2 的数组并记住索引 0 代表设备 2,索引 1 代表设备 3,或者您可以创建一个大小为 4 的数组(0, 1, 2 , 3) 并忽略前 2 个元素,或者您可以创建一个从 2 到 3 包含 2 个元素的数组 ( :ARRAY [2..3] OF BOOL;)。
这种语言功能只是为您提供了更多表达意图的选项,如果您不喜欢它,则不必使用它(但请注意,如果您在函数中接受任何大小的数组,请不要忘记使用该LOWER_BOUND功能:D)
最后,如果您必须使用其他人的数组并且绝对讨厌它的起始索引不为 0 的想法,因为数组本质上是带有(编译时)元数据的指针,您可以将数组转换为指针,并将该指针用作一个数组,您必须从 0 开始访问它:
arr: ARRAY [7..13] OF INT := [7, 8, 9, 10, 11, 12, 13];
up_bound: DINT := UPPER_BOUND(arr, 1) - LOWER_BOUND(arr, 1);
ptr: POINTER TO INT := ADR(arr);
i: DINT;
str: STRING;
// ---
str := '[';
FOR i := 0 TO up_bound - 1 DO
str := CONCAT(str, INT_TO_STRING(ptr[i]));
str := CONCAT(str, ', ');
END_FOR
str := CONCAT(str, INT_TO_STRING(ptr[i]));
str := CONCAT(str, ']');
Run Code Online (Sandbox Code Playgroud)
上面例子的结果是:
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |