我知道在声明之后需要使用分号(我说的是Java,C ++和类似语言),但在卷曲括号后不需要。为什么这样?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
是什么原因?我的意思是,这背后的理论是什么?
答案 0 :(得分:8)
因为语言被定义为:
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
解析语句。
答案 1 :(得分:7)
因为花括号用于分组语句,但它们本身不是语句。
答案 2 :(得分:5)
除了语言推理之外,编译器必须知道将每个命令与下一个命令分开的位置。支架本身就是一个分隔符,因此不需要分号。
答案 3 :(得分:3)
大多数人认为语句是一个简单的命令,通常带有关键字,以及一些参数,例如“goto x”,“a = y + 2”等。必须作为一个陈述结束和另一个陈述开始的一些迹象,就像英语句子需要以句号结束一样。传统上,大多数语言的语法在语句之后需要用分号作为指示。
一个{...}“大括号对”是一个块,它是一种特殊的语句,但不需要分号,因为花括号使边界清晰。
许多语言也允许“;”单独表示空语句。你为什么需要一个?出于同样的原因,自然数系统需要“零”而不是“一”,并且集合可以为空。
但这意味着你可以写:
{ ... } ;
并且大多数langauge编译器都会接受它而不说评论。但你应该把它想象成:
{ ... }
;
并且通常没有充分的理由来写这个。
实际上,接受 {} 的语言(例如“空括号”)不需要空语句; ,因为它们在语义上是相同的。但语言设计师似乎仍然坚持传统;你有没有注意到每一种“现代”语言似乎都是一个糟糕的C语法副本?
答案 4 :(得分:1)
这是一个公平的问题。块是一个语句。期望一致性是很自然的,并且想知道为什么所有陈述都不会被终止。如果我们在阻止后需要;
,则没有技术问题。但我们也很懒,因为}
可以明确地标记语句的结尾,我们不希望必须键入另一个标记。
相关观察:在C ++中,您必须使用;
class A
{
...
}; // the semicolon is mandatory!
这让许多人感到恼火。分号是必需的,因为语言允许}
后的其他内容,因此}
不是可靠的结束标记。
在Java中,情况并非如此。 }
结束了类声明,就是这样。因此不需要;
。
答案 5 :(得分:0)
使用分号与
具有相同的效果if (a > b) {
printf("hello!");
}printf("Goodbye");
并将printf("Goodbye")
部分退出。
答案 6 :(得分:0)
如果您在C#3+中使用对象初始化语法,则在括号
后面加一个分号var foo = new Foo
{
Bar = "Fizzbuzz"
};
答案 7 :(得分:0)
在这种情况下,花括号定义了一个语句块。像任何其他块一样。当您即将声明并初始化阵列时,您必须提供;因为在这种情况下你正在撰写一份声明。
答案 8 :(得分:0)
注意:这个答案特定于C ++语言,而不是Java。
我会说语言语法(2003)不要求分号。这就是语言定义语法的方式。
您编写的代码称为复合语句或块,语言规范(2003)在第6.3.3节中定义复合语句的语法,
因此可以使用多个语句 在预期的地方,化合物 声明(也是等同于 被称为“阻止”)。
compound-statement: { statement-seqopt } statement-seq: statement statement-seq statement
你看到上面显示的语法中有任何分号吗?不。这就是为什么在代码中的大括号之后不需要分号。
答案 9 :(得分:0)
在关闭大括号之后,你需要一个分号的唯一地方是在数组初始化之后,因为你可以继续行例如
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.
答案 10 :(得分:-1)
因为curly不是语句,所以它用于对语句进行分组。它不需要终结器。
答案 11 :(得分:-1)
使用花括号括起一段代码时,不需要分号:
namespace Some
{
void fun(int i)
{
while(i != 0)
{
cout<<"i = "<<i<<endl;
i --;
} // semicolon not needed
} // semicolon not needed
} // semicolon not needed
在其他情况下,您需要分号(如初始化,声明等):
struct A {
// ... declare members
}; // declaration; put semicolon
int a[] = {0, 1, 2}; // initialization; put semicolon