Czy „inaczej, jeśli” to jedno słowo kluczowe?


100

Jestem nowy w C ++. Często widzę warunkowe oświadczenie, jak poniżej:

if 
  statement_0;
else if
  statement_1;

Pytanie:

Składniowo , czy należy traktować else ifjako jedno słowo kluczowe? A może jest to faktycznie zagnieżdżona ifinstrukcja w zewnętrznej, elsejak poniżej?

if 
  statement_0;
else 
  if
    statement_1;

5
Do drugiego punktu. Syntaktycznie jest prawie zawsze napisaneelse if
TheNorthWes

8
Nie, ponieważ to jeszcze bardziej skomplikowałoby gramatykę: słowo to słowo bez spacji. Jednak inne języki mają słowa kluczowe takie jak elseifi ELIF. W rzeczywistości tylko (?) Język programowania Algol68 dopuszcza spację w identyfikatorze; też miło:PROC walk through tree ()
Joop Eggen

3
Fortran (przynajmniej wersje o ustalonej formie) i wszystkie standardowe wersje Algola pozwalają na spacje w dowolnym miejscu. Jedna z historii głosi, że najwyraźniej dziurkacze do kart miały skłonność do dodawania spacji podczas wpisywania kodu; po drugie, zezwalanie na spacje w nazwach zmiennych pozwoliłoby programistom na używanie lepszych nazw, a problemy nie były przewidywane.
prosfilaes

1
elseifKluczowe istnieje w VB i PHP.
Salman A,

3
Nitpick: chociaż C ++ oficjalnie nie ma słów kluczowych ze spacjami, ma konstrukcje, takie jak dla wszystkich intencji i celów, które działają w ten sposób. Na przykład long doublemusisz to napisać w ten sposób. longdoublejest nieprawidłowe.
Pan Lister,

Odpowiedzi:


133

Nie są one pojedynczym słowem kluczowym, jeśli przejdziemy do roboczej wersji standardowej sekcji C ++ Tabela 2.12 słów kluczowych4 zawiera zarówno listę słów kluczowych, jak ifi elseosobno i nie ma tam żadnego else ifsłowa kluczowego. Bardziej przystępną listę słów kluczowych C ++ możemy znaleźć, przechodząc do sekcji cppreferences na temat słów kluczowych .

Gramatyka w sekcji 6.4również to wyjaśnia:

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

ifW else ifto oświadczenie zgodnie z elseterminem. Sekcja mówi również:

[...] Podstatunek w instrukcji selekcji (każdy podstacji, w innej postaci instrukcji if ) niejawnie definiuje zakres blokowy (3.3). Jeśli podstacja w instrukcji selekcji jest pojedynczą instrukcją, a nie instrukcją złożoną , to wygląda na to, że została przepisana na instrukcję złożoną zawierającą pierwotne podstawienie.

i podaje następujący przykład:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

Jak więc analizowany jest twój nieco rozszerzony przykład?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

zostanie przeanalizowany w ten sposób:

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

Uwaga

Możemy również stwierdzić, że else ifnie może to być jedno słowo kluczowe, zdając sobie sprawę, że słowa kluczoweidentyfikatorami i możemy zobaczyć na podstawie gramatyki identyfikatora w mojej odpowiedzi na pytanie Czy możesz rozpocząć nazwę klasy od cyfry? że spacje nie są dozwolone w identyfikatorach i dlatego else ifnie mogą być pojedynczym słowem kluczowym, ale muszą być dwoma oddzielnymi słowami kluczowymi .


1
Można to wywnioskować bez standardu? W ASM to: jeq( if| else if), jne( if| else if), jmp( else). Opierając się na tym, powiedziałbym, że to jedno słowo kluczowe… prawdopodobnie nie syntaktycznie, ale pod względem instrukcji.
Brandon

18
@Brandon Bardzo wątpię, abyś mógł niezawodnie przejść od języka asemblera do konstrukcji wysokiego poziomu bez gruntownej wiedzy o używanej gramatyce i samym kompilatorze.
Shafik Yaghmour

Chociaż należy zauważyć, że ta definicja potencjalnie prowadzi do cudownego problemu z niejednoznacznym drzewem składni „wiszącego innego” podczas definiowania gramatyki w parserze ...
LinearZoetrope

2
Niektóre języki nie obsługują else if, ale zamiast tego elsif. W tych językach else ifto naprawdę jedno słowo kluczowe. Jednak języki oparte na C generalnie nie, jak stwierdzono w tej odpowiedzi.
sfdcfox,

1
Myślę, że @Krumia chciał zobaczyć końcowe elseoświadczenie. Też bym to docenił.
Matthias,

78

Składniowo nie jest to pojedyncze słowo kluczowe; słowa kluczowe nie mogą zawierać spacji. Logicznie rzecz biorąc, pisząc listy else if, prawdopodobnie lepiej będzie , jeśli zobaczysz to jako jedno słowo kluczowe i napisz:

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

Kompilator widzi to dosłownie jako:

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

