Почему после каждого кода на C мы должны писать точку с запятой?

Почему после каждого кода на языке программирование C мы должны писать точку с запятой (;)? Я знаю, что это для того, чтобы код правильно работал, но как это работает?


Ответы (2 шт):

Автор решения: user7860670

Одной из особенностей языка С является компактность синтаксиса, позволяющая экономить байты, используемые для хранения исходного кода. В свое время это было одним из факторов, помогавших С набирать популярность. Однако помимо ухудшения читабельности, многие синтаксические конструкции получились неоднозначными без привлечения дополнительных разделителей. Например

int x = 3;
int y = 5;
int z = x;
++y -= 2;

без разделителей выглядит как

int x = 3
int y = 5
int z = x
++y -= 2

делая невозможным отличить от

int x = 3
int y = 5
int z = x++
y -= 2
→ Ссылка
Автор решения: eanmos

На самом деле ничего волшебного или особенного в точке с запятой нет. Она ни чем не лучше и не хуже любого другого символа в исходном коде.

Другое дело, что конкретные правила употребления того или иного символа определяются грамматикой языка. Грамматика языка C устроена так, что требует использования точки с запятой в конце объявления (англ. declaration), в конце объявления структуры (англ. struct declaration), в конце expression statement, в конце jump statement, а также в конце do while и внутри for:

(6.7) declaration:
         declaration-specifiers init-declarator-listopt ;

(6.7.2.1) struct-declaration:
             specifier-qualifier-list struct-declarator-list ;

(6.8.3) expression-statement:
           expressionopt ;

(6.8.5) iteration-statement:
           while ( expression ) statement
           do statement while ( expression ) ;
           for ( expressionopt ; expressionopt ; expressionopt ) statement
           for ( declaration expressionopt ; expressionopt ) statement

(6.8.6) jump-statement:
           goto identifier ;
           continue ;
           break ;
           return expressionopt ;

— Отрывок из ISO/IEC 9899:1999 Appendix A.


Использование точки с запятой не является каким-то обязательным требованием. Главное, чтобы грамматика языка не была неоднозначной (англ. ambiguous).

Один из классических примеров неоднозначной конструкции в языках программирования — это «висячий else»:

/* К какому if относится этот else? */
if (a) if (b) s1; else s2;

Для решения этой неоднозначности можно ввести ключевое слово fi (так сделано в Bash); дополнительные begin и end (Pascal); или требовать, чтобы else относился к ближайшему if — так сделано в C.

Точно также точка с запятой просто является инструментом для решения различных неоднозначностей в языке C, которые проявились бы, если бы этой точки с запятой не было.


Во многих других языках программирования точка с запятой, хоть и входит в грамматику, но не является обязательной для использования и может быть опущена в некоторых контекстах. В Go, например, лексический анализатор в большинстве случаев сам вставляет точку с запятой в конце каждой строки. (Кстати, это одна из причин, почему в Go нельзя переносить фигурную скобку { на новую строку.)

Этого будет достаточно в плане семантики, но чтобы избавится от неоднозначности грамматики потребуются дополнительные { и }.

→ Ссылка