“Else if” é uma única palavra-chave?


100

Eu sou novo em C ++. Costumo ver declarações condicionais como abaixo:

if 
  statement_0;
else if
  statement_1;

Questão:

Sintaticamente , devo tratar else ifcomo uma única palavra-chave? Ou é realmente uma ifdeclaração aninhada dentro do exterior elsecomo abaixo?

if 
  statement_0;
else 
  if
    statement_1;

5
Para o seu segundo ponto. Sintaticamente, quase sempre é escritoelse if
TheNorthWes

8
Não, pois isso tornaria a gramática ainda mais complexa: uma palavra é uma palavra sem espaço. Porém, outros idiomas têm palavras-chave como elseife ELIF. Na verdade, apenas (?) A linguagem de programação Algol68 permite um espaço em um identificador; legal também:PROC walk through tree ()
Joop Eggen

3
Fortran (pelo menos as versões de forma fixa) e todas as versões padronizadas de Algol permitem espaços em qualquer lugar. Uma história conta que, aparentemente, os perfuradores de cartões eram propensos a adicionar espaços ao digitar o código; outro simplesmente que permitir espaços em nomes de variáveis ​​permitiria aos programadores usar nomes melhores e os problemas não foram previstos.
prosfilaes

1
A elseifpalavra-chave existe em VB e PHP.
Salman A

3
Nitpick: embora o C ++ oficialmente não tenha palavras-chave com espaços, ele possui construções como para todos os efeitos e propósitos que funcionem dessa maneira. Por exemplo, long doublevocê tem que escrever dessa forma. longdoubleestá incorreto.
Sr. Lister

Respostas:


133

Eles não são uma única palavra-chave se formos para o rascunho da seção padrão C ++. A tabela de 2.12 palavras-chave4 lista ambas ife elseseparadamente e não há else ifpalavra-chave. Podemos encontrar uma lista mais acessível de palavras-chave C ++ acessando a seção cppreferences sobre palavras-chave .

A gramática na seção 6.4também deixa isso claro:

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

O ifin else ifé uma declaração após o elsetermo. A seção também diz:

[...] A subinstrução em uma instrução de seleção (cada subinstrução, na forma else da instrução if ) define implicitamente um escopo de bloco (3.3). Se a subinstrução em uma instrução de seleção for uma instrução única e não uma instrução composta , é como se ela tivesse sido reescrita para ser uma instrução composta contendo a subexposição original.

e fornece o seguinte exemplo:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

Então, como seu exemplo ligeiramente estendido é analisado?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

será analisado assim:

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

Nota

Também podemos determinar que else ifnão pode ser uma palavra-chave percebendo que palavras-chave são identificadores e podemos ver a gramática de um identificador em minha resposta a Você pode iniciar o nome de uma classe com um dígito numérico? que espaços não são permitidos em identificadores e, portanto, else ifnão podem ser uma única palavra-chave, mas devem ser duas palavras-chave separadas .


1
Você poderia deduzir isso sem o padrão? No ASM é: jeq( if| else if), jne( if| else if), jmp( else). Com base nisso, eu diria que era uma única palavra-chave ... provavelmente não sintaticamente, mas em termos de instrução.
Brandon

18
@Brandon Duvido muito que você possa ir de forma confiável da linguagem assembly para construções de alto nível sem um conhecimento profundo da gramática que está sendo usada e do próprio compilador.
Shafik Yaghmour

No entanto, observe que esta definição potencialmente leva ao maravilhoso problema da árvore de sintaxe ambígua "dangling else" ao definir a gramática no analisador ...
LinearZoetrope

2
Alguns idiomas não suportam else if, mas sim elsif. Nessas línguas, else ifé realmente uma palavra-chave. No entanto, as linguagens baseadas em C geralmente não, como afirma esta resposta.
sfdcfox

1
Acho que @Krumia queria ver uma elsedeclaração final . Eu apreciaria isso também.
Matthias

78

Sintaticamente, não é uma única palavra-chave; palavras-chave não podem conter espaços em branco. Logicamente, ao escrever listas de else if, provavelmente é melhor se você vê-lo como uma única palavra-chave e escrever:

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

O compilador literalmente vê isso como:

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

