"Else if" è una singola parola chiave?


100

Sono nuovo in C ++. Vedo spesso una dichiarazione condizionale come di seguito:

if 
  statement_0;
else if
  statement_1;

Domanda:

Sintatticamente , devo trattare else ifcome una singola parola chiave? O è effettivamente un'istruzione annidata ifall'interno dell'esterno elsecome di seguito?

if 
  statement_0;
else 
  if
    statement_1;

5
Al tuo secondo punto. Sintatticamente è quasi sempre scrittoelse if
— TheNorthWes

8
No, perché ciò renderebbe la grammatica ancora più complessa: una parola è una parola senza spazio. Altre lingue però hanno parole chiave come elseife ELIF. Infatti solo (?) Il linguaggio di programmazione Algol68 consente uno spazio in un identificatore; bello anche:PROC walk through tree ()
— Joop Eggen

3
Fortran (almeno le versioni a forma fissa) e tutte le versioni standardizzate di Algol consentono spazi ovunque. Una storia narra che apparentemente i perforatori di schede perforate erano inclini ad aggiungere spazi durante la digitazione del codice; un altro semplicemente che consentire spazi nei nomi delle variabili avrebbe consentito ai programmatori di utilizzare nomi migliori e i problemi non erano previsti.
— prosfilaes

1
La elseifparola chiave esiste in VB e PHP.
— Salman A

3
Nitpick: sebbene C ++ ufficialmente non abbia parole chiave con spazi, ha costrutti che a tutti gli effetti funzionano in questo modo. Ad esempio, long doubledevi scriverlo in questo modo. longdoublenon è corretto.
— Mr Lister

Risposte:


133

Non sono una singola parola chiave se andiamo alla bozza della sezione standard C ++ La tabella delle 2.12 parole chiave4 elenca sia ife elseseparatamente che non ci sono else ifparole chiave. Possiamo trovare un elenco più accessibile di parole chiave C ++ andando alla sezione cppreferences sulle parole chiave .

La grammatica nella sezione 6.4chiarisce anche questo:

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

Il ifin else ifuna dichiarazione a seguito del elsetermine. La sezione dice anche:

