为什么单元格数组中的尾随逗号有效Matlab语法?

时间:2015-09-29 16:59:13

标签: arrays matlab syntax operators cell-array

今天我很惊讶发现

A = {1,2,3}

B = {1,2,3,}

都是MATLAB中的有效语法。我原以为第二个语句会产生错误。尽我所知,他们生成相同的单元格数组(all([A{:}]==[B{:}])返回true)。

是否有理由允许使用第二种语法?这是解析器中的错误吗? AB真的相同吗?

有趣的是,以下是允许:

C = {1,2,3,,,}

3 个答案:

答案 0 :(得分:21)

这些是更多的猜测,而不是答案。

可以检查Symbol reference并发现逗号, 可以用作

命令或声明分隔符

  

要在同一行输入多个MATLAB命令或语句,   用逗号分隔每个命令或语句:

     

for k = 1:10, sum(A(k)), end

在第

B = {1,2,3,}

因此,在3之后的语句中,只有},这意味着单元格数组的结尾,这是一个有效的语句。

分号; 有三种官方用法:

数组行分隔符

  

在方括号内使用时,可以创建新数组或连接   现有数组,分号在数组中创建一个新行:

     

A = [5, 8; 3, 4]

输出抑制

  

当放在命令末尾时,分号告诉MATLAB不要   显示该命令的任何输出。在这个例子中,MATLAB没有   显示生成的100×100矩阵:

     

A = ones(100, 100);

命令或声明分隔符

  

与逗号运算符一样,您可以输入多个MATLAB命令   用分号分隔每个命令的一行。 MATLAB抑制   这些命令的输出以分号结束,并显示   命令的输出以逗号结尾。

     

在此示例中,变量A和C的赋值以终止   分号,因此不显示。因为B的分配是   以逗号结束,显示此命令的输出:

     

A = 12.5; B = 42.7, C = 1.25;

所以在行

x = {1,2,3,;5,6,7}

它遵循3,之后的有效语句数组行分隔符。之后会出现一个新的陈述,在这种情况下是双 5 。有效的。

现在考虑案例

x = {1,2,3,;;;;4,5,6;;;}

如上所述,3,跟在语句数组行分隔符之后,之后的语句大概是从某些底层程序借来的null statement - NOP C 写的核心,基本上意味着:什么都不做。所以在3,;跟随三次“什么都不做”后,才会出现下一个声明。 毫无意义,正如Matlab告诉你的那样:不需要额外的分号。 - 但是有效。

它还允许你毫无意义的事情:

if true
    ;
end

大概是也是

的原因
C = {1,2,3,,,} 

返回错误,因为逗号,不是空语句,但在第一个逗号之后会有一个语句。

底线:它看起来很奇怪,但实际上对我来说似乎是逻辑,因为Matlab在内部使用了很多C-Code并考虑了null语句,所提到的一切都是有效的语法。

其他语言怎么样?

像Python中的x = [1,2,3,;;;;4,5,6;;;]一样使用的半冒号即使在预期的Matlab克隆 numpy 中也是无效的,除非包含在这种不常见的语法a = np.matrix('1,2,3;4,5,6')中。

a = np.matrix('1,2,3,;;;;4,5,6;;;')

也会抛出错误,因为;在任何情况下都被解释为数组行分隔符,这会让编译器抱怨行不一致的行大小。

然而,

x = [1,2,3,]

也是PythonIronPython中的有效语法,正如VBScript中提到的Lua和{{1}}一样。所有这些语言有什么共同之处?它们是在运行时解释的所有(或多或少)脚本语言。这不仅仅是Matlab。因此,OP的兴奋仍然没有原因。

答案 1 :(得分:4)

许多语言已经在列表中允许一个额外的元素分隔符。但这与运行时解析无关。甚至C都允许。它与易用性有关。此功能旨在帮助用户。例如,在C中,您可以如下定义enum

enum E {
   a,
   b,
   c,
};

c之后的逗号不是必需的,但允许使用逗号。这样可以更轻松地从这样的列表中添加和删除元素,并且可以更容易地以编程方式生成这样的列表(mlepage's answer是正确的!)。

因此,在大多数(如果不是全部)编程语言中,最后都允许使用一个逗号是很常见的,MATLAB也支持它。列表开头的逗号不太有意义,但我想他们支持它,因为它也不会对它造成伤害。

连续多个逗号没有意义,这意味着还有其他未指定的元素。

但是,多个分号又是怎么回事呢?与Luis Mendo mentioned一样,[1;;2]是合法语法。这与其他语言的确有很大的出入。

但是,这与MATLAB对换行符的使用是一致的。在MATLAB中,换行很重要。使用[]定义数组时,换行符指示新的数据行:

M = [ 1, 2, 3,
      4, 5, 6,
      7, 8, 9,
    ];

相同
M = [1,2,3; 4,5,6; 7,8,9];

(请注意,有时有时在每行的末尾允许逗号会很方便。)

(还要注意,我在这里使用[]进行串联,完全相同的逻辑适用于{}。)

但是因为MATLAB希望尽可能地允许它,只要它保持明确,上面的内容就是:

M = [ 1, 2, 3,
      4, 5, 6,


      7, 8, 9,
    ];

如果允许使用空行并没有什么坏处,为什么不允许使用空行呢?

由于每个换行符都对应一个分号,因此以上内容与以下内容相同:

M = [ 1, 2, 3,;...
      4, 5, 6,;...
              ;...
              ;...
      7, 8, 9,;...
    ];

相同
M = [ 1, 2, 3,; 4, 5, 6,; ; ; 7, 8, 9,; ];

所以MATLAB必须能够解析它,无论它是否有意义。


thewaywewalk's answer的反驳:

该论点是,;都被定义为语句分隔符,但是以某种方式假定;;;是有效语句,而,,,不是有效语句。这根本不是真的:

disp(0),,,disp(1)
disp(0);;;disp(1)

都是有效的MATLAB语法(R2017a解析两者都没有错误)。

此外,答案使expressionsstatements感到困惑。 disp(0)是一个声明。该语句中的0是一个表达式。在M=[1,2,3]中,用逗号分隔的内容是表达式,而不是语句。那里的逗号不能用作语句分隔符。

实际上,在MATLAB中,逗号和分号根据上下文具有多种含义。语句(包括空语句)末尾的逗号和分号与串联表达式([1,2;3,4])中的逗号和分号不同。而且逗号还可以在不允许使用分号的函数调用括号内分隔表达式。

只需阐明这一点:

1,,,4

有效,而

[1,,,4]

不是。这两个语句中的逗号具有不同的功能。

简而言之,该答案中使用的逻辑完全不正确。

答案 2 :(得分:2)

如果要从其他代码生成代码,则允许在语言中使用尾随标点符号很方便。

例如,Lua允许使用尾随逗号,因此生成Lua代码很容易。

生成代码中没有特殊情况可以省略最后一个逗号,您可以为每个项目打印ITEM-THEN-COMMA。