มีเหตุผลที่องค์ประกอบแรกของอาร์เรย์ Zsh ถูกจัดทำดัชนีโดย 1 แทน 0 หรือไม่?


27

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

ฉันแน่ใจว่าฉันได้ยินภาษาอื่นมากกว่า Zsh ที่มีพฤติกรรมคล้ายกันกับอาร์เรย์ ฉันสบายดีเพราะมันสะดวกสบายไม่แพ้กัน
อย่างไรก็ตามเมื่อก่อนหน้านี้มีการเปิดตัวและใช้กันอย่างแพร่หลายในภาษาสคริปต์เชลล์เช่น ksh และ bash ทั้งหมดใช้ 0 เหตุใดจึงมีคนเลือกที่จะเปลี่ยน "มาตรฐาน" ทั่วไปนี้

คำตอบสำหรับคำถามของฉันจะเป็น "ไม่แน่นอน";
จากนั้นคำอธิบายเดียวที่ฉันนึกได้เกี่ยวกับเรื่องนี้คือ "คุณสมบัติพิเศษ" สำหรับหอยคือ " พวกเขาทำสิ่งนี้เพื่ออวดเปลือกหอยที่สวยงามกว่านี้อีกเล็กน้อย"

ฉันไม่รู้มากทั้ง Zsh หรือประวัติของมันและมีโอกาสสูงที่ฉันจะรู้ทฤษฎีเกี่ยวกับเรื่องนี้ไม่สมเหตุสมผล

มีคำอธิบายสำหรับเรื่องนี้? หรือมันเป็นแค่รสนิยมส่วนตัว?


5
การวิจัยทางประวัติศาสตร์บางส่วน (หรือ rantish ruminations?) ในหัวข้อ 0 กับ 1: exple.tive.org/blarg/2013/10/22/citation-needed
thrig

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

3
ทุกวันนี้ sh เป็นภาษามาตรฐาน (ไม่ใช่การนำไปใช้) ซึ่งมีล่ามที่เป็นไปได้ที่แตกต่างกัน ล่ามเหล่านี้บางส่วนสำหรับภาษา sh เช่น bash, ksh และ yash สนับสนุนอาร์เรย์เป็นส่วนขยาย แต่ไม่ได้เป็นส่วนหนึ่งของภาษาเช่น gcc ซึ่งเป็นคอมไพเลอร์สำหรับภาษา C มาตรฐานรองรับการขยายมากกว่าภาษา C มาตรฐาน และเช่นเดียวกับ C ไม่มีการใช้งานล่าม "sh" อย่างเป็นทางการ
Stéphane Chazelas

1
ที่เกี่ยวข้อง - ความคิดเห็นในคำตอบ PPCG นี้
Digital Trauma

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

คำตอบ:


32
  • แทบทุกเชลล์อาร์เรย์ (Bourne, csh, tcsh, ปลา, rc, es, yash) เริ่มต้นที่ 1 ksh เป็นข้อยกเว้นเพียงอย่างเดียวที่ฉันรู้ (ทุบตีเพิ่งคัดลอก ksh)
  • แปลภาษามากที่สุดในเวลานั้น (ช่วงต้นยุค 90) awk, tclอย่างน้อย, และเครื่องมือที่ใช้โดยทั่วไปจากเชลล์ ( cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) เริ่มต้นที่ 1 sed, ed, viจำนวนเส้นของพวกเขาจาก 1 ...
  • zsh ใช้ประโยชน์สูงสุดจาก Bourne shell และ csh อาร์เรย์เชลล์เป้าหมาย$@เริ่มต้นที่ 1 zsh สอดคล้องกับการจัดการ$@(เช่นใน Bourne) หรือ$argv(เช่นเป็น csh) ดูว่ามันทำให้เกิดความสับสนในkshที่ที่${@:0:1}ไม่ได้ให้พารามิเตอร์ตำแหน่งแรกกับคุณอย่างไร
  • เชลล์เป็นเครื่องมือผู้ใช้ก่อนที่จะเป็นภาษาการเขียนโปรแกรม มันสมเหตุสมผลสำหรับผู้ใช้ส่วนใหญ่ที่จะมีองค์ประกอบแรก$a[1]มา นอกจากนี้ยังหมายความว่าจำนวนขององค์ประกอบเป็นเช่นเดียวกับดัชนีล่าสุด (ใน zsh เหมือนในเปลือกอื่น ๆ ส่วนใหญ่ยกเว้น ksh, อาร์เรย์ไม่กระจัดกระจาย)
  • a[1]สำหรับองค์ประกอบแรกนั้นสอดคล้องกับองค์ประกอบa[-1]สุดท้าย

