为什么大括号后不需要分号?

时间:2011-04-06 05:29:11

标签: java c++ syntax language-theory

我知道在声明之后需要使用分号(我说的是Java,C ++和类似语言),但在卷曲括号后不需要。为什么这样?

if (a > b) 
  printf("hello!"); // semicolon is mandatory

if (a > b) {
  printf("hello!");
} // semicolon is not required

是什么原因?我的意思是,这背后的理论是什么?

12 个答案:

答案 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