ฉันควรใช้วงเล็บในคำสั่งทางตรรกะแม้ว่าไม่จำเป็น?


100

สมมติว่าผมมีสภาพบูลีนa AND b OR c AND dและฉันใช้ภาษาที่มีการสั่งซื้อที่สูงขึ้นของแบบอย่างการดำเนินงานกว่าAND ORฉันสามารถเขียนรหัสบรรทัดนี้:

If (a AND b) OR (c AND d) Then ...

แต่จริงๆแล้วมันเทียบเท่ากับ:

If a AND b OR c AND d Then ...

มีข้อโต้แย้งใด ๆ ในหรือต่อต้านรวมถึงวงเล็บนอก? ประสบการณ์ภาคปฏิบัติแนะนำว่ามันคุ้มค่าหรือไม่ที่จะต้องอ่านให้เข้าใจ หรือมันเป็นสัญญาณว่านักพัฒนาต้องการนั่งลงและมั่นใจในพื้นฐานของภาษาของพวกเขา?


90
ฉันอาจขี้เกียจ แต่ฉันชอบที่จะมีวงเล็บในสถานการณ์ส่วนใหญ่เพื่อให้สามารถอ่านได้
thorsten müller

6
ฉันด้วย. ฉันแค่หวังว่าฉันจะทำมันมากขึ้นเพื่อให้อ่านง่ายขึ้นและน้อยลงเพราะฉันขี้เกียจเกินกว่าจะมั่นใจ / มีความสามารถในพื้นฐานของการจองของฉัน
Jeff Bridgman

16
การใช้วงเล็บอย่างดีก็เหมือนกับการใช้ไวยากรณ์ได้ดี 2 * 3 + 2อาจเหมือนกัน(2 * 3) + 2แต่อ่านง่ายกว่า
ซ้ำ

16
@Mathew บางทีถ้าคุณอ่อนแอในวิชาคณิตศาสตร์ สำหรับกรณีที่ซับซ้อนมากขึ้นโปรดใช้วงเล็บ แต่สำหรับคนที่เห็นได้ชัดเจน (BODMAS ... ) พวกเขาลดความสามารถในการอ่านมากกว่าการช่วยเหลือเนื่องจากความยุ่งเหยิง
Konrad Rudolph

3
ที่กล่าวมาก่อนหน้านี้ของ AND / OR ถืออยู่ใน Basic, Python, SQL ... ความประทับใจของฉันคือว่านี่เป็นกฎในภาษาสมัยใหม่ส่วนใหญ่ (แม้ว่าจะไม่ใช่ทั้งหมด)
ทิมกู๊ดแมน

คำตอบ:


117

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

สำหรับความชัดเจนให้นึกถึงวงเล็บเช่นความคิดเห็นในโค้ด: พวกมันไม่จำเป็นอย่างยิ่งและในทางทฤษฎีแล้วผู้พัฒนาที่มีความสามารถจะต้องสามารถคิดรหัสโดยไม่มีพวกมัน และยังชี้นำเหล่านี้มีประโยชน์มากเพราะ:

  • พวกเขาลดงานที่จำเป็นในการเข้าใจรหัส
  • พวกเขาให้การยืนยันความตั้งใจของนักพัฒนา

นอกจากนี้วงเล็บพิเศษเช่นเดียวกับการเยื้องช่องว่างและมาตรฐานสไตล์อื่น ๆ จะช่วยจัดระเบียบโค้ดในลักษณะที่เป็นตรรกะ

สำหรับความถูกต้องเงื่อนไขที่ไม่มีวงเล็บเป็นสูตรสำหรับข้อผิดพลาดโง่ ๆ เมื่อเกิดขึ้นพวกเขาอาจเป็นแมลงที่หายากเพราะบ่อยครั้งที่สภาพที่ไม่ถูกต้องจะทำงานได้อย่างถูกต้องเกือบตลอดเวลาและบางครั้งก็ล้มเหลวเท่านั้น

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

ฉันมักจะใช้วงเล็บสำหรับการแสดงออกที่รวมandและor(และสำหรับการดำเนินการทางคณิตศาสตร์ที่มีปัญหาสำคัญที่คล้ายกัน)


3
ถึงแม้ว่าฉันเคยได้ยินว่ามีความคิดเห็นว่าเป็นการขอโทษ (สำหรับโค้ดที่อ่านยาก / อ่านยาก) ... มีโอกาสที่คุณจะเขียนได้ดีขึ้น ฉันเดาว่าคุณสามารถพูดสิ่งที่คล้ายกันเกี่ยวกับวงเล็บ
Jeff Bridgman

