为什么有些语言需要分号?

时间:2011-01-15 17:48:33

标签: programming-languages

我知道分号表示像Java这样的语言的行结尾,但为什么呢?

我被其他人问了很多,而且我真的想不出一个好方法来解释它如何比仅使用换行符或空格更好。

7 个答案:

答案 0 :(得分:16)

他们没有发出结束信号,他们发出声明的结束。

有些语言不需要它们,但这些语言不允许单行或单个语句上的多个语句跨越多行(没有其他信号,如VB的_信号)。

为什么某些语言允许多行语句?理念是空白是无关紧要的(行尾字符是空格)。这样可以灵活地设置代码的格式,因为格式化不是语义的一部分。

答案 1 :(得分:12)

首先,分号是一个语句分隔符,而不是行分隔符。有些语言使用新行字符作为语句分隔符,但忽略所有空格的语言倾向于使用分号。

为什么语言会忽略空格?

语言忽略空格以允许程序员根据自己的喜好格式化源代码。例如,在Java中,

之间没有区别
if (welcome)
    System.out.println("hello world");

if (welcome) System.out.println("hello world");

这不是因为在语言的语法中每个都有一个单独的案例,但因为空格被忽略了。

为什么编程语言需要语句分隔符?

这是问题的核心。要理解它,让我们考虑一种没有任何语句分隔符的小语言。它包含以下语句类型:

var x = foo()
y[0, 1] = x
bar()

此处,y是一个二维数组,x被写入y的其中一个条目。

现在让我们看一下编译器会看到的这些语句:

var x = foo() y[0, 1] = x bar()

因为没有语句分隔符,所以编译器必须自己识别每个语句的结尾,以理解输入。编译器能够这样做吗?我猜在上面的例子中编译器可以做到。

现在,让我们在语言中添加另一种语句:

[x, y] = ["hello", "world"]

多重分配允许程序员一次分配多个值。在此行之后,变量x将包含值"hello",而变量y包含"world"。这可能非常方便允许函数的多个返回值。现在,它如何与剩余的语句类型一起工作?

考虑以下语句序列:

foo()
[x, y] = [1, 2]

首先,我们调用方法foo。之后,我们将1分配给x,将2分配给y。至少这是我们打算做的。这是编译器看到的内容:

foo() [x, y] = [1, 2]

编译器能够识别每个语句吗?不,至少有两种可能的解释。第一个是我们想要的。这是第二个:

foo()[x, y] = [1, 2]

这是什么意思?首先,我们调用方法foo。该方法应该返回一个二维数组。现在,我们将数组[1, 2]写在返回数组中的[x, y]位置。

编译器无法识别语句,因为给定输入至少有两种有效解释。当然,这绝不应该在真正的编程语言中发生。在给定的示例中,它可能很容易解决,但重点是,如果没有语句分隔符,则很难设计编程语言。这很难,因为语言设计者必须考虑语句类型的所有可能的排列,以确保语言不含糊。

因此,语句分隔符有助于语言设计者最初设计语言,但更重要的是,它允许语言设计者在将来轻松扩展语言,例如通过添加新的语句类型。这是一件大事,因为一旦用您的语言编写代码,您就不能简单地更改现有语句类型的语法,因为这将导致所有现有代码不再编译。

TL; DR

总结一下,分号是在空格忽略语言时作为语句分隔符引入的,因为设计和扩展具有语句分隔符的语言更容易。

答案 2 :(得分:8)

许多语言允许您根据需要添加多少间距。这使您可以控制代码的外观。

考虑:

 String result = "asdfsasdfs"
               + "asdfs"
               + "asdfsdf";

由于您可以插入额外的换行符,因此可以将该行划分为多行而不会出现问题。语言仍然需要知道行已完成,这就是你需要分号的原因。

答案 3 :(得分:1)

语言会这样做,因为它表示statement的结束,而不是line的结尾,这意味着您可以压缩代码,使其更小并占用更少的空间。

获取C ++代码(#include <iostream>):

for(int i = 0; i < 5; ++i){
    std::cout << "did you know?" << std::endl; 
    std::cout << "; signifies **end of statement**" << std::endl;
    std::cout << "**not the end of the line**" << std::endl;
}

也可以写成

for(int i = 0; i < 5; ++i){std::cout << "did you know?" << std::endl; std::cout << "; signifies **end of statement**" << std::endl; std::cout << "**not the end of the line**" << std::endl;}

答案 4 :(得分:1)

一些编程语言使用它来表示语句的结束,从而使语言从语句的角度看不出白色空间。在中期要承担的一件事是,如果在编译时你要检查新行或分号,那么你必须评估几种不同的情况&#34;编译器可能会得到你想做的错误,并且需要花费更长的时间来查找这些情况,而不是简单地在语句的末尾查找分号。一些更高级别的语言尝试减少分号使用或完全删除它以节省一些击键,这种语言更倾向于程序员的舒适度,并且通常带有各种语法糖;有人可能会争辩说,不使用分号是一种语法糖。 在语言中使用或不使用分号应该根据语言试图完成的内容,C和C ++等语言主要是关于性能,Java和C#在抽象意义上比C和C ++高一点然后我们有像Scala,Python和Ruby这样的东西,它们主要是为了让编程更加舒适而牺牲性能,(Ruby公开承认这一点,而且它在Python上非常明显)。 那么为什么有些语言需要&#34;分号?

  • 使编译更容易
  • 该语言的设计者认为它更加一致
  • 历史原因(例如,Java,C#和C ++也是C&C的孩子)

最后一件事是Javascript实际上在编译期间或IIRC之前添加了分号,所以它实际上并不是分号。

答案 5 :(得分:0)

简短回答:

  

因为其他人都这样做了。

理论上,语言的语句是语言设计者在解析文件时能够语法解释的语句。因此,如果语言设计者不想使用分号,则可以使用句点,短划线,空格,换行符或任何其他来表示语句的分离。

语言设计师经常使语法易于理解,以便它变得流行。

Wikipedia: Semicolon Usage in Computer Languages

因此,如果某个语言设计者创建了一种使用':-)'来表示语句结束的语言,那么1)难以阅读; 2)不习惯已经习惯使用';'的人。

回声“小心”: - )

答案 6 :(得分:0)

  

简短回答:

     
    

因为其他人都这样做了。

  

不是,也不是每个人。此外,许多流行的语言,如Python,Ruby或Visual Basic,不使用分号作为语句结尾但换行符。许多人,而不是&#34;每个人&#34;仍然使用分号,因为历史原因,而不是理性论证:分号在第一个计算时代取代穿孔卡格式有重要作用,但今天它可以完全丢弃。 / p>

事实上,有两种流行的方式来指定陈述的结尾:

  1. 使用分号。
  2. 原样离开。这使得编译器读取换行符作为语句结束。如果要将语句扩展到多行,只需使用特殊字符(如Python中的\)来表示语句尚未完成。
  3. 为了使代码更具可读性,使用特殊字符指定语句结尾应该是一个例外,而不是规则。