«Else if» - одно ключевое слово?

100

Я новичок в C ++. Я часто вижу условное выражение, подобное приведенному ниже:

if 
  statement_0;
else if
  statement_1;

Вопрос:

Синтаксически я должен рассматривать else ifкак одно ключевое слово? Или это действительно вложенный ifоператор внутри внешнего, elseкак показано ниже?

if 
  statement_0;
else 
  if
    statement_1;
модельер
источник
5
К вашему второму пункту. Синтаксически это почти всегда написаноelse if
TheNorthWes
8
Нет, поскольку это усложнит грамматику: слово - это слово без пробела. В других языках есть такие ключевые слова, как elseifи ELIF. Фактически только (?) Язык программирования Algol68 допускает пробел в идентификаторе; тоже приятно:PROC walk through tree ()
Joop Eggen
3
Fortran (по крайней мере, версии с фиксированной формой) и все стандартизированные версии Algol допускают пробелы где угодно. Одна история гласит, что перфокарты, очевидно, были склонны к добавлению пробелов при вводе кода; другой просто то, что разрешение пробелов в именах переменных позволит программистам использовать лучшие имена, и проблем не предвидится.
prosfilaes
1
elseifКлючевое слово существует в VB и PHP.
Salman A
3
Nitpick: хотя C ++ официально не имеет ключевых слов с пробелами в них, у него есть такие конструкции, как для всех целей и задач, которые работают таким образом. Например, long doubleвы должны это написать таким образом. longdoubleэто неверно.
Mr Lister

Ответы:

133

Они не одно ключевое слово , если мы идем в проект C ++ стандартный раздел 2.12 Ключевые слова таблицы 4списков как ifи по elseотдельности , и нет else ifключевых слов. Мы можем найти более доступный список ключевых слов C ++ , перейдя в раздел cppreferences по ключевым словам .

Грамматика в разделе 6.4также проясняет это:

selection-statement:
 if ( condition ) statement
 if ( condition ) statement else statement

ifВ else ifэто заявление после elseтермина. В разделе также говорится:

[...] Подставление в операторе выбора (каждое подложение в форме else оператора if ) неявно определяет область действия блока (3.3). Если подзапрос в операторе выбора является одиночным оператором, а не составным оператором , это как если бы оно было переписано как составное-выражение, содержащее исходное подзаголовок.

и предоставляет следующий пример:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

Так как же анализируется ваш слегка расширенный пример?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

будет анализироваться так:

if 
{
  statement_0;
}
else
{ 
    if
    {
      statement_1;
    }
    else
    {
        if
        {
         statement_2 ;
        }
    }
}

Заметка

Мы также можем определить, что else ifэто не может быть одно ключевое слово, понимая, что ключевые слова являются идентификаторами, и мы можем видеть из грамматики идентификатора в моем ответе на вопрос « Можете ли вы начать имя класса с числовой цифры?» что пробелы не допускаются в идентификаторах и поэтому else ifне могут быть одним ключевым словом, а должны быть двумя отдельными ключевыми словами .

Шафик Ягмур
источник
1
Вы могли бы вывести это без стандарта? В ASM это: jeq( if| else if), jne( if| else if), jmp( else). Исходя из этого, я бы сказал, что это было одно ключевое слово ... вероятно, не синтаксически, а по инструкции.
Brandon
18
@Brandon Я очень сомневаюсь, что вы могли бы надежно перейти от языка ассемблера к конструкциям высокого уровня без глубоких знаний используемой грамматики и самого компилятора.
Shafik Yaghmour
Хотя обратите внимание, что это определение потенциально приводит к замечательной проблеме неоднозначного синтаксического дерева "dangling else" при определении грамматики в синтаксическом анализаторе ...
LinearZoetrope
2
Некоторые языки не поддерживают else if, но вместо этого elsif. В этих языках else ifэто действительно одно ключевое слово. Однако, как говорится в этом ответе, языки на основе C обычно этого не делают.
sfdcfox
1
Думаю, @Krumia хотела увидеть последнее elseзаявление. Я тоже был бы признателен за это.
Matthias
78

Синтаксически это не одно ключевое слово; ключевые слова не могут содержать пробелов. По логике вещей, при написании списков else if, вероятно, лучше, если вы увидите его как одно ключевое слово и напишите:

if ( c1 ) {
    //  ...
} else if ( c2 ) {
    //  ...
} else if ( c3 ) {
    //  ...
} else if ( c4 ) {
    //  ...
} // ...

Компилятор буквально видит это как:

if ( c1 ) {
    //  ...
} else {
    if ( c2 ) {
        //  ...
    } else {
        if ( c3 ) {
            //  ...
        } else {
            if ( c4 ) {
                //  ...
            } // ...
        }
    }
}

но обе формы приводят к одному и тому же, и первая гораздо более читабельна.