6
ความถูกต้องอีกประการหนึ่งคือการรักษามันไว้ผ่านการเปลี่ยนแปลง: ในขณะที่ผู้พัฒนาดั้งเดิมอาจมีสิทธิเหนือกว่าโดยไม่ต้องวงเล็บเมื่อเขาเขียนรหัสโดยมีวัตถุประสงค์และบริบทใหม่ในใจเขา (หรืออื่น ๆ ) ที่มาพร้อมกันในภายหลังและจำไม่ได้ทั้งหมด รายละเอียดอาจเลอะเมื่อพวกเขาเพิ่มคำเพิ่มเติมในนิพจน์ (นั่นก็ส่อให้เห็นเป็นส่วนใหญ่อยู่แล้ว แต่ฉันรู้สึกว่ามันคุ้มค่าที่จะเน้น)
LarsH

1
@ LarsH ขอบคุณฉันเพิ่มคำตอบนี้ไว้อย่างชัดเจน

8
+1 "พวกเขาให้การยืนยันเจตนาของนักพัฒนา" - โปรแกรมเมอร์คนใดก็ได้ (ตกลงอาจจะไม่ใช่ทั้งหมด แต่ทุกคนที่อยู่ที่นี่ .... ) สามารถทำงานสิ่งที่คอมไพเลอร์จะทำกับตรรกะที่ซับซ้อนที่สุด ไม่มีใครสามารถทำงานได้ตามที่นักพัฒนาดั้งเดิมตั้งใจ (รวมถึงตัวเอง) ไม่กี่สัปดาห์เพื่อติดตามสิ่งที่เกินความสะดวก .....
mattnz

2
ฉันคิดว่า @JeffBridgman อ้างถึงจุดยืนที่เป็นที่รู้จักกันดีของ "ความคิดเห็นบางครั้งอาจเป็นกลิ่นรหัส" เช่นดูข้อมูลสรุปของ Jeff Atwoodซึ่งรวมถึงคำถาม "คุณสามารถกำหนดรหัสใหม่ได้หรือไม่เพื่อแสดงความคิดเห็น?" ฉันขอยืนยันว่าหากความคิดเห็นของคุณอธิบายว่าทำไมรหัสของคุณถึงใช้งานไม่ได้จริง ๆ มันอาจเป็นคำใบ้ว่ามีบางอย่างผิดปกติ ในบางครั้งเช่นนี้เป็นความคิดที่ดีที่จะทำให้รหัสง่ายขึ้น ฉันเห็นด้วยอย่างแท้จริงกับคำตอบที่แท้จริงของคุณแม้ว่าและรับไว้ในวงเล็บอย่างไรก็ตาม
Daniel B

94

มันมีความสำคัญน้อยลงไม่ว่าคุณจะมีความมั่นใจในการเข้าใจภาษาหรือไม่ สิ่งที่สำคัญคือความเข้าใจในภาษาของ n00b ที่ตามมาคุณ

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

มีสิ่งต่าง ๆ เช่นวงเล็บมากเกินไป แต่เป็นหนึ่งในสถานการณ์เหล่านั้นที่คุณไม่ต้องการคำแนะนำ - คุณจะรู้เมื่อคุณเห็นมัน ณ จุดนั้น refactor รหัสของคุณเพื่อลดความซับซ้อนของคำสั่งแทนที่จะลบวงเล็บ


72
อย่าลืมว่าแม้ว่าคุณจะเป็นนักพัฒนาเดี่ยวเมื่อป่วยเหนื่อยล้าหรือจัดการกับโค้ดที่คุณเขียนเมื่อปีที่แล้ว ระดับความเข้าใจของคุณลดลงเป็น n00b
Dan Neely

30
There is such a thing as too many parenthesis- เห็นได้ชัดว่าคุณไม่ได้เป็นคนขี้เกียจ;)
พอล

18
นั่นเป็นคำแนะนำที่ไม่ดี: อย่าเขียนเพื่อ noobs วิธีนี้จะลดคุณภาพรหัสของคุณ (มาก) เพราะคุณไม่สามารถใช้สำนวนที่มีชื่อเสียงที่ดีเกินกว่าสองบทแรกของหนังสือเริ่มต้น
Konrad Rudolph

10
@ KonradRudolph: อาจจะเป็นเช่นนั้น แต่อย่าเขียนเพื่อคนเดียวที่รู้ศิลปะการเขียนโปรแกรมคอมพิวเตอร์จากหน้าปกเพื่อปกอย่างใดอย่างหนึ่งหรือเตรียมที่จะต้องแก้จุดบกพร่องรหัสของพวกเขาในภายหลังและไม่มีเงื่อนงำทำไมคุณทำสิ่งต่าง ๆ . รหัสอ่านมากกว่าที่เขียนไว้มาก
haylem