ดังนั้น IMO ควรเป็นคำถาม: อะไรคือสิ่งที่อยู่ในหัวของ David Korn เพื่อให้อาร์เรย์เริ่มต้นที่ 0


7
มันเป็นข้อผิดพลาดในภาษามนุษย์ที่มีหมายเลขเป็นหนึ่งเดียวและน่าสนใจที่ภาษาโปรแกรมส่วนใหญ่จัดการเพื่อป้องกันมรดกนั้นจากการออกแบบของพวกเขา ทั้งหมดเศร้าที่ว่าหลังจากการจัดทำดัชนี zero-based ก่อตั้งขึ้นแทบเป็นมาตรฐานดังนั้นหลาย“ผู้ใช้ที่มุ่งเน้น” ภาษาได้มันย้อนกลับพยายามที่จะ“ง่าย” โดยใช้ผิดการจัดทำดัชนีหนึ่งที่ใช้อีกครั้ง - กล่าวว่า: วิธีที่ดีที่สุดในการหลีกเลี่ยงความสับสนในการจัดทำดัชนีเป็นวิธีการหลีกเลี่ยงดัชนีตัวเลขทั้งหมด
leftaroundabout

อ่านที่นี่: "เมื่อจัดการกับลำดับความยาว N องค์ประกอบที่เราต้องการแยกแยะด้วยตัวห้อย ... a) อัตราผลตอบแทนเมื่อเริ่มต้นด้วยตัวห้อย 1 ช่วงตัวห้อย 1 ≤ i <N + 1 เริ่มต้นด้วย 0 อย่างไรก็ตามให้ช่วงที่ดีกว่า 0 ≤ i <N . " ไม่ทราบว่า TROLL หรือ STUPID แต่คุณสามารถใช้ "1 ≤ i ≤ N" สำหรับตัวห้อยที่เริ่มต้นด้วย 1 ในอาร์เรย์ ไม่จำเป็นต้องใส่ +1 ในตอนท้ายของการสแกนอาร์เรย์และไม่มีมุมมองใด ๆ ที่พิสูจน์ได้ว่าดัชนีเริ่มต้นด้วย 1 หรือ 0 นั้นดีกว่า

1
คุณสามารถพิสูจน์ได้ว่ามีการเพิ่ม 0 หลังจากความรู้ของมนุษย์และมันทำให้สิ่งต่าง ๆ สับสนในเวลานั้น theguardian.com/notesandqueries/query/0,5753,-1358,00.html - อีกครั้งเพียงแค่เป็นมุมมอง :)

3
Bourne shell array $ @ เริ่มต้นที่ 0 (ไม่ใช่ 1) $ 0 เป็นชื่อของโปรแกรมที่คุณใช้ คุณควรแก้ไขจุดที่สามของคุณ
Edward Torvalds

2
@edwardtorvalds, ไม่$0ไม่ใช่พารามิเตอร์ตำแหน่ง $@มันไม่ได้เป็นส่วนหนึ่งของ เป็น"$@" "$1" "$2" ...เมื่อพูดถึงฟังก์ชั่นในเชลล์หลาย ๆ ตัวคุณจะเห็นว่า"$@"เป็นอาร์กิวเมนต์ของฟังก์ชันในขณะที่$0ยังคงพา ธ สคริปต์ (หรือเชลล์ argv [0] เมื่อไม่ได้ใช้งานสคริปต์)
Stéphane Chazelas

