"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.