15
@dodgethesteamroller: ฉันเคยเห็นนักพัฒนาที่มีความสามารถ / มีชื่อเสียงมากเกินไปแนะนำบั๊กที่มีมาก่อน (ทุกคนมีวันที่แย่แล้วตอนนี้) ที่ยังไม่มีใครสังเกตเห็นมานาน สำหรับนักพัฒนาที่ดีที่รู้กฎมาก่อนความเสี่ยงของข้อผิดพลาด / การตรวจจับที่ผิดพลาดนั้นสูงเกินไป สำหรับคนอื่น ๆ มีความเสี่ยงสูงกว่า นักพัฒนาซอฟต์แวร์ที่ดีที่สุดคือนักพัฒนาที่เคยจดจำกฎสำคัญของภาษา แต่ลืมพวกเขาเนื่องจากการใช้วงเล็บเป็นประจำสำหรับสิ่งที่ไม่ชัดเจน
เบรนแดน

31

ใช่

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

เหตุผลในโลกแห่งความจริง

ฉันสืบทอดแอปพลิเคชันเฟรมหลัก อยู่มาวันหนึ่งจากฟ้าใสมันหยุดทำงาน แค่นั้นแหละ ... มันหยุดแล้ว

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

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

ดังนั้นฉันตัดสินใจที่จะเริ่มต้นที่ด้านบนของซอร์สโค้ดและเพิ่ม whitespce และ line brakes เพื่อให้โค้ดอ่านง่ายขึ้น ฉันสังเกตเห็นว่าในบางกรณีจะมีเงื่อนไขที่รวมกันANDและORและมันก็ไม่สามารถแยกแยะได้อย่างชัดเจนระหว่างข้อมูลที่ถูกANDแก้ไขและข้อมูลใดที่ถูกORแก้ไข ดังนั้นฉันจึงเริ่มใส่วงเล็บไปรอบ ๆANDและORเงื่อนไขเพื่อให้อ่านง่ายขึ้น

เมื่อฉันค่อยๆทำความสะอาดมันฉันจะช่วยงานของฉันเป็นระยะ ณ จุดหนึ่งฉันพยายามรวบรวมรหัสและสิ่งที่แปลกประหลาดเกิดขึ้น ข้อผิดพลาดเพิ่มขึ้นผ่านบรรทัดของรหัสต้นฉบับและตอนนี้ก็ลงต่อไป ดังนั้นฉันจึงแยกกันANDและทำตามORเงื่อนไขด้วย parens เมื่อฉันทำความสะอาดเสร็จมันก็ทำงานได้ ไปรูป

จากนั้นฉันตัดสินใจไปที่ร้านค้าปฏิบัติการและถามพวกเขาว่าพวกเขาเพิ่งติดตั้งส่วนประกอบใหม่ใด ๆ บนเฟรมหลักหรือไม่ พวกเขาบอกว่าใช่เราเพิ่งอัพเกรดคอมไพเลอร์ hmmmm

ปรากฎว่าคอมไพเลอร์เก่าทำการประเมินนิพจน์จากซ้ายไปขวาโดยไม่คำนึงถึง คอมไพเลอร์เวอร์ชันใหม่ยังประเมินนิพจน์จากซ้ายไปขวา แต่โค้ดคลุมเครือซึ่งหมายถึงการผสมที่ไม่ชัดเจนของANDและORไม่สามารถแก้ไขได้

บทเรียนที่ฉันเรียนรู้จากสิ่งนี้ ... เสมอ, เสมอ, ใช้ parens เพื่อแยกANDเงื่อนไขและORเงื่อนไขเมื่อใช้ร่วมกัน

ตัวอย่างแบบง่าย

IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...(รหัสที่ทิ้งกระจุยกระจายกับหลายสิ่งเหล่านี้)

นี่เป็นเวอร์ชั่นที่เรียบง่ายของสิ่งที่ฉันพบ มีเงื่อนไขอื่นที่มีคำสั่งตรรกะบูลีนเช่นกัน

ฉันจำได้ว่าการ chaging ไปที่:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...



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


22
นี่เป็นภาพประกอบที่ดีกว่าว่าทำไมการมีคอมไพเลอร์ที่ดีจึงเป็นสิ่งสำคัญ
ruakh

6
@CapeCodGunny: ฉันแน่ใจว่าคุณไม่ได้ แต่ปัญหาที่นี่คือคุณมีผู้จำหน่ายคอมไพเลอร์ที่ไม่ดีซึ่งทำให้เกิดการเปลี่ยนแปลงครั้งใหญ่ ฉันไม่เห็นว่าคุณเรียนรู้บทเรียนเกี่ยวกับ "เสมออยู่เสมอ" แก้ไขปัญหานั้นได้แม้ว่าจะใช้คอมไพเลอร์ที่ดีขึ้นก็ตาม
ruakh

