“ else if” เป็นคำหลักคำเดียวหรือไม่


100

ฉันยังใหม่กับ C ++ ฉันมักจะเห็นคำสั่งเงื่อนไขดังต่อไปนี้:

if 
  statement_0;
else if
  statement_1;

คำถาม:

syntacticallyฉันจะรักษาelse ifเป็นคำหลักเดียว? หรือจริงๆแล้วมันเป็นifคำสั่งซ้อนกันภายในด้านนอกelseเหมือนด้านล่าง?

if 
  statement_0;
else 
  if
    statement_1;

5
ไปยังจุดที่สองของคุณ มีการเขียนทางelse if
ไวยากรณ์

8
ไม่ได้เนื่องจากจะทำให้ไวยากรณ์ยังคงซับซ้อนมากขึ้น: word คือคำที่ไม่มีช่องว่าง ภาษาอื่น ๆ แม้ว่าจะมีคำหลักที่เหมือนและelseif ELIFในความเป็นจริงเท่านั้น (?) ภาษาโปรแกรม Algol68 อนุญาตให้มีช่องว่างในตัวระบุ ก็ดีเหมือนกัน:PROC walk through tree ()
Joop Eggen

3
Fortran (อย่างน้อยก็คือเวอร์ชันฟอร์มคงที่) และ Algol เวอร์ชันมาตรฐานทั้งหมดอนุญาตให้มีช่องว่างได้ทุกที่ มีเรื่องหนึ่งที่เห็นได้ชัดว่าเครื่องเจาะบัตรเจาะมีแนวโน้มที่จะเพิ่มช่องว่างเมื่อพิมพ์รหัส อีกประการหนึ่งก็คือการปล่อยให้มีช่องว่างในชื่อตัวแปรจะทำให้โปรแกรมเมอร์ใช้ชื่อที่ดีขึ้นและปัญหาไม่ได้คาดการณ์ไว้
prosfilaes

1
elseifคำหลักที่มีอยู่ใน VB และ PHP
Salman A

3
Nitpick: แม้ว่า C ++ อย่างเป็นทางการจะไม่มีคำหลักที่มีช่องว่างอยู่ แต่ก็มีโครงสร้างเช่นเดียวกับเจตนาและวัตถุประสงค์ทั้งหมดที่ทำงานในลักษณะนั้น ตัวอย่างเช่นlong doubleคุณต้องเขียนในลักษณะนั้น longdoubleไม่ถูกต้อง
Mr Lister

คำตอบ:


133

พวกเขาจะไม่ได้เป็นคำหลักเดียวถ้าเราไปที่ร่าง c ++ มาตรฐานส่วน2.12 คำตาราง4ทั้งสองรายการifและelseแยกจากกันและไม่มีelse ifคำหลัก เราสามารถหารายชื่อที่สามารถเข้าถึงได้มากขึ้นของ C ++ คำหลักโดยไปที่ส่วน cppreferences คำหลัก

ไวยากรณ์ในส่วน6.4นี้ยังทำให้ชัดเจน:

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

ifในelse ifเป็นคำสั่งดังต่อไปนี้elseระยะ ส่วนนี้ยังกล่าวว่า:

[... ] การแทนที่ในคำสั่งการเลือก (การแทนที่แต่ละรายการใน รูปแบบอื่นของคำสั่งif ) กำหนดขอบเขตบล็อกโดยปริยาย (3.3) ถ้าการย่อยในคำสั่งการเลือกเป็นคำสั่งเดียวและไม่ใช่คำสั่งผสมจะเหมือนกับว่ามันถูกเขียนใหม่ให้เป็นคำสั่งผสมที่มีส่วนย่อยเดิม

และให้ตัวอย่างต่อไปนี้:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

ตัวอย่างส่วนขยายเล็กน้อยของคุณมีการแยกวิเคราะห์อย่างไร?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

จะถูกแยกวิเคราะห์ดังนี้:

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

บันทึก

นอกจากนี้เรายังสามารถระบุได้ว่าelse ifไม่สามารถเป็นคีย์เวิร์ดเดียวได้โดยตระหนักว่าคีย์เวิร์ดเป็นตัวระบุและเราสามารถดูได้จากไวยากรณ์สำหรับตัวระบุในคำตอบของฉันคุณสามารถเริ่มต้นชื่อคลาสด้วยตัวเลขได้หรือไม่? ว่าช่องว่างไม่ได้รับอนุญาตในตัวบ่งชี้และดังนั้นจึงelse ifไม่สามารถที่จะเป็นหนึ่งเดียวคำหลักแต่ต้องแยกออกเป็นสองคำหลัก


