&& และ || ไม่ได้เป็นตรรกะ แต่ผู้ประกอบการตามเงื่อนไข?


62

ฉันเป็นบิตสับสนโดยเอกสาร # MSDN C ซึ่งระบุว่า&และ|ผู้ประกอบการเชิงตรรกะและที่&&และ||ผู้ประกอบการที่มีเงื่อนไข

ฉันให้โทร&&, ||และ!ดำเนินการทางตรรกะดังนั้นผมผิดหรือเปล่า?


4
ดูเหมือนจะไร้เหตุผล แต่มีความแตกต่างที่สำคัญระหว่างสองคลาสและเป็นสิ่งสำคัญที่คุณไม่คิดว่า|มันสามารถใช้แทนกัน||ได้แม้ว่าในหลาย ๆ กรณีพวกเขาสามารถเปลี่ยนได้โดยไม่มีการเปลี่ยนแปลงที่ชัดเจนในพฤติกรรมของโปรแกรม
Daniel R Hicks

คำตอบ:


120

ฉันเป็นบิตสับสนโดยเอกสาร # MSDN C ซึ่งระบุว่า&และ|ผู้ประกอบการเชิงตรรกะและที่&&และ||ผู้ประกอบการที่มีเงื่อนไข ฉันให้โทร&&, ||และ!ดำเนินการทางตรรกะดังนั้นผมผิดหรือเปล่า?

ไม่มี คุณถูกต้อง

มีข้อผิดพลาดเล็ก ๆ น้อย ๆ ส่วนใหญ่ที่ไม่สำคัญในระบบการตั้งชื่อเอกสาร MSDN; ฉันพยายามทำให้พวกเขาออกมาให้มากที่สุดเท่าที่จะทำได้ แต่ในกรณีที่มันไม่ผิดอย่างผิดปกติและทำให้เข้าใจผิดมันไม่ได้ใช้เวลาอย่างชาญฉลาดเสมอไป ไปที่สเปคถ้าคุณต้องการคำสั่งที่ชัดเจนเกี่ยวกับชื่อของคุณสมบัติ C #

ดังนั้น: หน่วยงานที่เกี่ยวข้องคือข้อกำหนด C # ซึ่งระบุไว้ในหัวข้อ 7.11:

เครื่องหมาย&, ^และ, |เรียกว่าตัวดำเนินการเชิงตรรกะ

จากนั้นจะทำการแยกตัวดำเนินการทางตรรกะภายในออกเป็นจำนวนเต็มการแจงนับบูลีนและ nullable-Boolean ตัวดำเนินการทางตรรกะ นอกจากนี้ยังมีตัวดำเนินการเชิงตรรกะที่ผู้ใช้กำหนด ดูรายละเอียดสเปค

ในมาตรา 7.12 เรามี

ตัวดำเนินการ&&และ||เรียกว่าตัวดำเนินการโลจิคัลแบบมีเงื่อนไข พวกเขาจะเรียกว่าตัวดำเนินการตรรกะ "ลัดวงจร"

ดังนั้นทั้งหมดของพวกเขาเป็นตัวดำเนินการเชิงตรรกะ บางส่วนของพวกเขาเป็นผู้ประกอบการตรรกะเงื่อนไข

ทำให้ตัวดำเนินการเชิงตรรกะเงื่อนไขอะไร บางคนอาจคาดเดาอย่างกว้างขวางว่าเป็นเพราะพวกเขามักจะใช้ในข้อความสั่งเงื่อนไข ( if) หรือนิพจน์เงื่อนไข ( ? :) เหตุผลที่แท้จริงได้รับจากข้อกำหนด:

ตัวดำเนินการ&&และ||ตัวดำเนินการเป็นรุ่นที่มีเงื่อนไขของ&และ|ตัวดำเนินการ: การดำเนินการที่x && yสอดคล้องกับการดำเนินการx & yยกเว้นว่าyจะได้รับการประเมินก็ต่อเมื่อxไม่ใช่เท็จ การดำเนินการx || yสอดคล้องกับการดำเนินการx | yยกเว้นว่าyจะได้รับการประเมินก็ต่อเมื่อxไม่เป็นความจริง

ตัวดำเนินการโลจิคัลแบบมีเงื่อนไขจะถูกตั้งชื่อเนื่องจากตัวถูกดำเนินการทางด้านขวาถูกประเมินตามเงื่อนไขขึ้นอยู่กับค่าของตัวถูกดำเนินการทางด้านซ้าย