5
@ruakh - ไม่ผู้ขายเพียงเปลี่ยน parser รหัสของพวกเขา ฉันเป็นโรงเรียนเก่าฉันไม่พึ่งพาความสามารถในการจดจำทุกระบบที่ฉันเขียนหรือมีส่วนร่วมโดยไม่ต้องมีเอกสารทั้งหมดที่คุณมีคือซอร์สโค้ด เมื่อซอร์สโค้ดอ่านยากและปฏิบัติตามจะสร้างสถานการณ์ที่ตึงเครียดอย่างยิ่ง โปรแกรมเมอร์ที่ไม่ได้ใช้ช่องว่างอาจไม่เคยจัดการกับสถานการณ์เช่นเดียวกับที่ฉันเผชิญ ฉันได้เรียนรู้ด้วยว่าการเขียนโค้ดเช่น: ดู Dick; ดูเจน; ดูดิ๊กและเจน; ข้อความง่ายๆที่อ่านง่าย ... แสดงความคิดเห็น ... และติดตาม
Michael Riley - AKA Gunny

2
เป็นเรื่องที่ดี แต่ฉันยอมรับว่าไม่ใช่เหตุผลที่จะใช้วงเล็บ และ / หรือลำดับความสำคัญเกือบเป็นสากลและเกี่ยวกับสิ่งที่มีโอกาสน้อยที่สุดที่จะเปลี่ยนแปลงซึ่งเราอาจนึกถึง หากคุณไม่สามารถพึ่งพาพฤติกรรมที่สอดคล้องกันสำหรับมาตรฐานการดำเนินงานพื้นฐานคอมไพเลอร์ของคุณเป็นขยะและคุณถูก hosed ไม่ว่าคุณจะทำอะไร เรื่องราวของคุณเป็นปัญหาคอมไพเลอร์ 100% และปัญหารหัส 0% โดยเฉพาะอย่างยิ่งพฤติกรรมที่เป็นค่าเริ่มต้นคือการประเมินจากซ้ายไปขวาอย่างง่าย - ลำดับจะชัดเจนเสมอดังนั้นทำไมทุกคนจะใช้วงเล็บ?

7
ผมคิดว่ามีบทเรียนที่นี่ทั้งสองด้าน ... คุณดีกว่าใช้วงเล็บเฉพาะอย่างยิ่งเมื่อทางเลือกจะอาศัยพฤติกรรมที่ไม่มีเอกสารของคอมไพเลอร์ในเรื่องที่เกี่ยวกับรหัสไม่ชัดเจน และถ้าโปรแกรมเมอร์ไม่รู้ว่านิพจน์ใดคลุมเครือให้ใช้ parens ดีกว่า ในอีกด้านหนึ่งมันเป็นอันตรายที่จะเปลี่ยนพฤติกรรมของคอมไพเลอร์ แต่อย่างน้อยก็โยนข้อผิดพลาดในกรณีที่พฤติกรรมเปลี่ยนไป มันจะแย่กว่านี้หากคอมไพเลอร์ไม่ได้โยนข้อผิดพลาด แต่เริ่มคอมไพล์ต่างกัน ข้อผิดพลาดปกป้องคุณจากข้อบกพร่องที่ไม่ได้สังเกต
LarsH

18

ใช่ถ้ามี 'และ' และ 'หรือ' ผสมกัน

ยังเป็นความคิดที่ดีที่จะ () ตรวจสอบทางตรรกะหนึ่งสิ่ง

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


6
จริงมีโอกาสที่ดีมากที่a AND bอาจถูกแทนที่ด้วยฟังก์ชันหรือค่าบูลีนที่คำนวณล่วงหน้าซึ่งมีชื่อที่อธิบายได้มากกว่า
Jeff Bridgman

14

วงเล็บมีความหมายซ้ำซ้อนดังนั้นคอมไพเลอร์ไม่สนใจ แต่นั่นคือปลาเฮอริ่งแดง - ความกังวลที่แท้จริงคือโปรแกรมเมอร์สามารถอ่านและเข้าใจได้

ฉันกำลังจะไปรับตำแหน่งที่รุนแรงที่นี่และให้สหาย "ไม่" a AND b OR c AND dในวงเล็บ โปรแกรมเมอร์ทุกคนควรรู้ด้วยใจว่าความสำคัญในนิพจน์บูลีนนั้นไม่ใช่> และ> หรือเช่นเดียวกับความทรงจำโปรดแก้ตัวป้าที่รักของฉันแซลลี่สำหรับการแสดงออกทางพีชคณิต เครื่องหมายวรรคตอนที่ซ้ำซ้อนเพียงเพิ่มความยุ่งเหยิงทางสายตาเกือบตลอดเวลาในรหัสโดยไม่มีประโยชน์ในการอ่านโปรแกรมเมอร์

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