[...] L'istruzione secondaria in un'istruzione di selezione (ciascuna affermazione secondaria, nella forma else dell'istruzione if ) definisce implicitamente uno scope di blocco (3.3). Se l'istruzione secondaria in un'istruzione di selezione è un'istruzione singola e non un'istruzione composta , è come se fosse riscritta per essere un'istruzione composta contenente l'istruzione secondaria originale.

e fornisce il seguente esempio:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

Allora come viene analizzato il tuo esempio leggermente esteso?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

sarà analizzato in questo modo:

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

Nota

Possiamo anche determinare che else ifnon può essere una parola chiave rendendoci conto che le parole chiave sono identificatori e possiamo vedere dalla grammatica per un identificatore nella mia risposta a Puoi iniziare un nome di classe con una cifra numerica? che gli spazi non sono consentiti negli identificatori e quindi else ifnon può essere una singola parola chiave ma devono essere due parole chiave separate .


1
Potresti dedurlo senza lo standard? In ASM sono: jeq( if| else if), jne( if| else if), jmp( else). Basandomi su questo, avrei detto che era una singola parola chiave ... probabilmente non sintatticamente ma dal punto di vista delle istruzioni.
— Brandon

18
@Brandon Dubito fortemente che tu possa passare in modo affidabile dal linguaggio assembly a costrutti di alto livello senza una conoscenza approfondita della grammatica utilizzata e del compilatore stesso.
— Shafik Yaghmour

Anche se si noti che questa definizione porta potenzialmente al meraviglioso problema dell'albero di sintassi ambiguo "penzoloni altro" quando si definisce la grammatica nel parser ...
— LinearZoetrope

2
Alcune lingue non supportano else if, ma invece elsif. In quelle lingue, else ifè davvero una parola chiave. Tuttavia, i linguaggi basati su C generalmente non lo fanno, come afferma questa risposta.
— sfdcfox

1
Penso che @Krumia volesse vedere una elsedichiarazione finale . Lo apprezzerei anche questo.
— Matthias

78

Sintatticamente, non è una singola parola chiave; le parole chiave non possono contenere spazi bianchi. Logicamente, quando scrivi elenchi di else if, è probabilmente meglio se lo vedi come una singola parola chiave e scrivi:

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

Il compilatore lo vede letteralmente come:

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

ma entrambe le forme danno la stessa cosa, e la prima è molto più leggibile.


1
In realtà, il compilatore non ha visto letteralmente elseseguito da un file compound-statement. Dopo un else, cerca statement(che potrebbe essere come return;o f()) o un compound-statement...
— The Mask

@TheMask: Secondo la risposta di Shafik Yaghmour sopra, il compilatore vede letteralmente una singola affermazione, ma finge di aver visto un'istruzione composta.
— Ilmari Karonen

Questa risposta determina il modo in cui il parser estrae i token. Buona.
— haccks

24

No non lo è.
Sono due parole chiave e, inoltre, il secondo "if" è una sottostrazione "all'interno" dell'ambito determinato dalla prima istruzione "else".


2
Sebbene questo descriva bene cosa sta succedendo, potresti voler aggiungere alcuni riferimenti per le definizioni della lingua effettiva per dimostrare meglio ciò che stai dicendo.
— πάντα ῥεῖ

2
@ πάνταῥεῖ: Hai ragione sui riferimenti, ma questo lavoro è stato ancora ben fatto da Shafik Yaghmour. La sua risposta è stata quella accettata e anch'io ho votato. Il mio lavoro è finito qui.
— pablo1977

16

Puoi vedere l'ambito usando le parentesi graffe:

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

E normalmente attuata con due parole chiave distinte, uno è se e uno è altro .


Quindi suppongo che coloro che insistono sul fatto che le parentesi graffe dovrebbero essere usate ovunque sia accettata un'affermazione composta dovrebbero scrivere tutti i loro condizionali non banali come questo, eh? :)
— dlf

5
Penso che si possa esagerare con qualsiasi cosa, anche le nostre adorate parentesi graffe. Non farlo a casa.
— renne

1
Tutti i linguaggi strutturati con parentesi graffe (che io sappia) che richiedono parentesi graffe attorno a tutte le sottostituzioni, anche se composti da una singola istruzione, hanno una parola chiave a segno singolo con il significato "altro se". Penso che sia significativo.
— zwol

@ Zack: Swift è un linguaggio che infrange le tue regole. Richiede parentesi graffe anche per blocchi di codice a istruzione singola, ma non ha una parola chiave "else if". D'altra parte, la grammatica è abbastanza diversa da C. An if-statementtermina con un opzionale else-clause. Una else-clauseè sia else code-block o else if-statement. code-blockinclude parentesi graffe obbligatorie. Quindi la elseparola chiave può essere seguita solo da {o if.
— GraniteRobert

@GraniteRobert Non ho avuto il tempo di guardare molto a Swift da solo, ma questo è un dato interessante; Pensavo che una grammatica del genere fosse una possibilità ma non l'avevo mai vista fare. E noterai che anche questo evita di far scrivere " else { if ... }".
— zwol

10

Come già risposto, non lo è. Sono due parole chiave. È l'inizio di due affermazioni che si susseguono. Per provare a renderlo un po 'più chiaro, ecco il gramar BNF che tratta ife le elseistruzioni in linguaggio 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

Nota che esso statementstesso include selection-statement. Quindi, combinazioni come:

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

sono possibili e validi secondo lo standard / semantica C ++.

Nota: la grammatica C ++ prende da questa pagina.



-1

Vorrei solo aggiungere il mio punto di vista a tutte queste spiegazioni. A mio modo di vedere, se puoi usare queste parole chiave separatamente, devono essere DUE parole chiave. Forse puoi dare un'occhiata alla grammatica C ++, da questo link in stackoverflow: Esiste una grammatica C ++ standard?

Saluti


-1

Un'istruzione if può essere seguita da un'istruzione else if ... else opzionale, che è molto utile per testare varie condizioni utilizzando l'istruzione if ... else if.

Quando si usano le istruzioni if, else if, else ci sono pochi punti da tenere a mente.

Un if può avere zero o un altro e deve venire dopo qualsiasi altro se.

Un if può avere da zero a molti altri se e devono venire prima dell'altro.

Una volta che un altro se ha successo, nessuno dei rimanenti se è o altro sarà testato.

dai un'occhiata al tutorial sull'istruzione if ... else .


2
Questo semplicemente non corrisponde allo standard e inoltre è ridondante. Il linguaggio ha tutto il potere espressivo per simulare else ifcome se fosse una parola chiave, quindi non avrebbe senso definirlo esplicitamente.
— Ruslan

1
Questa è un'utile semplificazione per i programmatori. Ma la domanda non è come usare le istruzioni if.
— Cruncher
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.