1
คุณสามารถสรุปสิ่งนี้ได้โดยไม่ต้องมีมาตรฐาน? ใน ASM: jeq( if| else if), jne( if| else if), jmp( else) จากนั้นฉันจะบอกว่ามันเป็นคีย์เวิร์ดคำเดียว .. อาจจะไม่ได้ใช้ไวยากรณ์ แต่เป็นการสอนที่ชาญฉลาด
Brandon

18
@ แบรนดอนฉันสงสัยอย่างมากว่าคุณสามารถเปลี่ยนจากภาษาแอสเซมบลีไปเป็นโครงสร้างระดับสูงได้อย่างน่าเชื่อถือโดยที่ไม่มีความรู้เกี่ยวกับไวยากรณ์ที่ใช้และตัวคอมไพเลอร์เอง
Shafik Yaghmour

แม้ว่าคำจำกัดความนี้อาจนำไปสู่ปัญหาโครงสร้างไวยากรณ์ที่คลุมเครือ "dangling else" ที่ยอดเยี่ยมเมื่อกำหนดไวยากรณ์ในโปรแกรมแยกวิเคราะห์ ...
LinearZoetrope

2
บางภาษาไม่สนับสนุนแต่แทนที่จะelse if elsifในภาษาเหล่านั้นelse ifเป็นหนึ่งคำหลักอย่างแท้จริง อย่างไรก็ตามภาษาที่ใช้ C โดยทั่วไปไม่เป็นไปตามคำตอบนี้
sfdcfox

1
ฉันคิดว่า @Krumia ต้องการเห็นelseคำสั่งสุดท้าย ฉันจะขอบคุณสิ่งนี้เช่นกัน
Matthias

78

ในทางไวยากรณ์ไม่ใช่คำหลักคำเดียว คำหลักต้องไม่มีช่องว่าง ตามหลักเหตุผลเมื่อเขียนรายการelse ifน่าจะดีกว่าถ้าคุณเห็นว่าเป็นคำหลักคำเดียวและเขียน:

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

คอมไพเลอร์มองว่าสิ่งนี้เป็น:

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

แต่ทั้งสองรูปแบบออกมาเหมือนกันและแบบแรกอ่านได้ไกลกว่า


1
อันที่จริงคอมไพเลอร์ไม่เห็นelseตามด้วยไฟล์compound-statement. หลังจากนั้นelseจะมองหาstatement(ซึ่งอาจจะเหมือนreturn;หรือf()) หรือcompound-statement...
The Mask

@TheMask: ตามคำตอบของ Shafik Yaghmour ข้างต้นคอมไพเลอร์เห็นข้อความเดียว แต่แสร้งทำเป็นว่ามันเห็นคำสั่งผสม
Ilmari Karonen

คำตอบนี้กำหนดว่าวิธีแยกวิเคราะห์โทเค็น ดี.
haccks

24

ไม่มันไม่ใช่.
เป็นคำหลักสองคำและยิ่งกว่านั้นคำที่สอง "if" เป็นส่วนย่อย "ภายใน" ขอบเขตที่กำหนดโดยคำสั่ง "else" คำแรก


2
แม้ว่าสิ่งนี้จะอธิบายถึงสิ่งที่เกิดขึ้นได้เป็นอย่างดี แต่คุณอาจต้องการเพิ่มการอ้างอิงสำหรับคำจำกัดความภาษาจริงเพื่อพิสูจน์สิ่งที่คุณกำลังพูดได้ดีขึ้น
πάνταῥεῖ

2
@ πάνταῥεῖ: คุณพูดถูกเกี่ยวกับข้อมูลอ้างอิง แต่งานนี้ยังทำได้ดีโดย Shafik Yaghmour คำตอบของเขาคือคำตอบที่ได้รับการยอมรับและฉันก็โหวตด้วยเช่นกัน งานของฉันเสร็จแล้วที่นี่
pablo1977

16

คุณสามารถดูขอบเขตได้โดยใช้วงเล็บปีกกา:

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

และโดยปกติใช้กับคำหลักสองคำที่แตกต่างกันคำหนึ่งคือifและอีกคำ


ดังนั้นฉันคิดว่าผู้ที่ยืนยันว่าควรใช้วงเล็บปีกกาทุกที่ที่ยอมรับคำสั่งผสมควรเขียนเงื่อนไขที่ไม่สำคัญทั้งหมดของพวกเขาเช่นนี้ใช่มั้ย? :)
dlf

5
ฉันคิดว่าใคร ๆ ก็สามารถหักโหมทำอะไรก็ได้แม้แต่การดัดฟันที่เป็นที่รักของเรา อย่าทำที่บ้าน
กวางเรนเดียร์