ฉันจะยกเว้นอะไรนอกขอบเขตของพีชคณิต (บูลีนหรือไม่) เช่นการแสดงออกของตัวชี้ใน C ที่สิ่งใดที่ซับซ้อนกว่าสำนวนมาตรฐานเช่น*p++หรือp = p->nextอาจจะต้องวงเล็บเพื่อรักษา dereferencing และเลขคณิตตรง และแน่นอนว่าไม่มีสิ่งใดที่ใช้กับภาษาอย่าง Lisp, Forth หรือ Smalltalk ที่ใช้สัญกรณ์ภาษาโปแลนด์บางรูปแบบสำหรับการแสดงออก แต่สำหรับภาษากระแสหลักส่วนใหญ่ความสำคัญเชิงตรรกะและเลขคณิตนั้นเป็นมาตรฐานโดยสิ้นเชิง


1
+1, วงเล็บสำหรับความชัดเจนนั้นใช้ได้ แต่ANDvs ORเป็นกรณีพื้นฐานที่ค่อนข้างเป็นธรรมซึ่งฉันต้องการให้ devs อื่น ๆ ในทีมของฉันรู้ ฉันกังวลว่าบางครั้ง "การใช้วงเล็บเพื่อความชัดเจน" จริงๆแล้วคือ "การใช้วงเล็บดังนั้นฉันไม่ต้องกังวลกับการเรียนรู้สิ่งที่มาก่อน"
ทิมกู๊ดแมน

1
ในทุกภาษาที่ผมทำงานกับมันอย่างสม่ำเสมอ.memberก่อนที่ผู้ประกอบการเอก, เอกก่อนที่ผู้ประกอบการไบนารี*และ/ก่อน+และ-ก่อน<และ>และ==ก่อน&&ก่อน||ก่อนที่จะได้รับมอบหมาย กฎเหล่านั้นจำง่ายเพราะตรงกับ "สามัญสำนึก" ของฉันเกี่ยวกับวิธีการใช้งานตัวดำเนินการตามปกติ (เช่นคุณจะไม่ให้==ความสำคัญมากกว่า+หรือ1 + 1 == 2หยุดทำงาน) และครอบคลุม 95% ของคำถามที่มีมาก่อน .
ทิมกู๊ดแมน

4
@TimGoodman ใช่ถูกต้องทั้งความคิดเห็นของคุณ ผู้ตอบคำถามคนอื่น ๆ ที่นี่คิดว่าเป็นคำถามดำหรือขาว - ใช้วงเล็บตลอดเวลาไม่มีข้อยกเว้นหรือบินโดยไม่ใส่ใจที่กางเกงของคุณผ่านทะเลที่มีกฎเกณฑ์ตามอำเภอใจและเป็นไปไม่ได้ พร้อมบั๊กที่หายาก (อุปมาอุปมัยผสมโดยเจตนามาก) แน่นอนว่าทางที่ถูกต้องคือการควบคุม ความชัดเจนของรหัสนั้นสำคัญ แต่การรู้จักเครื่องมือของคุณดีและคุณควรคาดหวังความเข้าใจขั้นต่ำเกี่ยวกับการเขียนโปรแกรมและหลักการ CS จากเพื่อนร่วมทีมของคุณ
dodgethesteamroller

8

ตามที่เห็น:

ใช่ข้อดี:

  • คำสั่งของการดำเนินการที่ชัดเจน
  • ปกป้องคุณจากนักพัฒนาในอนาคตที่ไม่เข้าใจคำสั่งของการดำเนินการ

ใช่ข้อเสีย:

  • อาจทำให้เกิดโค้ดที่อ่านยาก

ไม่มีข้อดี:

  • ?

ไม่มีข้อด้อย:

  • ลำดับของการดำเนินการโดยปริยาย
  • รหัสนั้นสามารถบำรุงรักษาได้น้อยสำหรับนักพัฒนาโดยไม่เข้าใจคำสั่งการดำเนินการ

พูดได้ดีถึงแม้ว่าฉันคิดว่า"อาจส่งผลให้รหัสยุ่งอ่านยาก"ค่อนข้างเป็นอัตนัย
FrustratedWithFormsDesigner

2
การทำให้ซีแมนติกส์ของโค้ดของคุณชัดเจนทำให้อ่านยากได้อย่างไร?
Mason Wheeler

1
ฉันเห็นด้วยกับคนอื่น ๆ ในการตั้งคำถาม "ใช่จุดด้อย" ของคุณ ฉันคิดว่ามันเกือบจะตรงกันข้าม

@ เฟร็ดเป็นแบบอัตนัยเช่นเดียวกับการเรียกร้องตรงข้าม ความหมายไม่ใช่ทั้งหมด ยากที่จะวัด
Konrad Rudolph

