ทำไม (ตำแหน่ง <ขนาด) รูปแบบที่แพร่หลายเช่นนี้ในเงื่อนไข


9

ในคำสั่งเงื่อนไข (IF) ทุกคนใช้(position < size)แต่ทำไม?
การประชุมเท่านั้นหรือมีเหตุผลที่ดีสำหรับสิ่งนั้น?

พบในป่า:

if (pos < array.length) {
   // do some with array[pos];
}

ไม่ค่อยพบ:

if (array.length > pos) {
   // do some with array[pos];
}

7
หนึ่งกรณีที่ฉันไม่คิดมี "ตัวแปร" if (MIN <= x && x <= MAX)ที่มีที่ที่เหมาะสม (ในบางภาษาสิ่งนี้สามารถเขียนเป็นMIN <= x <= MAX; ใน C มันถูกกฎหมายอย่างสมบูรณ์ แต่ไม่ได้หมายความว่าคุณอาจคิดว่ามันหมายถึง)
Keith Thompson

1
ซ้ำกันเป็นไปได้ของif ('constant' == $ variable) vs. if ($ variable == 'constant')
gnat

5
อาจจะเกี่ยวข้องกับวิธีการที่ช่วงเวลาที่มีการเขียนและการไม่ได้[min, max] [max, min]ดังนั้นจึงเป็นเพียงธรรมชาติที่จะตรวจสอบกว่าองค์ประกอบเป็นช่วงเวลาโดยการเขียนx min <= x <= max
Andres F.

สิ่งที่เป็นเรื่องยาก
Tulains Córdova

ตัวอย่างที่สองสามารถชี้แจงเพิ่มเติมได้หาก (! (array.lengh <= pos)) ...
OldFart

คำตอบ:


48

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

ข้อยกเว้นทั่วไปเพียงอย่างเดียวคือเมื่อทดสอบความเท่าเทียมกันโปรแกรมเมอร์บางคนฝึกฝนตัวเองให้ใช้คำสั่งตรงกันข้าม (เรียกว่าเงื่อนไขโยดา ) เพื่อหลีกเลี่ยงข้อผิดพลาดทั่วไปvariable = constantมากกว่าvariable == constantข้อผิดพลาด - ฉันไม่ได้ถือความคิดนี้เพราะฉันพบคำสั่งตามธรรมชาติ เหนือสิ่งอื่นใดที่สามารถอ่านได้ส่วนใหญ่เป็นเพราะมันเป็นวิธีที่เราแสดงความคิดเป็นภาษาอังกฤษและเพราะคอมไพเลอร์สมัยใหม่ส่วนใหญ่จะตรวจจับสิ่งนี้และออกคำเตือน


3
ขึ้นอยู่กับเครื่องมือในการพัฒนาของคุณหลายคนจะเตือน (หรือข้อผิดพลาด) ในการvariable = constantสร้าง
GalacticCowboy

5
+1 ค้นหา "เงื่อนไขโยดา" เพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับconstant == variableปรากฏการณ์
John M Gant

