เหตุใดภาษาต่างๆจึงไม่ใช้คำสั่งสลับอย่างชัดเจนบนคำสั่งสวิตช์


17

ผมอ่านทำไมเราต้องใช้breakในswitch? และทำให้ฉันสงสัยว่าทำไมอนุญาตให้ใช้งาน fall-through โดยนัยในบางภาษา (เช่น PHP และ JavaScript) ในขณะที่ไม่มีการสนับสนุน (AFAIK) สำหรับ fall-through อย่างชัดเจน

ไม่ใช่ว่าจะต้องสร้างคำหลักใหม่ขึ้นมาตามความcontinueเหมาะสมอย่างสมบูรณ์และจะแก้ปัญหาความกำกวมไม่ว่าผู้เขียนจะมีความหมายต่อกรณีใดก็ตาม

แบบฟอร์มที่รองรับในปัจจุบันคือ:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ... //ambiguous, was break forgotten?
    case 3:
        ...
        break;
    default:
        ...
        break;
}

ในขณะที่มันเหมาะสมที่จะเขียนเป็น:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ...
        continue; //unambiguous, the author was explicit
    case 3:
        ...
        break;
    default:
        ...
        break;
}

สำหรับวัตถุประสงค์ของคำถามนี้ให้ละเว้นปัญหาว่า fall-throughs เป็นรูปแบบการเข้ารหัสที่ดีหรือไม่

มีภาษาใดบ้างที่อนุญาตให้ล้มลงและทำให้ชัดเจน

มีเหตุผลทางประวัติศาสตร์ใดบ้างที่switchยอมให้มีการล้มโดยปริยายแทนที่จะชัดเจน


4
C # กำหนดให้คุณต้องระบุอย่างชัดเจนgoto caseดังนั้นหลักฐานของคำถามของคุณผิดเล็กน้อย
pdr

1
@pdr ฉันถามอย่างชัดเจนว่ามีภาษาใดบ้างที่รองรับการล่มสลายอยู่แล้วฉันไม่ทราบgoto caseใน C #
zzzzBov

ใช่ขอโทษฉันพลาดว่าคำถามของคุณมีสองส่วน น่าเสียดายที่ใช้ถ้อยคำอย่างนี้ฉันลงคะแนนให้ปิดเพราะมันอยู่ใกล้กับคำถามแบบสำรวจความคิดเห็น จะมีคำตอบที่ถูกต้องมากมาย
pdr

C # ยังช่วยให้คุณมีป้ายกำกับหลายรายการที่แบ่งปันรายการคำสั่งเดียวกันซึ่งจะลบบางสถานการณ์ที่ต้องใช้แบบหล่นลง สำหรับส่วนที่เหลือก็มีgoto caseดังที่พีดีเอกล่าวถึง
Brian

คำตอบ:


20

มันเป็นเรื่องเกี่ยวกับประวัติศาสตร์ภาษาส่วนใหญ่เพิ่งคัดลอกสิ่งที่ C ทำ

เหตุผลที่ C ทำอย่างนั้นคือผู้สร้าง C ตั้งใจเปลี่ยนงบให้ง่ายต่อการปรับให้เหมาะสมในตารางการกระโดด นี่คือเหตุผลที่ C จำกัด การสลับคำสั่งเป็นค่าที่สำคัญ

ในตารางการกระโดดโปรแกรมจะคำนวณตำแหน่งที่จะข้ามไปตามนิพจน์ โปรแกรมจะข้ามไปยังจุดนั้นจากนั้นดำเนินการต่อจากจุดนั้น หากคุณต้องการข้ามส่วนที่เหลือของตารางคุณต้องรวมการข้ามไปยังจุดสิ้นสุดของตาราง C ใช้breakข้อความที่ชัดเจนเพื่อให้มีการโต้ตอบโดยตรงกับโครงสร้างนี้


7
ตามบันทึกเล็ก ๆ น้อย ๆ ในหนังสือ "Expert C Programming" ของเขา Peter van der Linden กล่าวว่าในขณะที่เขาทำงานให้กับซอนในคอมไพเลอร์ C ของพวกเขาบางกรณีประมาณ 97% ของกล่องสวิตช์มีอยู่breakและน้อยกว่า 3% เท่านั้นที่ล้มลง . จากนั้นเขาก็ใช้สิ่งนี้เป็นตัวอย่างที่พฤติกรรมการล้มผ่านเริ่มต้นนั้นใช้การตอบโต้ได้ง่ายกว่าและจะดีกว่าการย้อนกลับ โอ้และหนังสือเล่มนี้ยอดเยี่ยมมากในการอธิบายสิ่งแปลกประหลาดอื่น ๆ ของ C เช่นกันซึ่งบางเล่มพบใน C ++ และแม้แต่ใน C # และ Java ด้วย! มันคือรากฐานของ B และ BCPL :)
zxcdw

3
มีภาษาการเขียนโปรแกรมที่ล้มลงชัดเจนเช่น c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ) ในทางตรงกันข้ามการแตกหักก็ชัดเจนใน c #
linkerro

@zxcdw: เลวร้ายเกินไปไม่มีทางที่เบอร์ดี้เล็ก ๆ น้อย ๆ สามารถย้อนเวลากลับไปได้และแนะนำว่าฉลากใด ๆ ที่ทำเครื่องหมายcaseนอกเหนือจากชื่อแรกควรนำหน้าโดยอัตโนมัติbreakแต่สิ่งที่ทำเครื่องหมายไว้+case(หรือผู้ออกแบบอื่น ๆ ) นั่นจะเป็นเรื่องง่ายสำหรับคอมไพเลอร์ที่จะจัดการและอนุญาตให้ข้อได้เปรียบทางความหมายของข้อตกลงปัจจุบันในขณะที่กำจัดรหัสหลายบรรทัด
supercat

7

อนุญาตให้ใช้งานข้อผิดพลาดอย่างชัดเจนโดยใช้fallthroughคำหลัก (ตัวแบ่งหมายถึง แต่อาจชัดเจน):

switch val {
case 1: // breaks
case 2:
    fallthrough
case 3:
    goto 
case 4, 5, 6: // equivalent to defining individual cases with explicit fallthough
    break // unnecessary
default:
}

นี่คือบิตที่เกี่ยวข้องจากการเดินทางที่มีประสิทธิภาพและภาษาสเปค

ฉันไม่คิดว่าคุณสามารถใช้gotoเพื่อไปที่กรณีที่เฉพาะเจาะจง แต่คุณสามารถสร้างป้ายชื่อภายในกรณีและใช้gotoเหมือนปกติ

ในฐานะโบนัสไปให้คุณใช้นิพจน์ไบนารีสตริงหรือประเภทในสวิตช์เป็นคำสั่งกรณี

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