1
@MasonWheeler: ในขณะที่ฉันยอมรับว่า parens ชัดเจนมีความสำคัญมากในหลายกรณีฉันสามารถดูวิธีหนึ่งที่สามารถไปลงน้ำในการทำให้ความหมายชัดเจน ฉัน3 * a^2 + 2 * b^2อ่านง่ายกว่า(3 * (a^2)) + (2 * (b^2))เพราะรูปแบบและลำดับความสำคัญนั้นคุ้นเคยและเป็นมาตรฐาน ในทำนองเดียวกันคุณสามารถ (จะสุดขีด) ห้ามการใช้ฟังก์ชั่นและมาโคร (หรือคอมไพเลอร์!) เพื่อให้ความหมายของรหัสของคุณชัดเจนยิ่งขึ้น เห็นได้ชัดว่าฉันไม่ได้เรียกร้อง แต่ฉันหวังที่จะตอบคำถามของคุณว่าทำไมต้องมีข้อ จำกัด (ยอดเงิน) ในการทำให้สิ่งต่าง ๆ ชัดเจน
LarsH

3

มีข้อโต้แย้งใด ๆ ในหรือต่อต้านรวมถึงวงเล็บนอก? ประสบการณ์ภาคปฏิบัติแนะนำว่ามันคุ้มค่าหรือไม่ที่จะต้องอ่านให้เข้าใจ หรือมันเป็นสัญญาณว่านักพัฒนาต้องการนั่งลงและมั่นใจในพื้นฐานของภาษาของพวกเขา?

หากไม่มีใครอื่นที่จะต้องดูรหัสของฉันอีกครั้งฉันไม่คิดว่าฉันจะดูแล

แต่จากประสบการณ์ของฉัน:

  • ฉันดูรหัสของฉันอีกครั้งในบางครั้ง (บางครั้งหลายปีหลังจากเขียนมัน)
  • บางครั้งคนอื่นดูรหัสของฉัน
    • หรือแม้กระทั่งต้องขยาย / แก้ไข!
  • ทั้งตัวฉันเองและคนอื่น ๆ จำสิ่งที่ฉันคิดไม่ได้เมื่อเขียนมัน
  • การเขียนรหัส "ลดจำนวนตัวอักษร" เป็นความลับทำให้สามารถอ่านได้ง่าย

ฉันมักจะทำสิ่งนี้เพราะฉันเชื่อมั่นในความสามารถของฉันในการอ่านได้อย่างรวดเร็วและไม่ทำผิดพลาดอะไรมากมายกับ parens มากกว่าสิ่งอื่นใด

ในกรณีของคุณฉันเกือบจะทำสิ่งต่าง ๆ เช่น:

if (a AND b) then ab = true
if (c AND d) then cd = true
If (ab OR cd) Then ...

ใช่มันเป็นรหัสเพิ่มเติม ใช่ฉันสามารถใช้โอเปอเรเตอร์บูลแฟนซีได้ ไม่ฉันไม่ชอบโอกาสที่จะอ่านรหัส 1 ปีขึ้นไปในอนาคตฉันอ่านโอเปอเรเตอร์บูลแฟนซีผิด จะเกิดอะไรขึ้นถ้าฉันกำลังเขียนโค้ดในภาษาที่มีความแตกต่างระหว่าง AND และ / หรือลำดับความสำคัญและต้องข้ามกลับเพื่อแก้ไขปัญหานี้ ฉันกำลังจะไป "อ้า! ฉันจำได้ว่าสิ่งเล็ก ๆ น้อย ๆ ที่ฉลาดนี้ซึ่งฉันทำ! ฉันไม่ต้องรวม parens เมื่อฉันเขียนเมื่อปีที่แล้วสิ่งที่ดีที่ฉันจำได้ในตอนนี้!" หากเป็นเช่นนั้น (หรือแย่กว่านั้นคือคนอื่นที่ไม่ทราบถึงความฉลาดนี้หรือถูกโยนลงในสถานการณ์ประเภท "แก้ไขโดยเร็ว")?

การแยกด้วย () ทำให้ตรงไปตรงมามากขึ้นเพื่ออ่านอย่างรวดเร็วและเข้าใจในภายหลัง ...


7
หากคุณกำลังจะทำเช่นนั้นทำไมไม่ab = a AND b?
Eric

1
บางทีอาจเป็นเพราะจะยังคงไม่เปลี่ยนแปลงหากไม่ได้ab a AND b
Armali

3

กรณีทั่วไป

ใน C # การคูณและการหารมีความสำคัญเหนือกว่าการบวกและการลบ

ยัง StyleCop เครื่องมือซึ่งบังคับใช้สไตล์ทั่ว codebase ที่มีเป้าหมายเพิ่มเติมเพื่อลดความเสี่ยงของบักแนะนำตามรหัสซึ่งอาจจะไม่ชัดเจนเพียงพอให้มีSA1407 กฎ กฎนี้จะสร้างคำเตือนด้วยรหัสชิ้นนี้:

var a = 1 + 2 * 3;

เป็นที่ชัดเจนว่าผลลัพธ์นั้นเป็น7และไม่ใช่9แต่ก็ยัง StyleCop แนะนำให้ใส่วงเล็บ:

var a = 1 + (2 * 3);

กรณีของคุณโดยเฉพาะ

