c++ - para - manual programacion android español pdf
El bloque "if" sin llaves hace que "else if" sea anidado posteriormente (5)
AFAIK, si no se proporciona un bloque "si" en las llaves, entonces solo se considera 1 instrucción dentro de él. p.ej
if(..)
statement_1;
statement_2;
Independientemente de las pestañas, solo la statement_1
se considera dentro del bloque if
.
El siguiente código no se lleva bien con eso:
int main ()
{
if(false) // outer - if
if(false) // nested - if
cout << "false false/n";
else if(true)
cout << "true/n";
}
El código anterior no imprime nada. Debería haber impreso "true"
.
Aparece a partir de la else if
se anida automáticamente dentro del bloque if
exterior . g++ -Wall
emite una advertencia, pero esa no es la pregunta aquí. Una vez que colocas las llaves, todo va bien como se esperaba.
¿Por qué tan diferente comportamiento?
[Demostración de GCC: sin tirantes y con tirantes ].
El comportamiento no es realmente diferente, es completamente consistente: todo el bloque interior if
, incluido else if
, se considera como un bloque.
Esta es una ambigüedad clásica en el análisis, conocida como el "problema else
cuelga" : hay dos formas válidas de analizar esto cuando la gramática está escrita en el BNF normal:
O bien el final es parte del bloque externo, o del bloque interno.
La mayoría de los idiomas resuelven la ambigüedad decidiendo (arbitrariamente) que los bloques se combinan con avidez por el analizador, es decir, el else
[ if
] se asigna al más cercano if
.
Es bastante natural desde el punto de vista C parser.
El analizador, mientras analiza la instrucción if, analiza primero la expresión de condición, luego analiza la primera instrucción después de la condición, luego busca la palabra clave else y, si el otro presenta, analiza la segunda declaración (alternativa).
Sin embargo, la primera declaración también es una declaración if, por lo que el analizador llama al "if-parser" recursivamente (antes de probar otra palabra clave). Esta llamada recursiva analiza completamente la instrucción if-else interna (incluyendo else ), y mueve la posición del token "más allá del final" del fragmento de código completo.
Cualquier intento de implementar un comportamiento alternativo debe implicar una comunicación adicional entre los analizadores "externos" e "internos": el analizador externo debe informar a los "internos" para que no sean codiciosos (es decir, que no se coman la sentencia else ). Esto agregaría complejidad adicional a la sintaxis del lenguaje.
No debería imprimir nada. Es el equivalente a esto, ya que el segundo if / else if es un bloque que pertenece al primero if:
if(false) {
if(false) // nested - if
cout << "false false/n";
else if(true)
cout << "true/n";
}
Porque la else
realidad está siendo agrupada con la interna if
, no la externa. En realidad se está analizando como
int main ()
{
if(false) // outer - if (never gets executed)
{
if(false) // nested - if
{
cout << "false false/n";
} else if(true) {
cout << "true/n";
}
}
}
Puede resolver el problema colocando explícitamente las llaves donde las desee.
else
declaración siempre se adjunta al más cercano if
. Sin ramas anidadas, if
no forma una declaración significativa, el analizador continúa.