¿Es "más si" una sola palabra clave?

100

Soy nuevo en C ++. A menudo veo una declaración condicional como la siguiente:

if 
  statement_0;
else if
  statement_1;

Pregunta:

Sintácticamente , ¿debo tratar else ifcomo una sola palabra clave? ¿O es en realidad una ifdeclaración anidada dentro del exterior elsecomo se muestra a continuación?

if 
  statement_0;
else 
  if
    statement_1;
modelador
fuente
5
A tu segundo punto. Sintácticamente casi siempre está escritoelse if
TheNorthWes
8
No, ya que eso complicaría aún más la gramática: una palabra es una palabra sin espacio. Sin embargo, otros idiomas tienen palabras clave como elseify ELIF. De hecho, sólo (?) El lenguaje de programación Algol68 permite un espacio en un identificador; agradable también:PROC walk through tree ()
Joop Eggen
3
Fortran (al menos las versiones de formulario fijo) y todas las versiones estandarizadas de Algol permiten espacios en cualquier lugar. Una historia dice que aparentemente los perforadores de tarjetas perforadas eran propensos a agregar espacios al escribir código; otro simplemente que permitir espacios en los nombres de las variables permitiría a los programadores usar mejores nombres y los problemas no fueron previstos.
prosfilaes
1
La elseifpalabra clave existe en VB y PHP.
Salman A
3
Nitpick: aunque C ++ oficialmente no tiene palabras clave con espacios en ellas, tiene construcciones que para todos los efectos funcionan de esa manera. Por ejemplo, long doubletienes que escribir eso de esa manera. longdoubleEs incorrecto.
Mr Lister

Respuestas:

133

No son una sola palabra clave si vamos al borrador de la sección estándar de C ++. La tabla de 2.12 palabras clave4 enumera ambos ify por elseseparado y no hay una else ifpalabra clave. Podemos encontrar una lista más accesible de palabras clave de C ++ yendo a la sección de referencias sobre palabras clave .

La gramática en la sección 6.4también deja esto en claro:

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

El ifen else ifun comunicado tras el elsetérmino. La sección también dice:

[...] La subenunciación en una instrucción de selección (cada subenunciación, en la forma else de la instrucción if ) define implícitamente un alcance de bloque (3.3). Si la subenunciación en un enunciado de selección es un enunciado único y no un enunciado compuesto , es como si fuera reescrito para ser un enunciado compuesto que contiene el enunciado original.

y proporciona el siguiente ejemplo:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

Entonces, ¿cómo se analiza su ejemplo ligeramente extendido?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

se analizará así:

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

Nota

También podemos determinar que else ifno puede ser una palabra clave al darnos cuenta de que las palabras clave son identificadores y podemos ver en la gramática de un identificador en mi respuesta a ¿Puede comenzar un nombre de clase con un dígito numérico? que los espacios no están permitidos en los identificadores y, por lo tanto else if, no pueden ser una sola palabra clave sino dos palabras clave separadas .

Shafik Yaghmour
fuente
1
¿Podrías deducir esto sin el estándar? En ASM es: jeq( if| else if), jne( if| else if), jmp( else). Basado en eso, habría dicho que era una sola palabra clave ... probablemente no sintácticamente, pero sí en cuanto a instrucciones.
Brandon
18
@Brandon Dudo mucho que pueda pasar de manera confiable del lenguaje ensamblador a construcciones de alto nivel sin un conocimiento profundo de la gramática que se usa y del compilador en sí.
Shafik Yaghmour
Aunque tenga en cuenta que esta definición conduce potencialmente al maravilloso problema del árbol de sintaxis ambiguo "colgando más" al definir la gramática en el analizador ...
LinearZoetrope
2
Algunos idiomas no son compatibles else if, pero en su lugar elsif. En esos idiomas, else ifes realmente una palabra clave. Sin embargo, los lenguajes basados ​​en C generalmente no lo hacen, como dice esta respuesta.
sfdcfox
1
Creo que @Krumia quería ver una elsedeclaración final . Yo también agradecería esto.
Matthias
78

Sintácticamente, no es una sola palabra clave; las palabras clave no pueden contener espacios en blanco. Lógicamente, al escribir listas de else if, probablemente sea mejor si lo ve como una sola palabra clave y escribe:

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

El compilador literalmente ve esto como:

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

pero ambas formas resultan iguales y la primera es mucho más legible.

