ฉันคือ j = 1 ทำให้เข้าใจผิดจริงเหรอ? [ปิด]


11

มีข้อโต้แย้งทั่วไปเกี่ยวกับการกำหนดค่าเริ่มต้นหลายตัวแปรในหนึ่งซับคือ:

ลองพิจารณาตัวอย่าง int i, j = 1; ซึ่งอาจทำให้บางคนเชื่อว่าตัวแปรทั้งสองกำลังเริ่มต้นผิดพลาด

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

อย่างไรก็ตามสำหรับกรณีที่เฉพาะเจาะจงฉันสงสัยว่าต่อไปนี้จะมีภาษาที่ไวยากรณ์มากi, j = 1เริ่มต้นตัวแปรทั้งสองหรือไม่

หากไม่ใช่ข้อโต้แย้งนั้นก็จะไม่มีผล


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

4
@CodesInChaos คุณกำลังพูดว่า C ไม่ได้สติ?
Baldrickk

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

2
ใน Visual Basic 6 Dim Apple, Orange, Pear as Fruitเป็นการประกาศทางกฎหมาย สมมติว่าคุณไม่รู้จัก VB ความประทับใจครั้งแรกของคุณAppleเป็นแบบFruitไหน? มันไม่ใช่. จำไว้ว่าผู้คนที่ไม่ใช่ผู้เชี่ยวชาญด้านภาษามักอ่านภาษานั้น ๆ หากคุณเป็นผู้เชี่ยวชาญให้ใช้ภาษาอย่างชาญฉลาดเพื่อสื่อสารความตั้งใจของคุณอย่างชัดเจนแม้กับผู้ที่ไม่ใช่ผู้เชี่ยวชาญ ฉันไม่เคยใช้การเริ่มต้นหลายครั้งในภาษาใด ๆ
Eric Lippert

13
ในทำนองเดียวกัน: พิจารณาvar x = 1, y = 1.5; นี่เป็นสิ่งเดียวกันint x = 1; double y = 1.5;หรือเหมือนกันdouble x = 1, y = 1.5;หรือไม่? เมื่อเราเพิ่มvarใน C # 3.0 ฉันทำแบบสำรวจและพบว่าประมาณครึ่งหนึ่งของผู้คนเชื่อว่าสิ่งแรกคือ "เห็นได้ชัด" ถูกต้องและอีกครึ่งหนึ่งเชื่อว่าอีกคนหนึ่งเห็นว่า "ชัดเจน" ถูกต้องและเราก็ทำให้มันผิดกฎหมาย คุณลักษณะที่ทำให้เข้าใจผิดประชากรครึ่งหนึ่งเป็นคุณลักษณะที่ไม่ถูกต้อง
Eric Lippert

คำตอบ:


37

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


3
ฉันก็จะยืนยันว่าถ้าคำสั่งดังกล่าวไม่ได้เริ่มต้นงบทั้งสองทำไมมันถึงมีอยู่?
Berin Loritsch

2
@BerinLoritsch ขึ้นอยู่กับภาษา สิ่งนี้มักจะทำใน JavaScript เนื่องจากการประกาศการชักรอก: มันเป็นวิธีปฏิบัติที่ดีที่สุดในการประกาศตัวแปรที่ด้านบนของขอบเขตที่มีให้แม้ว่าคุณจะไม่ได้เริ่มต้นจนกว่าจะมีการใช้จุดในรหัส . เครื่องมือการแปลงรหัสเกือบทั้งหมดแสดงผลแบบนี้
Jared Smith

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

2
@ JaredSmith นอกเหนือจาก Maple ฉันไม่สามารถนึกถึงภาษาที่ต้องการได้ในขณะนี้แม้ตอนนี้ C ชอบที่จะใกล้ชิดกับขอบเขตมากขึ้น (เช่น C ++ และภาษาอื่น ๆ ส่วนใหญ่ที่มีคอมไพเลอร์คงที่ครึ่งหนึ่ง) เพราะมันให้ประโยชน์ในการหยุดข้อบกพร่อง คอมไพเลอร์ในการตัดสินใจว่าจะทำอย่างไรกับตัวแปรตราบใดที่ฟังก์ชันไม่เปลี่ยนแปลงอาจช่วยให้การปรับให้เหมาะสมดีขึ้นเนื่องจากคุณสามารถหลีกเลี่ยงการลงทะเบียนน้อยลง
WHN

6
ไม่ว่าจะใช้ภาษาใดเราควรถามว่า "อะไรคือประโยชน์ของการเขียนint i, j=1เมื่อเทียบกับint i; int j = 1(หรือดีกว่าแยกบรรทัด)"
chepner

2

