Почему точка с запятой не требуется после скрученной скобки?
Я знаю, что точка с запятой необходима после оператора (я говорю о Java, C++ и подобных языках), но не обязательна после скрученной скобки. Почему так?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
Какова причина? Я имею в виду, какая теория стоит за этим?
12 ответов
Потому что фигурные скобки используются для группировки операторов, но сами по себе они не являются.
Потому что язык определяется как:
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 x", "a=y+2" и т. Д. Должно быть какое-то указание того, где заканчивается один оператор, а другой - начинается, так же, как английские предложения должны заканчиваться точкой. Традиционно грамматики большинства языков требуют точек с запятой после такого утверждения в качестве такого указания.
{ ... } "пара фигурных скобок" - это блок, который является особым видом оператора, но точка с запятой не нужна, потому что фигурные скобки проясняют границы.
Многие языки также позволяют ";" само по себе, чтобы представить пустое утверждение. Зачем вам нужен? По той же причине система натуральных чисел требует "ноль" вместо "один", и множества могут быть пустыми.
Но это означает, что вы можете написать:
{ ... } ;
и большинство компиляторов языка принимает это без замечаний. Но вы должны думать об этом как:
{ ... }
;
и вообще нет веской причины писать это.
На практике, языки, которые принимают {} (например, "пустые скобки"), не нуждаются в пустом выражении ; потому что они семантически идентичны. Но дизайнеры языка, похоже, застряли на традициях; Вы заметили, что каждый "современный" язык кажется плохой синтаксической копией C?
Это справедливый вопрос. Блок это утверждение. Естественно стремиться к единообразию и удивляться, почему все утверждения не заканчиваются одинаково. Нет технической проблемы, если нам требуется ;
после блока. Но мы также ленивы, так как }
можем однозначно отметить конец оператора, нам не нужно вводить другой маркер.
Связанное наблюдение: в C++ вы должны завершить объявление класса ;
class A
{
...
}; // the semicolon is mandatory!
Это раздражает чертовски много людей. Точка с запятой обязательна, потому что язык позволяет некоторые другие вещи после }
Итак }
не является надежным маркером конца.
В Java это не так. }
заканчивает объявление класса и все. Так ;
не нужен
Если вы используете синтаксис инициализации объекта в C# 3+, после скобки следует точка с запятой
var foo = new Foo
{
Bar = "Fizzbuzz"
};
Единственное место, где вам понадобится точка с запятой после закрывающей фигурной скобки, это после инициализации массива, так как вы можете продолжить строку, например
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.
В этом случае фигурные скобки определяют блок операторов. Как и любой другой блок. пока вы собираетесь объявить и инициализировать массив, вы должны предоставить; потому что в этом случае вы пишете заявление.
Ввод точки с запятой такой же, как
if (a > b) {
printf("hello!");
}printf("Goodbye");
и оставив printf("Goodbye")
расстаться.
Примечание: этот ответ относится только к языку C++, а не к Java.
Я бы сказал, что точка с запятой не требуется для грамматики языка (2003). Вот как язык определяет грамматику.
Код, который вы написали, называется составным оператором или блоком, а языковая спецификация (2003) определяет грамматику составного оператора в разделе §6.3/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
Поскольку curly не является оператором, он используется для группировки операторов. Для этого не нужен терминатор.