ale obie formy prowadzą do tego samego, a pierwsza jest o wiele bardziej czytelna.


1
W rzeczywistości kompilator nie widział dosłownie, elsepo którym następuje compound-statement. Po else, Poszukaj statement(co może być takie jak return;lub f()) lub compound-statement...
Maska

@TheMask: Zgodnie z powyższą odpowiedzią Shafika Yaghmoura, kompilator dosłownie widzi pojedynczą instrukcję, ale udaje, że widział instrukcję złożoną .
Ilmari Karonen

Ta odpowiedź podpowiada, jak parser wyodrębnia tokeny. Dobry.
haccks

24

Nie, nie jest.
Są to dwa słowa kluczowe, a ponadto drugie „if” jest podrzędnym elementem „wewnątrz” zakresu określonego przez pierwszą instrukcję „else”.


2
Chociaż to dobrze opisuje, co się dzieje, możesz dodać kilka odniesień do rzeczywistych definicji języka, aby lepiej udowodnić, co mówisz.
πάντα ῥεῖ

2
@ πάνταῥεῖ: Masz rację co do odniesień, ale Shafik Yaghmour już dobrze wykonał tę pracę. Jego odpowiedź była zaakceptowana i ja również zagłosowałem. Moja praca jest tutaj skończona.
pablo1977

16

Możesz zobaczyć zakres, używając nawiasów klamrowych:

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

Zwykle implementowane z dwoma różnymi słowami kluczowymi, jedno to if, a drugie to else .


Więc przypuszczam, że ci, którzy nalegają, aby używać nawiasów klamrowych wszędzie tam, gdzie akceptowane jest wyrażenie złożone, powinni pisać wszystkie nietrywialne warunki warunkowe, takie jak ten, co? :)
dlf

5
Myślę, że można przesadzić ze wszystkim, nawet z naszymi ukochanymi aparatami ortodontycznymi. Nie rób tego w domu.
renifer

1
Wszystkie języki zbudowane w nawiasach klamrowych (o których wiem), które wymagają nawiasów klamrowych wokół wszystkich podstacji, nawet jeśli składają się z pojedynczej instrukcji, mają słowo kluczowe składające się z pojedynczego tokena o znaczeniu „inaczej, jeśli”. Myślę, że to mówi.
zwolniony

@Zack: Swift to język, który łamie Twoje reguły. Wymaga nawiasów klamrowych nawet w przypadku bloków kodu zawierających pojedyncze instrukcje, ale nie ma słowa kluczowego „else if”. Z drugiej strony gramatyka jest zupełnie inna niż C. An if-statementkończy się fakultatywnie else-clause. else-clauseJest albo else code-block albo else if-statement. code-blockzawiera obowiązkowe szelki. Dlatego po elsesłowie kluczowym można umieścić tylko {lub if.
GraniteRobert

@GraniteRobert Sam nie miałem czasu, aby przyjrzeć się Swiftowi za dużo, ale to interesujący punkt danych; Myślałem, że taka gramatyka jest możliwa, ale nigdy nie widziałem, żeby to zrobiono. Zauważysz, że to również pozwala uniknąć zmuszania ludzi do pisania „ else { if ... }”.
zwolni

10

Jak już odpowiedziałem, nie jest. To dwa słowa kluczowe. To początek dwóch zdań, które następują po sobie. Aby było to trochę jaśniejsze, oto gramatyka BNF, która dotyczy ifi elseoświadczeń w języku 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

Zwróć uwagę, że statementsamo obejmuje selection-statement. Tak więc kombinacje takie jak:

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

są możliwe i poprawne zgodnie ze standardem / semantyką C ++.

Uwaga: gramatyka C ++ pochodzi z tej strony.



-1

Chciałbym tylko dodać swój punkt widzenia do wszystkich tych wyjaśnień. Jak widzę, jeśli możesz użyć tych słów kluczowych oddzielnie, muszą to być DWA słowa kluczowe. Może możesz rzucić okiem na gramatykę C ++, korzystając z tego linku w stackoverflow: Czy istnieje standardowa gramatyka C ++?

pozdrowienia


-1

Po instrukcji if może następować opcjonalna instrukcja else if ... else, która jest bardzo przydatna do testowania różnych warunków przy użyciu pojedynczej instrukcji if ... else if.

Używając instrukcji if, else if, else, należy pamiętać o kilku kwestiach.

Jeśli może mieć zero lub jeden inny i musi następować po każdym innym jeśli.

Jeśli może mieć zero do wielu innych ifów i muszą one występować przed innymi.

Raz inny, jeśli się powiedzie, żaden z pozostałych „jeśli” lub „innego” nie zostanie poddany próbie.

zobacz instrukcję instrukcji if ... else .


2
To po prostu nie odpowiada standardowi, a ponadto jest zbędne. Język ma całą moc ekspresyjną do symulacji else iftak, jakby był słowem kluczowym, więc nie ma sensu definiować go bezpośrednio.
Ruslan

1
To przydatne uproszczenie dla programistów. Ale nie chodzi o to, jak używać instrukcji if.
Cruncher
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.