ฉันคิดว่าคุณสามารถโต้เถียงทั้งสองด้าน:

  • Kontra i, j = 0: นัก
    คณิตศาสตร์ใช้สิ่งนี้เพื่อหมายความว่าทั้งคู่iและjควรจะเป็นศูนย์

  • Pro i, j = 0:
    มันเป็นเรื่องง่ายที่จะทราบความสำคัญของผู้ให้บริการของคุณ และหากคุณสงสัยเกี่ยวกับความเป็นผู้นำของพวกเขาตอนนี้เป็นเวลาที่จะมองหามัน

    มันเป็นเหตุผลเดียวกันกับที่เราเขียนสิ่งต่าง ๆa.b += c[i]*d[i];โดยไม่มีวงเล็บ แน่นอนว่านี่เทียบเท่ากับ(a.b) += ((c[i])*(d[i]));แต่โปรแกรมเมอร์สามารถคาดเดาได้ถึงความสำคัญของโอเปอเรเตอร์ที่ใช้มากที่สุดด้วยใจและสามารถค้นหาความสำคัญของโอเปอเรเตอร์เมื่อพวกเขาไม่แน่ใจ ดังนั้นโดยทั่วไปวงเล็บจะถือเป็นความยุ่งเหยิงที่ไร้ประโยชน์เว้นแต่ว่าพวกเขาจะบังคับลำดับการประเมินที่แตกต่างจากที่ผู้ปฏิบัติงานกำหนดไว้ก่อน

    แน่นอนว่ามีข้อยกเว้น ความสำคัญของ<<และ+โดยทั่วไปถือว่าไม่ชัดเจนเพียงพอที่จะใช้วงเล็บในทั้งสองกรณี แต่นั่นเป็นข้อยกเว้นที่พิสูจน์กฎ

สำหรับฉันคนหนึ่งจะตกไปสู่ด้าน Pro มากขึ้น แต่ฉันก็เตรียมที่จะยึดแนวทางที่ห้ามการประกาศเช่นนั้น มันไม่ใช่เรื่องที่ควรค่าแก่การต่อสู้


7
ฉันทราบว่าint i, j = 0;ไม่มีตัวดำเนินการอยู่ในนั้น การแสดงออกเพียงอย่างเดียวในคำสั่งนั้น0จึงมีความสำคัญเหนือผู้ประกอบการไม่ได้เข้ามา ตัวแยกวิเคราะห์ไม่ถือว่า,เป็นตัวดำเนินการคอมม่าหรือ=เป็นตัวดำเนินการกำหนดค่า ค่อนข้างเหล่านี้เป็นส่วนไวยากรณ์ของคำสั่งประกาศ
Eric Lippert

@EricLippert เท่าที่กฎระเบียบมีความกังวลความแตกต่างนั้นไม่เกี่ยวข้อง: ภาษา C สไตล์ใด ๆ ที่ฉันรู้ว่าใช้ความสำคัญเดียวกันในการประกาศเช่นเดียวกับในการแสดงออกอื่น ๆ อะไรก็ได้ที่จะเชิญผู้ทำลาย
cmaster - คืนสถานะโมนิก้า

but programmers can be expected to know the precedence of the most used operators by heart, คุณพูด. ในตัวอย่างที่คุณให้ฉันไม่แน่ใจนักโปรแกรมเมอร์ส่วนใหญ่เข้าใจการเข้าถึงตัวดำเนินการสมาชิกหรือตัวดำเนินการดัชนีอาร์เรย์ว่าเป็นตัวดำเนินการในแง่คณิตศาสตร์ แต่แทนที่จะคิดว่ามันเป็นคำนามภาษาธรรมชาติและการคูณ ผู้ประกอบการเป็นคำกริยา นั่นเป็นเหตุผลที่int i, j, k = 0;โครงสร้างโหดเหี้ยมเช่นนี้เพราะมันแสดงเป็นภาษาธรรมชาติของ "ตัวแปร int i, j, และ k ถูกประกาศและจะถูกตั้งค่าเป็น 0"!
Steve

@Steve วิธีที่คุณจำกฎความสำคัญในฐานะโปรแกรมเมอร์นั้นขึ้นอยู่กับคุณอย่างเต็มที่ ถ้ามันช่วยให้คุณคิดว่าพวกเขาเป็นคำนามของภาษาทำมัน อย่างไรก็ตามในกรณีนี้คุณจะพบปัญหาเมื่อคุณเห็นสิ่งต่าง ๆ เช่น*a[i]ฉันไม่คิดว่าคุณสามารถแยกวิเคราะห์ได้อย่างเพียงพอด้วยการเปรียบเทียบ "คำนาม" ในฐานะที่เป็นint i, j, k = 0;ที่อาจหมายถึงอะไรถ้าคุณไม่ได้มองถึงกฎ: ตีความที่สามจะมีการประกาศint iแล้วประเมินและในที่สุดก็กำหนดj k = 0หากคุณไม่ทราบไวยากรณ์ของภาษาของคุณคุณจะไม่สามารถแยกวิเคราะห์โครงสร้างดังกล่าวได้ มันเป็นปัญหาของคุณถ้าคุณทำอยู่ดี
cmaster - คืนสถานะโมนิก้า

@cmaster ฉันไม่ได้แสดงกลยุทธ์การท่องจำเฉพาะของฉันฮ่าฮ่า ฉันไม่ใช่โปรแกรมเมอร์ C ดังนั้นความคุ้นเคยกับลำดับความสำคัญของโอเปอเรเตอร์ใน C จึงเป็นอัตราที่สอง แต่สิ่งที่ฉันสังเกตเห็นเมื่อฉันดูตัวอย่างของคุณคือฉันไม่เคยนึกถึงตัวคูณการคูณว่ามีความสำคัญกว่าญาติกับตัวดำเนินการดัชนีอาร์เรย์ นั่นคือฉันไม่ได้อ่านa[i]เป็นตัวดำเนินการดัชนีที่ใช้กับaแต่อ่านทั้งสองร่วมกันเป็นองค์ประกอบไวยากรณ์ลดลงไม่ได้ระบุตัวถูกดำเนินการของตัวดำเนินการคูณและดังนั้นฉันไม่ได้รับแจ้งให้ประเมินความสำคัญ (1/2)
Steve
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.