James Kanze
fuente
1
En realidad, el compilador no vio literalmente elseseguido de un compound-statement. Después de una else, se busque statement(que podría ser como return;o f()) o una compound-statement...
La máscara
@TheMask: Según la respuesta anterior de Shafik Yaghmour, el compilador literalmente ve una sola declaración, pero finge haber visto una declaración compuesta.
Ilmari Karonen
Esta respuesta dicta que cómo el analizador extrae tokens. Bueno.
haccks
24

No, no es.
Son dos palabras clave y, además, el segundo "si" es una subenunciación "dentro" del alcance determinado por la primera declaración "más".

pablo1977
fuente
2
Aunque esto describe bien lo que está sucediendo, es posible que desee agregar algunas referencias a las definiciones reales del idioma para demostrar mejor lo que está diciendo.
πάντα ῥεῖ
2
@ πάνταῥεῖ: Tienes razón sobre las referencias, pero este trabajo ha sido bien hecho por Shafik Yaghmour. Su respuesta fue la aceptada y yo también he votado a favor. Mi trabajo ha terminado aquí.
pablo1977
16

Puede ver el alcance usando llaves:

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

Y normalmente se implementa con dos palabras clave distintas, una es si y otra es otra .

reno
fuente
Así que supongo que aquellos que insisten en que se deben usar llaves donde se acepte una declaración compuesta deberían escribir todos sus condicionales no triviales como este, ¿eh? :)
dlf
5
Creo que uno puede exagerar con cualquier cosa, incluso con nuestros amados tirantes. No hagas esto en casa.
Reno
1
Todos los lenguajes estructurados con llaves (que yo sepa) que requieren llaves alrededor de todas las subdeclaraciones, incluso si están compuestas por una sola declaración, tienen una palabra clave de un solo token con el significado "si no". Creo que eso es revelador.
zwol
@Zack: Swift es un lenguaje que rompe tu regla. Requiere llaves incluso para bloques de código de declaración única, pero no tiene una palabra clave "else if". Por otro lado, la gramática es bastante diferente de C. Una if-statementtermina con un opcional else-clause. An else-clausees una else code-block o la otra else if-statement. code-blockincluye tirantes obligatorios. Por tanto, la elsepalabra clave solo puede ir seguida de {o if.
GraniteRobert
@GraniteRobert No he tenido tiempo de mirar mucho a Swift yo mismo, pero ese es un dato interesante; Estaba pensando que una gramática como esa era una posibilidad pero nunca la había visto hacer. Y notarás que eso también evita que la gente escriba " else { if ... }".
zwol
10

Como ya se respondió, no lo es. Son dos palabras clave. Es el comienzo de dos declaraciones una tras otra. Para intentar hacerlo un poco más claro, aquí está la gramática de BNF que trata sobre ify elsedeclaraciones en lenguaje 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

Tenga en cuenta que statementsí incluye selection-statement. Entonces, combinaciones como:

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

son posibles y válidos de acuerdo con el estándar / semántica de C ++.

Nota: la gramática de C ++ se toma de esta página.

La máscara
fuente
1

else y if son dos palabras clave de C ++ diferentes . Una instrucción if puede ir seguida de una instrucción else if ... else opcional . Una instrucción if puede tener cero o más si y deben ir antes que el else .

Puede encontrar la sintaxis y el ejemplo en este tutorial de instrucciones if ... else

clever_bassi
fuente
-1

Solo me gustaría agregar mi punto de vista a todas estas explicaciones. Como yo lo veo, si puede usar estas palabras clave por separado, deben ser DOS palabras clave. Tal vez pueda echar un vistazo a la gramática de C ++, desde este enlace en stackoverflow: ¿Existe una gramática estándar de C ++?

Saludos

Lling de problemas
fuente
-1

Una instrucción if puede ir seguida de una instrucción else if ... else opcional, que es muy útil para probar varias condiciones utilizando una instrucción if ... else if.

Al usar declaraciones if, else if, else, hay algunos puntos a tener en cuenta.

Un if puede tener cero o uno más y debe ir después de cualquier otro if.

Un if puede tener de cero a muchos otros if y deben venir antes que el else.

Una vez que un else if tiene éxito, no se probará ninguno de los demás if o else.

eche un vistazo al tutorial de declaración if ... else .

CONOCEME
fuente
2
Esto simplemente no se corresponde con el estándar y, además, es redundante. El lenguaje tiene todo el poder expresivo para simular else ifcomo si fuera una palabra clave, por lo que no tendría sentido definirlo explícitamente.
Ruslan
1
Esta es una simplificación útil para los programadores. Pero la pregunta no es cómo usar las declaraciones if.
Cruncher