เราสามารถมองเห็นได้มากขึ้นเต็มตาโดยสังเกตว่าดำเนินการทางตรรกะเงื่อนไขเป็นเพียง "น้ำตาลประโยค" สำหรับการแสดงออกเงื่อนไข x && yเป็นเพียงวิธีที่สะดวกสบายมากขึ้นในการเขียนx ? y : falseและเป็นเพียงวิธีที่สะดวกสบายมากขึ้นในการเขียน x || y นิพจน์เชิงตรรกะแบบมีเงื่อนไขเป็นนิพจน์แบบมีเงื่อนไขจริง ๆx ? true : y

นอกจากนี้ยังมีรูปแบบที่ผู้ใช้กำหนดของตัวดำเนินการเชิงตรรกะที่มีเงื่อนไขและมันก็ยุ่งยากเล็กน้อย ดูข้อกำหนดสำหรับรายละเอียด

อ่านเพิ่มเติมถ้าเรื่องนี้คุณสนใจ:


3
@RobertHarvey: ใช่แล้วความจริงที่ว่า & สามารถทำงานกับ bools, ประเภทจำนวนเต็มหรือประเภท enum แต่ && & ทำงานเฉพาะใน bools เท่านั้นไม่มีอะไรเกี่ยวข้องกับการเลือกตั้งชื่อหนึ่งในรูปแบบ "เงื่อนไข" ของผู้ดำเนินการ ตัวดำเนินการเงื่อนไขเป็นเงื่อนไขเนื่องจากมีสาขาตามเงื่อนไขในความหมายของการประเมิน
Eric Lippert

16
ฉันอยู่ภายใต้การแสดงผลคำว่า "ผู้ดำเนินการลัดวงจร" เป็นที่นิยมมาก (และอาจจะคลุมเครือน้อย) กว่า "ผู้ดำเนินการตามเงื่อนไข" ในความหมายที่อธิบายไว้
Doc Brown

15
@DocBrown: มันเป็นที่นิยมอย่างแน่นอน แต่ฉันมักจะพบว่าชื่อที่ทำให้เข้าใจผิด; ดูเหมือนว่าจะมีการประกาศเกียรติคุณจากคนที่คิดว่า "ลัดวงจร" และ "ลัด" เพื่อให้ได้ผลลัพธ์เป็นสิ่งเดียวกัน การลัดวงจรเป็นความผิดที่เป็นอันตรายซึ่งสามารถทำลายระบบไฟฟ้าได้อย่างรวดเร็ว เราตั้งชื่อ "ไม่ปลอดภัย" บล็อกใน C # "ไม่ปลอดภัย" เพราะพวกเขากำลังอันตรายถ้าใช้ไม่ถูกต้อง ; อย่าให้ชื่อที่คุ้มค่ากับภาระที่ทำให้เข้าใจผิด อย่าให้ฉันเริ่มต้นกับผู้ดำเนินการ Elvis :-)
Eric Lippert

26
@EricLippert: ในขณะที่ "ลัดวงจร" อาจฟังดูน่ากลัวสำหรับประชาชนทั่วไปฉันไม่คิดว่า K&R สับสนเกี่ยวกับคำจำกัดความที่แท้จริง ในวิศวกรรมไฟฟ้าการลัดวงจรไม่ได้เป็นความผิดที่เป็นอันตรายเสมอไปในความเป็นจริงเราตั้งใจทำตลอดเวลา มันหมายถึงการตัดส่วนที่ไม่ต้องการของวงจรออกโดยให้กระแสไฟฟ้าสั้นลงตามไป
hackerb9

1
@CortAmmon: คุณจะต้องอ่านย่อหน้าต่อไปนี้โดยที่ฉันเรียกว่าซีแมนทิกส์ที่ผู้ใช้กำหนดเองนั้นมีความแตกต่างกันเล็กน้อยและคุณควรจะเห็นสเป็กสำหรับรายละเอียด
Eric Lippert

27

ใน C # นี่คือ ตัวดำเนินการเชิงตรรกะทั้งหมด

int x = 0xABCD & 0xFF // x == 0xCD

&&และ||ถูกเรียกว่า " ตัวดำเนินการเชิงตรรกะแบบมีเงื่อนไข " เพราะมันจะลัดวงจร

bool someOtherCondition = true;
if (x == 0xEF && someOtherCondition) // someOtherCondition is not evaluated, 
                                     // because x == 0xEF is false

โปรดทราบว่าคำศัพท์นี้แตกต่างจากภาษาเป็นภาษา ใน C และ C ++ &&และ||เป็นเพียงตัวดำเนินการเชิงตรรกะ ใน Java &และ|จะเรียกว่าผู้ประกอบการ Bitwiseขณะที่ C และ C ++ classifies พวกเขาเป็นผู้ประกอบการทางคณิตศาสตร์


3
ใช่ Microsoft เป็นหน่วยงานที่มีอำนาจ แต่เอกสารที่มีสิทธิ์เป็นข้อกำหนด โปรดดูที่ส่วน 7.12, Operators Logical เงื่อนไข
Eric Lippert