ในกรณีเฉพาะของคุณจะมีความสำคัญของและเทียบกับหรือในภาษาที่คุณใช้

นี่ไม่ใช่วิธีการทำงานของทุกภาษา คนอื่น ๆ ปฏิบัติต่อ AND และ OR อย่างเท่าเทียมกัน

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

ลักษณะเฉพาะนี้และความเสี่ยงที่นักพัฒนาบางคนอาจเชื่อว่า AND และ OR มีลำดับความสำคัญเท่ากันทำให้มีความสำคัญยิ่งขึ้นในการเพิ่มวงเล็บ

อย่าเขียนโค้ดโดยมีเป้าหมายเพื่อแสดงว่าคุณฉลาด เขียนโค้ดโดยมีเป้าหมายในการอ่านรวมถึงคนที่อาจไม่คุ้นเคยกับทุกด้านของภาษา


1
"นี่เป็นเรื่องแปลกมาก": ตาม Stroustrup2013, C ++ 11 ดูเหมือนว่าจะมีความสำคัญเหนือกว่า AND และ OR (หน้า 257) เหมือนกันสำหรับ Python: docs.python.org/2/reference/expressions.html
Dirk

10
Re: "ทุกภาษาที่ฉันรู้จักปฏิบัติและและเท่าเทียมกัน": ฉันสงสัยว่าเป็นเรื่องจริง ถ้ามันเป็นความจริงแล้วคุณไม่ทราบใด ๆของภาษาที่นิยมมากที่สุดสิบ (C, Java, C ++, PHP, JavaScript, งูหลาม, C #, Perl, SQL, และทับทิม) และอยู่ในตำแหน่งที่ไม่มีที่จะแสดงความคิดเห็นใน "ผิดปกติ" คืออะไรให้คนเดียว "ผิดปกติมาก"
ruakh

1
ฉันเห็นด้วยกับ ruakh และค้นหา C ++ 11, python, matlab และ java
Dirk

3
ภาษาที่ AND และ OR เป็นตัวดำเนินการไบนารี่และซึ่งไม่ถือว่าและมีลำดับความสำคัญสูงกว่า OR นั้นเป็นอึที่ถูกทำลายสมองซึ่งผู้เขียนเป็นวิทยาศาสตร์คอมพิวเตอร์ flunkies สิ่งนี้มาจากสัญกรณ์ตรรกะ สวัสดี "ผลรวมของผลิตภัณฑ์" ไม่ได้มีความหมายอะไรเลยหรือ แม้จะมีเครื่องหมายบูลีนซึ่งใช้การคูณ (การวางเคียงกันของปัจจัย) สำหรับ AND และและสัญลักษณ์ + สำหรับ OR
Kaz

3
@ruakh คุณเพิ่งทำให้ฉันมีคะแนนสำหรับฉัน เนื่องจากมีกรณีขอบพยาธิวิทยาจำนวนหยิบยื่นไม่ได้หมายความว่าคุณไม่ควรเรียนรู้ลำดับความสำคัญของบูลีนมาตรฐานและสันนิษฐานว่ามันเก็บไว้จนกว่าจะพิสูจน์เป็นอย่างอื่น เราไม่ได้พูดถึงการตัดสินใจออกแบบโดยพลการที่นี่ พีชคณิตบูลีนถูกคิดค้นมานานก่อนคอมพิวเตอร์ แสดงให้ฉันเห็น Pascal spec ที่คุณกำลังพูดถึงด้วย ที่นี่และที่นี่โชว์และก่อนหรือ
dodgethesteamroller

1

ดังที่ทุกคนพูดใช้วงเล็บทุกครั้งที่ทำให้การแสดงออกสามารถอ่านได้มากขึ้น แต่ถ้าการแสดงออกมีความซับซ้อนผมแนะนำให้ไปแนะนำฟังก์ชั่นใหม่สำหรับ subexpressions


0

หรือมันเป็นสัญญาณว่านักพัฒนาต้องการนั่งลงและมั่นใจในพื้นฐานของภาษาของพวกเขา?

หากคุณใช้ภาษาเอกพจน์อย่างเข้มงวดอาจจะ ตอนนี้ใช้ภาษาทั้งหมดที่คุณรู้จักตั้งแต่อายุจนถึงทันสมัยที่สุดตั้งแต่การรวบรวมจนถึงการเขียนสคริปต์ไปจนถึง SQL ไปจนถึง DSL ของคุณเองที่คุณประดิษฐ์ขึ้นเมื่อเดือนที่แล้ว

คุณจำกฎสำคัญที่แน่นอนสำหรับแต่ละภาษาเหล่านี้โดยไม่ต้องมอง?


1
และตามที่ @Cape Cod Gunny ดังที่กล่าวไว้ข้างต้นถึงแม้ว่าคุณคิดว่าคุณรู้ภาษาหวัดมากคอมไพเลอร์ / รันไทม์อาจเปลี่ยนไปด้านล่างคุณ
Jordan

0

"ฉันควรใช้วงเล็บในคำสั่งทางตรรกะแม้ไม่จำเป็น"

ใช่เพราะคนสองคนจะพบว่ามีประโยชน์:

  • โปรแกรมเมอร์คนต่อไปที่มีความรู้ความสามารถหรือสไตล์อาจแตกต่างกัน

  • อนาคตของคุณที่กลับมาที่รหัสนี้ในภายหลัง!


-1

เงื่อนไขที่ซับซ้อนคือ "พีชคณิตแบบบูล" ซึ่งคุณเขียนด้วยวิธีการบางอย่างที่ทำให้มันดูสวยเหมือนพีชคณิตและคุณต้องใช้การเลียนแบบพีชคณิตใช่ไหม?

กฎที่มีประโยชน์จริงๆคือกฎการปฏิเสธ:

!(A || B) <=> !A && !B
!(A && B) <=> !A || !B

หรือในรูปแบบที่ชัดเจนขึ้นเล็กน้อย:

!(A + B) <=> !A * !B
!(A * B) <=> !A + !B

ซึ่งชัดเจนจริงๆเพียงพีชคณิตเมื่อเขียนเป็น:

-1*(A + B) = -A + -B
-1*(A * B) = -A * -B

แต่เราสามารถใช้การคิดสำหรับการทำให้เข้าใจง่ายและขยายพีชคณิต:

(A && B) || (C && D) => 
((A && B) || C) && ((A && B) || D) => 
(AC && BC) && (AD && BD) =>
AC && BC && AD && BD

แม้ว่าในรหัสคุณต้องเขียน:

(A||C) && (B||C) && (A||D) && (B||D)

หรือในรูปแบบที่ชัดเจนขึ้นเล็กน้อย:

(A + B) * (C + D) => 
((A + B) * C) + ((A + B) * D) => 
(AC + BC) + (AD + BD) =>
AC + BC + AD + BD

โดยพื้นฐานแล้วเงื่อนไขยังคงเป็นเพียงการแสดงออกเกี่ยวกับพีชคณิตและโดยการใช้วงเล็บอย่างชัดเจนคุณสามารถใช้กฎพีชคณิตต่าง ๆ ที่คุณรู้จักกับการแสดงออกได้ง่ายขึ้นรวมถึงแนวคิด olde ของ "ลดความซับซ้อนหรือขยายสูตรนี้"


2
ฉันไม่แน่ใจว่าคุณกำลังตอบคำถามจริง ๆ เนื่องจากคุณนำคำตอบของคุณมาด้วยสมมติฐานที่ไม่จำเป็นต้องเป็นจริง ฉันจะใช้วงเล็บเป็นพีชคณิตหรือไม่ ไม่ตลอดเวลา ถ้ามันช่วยในการอ่านได้แน่นอน แต่คนอื่น ๆ ก็แสดงให้เห็นแล้วว่าที่นี่ และการขยายพีชคณิตเชิงคณิตศาสตร์ไปสู่รูปแบบอื่นนั้นไม่มีความสอดคล้องแบบตัวต่อตัวกับการเขียนโปรแกรม - ถ้าคุณกำลังตรวจสอบสถานะของค่าสตริงสองสามตัว
Derek

ถ้าพีชคณิตบูลีนที่เกี่ยวข้องนั้นซับซ้อนเพียงพอที่จะรับประกัน parens เงื่อนไขของคุณควรใช้ parens ถ้ามันง่ายพอที่จะไม่รับประกันว่าคุณจะได้ไม่ต้องหรือไม่ควร ไม่ว่าจะด้วยวิธีใดลองคิดดูว่าคุณจะใช้นิพจน์ทางคณิตศาสตร์ได้อย่างไร
Narfanator

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

2
เพียง nitpicking แต่ใน!(A + B) <=> !A + !Bและ-1*(A + B) = -A + -Bไม่ควรให้ผู้ประกอบการได้รับการพลิกจาก+ไป*ในการแสดงออกที่สอง?
Jeff Bridgman

-1

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


-1

ใช่. คุณควรใช้ในกรณีใด ๆ เมื่อคุณรู้สึกว่ารหัสของคุณจะชัดเจนยิ่งขึ้น โปรดจำไว้ว่ารหัสของคุณควรชัดเจนเพียงพอเพื่อให้ผู้อื่นสามารถเข้าใจได้โดยไม่ต้องอ่านความคิดเห็นภายในโค้ด ดังนั้นจึงเป็นการดีที่จะใช้วงเล็บและวงเล็บปีกกา โปรดทราบว่าอาจขึ้นอยู่กับการปฏิบัติเฉพาะของ บริษัท / ทีมของคุณ เพียงรักษาวิธีการหนึ่งและไม่ผสม

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