C# C中的分号#

C# C中的分号#,c#,C#,为什么C#中每一行的末尾都需要分号? 为什么编译器不能只知道每行的结束位置?行结束符字符将使您能够在多行之间打断语句 另一方面,像VB这样的语言有一个行延续字符。我个人认为,用分号结束语句比继续使用下划线要干净得多。因此,除了标识符和关键字等内部内容外,空格并不重要。这是多少个语句 for (int i = 0; i < 100; i++) // <--- should there be a semi-colon here? Console.WriteLine("foo") 对于(

为什么C#中每一行的末尾都需要分号?
为什么编译器不能只知道每行的结束位置?

行结束符字符将使您能够在多行之间打断语句


另一方面,像VB这样的语言有一个行延续字符。我个人认为,用分号结束语句比继续使用下划线要干净得多。

因此,除了标识符和关键字等内部内容外,空格并不重要。

这是多少个语句

for (int i = 0; i < 100; i++) // <--- should there be a semi-colon here?
Console.WriteLine("foo")

对于(int i=0;i<100;i++)/否,编译器不知道换行符用于语句终止,也不应该知道。如果愿意,它允许您将语句带到多行

见:

或者大型方法重载如何:

CallMyMethod(thisIsSomethingForArgument1,
             thisIsSomethingForArgument2,
             thisIsSomethingForArgument2,
             thisIsSomethingForArgument3,
             thisIsSomethingForArgument4,
             thisIsSomethingForArgument5,
             thisIsSomethingForArgument6);
相反,分号还允许多语句行:

string s = ""; int i = 0;

严格地说,这是正确的:如果一个人能找出语句的结尾,那么编译器也能。这还没有真正流行起来,很少有语言实现这类功能。VB的下一个版本可能是实现对既不需要显式终止也不需要行继续[]的语句进行正确处理的第一种语言。这将允许这样的代码:

Dim a = OneVeryLongExpression +
        AnotherLongExpression
Dim b = 2 * a
让我们祈祷吧

另一方面,这确实会使解析变得更加困难,并且可能会导致错误消息(参见Haskell)


<> P,C语言使用C类语法的原因可能是因为营销原因,而不是其他任何东西:人们已经熟悉C语言、C++语言和java语言。不需要引入另一种语法。由于各种原因,这是有道理的,但它显然继承了这些语言的许多弱点。

我个人同意使用独特的字符作为行终止符。它使编译器更容易理解您要做什么

与流行的观点相反,编译器不可能在没有帮助的情况下100%地找出一条语句的结束和另一条语句的开始!在一些边缘情况下,无论是单个语句还是跨多行的多个语句,都是不明确的


阅读Visual Basic技术负责人Paul Vick的文章,了解为什么不像听起来那么简单。

我已经仔细考虑了这个问题,如果我可以猜测一下语言设计师的动机:

C#显然有分号,因为它来自C。我最近一直在重读K&R的书,很明显,丹尼斯·里奇真的不想强迫程序员以他认为最好的方式编写代码。书中充斥着这样的评论:“虽然我们对这件事不是教条式的,但似乎goto语句应该很少使用,如果有的话。”在函数部分,他们提到他们选择了许多格式样式中的一种,选择哪种并不重要,只是保持一致


因此,使用显式语句终止符可以让程序员随意格式化代码。不管是好是坏,它似乎与C最初的设计方式一致:按自己的方式去做。

你可以准确地说,要求分号来终止语句是多余的。从技术上讲,可以从C语言中删除分号,但分号仍然有效。问题是它给人类留下了误解的空间。我认为分号的必要性是为了人类的利益而消除歧义,而不是为了编译器。如果没有某种形式的陈述定界,人类很难解释这样的观点:

int i = someFlag ? 12 : 5 int j = i + 3
编译器应该能够很好地处理这个问题,但是对于人类来说,下面的代码看起来要好得多

int i = someFlag ? 12 : 5; int j = i + 3;

这是可以做到的。您所指的是“分号插入”。JavaScript在这方面取得了很大的成功,它为什么没有在C#中应用,这取决于它的设计者。也许他们不知道,或者担心这会引起程序员的困惑

有关JavaScript中分号插入的更多详细信息,请参阅指定JavaScript的位置

我引述第22页(PDF,第34页):

  • 当,当程序从左边解析时 向右,输入的结尾 遇到令牌流,并且 解析程序无法解析 将令牌流作为单个完整输入 ECMA脚本程序, 然后,分号自动插入到 输入流的结尾

  • 什么时候,作为 程序从左到右进行解析, 遇到一个标记,该标记为 某些产品允许 语法,但是 该产品为受限产品,代币为 终端或服务器的第一个令牌 紧跟在 注释“[无行终止符] 这里]“在限制生产中(因此,这样的标记是 称为受限令牌),并且 限制代币与 至少有一个以前的令牌 行终止符,然后是 分号自动插入到受限令牌之前

然而,还有一个额外的问题 在前面的 规则:分号永远都不是 如果出现以下情况,则自动插入 分号将被解析为空语句 或者如果这个分号 将成为for语句头中的两个分号之一 (第12.6.3节)

[……]


规范文档甚至包含示例

>我想说,每个语句之后分号是最必要的,这是熟悉C、C++和/或java的程序员熟悉的原因。C#继承了这些语言的许多句法选择,并不是简单地以类似的名称命名。以分号结尾的语句只是从这些语言中借用的众多语法选择之一。

另一个很好的理由是sem
int i = someFlag ? 12 : 5; int j = i + 3;
a = b + c = d
a = b + c; = d
a = b + ; c = d
a = b; c = d;
a = b = d
int i; for( i = 0; i < 10; i++ ) printf("hello world.\n"); printf("%d instance.\n", i);
int i;
for( i = 0; i < 10; i++ )
{
    printf("hello world.\n);
    printf("%d instance.\n", i);
}
int i
for i=0 i<10 i++
   printf "hello world.\n"
   printf "%d instance.\n" i
for i=1 to 10  // i is inferred to be an integer
    printf "hello world.\n"
    printf "%d instance.\n" i