Когда использовать "{ }" в C? [K&R Упражнение 1.8]

Я попытался решить эту проблему, которая заключается в подсчете количества строк, пробелов и вкладок.

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

main ()
{

    int newline; 
    int tab; 
    int blank;
    int c;

    newline = 0;
    tab = 0;
    blank = 0;

    while ((c = getchar()) != EOF) 
        if (c == '\n')
            ++newline;
        if (c == '\t')
            ++tab;
        if (c == 32)
            ++blank;

    printf("lines: %d tabs: %d blanks: %d\n", newline, tab, blank);
}

В моем коде учитывались только новые строки. Вкладки и пробелы никогда не учитывались. Я знаю, что ответ заключается в том, чтобы добавить {} вокруг раздела операторов if. Но я знаю это только потому, что искал решение в Google.

Возможно, это только я, но K&R не совсем объясняет, когда я должен использовать { }.

Может кто-нибудь объяснить, как я могу узнать, как добавить {} в мой код выше? Когда я читаю код, он выглядит нормально без { }. Это означает, что я действительно не понимаю его использование. Почему в приведенном выше коде не учитываются табуляции и пробелы?

Есть ли еще книга по Си, которую вы можете порекомендовать? У меня нет опыта программирования.

4 ответа

Решение

Одно относительно простое "правило большого пальца": ищите точку с запятой (и). Ссылаясь на ваш пример, начиная с "while", читайте вперед, пока не увидите точку с запятой. Если вы хотите, чтобы что-то кроме этой точки с запятой было выполнено как часть вашего блока while, вам нужно обернуть все это в фигурные скобки.

Другой способ взглянуть на это: точка с запятой - это терминатор оператора. Это закончилось пустым = 0 как ваше предыдущее утверждение; он завершается не только оператором if, но и оператором while. Таким образом, чтобы выполнить следующее if как часть блока while, вам нужно заключить if в фигурные скобки.

Да, и, кстати, C и подобные языки не придают синтаксическое значение пустому пространству. В большинстве случаев это рассматривается как разделитель. Любые отступы, выбранные вами, предназначены только для читателя; это не имеет значения для компилятора.

Синтаксис простого if является: if (<condition>) <statement>, <statement> может быть одним оператором (как в вашем коде) или блоком (ноль или более операторов заключены в фигурные скобки). Когда у вас есть одно утверждение, вопрос стиля заключается в том, окружаете ли вы его фигурными скобками - поведение такое же.

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

Например, while Цикл выполняет один оператор, в то время как он оценивается как true:

  while(some-condition)
    statement

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

За любым if / while / for может следовать один оператор без фигурных скобок или любое количество операторов, заключенных в фигурные скобки. Если вы пишете if / while / for, за которым следуют многие операторы и без скобок, только первый оператор попадает под if / while / for. Обратите внимание, что какой бы пробел вы не использовали, он не имеет значения, он только для удобства чтения.

Это эквивалент вашего кода, если он был написан в фигурных скобках:

while ((c = getchar()) != EOF) 
{
    if (c == '\n')
    {
        ++newline;
    }
}

if (c == '\t')
{
   ++tab;
}

if (c == 32)
{
   ++blank;
}

То, что ты хочешь:

while ((c = getchar()) != EOF) 
{
   if (c == '\n')
   {
       ++newline;
   }

   if (c == '\t')
   {
      ++tab;
   }

   if (c == 32)
   {
      ++blank;
   }
}

что эквивалентно

while ((c = getchar()) != EOF) 
{
   if (c == '\n')
       ++newline;

   if (c == '\t')
      ++tab;

   if (c == 32)
      ++blank;
}

Исключение скобок не служит абсолютно никакой цели, кроме стиля. Если у вас есть сомнения, включите фигурные скобки.

Другие вопросы по тегам