8
คุณธรรมของเรื่องราว: มันสำคัญกว่าที่จะเข้าใจอย่างแม่นยำว่าตัวดำเนินการเหล่านี้ทำอะไรได้มากกว่าที่จะแม่นยำเกี่ยวกับชื่อของพวกเขา
Robert Harvey

21
มุ่งเน้นไปที่สิ่งที่ผู้ปฏิบัติงานทำและหยุดยั้งการใช้คำศัพท์ ดูเพิ่มเติมการตั้งชื่อพิจารณาอันตราย
Robert Harvey

4
+1 ทุกอย่างที่ระบุในคำถามเป็นเพียงตัวดำเนินการที่ใช้นิพจน์หนึ่งหรือสองนิพจน์และประเมินค่า คำคุณศัพท์คือการแยกผมโดยไม่จำเป็น
Blrfl


-2

ประเด็นก็คือ&และ|เป็นผู้ประกอบการระดับบิตซึ่งหมายความว่าพวกเขาจะนำไปใช้และผลผลิตค่าสตริงบิต และ bitwise เป็นคำที่ใช้กันมากในหมู่โปรแกรมเมอร์

ยกตัวอย่างเช่นในขณะที่0xff & 0x00 == 0x000xff | 0x00 == 0xff

และ&&และ||นำไปใช้กับเงื่อนไขและให้ค่าปกติของเงื่อนไข คือและtruefalse

ยกตัวอย่างเช่นในขณะที่true && false == falsetrue || false == true

ดังนั้น&&และ||อาจเรียกได้ว่าโอเปอเรเตอร์ที่มีเงื่อนไขแม้ว่าจะไม่ใช่คำศัพท์ปกติในหมู่โปรแกรมเมอร์

แน่นอนโปรแกรมเมอร์ C, C ++, Java และ C # ทุกคนรู้ทุกอย่าง แต่ฉันเดาว่าการเข้าใจผิดเกิดขึ้นเพราะ "โอเปอเรเตอร์ที่มีเงื่อนไข" ไม่ใช่คำที่นักโปรแกรมเมอร์ใช้บ่อย


5
แน่นอนโปรแกรมเมอร์ C, C ++, Java และ C # ทุกคนรู้ทุกอย่าง นั่นเป็นสิ่งที่หยาบคายมากในการเขียนหมายความว่า OP นั้นโง่ เช่นเดียวกันโดยเขียนโปรแกรมเมอร์เราคุณไม่รวม OP โปรดอย่าทำอย่างนั้น
DarkDust

1
ฉันไม่คิดว่าคำตอบในภายหลังของคุณจะเพิ่มคุณค่าใด ๆหลังจากคำตอบที่ได้รับการยอมรับของ Eric Lippert และยิ่งไปกว่านั้นไม่ถูกต้องในความหมายที่ไม่เข้าใจประเด็นของคำถาม
Honza Zidek

@DarkDust โปรแกรมเมอร์ C, C ++, Java และ C # ทุกคนควรเข้าใจตัวดำเนินการเหล่านั้น นี้ไม่ได้ที่หยาบคายแต่ความเป็นจริง
Phil1970

1
@ Phil1970: OP ไม่ดูเหมือนจะเข้าใจผู้ประกอบการเหล่านี้ก็เกี่ยวกับการชี้แจงของการตั้งชื่อ ในแง่นี้และการเน้นย้ำถึงคำศัพท์ที่เกี่ยวข้องในคำตอบของฮิลตันประโยคของเขาสามารถตีความได้ว่าเป็นความหมายซึ่งโปรแกรมเมอร์ทุกคนรู้เกี่ยวกับรายละเอียดการตั้งชื่อเหล่านี้ แต่คุณไม่ต้องการ สิ่งนี้เป็นสิ่งที่ผิด (ดังที่เห็นได้จากการสนทนาของคำตอบอื่น ๆ ) และการใช้ถ้อยคำนั้นหยาบคาย
DarkDust

4
เรียนทั้งหมดฉันขอโทษถ้าคำตอบของฉันดูหยาบคาย ภาษาอังกฤษไม่ใช่ภาษาที่ 1 ไม่ว่าในกรณีใดฉันไม่เคยตั้งใจจะบอกว่า OP ไม่ใช่โปรแกรมเมอร์ ในทางตรงกันข้ามฉันหมายความว่าเขาหรือเธอรู้สึกสับสนกับการตั้งชื่อผิดปกติในข้อความที่เขาหรือเธออ่าน ทั้งหมดที่ฉันพยายามทำคือการชี้แจงการตั้งชื่อที่ผิดปกติโดยชิ้นส่วนของโปรแกรม
Hilton Fernandes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.