Джеймс Канце
источник
1
Собственно, компилятор не видел буквально elseследующего за compound-statement. После else, Он ищет statement(что может быть похоже на return;или f()) или compound-statement...
Маска
@TheMask: В ответе Шафика Ягмура выше компилятор буквально видит один оператор, но делает вид, что видел составной оператор.
Ilmari Karonen
Этот ответ подсказывает, как парсер извлекает токены. Хорошо.
haccks
24

Нет это не так.
Это два ключевых слова, и, более того, второе «if» является подзапросом «внутри» области, определенной первым оператором «else».

pablo1977
источник
2
Хотя это хорошо описывает то, что происходит, вы можете добавить несколько ссылок на фактические определения языка, чтобы лучше доказать то, что вы говорите.
πάντα ῥεῖ
2
@ πάνταῥεῖ: Вы правы насчет ссылок, но эта работа еще хорошо проделана Шафиком Ягмуром. Его ответ был принят, и я тоже проголосовал. Моя работа здесь закончена.
pablo1977
16

Вы можете увидеть объем, используя фигурные скобки:

if(X) {
  statement_0;
}
else {
  if(Y) {
    statement_1;
  }  
}

И обычно реализуется с двумя разными ключевыми словами, одно - if , другое - else .

олень
источник
Поэтому я полагаю, что те, кто настаивает на том, чтобы фигурные скобки использовались везде, где принимается составной оператор, должны писать все свои нетривиальные условные выражения вот так, а? :)
dlf
5
Я думаю, что можно переусердствовать, даже наши всеми любимые фигурные скобки. Не делайте этого дома.
северный олень
1
Все языки со структурой скобок (о которых я знаю), которые требуют фигурных скобок вокруг всех подзапросов, даже если они состоят из одного оператора, имеют ключевое слово с одним токеном со значением «else if». Думаю, это показательно.
zwol
@Zack: Swift - это язык, который нарушает ваше правило. Он требует фигурных скобок даже для блоков кода с одним оператором, но не имеет ключевого слова else if. С другой стороны, грамматика сильно отличается от C. An if-statementзаканчивается необязательным else-clause. else-clauseЯвляется либо else code-block или else if-statement. code-blockвключает обязательные скобки. Таким образом, за elseключевым словом может следовать только {или if.
GraniteRobert
@GraniteRobert У меня не было времени вообще много смотреть на Swift, но это интересные данные; Я думал , что грамматика , как это было в возможности , но никогда не видел его сделать. И вы заметите, что это тоже позволяет избежать написания " else { if ... }".
zwol
10

Как уже было сказано, это не так. Это два ключевых слова. Это начало двух следующих друг за другом утверждений. Чтобы попытаться сделать это немного понятнее, вот BNF gramar , которые имеют дело с ifи elseзаявления на языке C ++.

 statement:      
    labeled-statement
    attribute-specifier-seqopt expression-statement
    attribute-specifier-seqopt compound-statement    
    attribute-specifier-seqopt selection-statement  
    attribute-specifier-seqopt iteration-statement    
    attribute-specifier-seqopt jump-statement  
    declaration-statement
    attribute-specifier-seqopt try-block

   selection-statement: 
         if ( condition ) statement
     if ( condition ) statement else statement

Обратите внимание, что statementсам файл include selection-statement. Итак, комбинации вроде:

if (cond1)
   stat
else if(cond2)
   stat
else
   stat

возможны и действительны в соответствии со стандартом / семантикой C ++.

Примечание: грамматика C ++ взята с этой страницы.

Маска
источник
1

else и if - два разных ключевых слова C ++ . За оператором if может следовать необязательный оператор else if ... else . Если оператор может иметь ноль или больше другого , если «s и они должны прийти до другого .

Вы можете найти синтаксис и пример в этом руководстве по выражению if ... else

clever_bassi
источник
-1

Я просто хотел бы добавить ко всем этим объяснениям свою точку зрения. На мой взгляд, если вы можете использовать эти ключевые слова по отдельности, они должны быть ДВУМЯ ключевыми словами. Может быть, вы можете взглянуть на грамматику C ++ по этой ссылке в stackoverflow: Существует ли стандартная грамматика C ++?

С уважением

Проблемы
источник
-1

За оператором if может следовать необязательный оператор else if ... else, который очень полезен для проверки различных условий с помощью одного оператора if ... else if.

При использовании операторов if, else if, else следует иметь в виду несколько моментов.

Условие if может иметь ноль или еще одно, и оно должно стоять после любого другого if.

Условие if может иметь от нуля до многих других if, и они должны стоять перед else.

После того, как else if преуспевает, ни одно из оставшихся if или else не будет проверено.

посмотрите инструкцию if ... else .

ЗНАЙ МЕНЯ
источник
2
Это просто не соответствует стандарту и, более того, является избыточным. Язык обладает всеми выразительными возможностями для моделирования, else ifкак если бы это было ключевое слово, поэтому было бы бессмысленно определять его явно.
Руслан
1
Это полезное упрощение для программистов. Но вопрос не в том, как использовать операторы if.
Cruncher