"การลัดวงจร" ใน C ชอบภาษาคืออะไร?


14

ฉันเคยได้ยินคำว่า "การลัดวงจร" ที่ใช้ใน C, C ++, C #, Java และอื่น ๆ อีกมากมาย สิ่งนี้หมายความว่าอะไรและจะใช้ในสถานการณ์ใด


6
มีบทความ Wikipedia เกี่ยวกับแนวคิดคือ: en.wikipedia.org/wiki/Short-circuit_evaluationมันเป็นการเพิ่มประสิทธิภาพในการประเมินผลของ&&ผู้ประกอบการ
wirrbel

1
@wirrbel ฉันเชื่อว่ามันใช้กับ||เช่นกัน ... อย่างน้อยก็ควร
Radu Murzea

1
@RaduMurzea แน่นอน ความคมชัด||และ&&ไปยัง&และ|เพื่อดูความแตกต่างที่ลึกซึ้ง มีโปรแกรมที่เรียบง่ายประเมิน1 || printf("yay");เทียบ0 || printf("yay");และ1 | printf("yay");VS 0 | printf("yay");เพื่อดู differeces
wirrbel

คำตอบ:


35

การลัดวงจรใน C คือเมื่อตัวดำเนินการเชิงตรรกะไม่ได้ประเมินอาร์กิวเมนต์ทั้งหมด

ยกตัวอย่างและ&&มันค่อนข้างชัดเจนว่า0 && WhoCaresจะเป็นเท็จไม่ว่าWhoCaresจะเป็นอะไร ด้วยเหตุนี้ C WhoCaresเพียงข้ามประเมิน กันไปสำหรับ1 || WhoCaresมันจะเป็นจริงเสมอ ด้วยเหตุนี้เราจึงสามารถเขียนโค้ดได้

CanFireMissiles && FireMissiles()

วิธีนี้เราหลีกเลี่ยงการดำเนินการที่อาจเป็นไปไม่ได้ ถ้าเราไม่สามารถยิงขีปนาวุธเราก็ไม่อยากลอง สิ่งนี้มักใช้กับพอยน์เตอร์โดยเฉพาะพอยน์เตอร์พอยน์เตอร์

 bool isN(int* ptr, int n){
     return ptr && *ptr == n;
 }

วิธีนี้มีประโยชน์มากมายในการหลีกเลี่ยงการคำนวณที่ไม่จำเป็น

 isFileReady() || getFileReady()

หลีกเลี่ยงการทำงานพิเศษหากเราไม่ต้องการ


1
ทุกครั้งหากฉันตอบคำถามของคุณคุณสามารถทำเครื่องหมายที่ช่องด้านข้างเพื่อทำเครื่องหมายคำถามของคุณว่าตอบแล้ว
Daniel Gratzer

7
ฉันไม่ชอบCanFireMissiles && FireMissiles()เพราะทำให้ฉันสงสัยว่าคุณกำลังใช้ไฟฟ้าลัดวงจรเพื่อก่อให้เกิดผลข้างเคียง ฉันรู้สึกเหมือนคุณกำลังซ่อนการกระทำในเงื่อนไข รหัสดังกล่าวเป็นลายลักษณ์อักษรที่ดีกว่าหรือif(CanFireMissiles){FireMissiles();} if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}
Brian

2
ฉันขอยืนยันว่าการใช้เพียงอย่างเดียวคือการซ่อนผลข้างเคียง มักจะไม่ใช่การจัดเรียง "ระเบิดเมือง" แต่สิ่งต่าง ๆ เช่น dereferencing ตัวชี้หรือการใช้ทรัพยากรระบบจะทำในลักษณะนี้ใน C ค่อนข้างบ่อย ดูหน้าวิกิพีเดียส่วนที่อยู่ภายใต้การใช้งานทั้งหมดคือ "ซ่อนผลข้างเคียง"
Daniel Gratzer

2
@jozefg คุณสามารถใช้เพื่อป้องกันการดำเนินการที่มีราคาแพงเช่นIsInCache(value) || IsInDatabase(value)ที่ซึ่ง IsInDatabase อาจใช้เวลา (โดยเฉพาะถ้าใช้อุปกรณ์มือถือและเวลาแฝงเครือข่ายเป็นปัญหา)
mgw854

4

"Short Circuiting" โดยทั่วไปหมายถึง " Short Circuit Evaluation " ซึ่งเป็นแนวคิดทั่วไปไม่ใช่เฉพาะ C เท่านั้น

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

ตัวอย่าง:

while((x && y) == 1) {
    //This bit will not execute if x is 0 or y is 0 but y won't even be 
    //evaluated due to short circuit evaluation if x is 0.
}

ตัวอย่างที่ซับซ้อนมากขึ้น:

if((a || b || c || d || e || f || g || h || i || j || k) == 1) {
    /* If any of these are equal to 1 the whole expression is equal to 1,
     * thus doesn't it make sense to short circuit evaluate this?
     * Saves a bunch of time.
     */
}

8
การลัดวงจรในระยะสั้นนั้นใช้เวลาน้อยลง แต่ไม่ได้ประเมินผลมากกว่า ฟังก์ชั่นที่ไม่ได้รับการประเมินจะไม่มีผลข้างเคียงที่จะถูกประเมิน
Pieter B

คุณรู้หรือ== 0ไม่ว่าไม่จำเป็นเท่านั้นมันอาจทำให้บางคนสับสน
Deduplicator

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