ฉันได้เห็นสิ่งเดียวกันนี้เมื่อไม่นานมานี้ในฐานรหัสของฉันเอง (เช่นif(DBNull == row["fieldName"]) methodCall()และสงสัยว่าฉันบ้าไปแล้วหรือเปล่าเพราะส่วนใหญ่แล้วฉันเคยเห็นมันทำไปในทางอื่น ๆ
Andrew Gray

1
ฉันยังจะเพิ่มที่(position < size)มักจะแสดงขอบเขตบนดังนั้นในผลก็คือlowerbound <= position < upperboundการบูรณะส่วนหนึ่งของที่มีขนาดเป็นส่วนบน ด้วยข้อ จำกัด ทั้งสองอย่างชัดเจนpositionสามารถไปได้เพียงกลาง
Steve314

4
มันอาจเกี่ยวข้องกับภาษา เราแยก " ผู้ประกอบการ X Y " เป็น " Xคือ ( ประกอบ Y )" เช่นเดียวกับความสัมพันธ์เป็นลักษณะของX โดยการถามการเปรียบเทียบเราจะถามว่าXมีค่าดีหรือไม่ดี (และYได้รับการปฏิบัติในท้องถิ่นเป็นค่าคงที่) การถาม "pos <array.length" ให้ความรู้สึกเหมือนถามว่า: "ตำแหน่งนั้นโอเค (เล็กกว่าความยาวของแถวลำดับ) หรือไม่" หากไม่มีสิ่งผิดปกติเกี่ยวกับตำแหน่ง ขอตำแหน่งใหม่ให้ฉันและฉันยินดีที่จะทำสิ่งที่คุณต้องการ แต่ไม่มีอะไรผิดเกี่ยวกับความยาวของอาเรย์ การถาม "array.length> pos" ให้ความรู้สึกว่าเราควรเพิ่มอาร์เรย์ถ้ามันสั้นเกินไป

14

เหตุผลเดียวที่ฉันเคยเห็นก็คือมันเป็นเหมือนหมายเลขบรรทัดหรือสิ่งอื่น ๆ ที่เราเรียนรู้ในโรงเรียน ตัวอย่างเช่นเราเขียนบรรทัดตัวเลขดังนี้:

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

สิ่งเล็ก ๆ ปรากฏขึ้นทางด้านซ้ายของสิ่งที่ใหญ่กว่า เช่นเดียวกับสิ่งอื่น ๆ เช่นวันที่ (คิดว่าการวางปฏิทิน)

โดยทั่วไปแล้วเราจะคิดถึงสิ่งต่าง ๆ ตามลำดับ การอ่านแบบฟอร์มแรกนั้นง่ายกว่าเพราะคุณไม่ต้องใช้กระบวนการทางจิตมากนัก


1
คุณหมายถึงนิพจน์ที่ประเมินค่าน้อยกว่ามาก่อนหรือไม่? คุณจะมั่นใจได้อย่างไรว่าจะเป็นจริงหากค่าเปลี่ยนรันไทม์?
Tulains Córdova

@ user61852 คุณไม่จำเป็นต้องรู้ว่าค่าใดที่รันไทม์ เช่นฉันมี 2 ค่าที่ฉันคำนวณที่ runtime valueA และ valueB และฉันต้องการทดสอบว่า valueA นั้นเล็กกว่า valueB ฉันจะเขียน "if (valueA <valueB)" ไม่ว่า valueA จะเล็กกว่า valueB หรือไม่ก็ตาม มันง่ายกว่า (สำหรับฉันอย่างน้อย) เพื่อดูและรู้ว่าฉันกำลังมองหาเมื่อค่า A น้อยกว่าค่า B ถ้าฉันต้องดู "ถ้า (valueB> valueA)" ฉันต้องหยุดและคิดว่าสิ่งใดที่มีขนาดเล็กลงเมื่อฉันจะติดตามรหัสสาขานี้
Becuzz

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

@ user61852 คุณควรจะสามารถเปลี่ยนการลงคะแนนของคุณตอนนี้
Becuzz

11

ในขณะที่เรื่องของการประชุมส่วนใหญ่เป็นความคิดของฉันที่ดีที่สุดตรงกับวิธีที่เราคิด - มันแสดงรายการที่เราให้ความสำคัญ

ถ้าเราแปลสิ่งเหล่านี้เป็นภาษาอังกฤษมันจะเป็นวลี "ถ้าตำแหน่งน้อยกว่าความยาวของอาเรย์" โดยที่หัวเรื่องของประโยคนั้นเป็นรายการชั่วคราว

ในการแสดงวิธีอื่น "ถ้าความยาวของอาเรย์มากกว่าตำแหน่ง" ทำให้ความยาวของอาเรย์ (ถือว่าเป็นค่าคงที่) ในเรื่องและตำแหน่ง (ชั่วคราว) จะกลายเป็นวัตถุโดยตรง


3
ที่จริง (ในประโยคสุดท้ายของคุณ) ตำแหน่งกลายเป็นวัตถุของคำบุพบท แต่ฉันเห็นด้วยกับสิ่งที่คุณพยายามจะพูด ภาษาศาสตร์เราจะบอกว่าตำแหน่งเป็นหัวข้อและ "น้อยกว่าความยาวอาร์เรย์" คือการแสดงความคิดเห็น "แนวโน้มที่จะวางประโยคเกี่ยวกับหัวข้อที่มีเนื้อหาเฉพาะเริ่มต้น en.wikipedia.org/wiki/…
LarsH

4

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

มันเหมือนกับการสนทนาครึ่งหนึ่งที่ว่างเปล่ากับครึ่งเต็ม เหมือนกันทางคณิตศาสตร์ แต่สมองของฉันจะเห็นพวกเขาแตกต่างกันขึ้นอยู่กับบริบท

โดยส่วนตัวถ้าฉันเห็น

if (array.lengh > pos) {
    // do some with array[pos];
}

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

บางทีฉันอาจจะไม่สดใส แต่ถ้าฉันต้องทำการวิเคราะห์ในทุกบรรทัดของรหัสสมองของฉันก็จะเจ็บ


3

เพื่อแสดงสิ่งที่บางคนพยายามจะทำในวิธีที่แตกต่าง ...

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

ในภาษาศาสตร์หัวข้อของประโยคคือสิ่งที่กำลังพูดถึงและความคิดเห็นคือสิ่งที่ถูกพูดเกี่ยวกับหัวข้อ ในตัวอย่างนี้เราสามารถสรุปได้ว่าpositionเป็นหัวข้อและ "น้อยกว่าความยาวอาร์เรย์" คือการแสดงความคิดเห็น ในภาษาอังกฤษและในภาษาอื่น ๆ อีกมากมายหัวข้อมักจะแสดงก่อนความคิดเห็น
" แนวโน้มที่จะเป็นสถานที่ topicalized คนละประโยคแรก (หัวข้อบังหน้า) เป็นที่แพร่หลาย. "

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


1

มันเป็นการรวมสองสิ่งเข้าด้วยกันทั้งสองอย่างมาจากแอสเซมเบลอร์พื้นฐานที่ภาษายุคแรก ๆ ได้รวบรวมไว้

  1. อาร์เรย์เป็นออฟเซ็ตที่ไม่มี zero-based ในหน่วยความจำ (เช่นกลุ่มข้อมูลแรกอยู่ที่จุดเริ่มต้นของบล็อกหน่วยความจำที่จัดสรร ... ดัชนี 0) ดังนั้นการใช้ 0..n-1 สำหรับชิ้นส่วนที่แตกต่างกัน

  2. การแตกสาขาหากค่าน้อยกว่าค่าอื่น (หรือลงทะเบียน ฯลฯ ) โดยทั่วไปแล้วจะเป็นคำสั่งเดียว ดังนั้นการใช้โอเปอเรเตอร์น้อยกว่า (<) แบบง่าย

ดังนั้นรูปแบบจึงย้ายจากแอสเซมเบลอร์เก่าไปยัง ANSI-C (ซึ่งคล้ายกับแอสเซมเบลอร์แมโครในบางวิธี) และจากที่นั่นไปยัง Java และภาษา C-like อื่น ๆ


0

ดังที่คำตอบอื่น ๆ บอกไว้มากมายการอ่านง่ายกว่ามาก:

[thing that varies] [comparison] [thing that does not vary]

เกือบทุกคนที่ฉันรู้จักใช้สไตล์นี้โดยเฉพาะ

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

if (variable = 5) ...

แทน:

if (variable == 5) ...

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

อย่างไรก็ตามถ้าคุณเขียน:

if (5 == variable) ...

คอมไพเลอร์ / ล่ามจะเกิดข้อผิดพลาดเพราะนั่นไม่ใช่โครงสร้างที่ถูกต้อง (ในภาษาส่วนใหญ่แล้ว)

สวิทช์รอบนี้มักจะเรียกว่าสภาพ Yoda

UPDATE : นี่คือรายการของสถานที่ที่เงื่อนไข Yoda มีประโยชน์


-1

ส่วนตัวฉันชอบสิ่งนี้:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

... มันเป็นโค้ดมากกว่า แต่ก็อ่านง่ายมาก


4
+1 สำหรับการเปรียบเทียบชื่อ แม้ว่าจริงๆแล้วฉันชอบวิธีนี้ดีกว่าสำหรับเงื่อนไขที่ซับซ้อนมากขึ้นและไม่มากสำหรับกรณีง่าย ๆ เช่นนี้ มันจริงทำให้ฉันหยุดคิดเกี่ยวกับ "อาเรย์", "ขอบเขต", "ภายใน" และสิ่งเหล่านั้นทั้งหมดหมายถึงเมื่อฉันสัญชาตญาณรู้ว่ามันหมายถึงการที่จะเป็นpos > array.lengthกล่าวอีกนัยหนึ่งถึงแม้ว่ามันจะทำให้ความหมายของเงื่อนไขชัดเจนมาก แต่ก็ทำให้อ่าน IMO ได้ยากขึ้นเล็กน้อย
John M Gant

แต่อีกชื่อหนึ่งที่จะติดตาม ...
Deduplicator

-1

มันเป็นเรื่องของการตั้งค่าหรือการประชุม หากคุณต้องการให้สอดคล้องกันมีสองวิธีที่สมเหตุสมผลเท่า ๆ กันที่คุณสามารถทำได้:

  1. ใส่ "หัวเรื่อง" ก่อนเสมอ (คิดว่าเป็นประโยค) - ค่าที่การทดสอบเกี่ยวกับ ตัวอย่างเช่นคุณเขียนif (age>5)

  2. หรือวางองค์ประกอบที่เล็กกว่าก่อนเสมอ (คิดว่าเป็นค่าที่เรียงลำดับบนหน้าจอตามลำดับที่เป็นธรรมชาติ) ตัวอย่างเช่นคุณเขียนif (a<b)โดยไม่คำนึงว่ารหัสนี้ส่วนใหญ่เกี่ยวกับ a หรือส่วนใหญ่เกี่ยวกับ b

อนุสัญญาทั้งสองจะแนะนำตัวอย่างแรกที่คุณแสดงแทนที่จะเป็นวินาทีดังนั้นฉันเดาว่าในกรณีนี้คุณมีคำตอบ ฉันว่ามันควรหลีกเลี่ยงการเขียนโค้ดที่ละเมิดทั้ง (1) และ (2) ที่นี่เพราะจะทำให้การอ่านสำหรับคนส่วนใหญ่ยากขึ้น

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