7

ฉันคิดว่าคำตอบที่เป็นไปได้มากที่สุดสำหรับเรื่องนี้คืออาเรย์ย้อนกลับในตัว zsh

หากคุณมีอาร์เรย์ที่มี 4 องค์ประกอบให้พูดmyvar=(1 2 3 4)และคุณต้องการเข้าถึงองค์ประกอบที่ 4 มันจะprint $myvar[4]ใช่มั้ย

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

print $myvar[-1]   # will print 4
print $myvar[-2]   # will print 3
print $myvar[-3]   # will print 2
print $myvar[-4]   # will print 1

-0นี้ควรจะอธิบายตั้งแต่เริ่มต้นจากศูนย์คุณจะไม่สามารถเข้าถึงหนึ่งในองค์ประกอบเหล่านั้นเป็นไม่มี

เหตุผลที่สองที่อยู่เบื้องหลังนี้อาจเป็นรหัส C ที่เกี่ยวข้องกับตัวแปรใน zsh ที่ใช้intหรือdouble intเพื่อกำหนดดัชนีอาร์เรย์และเนื่องจากมันใช้Complement ของ Twoเพื่อเป็นตัวแทนจำนวนลบไม่มีทางที่จะเป็นตัวแทน-0( Signed zero ) เหมือนที่คุณทำบน float ตัวแปรชี้

หากคุณคุ้นเคยกับการจัดทำดัชนีเริ่มต้นที่ 0 ฉันขอแนะนำให้คุณใช้KSH_ARRAYSตัวเลือกในการแก้ไขปัญหานี้

และการใช้เบ็ดของความคิดเห็น @cuonglm ที่cshคุณสมบัติดำเนินการzshจะมีการอธิบายที่นี่ ดูเหมือนจะไม่เป็นเหตุผลทางประวัติศาสตร์ แต่เป็นวิธีการจัดสภาพแวดล้อมการทำงานที่สะดวกสบายสำหรับผู้ที่ใช้งานด้วยcsh


3
จากนั้นสิ่งนี้จะทำให้คุณเข้าถึงรายการอาเรย์แรกและสุดท้ายในเวลาเดียวกันทำลายตรรกะทั้งหมดของการสแกนอาเรย์;) สามารถสร้างไอ้ blackhole ได้ LOL

3
สำหรับอาร์เรย์ 0 การจัดทำดัชนีแทนที่ด้วย- ~
mikeserv

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

1
~คือการกลับกันแบบไบนารี เป็น~0 -1(บิตทั้งหมดพลิกขึ้นอยู่กับว่าตัวเลขลบมักจะแสดงบิตฉลาด) ในอาเรย์ที่ไม่มีการตั้งค่าหรืออาเรย์ที่มีเพียงองค์ประกอบเดียวของดัชนี 0, [0], [-0], [-1] และ [~ 0] จะให้สิ่งเดียวกันกับคุณในอาเรย์ ksh
Stéphane Chazelas

1
@ StéphaneChazelas - ใช่ฉันคิดว่าฉันจำการจัดการกับ~เมื่อ-indexไม่ได้ทำงาน ~-indexผมคิดว่าอาจจะทั้งหมดที่ฉันไม่ได้ ใช่. ฟังดูแล้วถูกต้อง ใช่! และแน่นอนว่าใช้ได้กับองค์ประกอบที่ไม่มีการตั้งค่าเช่นกัน ดังนั้นผมคิดว่าการแสดงความคิดเห็นดังกล่าวข้างต้นควรจะ - 0 จัดทำดัชนีอาร์เรย์เพิ่ม ~ฉันเดาว่ามันอาจจะจัดการกับส่วนที่ -1 ได้ง่ายขึ้น ฉันไม่รู้. ไม่กระโดดไปแถวหน้าของหน่วยความจำของฉันในขณะนี้ ...
mikeserv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.