1
ภาษาที่มีโครงสร้างวงเล็บปีกกาทั้งหมด (ที่ฉันรู้จัก) ที่ต้องใช้วงเล็บปีกการอบ ๆ ส่วนย่อยทั้งหมดแม้ว่าจะประกอบด้วยคำสั่งเดียว แต่ก็มีคีย์เวิร์ดโทเค็นเดี่ยวที่มีความหมายว่า "else if" ฉันคิดว่านั่นเป็นการบอก
zwol

@Zack: Swift เป็นภาษาที่แหกกฎของคุณ ต้องใช้วงเล็บปีกกาแม้กระทั่งสำหรับบล็อกรหัสคำสั่งเดียว แต่ไม่มีคำหลัก "else if" ในทางตรงกันข้ามไวยากรณ์ค่อนข้างแตกต่างจากซีปลายกับตัวเลือกif-statement เป็นอย่างใดอย่างหนึ่งหรือ รวมถึงการจัดฟันแบบบังคับ ดังนั้นคำหลักที่สามารถตามด้วยเท่านั้นหรือ else-clauseelse-clause else code-blockelse if-statementcode-blockelse{if
GraniteRobert

@GraniteRobert ไม่มีเวลาดู Swift มากนัก แต่นั่นเป็นจุดข้อมูลที่น่าสนใจ ฉันคิดว่าไวยากรณ์แบบนั้นเป็นไปได้แต่ไม่เคยเห็นมาก่อน และคุณจะทราบด้วยว่าหลีกเลี่ยงไม่ให้คนอื่นเขียน " else { if ... }"
zwol

10

อย่างที่ตอบไปแล้วมันไม่ใช่ เป็นคำหลักสองคำ เป็นจุดเริ่มต้นของสองคำสั่งหนึ่งต่อจากกัน เพื่อพยายามทำให้ชัดเจนขึ้นเล็กน้อยนี่คือไวยากรณ์ของ BNF ที่จัดการifและelseคำสั่งในภาษา 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

โปรดทราบว่าstatementตัวเอง selection-statementได้แก่ ดังนั้นชุดค่าผสมเช่น:

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

เป็นไปได้และถูกต้องตามมาตรฐาน C ++ / ความหมาย

หมายเหตุ: C ++ ใช้ไวยากรณ์จากนี้หน้า


1

อื่นและถ้ามีความแตกต่างกันสอง c ++ คำหลัก ถ้างบสามารถตามด้วยตัวเลือกอื่นถ้า ... อื่นคำสั่ง ถ้างบสามารถมีศูนย์หรือมากกว่าอื่นถ้า 's และพวกเขาจะต้องมาก่อนอย่างอื่น

คุณสามารถค้นหาไวยากรณ์และตัวอย่างในบทช่วยสอนคำสั่ง if ... else


-1

ฉันแค่อยากจะเพิ่มมุมมองของฉันในคำอธิบายทั้งหมดนี้ อย่างที่ฉันเห็นถ้าคุณสามารถใช้คำหลักเหล่านี้แยกกันคำหลักเหล่านี้จะต้องเป็นสองคำ บางทีคุณอาจดูไวยากรณ์ c ++ จากลิงค์นี้ใน stackoverflow: มีไวยากรณ์ C ++ มาตรฐานหรือไม่?

ความนับถือ


-1

คำสั่ง if สามารถตามด้วยคำสั่ง else if ... else ซึ่งมีประโยชน์มากในการทดสอบเงื่อนไขต่างๆโดยใช้คำสั่ง single if ... else if

เมื่อใช้คำสั่ง if, else if, else มีบางประเด็นที่ควรทราบ

ถ้าสามารถมีศูนย์หรืออย่างอื่นได้และจะต้องมาตามหลังถ้ามี

if สามารถมีศูนย์เป็นจำนวนมาก if และพวกเขาต้องมาก่อนที่อื่น

อีกครั้งหนึ่งหากทำสำเร็จจะไม่มีใครเหลืออีกเลยหากจะถูกทดสอบ

ได้ดูถ้า ... อื่นกวดวิชาคำสั่ง


2
สิ่งนี้ไม่สอดคล้องกับมาตรฐานและยิ่งไปกว่านั้นซ้ำซ้อน ภาษามีพลังในการแสดงออกทั้งหมดในการจำลองelse ifราวกับว่าเป็นคำหลักดังนั้นจึงไม่มีเหตุผลที่จะกำหนดอย่างชัดเจน
Ruslan

1
นี่เป็นการลดความซับซ้อนที่มีประโยชน์สำหรับโปรแกรมเมอร์ แต่คำถามไม่ได้ถามว่าจะใช้คำสั่ง if อย่างไร
Cruncher
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.