我知道在语句结束处需要加分号(我指的是Java、C++和类似的语言),但是在花括号结束后不需要。为什么呢?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
什么是原因?我是指,背后的理论是什么?
我知道在语句结束处需要加分号(我指的是Java、C++和类似的语言),但是在花括号结束后不需要。为什么呢?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
什么是原因?我是指,背后的理论是什么?
由于该语言定义如下:
statement:
labeled-statement
expression-statement
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
expression-statement:
expressionopt ;
compound-statement:
{ statement-seqopt }
statement-seq:
statement
statement-seq statement
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq declarator = assignment-expression
iteration-statement:
while ( condition ) statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ; expressionopt ) statement
for-init-statement:
expression-statement
simple-declaration
jump-statement:
break ;
continue ;
return expressionopt ;
goto identifier ;
declaration-statement:
block-declaration
所有正常的控制语句都是相互递归构建的。真正的工作由expression-statement
完成。如果您注意到expression-statement
总是以;
结束。其他需要注意的语句是jump-statement
。
但主要原因是它们在{}块后面不需要,以便easy
解析语句。
}
并不一定表示结束。而对于复合语句来说,情况就不同了。我能想到的只有复合语句、goto语句、break语句和continue语句是没有歧义的结束符号,不需要加上分号。我猜测语言设计者希望每个语句都以一个标点符号结尾,所以只省略了复合语句中的分号。 - James Kanzeexpression statement
后面没有分号会使解析变得更加困难。 - Martin York由于花括号用于分组语句,但它们本身不是语句。
{ _statement-seq_[opt] }
是一个复合语句;一种语句类型。他们不要求使用 ;
是因为语法不要求,纯粹简单如此。 - James Kanze;
终止符号和{ ... }
表示复合语句的语言在复合语句的生成中都省略了;
终止符号(可能是因为}
不会产生歧义地作为语句的结束)。 - James Kanze除了哲学推理之外,在引擎盖下,编译器知道在哪里将每个命令与下一个命令分开是至关重要的。括号本身就是分隔符,所以分号是不必要的。
}
和;
不是分隔符,而是终止符。但你的基本观点是正确的:分号不必要的原因是}
能够明确告诉编译器复合语句何时结束。 - James Kanze{ ... } ;
大多数语言编译器都能接受它而不做任何评论。但是你应该把它看作:
{ ... }
;
通常情况下,没有好的理由去编写这种代码。
实际上,接受{}(例如,“空括号”)的语言不需要空语句;,因为它们在语义上是相同的。但是语言设计者似乎被传统所束缚;你是否注意到每个“现代”语言似乎都是C语法的糟糕副本?
;
,那么就没有技术问题。但我们也很懒,因为 }
可以明确标记语句的结尾,所以我们不想再键入另一个标记。;
结束类声明。class A
{
...
}; // the semicolon is mandatory!
这让很多人感到非常烦恼。分号是必需的,因为语言允许在 }
之后添加其他内容,所以 }
不是可靠的结束标记。
在Java中,情况并非如此。 }
结束类声明,就是这样。因此不需要 ;
。
if (a > b) {
printf("hello!");
}printf("Goodbye");
并且省略掉 printf("Goodbye")
部分。
在关闭大括号后唯一需要使用分号的地方是在数组初始化之后,因为您可以继续该行,例如:
int[] i= { 1,2,3}, j= {1};
Runnable r = new Runnable() {
public void run() {
}
}, r2 = new Runnable() {
public void run() {
}
}; // required as you could define another Runnable or an array of Runnable.
var foo = new Foo
{
Bar = "Fizzbuzz"
};
注意:此答案特指C++语言,不适用于Java。
我认为分号在语言语法中并非必需(2003年)。这是语言如何定义语法的。
您编写的代码称为复合语句或块,语言规范(2003年)在第§6.3/1节中定义了复合语句的语法:
提供复合语句(也可以等效地称为“块”)以便可以使用多个语句来替代单个语句。
复合语句: { statement-seqopt }
语句序列: 语句 语句序列 语句
你在上面展示的语法中看到任何分号了吗?没有。因此,在您的代码中左花括号后面不需要分号。