mas ambas as formas resultam na mesma coisa, e a primeira é muito mais legível.


1
Na verdade, o compilador não viu literalmente elseseguido por a compound-statement. Depois de um else, procure statement(que pode ser como return;ou f()) ou um compound-statement...
The Mask

@TheMask: De acordo com a resposta de Shafik Yaghmour acima, o compilador literalmente vê uma única instrução, mas finge que viu uma instrução composta.
Ilmari Karonen

Essa resposta determina como o analisador extrai os tokens. Boa.
haccks

24

Não não é.
Eles são duas palavras-chave e, além disso, o segundo "if" é uma sub-declaração "dentro" do escopo determinado pela primeira declaração "else".


2
Embora isso descreva bem o que está acontecendo, você pode querer adicionar algumas referências para as definições de linguagem reais para provar melhor o que está dizendo.
πάντα ῥεῖ

2
@ πάνταῥεῖ: Você está certo sobre as referências, mas este trabalho foi bem feito por Shafik Yaghmour. Sua resposta foi aceita e eu também votei. Meu trabalho acabou aqui.
pablo1977

16

Você pode ver o escopo usando chaves:

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

E normalmente implementado com duas palavras-chave distintas, uma é if e a outra é else .


Então, suponho que aqueles que insistem que colchetes devem ser usados ​​sempre que uma instrução composta é aceita devem escrever todas as suas condicionais não triviais assim, hein? :)
dlf

5
Acho que se pode exagerar em qualquer coisa, até mesmo em nossos amados chaves. Não faça isso em casa.
rena

1
Todas as linguagens estruturadas com chaves (que eu conheço) que exigem chaves em torno de todas as subinstruções, mesmo se compostas de uma única instrução, têm uma palavra-chave de token único com o significado "else if". Eu acho que isso é revelador.
zwol

@Zack: Swift é uma linguagem que quebra suas regras. Requer chaves mesmo para blocos de código de instrução única, mas não possui uma palavra-chave "else if" Por outro lado, a gramática é bastante diferente de C. Um if-statementtermina com um opcional else-clause. Um else-clauseé tanto else code-block ou else if-statement. code-blockinclui chaves obrigatórias. Portanto, a elsepalavra - chave só pode ser seguida por {ou if.
GraniteRobert

@GraniteRobert Não tive tempo de olhar muito para Swift, mas esse é um dado interessante; Eu estava pensando que uma gramática como essa era uma possibilidade, mas nunca tinha visto isso acontecer. E você notará que isso também evita que as pessoas escrevam " else { if ... }".
zwol

10

Como já respondi, não é. São duas palavras-chave. É o início de duas declarações, uma após a outra. Para tentar tornar isso um pouco mais claro, aqui está o gramar BNF que trata das instruções ife elsena linguagem 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

Observe que statementse inclui selection-statement. Então, combinações como:

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

são possíveis e válidos de acordo com o padrão / semântica C ++.

Nota: gramática C ++ extraída desta página.



-1

Gostaria apenas de acrescentar meu ponto de vista a todas essas explicações. A meu ver, se você pode usar essas palavras-chave separadamente, elas devem ser DUAS palavras-chave. Talvez você possa dar uma olhada na gramática C ++, a partir deste link em stackoverflow: Existe uma gramática C ++ padrão?

Saudações


-1

Uma instrução if pode ser seguida por uma instrução else if ... else opcional, que é muito útil para testar várias condições usando uma instrução if ... else if única.

Ao usar as instruções if, else if, else, há alguns pontos a serem considerados.

Um if pode ter zero ou mais um e deve vir depois de qualquer outro if.

Um if pode ter zero a muitos else if's e eles devem vir antes do else.

Depois que um else for bem-sucedido, nenhum dos outros if's ou else's serão testados.

dê uma olhada no tutorial de instrução if ... else .


2
Isso simplesmente não corresponde ao padrão e, além disso, é redundante. A linguagem tem todo o poder expressivo para simular else ifcomo se fosse uma palavra-chave, então não há sentido em defini-la explicitamente.
Ruslan

1
Esta é uma simplificação útil para programadores. Mas a questão não é como usar as declarações if.
Cruncher
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.