Когда я могу опустить фигурные скобки в C?
Я почти уверен, что это было задано раньше, но я не могу найти ответа на него где-нибудь.
Когда я могу опустить фигурные скобки в C? Ранее я видел безрежимные выражения return
, такие как
if (condition)
return 5;
Но это не всегда работает для всех операторов, т.е. при объявлении метода.
изменить:
Являются ли правила для удержания без изменений такими же, как в Java?
Ответы
Ответ 1
Если вы посмотрите на синтаксис C, существует ряд контекстов, для которых требуется оператор, термин, который определяется самой грамматикой.
В любом из этих контекстов одним из форм оператора, который вы можете использовать, является составной оператор, состоящий из открывающей скобки {
, последовательности из нуля или более деклараций и/или операторов и закрывающей скобки }
. (В C90 все объявления в составном заявлении должны предшествовать всем операторам, C99 удалил это ограничение.)
Для определения функции явно требуется составной оператор, а не только какой-либо оператор. (Я думаю, что единственный случай, когда составной оператор является единственным типом оператора, который вы можете использовать). Если не для этого ограничения, вы сможете написать:
void say_hello(void) printf("Hello, world\n");
Но так как большинство определений функций содержат множественные объявления и/или инструкции, не было бы большого преимущества в разрешении этого.
Есть отдельный вопрос: когда вы должны опустить фигурные скобки. По моему личному мнению, ответ "почти никогда". Это:
if (condition)
statement;
является совершенно законным, но это:
if (condition) {
statement;
}
IMHO читает лучше и легче поддерживать (если я хочу добавить второй оператор, фигурные скобки уже есть). Это привычка, которую я выбрал из Perl, которая требует скобок во всех таких случаях.
Единственное время, когда я опускаю фигурные скобки, - это когда целой оператор if или что-то подобное подходит для одной строки, и это делает код более легким для чтения, и я вряд ли захочу добавить больше операторов для каждого if
:
if (cond1) puts("cond1");
if (cond2) puts("cond2");
if (cond3) puts("cond3");
/* ... */
Я нахожу такие случаи довольно редкими. И даже тогда я все равно подумал бы о добавлении брекетов:
if (cond1) { puts("cond1"); }
if (cond2) { puts("cond2"); }
if (cond3) { puts("cond3"); }
/* ... */
Ответ 2
Единственными местами, где вы можете опустить скобки, являются тела операторов if-else
, for
, while
или do-while
, если тело состоит из одного оператора:
if (cond)
do_something();
for (;;)
do_something();
while(condition)
do_something();
do
do_something()
while(condition);
Однако обратите внимание, что каждый из приведенных выше примеров считается единственным выражением в соответствии с грамматикой; это означает, что вы можете написать что-то вроде
if (cond1)
if (cond2)
do_something();
Это совершенно законно; if (cond2) do_something();
сводится к одному утверждению. Так что, если это так, if (cond1) if (cond2) do_something();
, так что вы могли бы спуститься дальше в безумие с чем-то вроде
for (i=0; i < N; i++)
if (cond1)
if (cond2)
while (cond3)
for (j=0; j < M; j++)
do_something();
Не делай этого.
Ответ 3
Но это не всегда работает для всех операторов.
В частности? Когда ожидается одно утверждение, оно отлично действует. Циклы, оператор if
и т.д. Все ожидают утверждения и что либо блок, либо, ну, один оператор, не будучи заключенным в блок.
Ответ 4
Пример:
int a[2][2] = {{1, 2}, {3, 4}};
вы можете использовать действительную эквивалентную форму:
int a[2][2] = {1, 2, 3, 4};
Некоторые подробные компиляторы могут предупреждать, но это действительно.
Обратите внимание, что для оператора if
(то же самое для while
, оператора for
,...) {}
не пропущены. Их просто не запрашивают. Оператор if
имеет этот синтаксис:
if (expression) statement
Если вам требуется несколько операторов вместо одного оператора, вы можете использовать составной оператор, который окружен {}
.
Ответ 5
В основном вам нужны фигурные скобки, когда вы хотите объединить несколько операторов или выражений в один, например:
{
x = 1;
y = 2;
}
Итак, если вы поместите выше в if
или else
, все это в фигурных скобках будет выполнено в целом, тогда как если вы опустите фигурные скобки, то только первый (x = 1;
в этом случае) будет использоваться как часть if
или else
.
Вы также обычно используете их с switch()
:
switch (x)
{
case 1:
// do smth
break;
case 2:
// do smth else
break;
}
Вам обычно нужны они с инструкцией do-while
:
do
{
printf("%d\n", x);
x++;
} while (x < 10);
Вам нужны они с компиляторами C89, когда вы хотите определить и использовать временную переменную в середине кода:
int main(void)
{
puts("Hello World!");
{
int x;
for (x = 0; x < 10; x++)
printf("%d\n", x);
}
return 0;
}
Вы используете их для начала и конца тела функции, определения структуры/объединения, определения перечисления, инициализации структуры/объединения/массива, например:
void blah(void)
{
}
enum e
{
e1 = 1,
e2 = 2
};
struct s
{
int foo;
int bar;
} s = { 1, 2 };
int a[3] = { 1, 2, 3 };
Иногда вы можете опускать их при инициализации, например:
char str2[] = { "abc" };
char str1[] = "abc";
Ответ 6
В любое время есть блок с более чем одной строкой (подсчет строк как один оператор с;)
<сильные > Примеры:
for (i = 0; i < j; i++ )
foo(i);
while (1)
foo();
if( bool )
foo();
void cheese()
printf("CHEESE");
Все после; в приведенных выше строках не считается "внутри" блока, как если бы они были {}.
Ответ 7
Вы можете опустить их, когда есть один оператор, который вы выполняете:
for(...)
printf("brackets can be omited here");
if(...)
printf("brackets can be omited here");
else
printf("brackets can be omited here too");
и т.д. Вы всегда можете добавить их, это никогда не повредит и поможет прояснить область действия, но вы довольно безопасны. Единственный "улов", о котором я могу думать, - это попытаться сделать объявление в этой области (что, кстати, бесполезно):
if(...)
int a = 5;
Это вызовет ошибку, но это потому, что вы можете выполнить один оператор без фигурных скобок, а не декларацию. Важное различие.
С технической точки зрения, вы даже можете сделать более одной операции без скобок, если они объединены с оператором ,
... не то, что я советую делать это, просто заслуживает внимания:
if(...)
value++, printf("updated value with brackets");
И для вашего редактирования вы можете увидеть в java specification, что правила одинаковы. Я специально привязался к разделу if
, но после if
он ожидал утверждения, поэтому вы можете пропустить фигурные скобки.
Ответ 8
Если есть сомнения, используйте фигурные скобки. Они не "стоят" лишних [если вы не используете их неправильно].
Довольно основное правило: "Если у вас более одной точки с запятой в том же отступе, у вас должны быть фигурные скобки". Это не совсем так просто, но, как "одно предложение без каких-либо проблем, новых или других осложнений", это нужно будет сделать.
И да, Java, основанный на C-синтаксисе, имеет одни и те же основные правила - возможно, какая-то странность, когда Java отличается от C или С++, но это необычные/странные вещи, а не то, что вы обычно нажимаете при написании типичных code [Я не сделал много java, поэтому не могу сказать, что я нашел их, но я уверен, что есть НЕКОТОРЫЕ отличия - в конце концов, это разные языки.
Ответ 9
Следующее выглядит немного сложным:
if (...)
printf("I'm conditional\n");
Я предполагаю, что препроцессор C заботится о пустых строках, так что это утверждение отлично. Конечно, очень плохая практика.