การใช้ตัวชี้และข้อดีของพอยน์เตอร์คืออะไร [ปิด]


10

ฉันมักจะดิ้นรนเพื่อดูข้อดีของพอยน์เตอร์ (ยกเว้นการเขียนโปรแกรมระดับต่ำ)

เหตุใดจึงใช้ถ่าน * แทนที่จะเป็นสตริงหรือถ่าน [] หรือเลขคณิตของตัวชี้ข้อดีคืออะไร

ดังนั้นข้อดีและการใช้งานของพอยน์เตอร์คืออะไร


6
สิ่งนี้จะทำให้เกิดเสียงชั้นนำเล็กน้อย แต่ IMHO ถ้าคุณต้องถามถึงข้อดีและข้อเสียของพอยน์เตอร์คุณอาจไม่ต้องการมัน
Jas

3
อาจ! แต่คำถามก็ยังคงใช้ได้!
Zolomon

1
สิ่งนี้ไม่ใช่ภาษาที่ไม่เชื่อเรื่องพระเจ้าเพราะภาษาการเขียนโปรแกรมทั้งหมดมีพอยน์เตอร์ที่แท้จริงในภาษาซี
David Thornley

คำตอบ:


6

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

ในภาษาส่วนใหญ่ที่ใช้พอยน์เตอร์มีการอ้างอิงบางประเภทที่เป็นพอยน์เตอร์และบางทีการอ้างอิงบางประเภทที่ไม่ได้เป็นและไม่มีความแตกต่างที่น่าสังเกตเพิ่มเติม consเซลล์เสียงกระเพื่อมเป็นคู่ของพอยน์เตอร์แม้ว่าfixnumจะไม่ใช่ตัวชี้ ใน Java ตัวแปรที่ใช้สำหรับอินสแตนซ์ของคลาสเป็นตัวชี้ แต่intไม่ใช่ ไวยากรณ์ภาษาไม่ได้สะท้อนถึงสิ่งนั้น

C เป็นเรื่องผิดปกติในพอยน์เตอร์ที่เป็นตัวเลือกชัดเจนและอนุญาตให้มีการคำนวณทางคณิตศาสตร์อย่างชัดเจน เป็นไปได้อย่างสมบูรณ์แบบในการเขียนstruct foo bar; struct foo * baz;และเมื่อคุณจัดสรรหน่วยความจำแล้วbazคุณสามารถใช้ทั้งสองbarและbazเพื่อเป็นตัวแทนstruct fooของ เนื่องจากพอยน์เตอร์เป็นทางเลือกจึงมีประโยชน์ที่จะมีความแตกต่างของสัญ (มันเป็นสิ่งจำเป็นใน C ++ สำหรับตัวชี้สมาร์ทตามที่กำหนดboost::shared_ptr<foo> bar;, bar.reset()มีหนึ่งความหมายและbar->reset()มีแนวโน้มที่จะมีความแตกต่างกันมากหนึ่ง.)

(ที่จริงแล้วพอยน์เตอร์ที่ชัดเจนมักใช้ในภาษาอื่นเมื่อ C ได้รับการพัฒนาอย่างเช่น^ใน Pascal C เป็นภาษาที่เก่ากว่าที่ใช้กันทั่วไปในปัจจุบันและแสดงให้เห็น)

หนึ่งในเป้าหมายการออกแบบของ C คือการเขียน Unix ดังนั้นจึงจำเป็นต้องจัดการตำแหน่งหน่วยความจำอย่างละเอียด (C เป็นจริงหนึ่งในตระกูลของภาษาที่ใช้งานกับระบบทั่วไปเมื่อมันถูกออกแบบขึ้นมาอีกตัวอย่างหนึ่งคือ Cybol สำหรับคอมพิวเตอร์ Data Data C เป็นภาษาที่ได้รับความนิยมอย่างมาก) ดังนั้นจึงเป็นไปได้ที่จะจัดการ C พอยน์เตอร์โดยตรง การกำหนดที่อยู่หน่วยความจำและการคำนวณใหม่ สิ่งนี้นำไปสู่การตัดสินใจออกแบบในซีซีอาเรย์นั้นขึ้นอยู่กับเลขคณิตของตัวชี้และแน่นอนว่าอาร์เรย์นั้นจะสลายตัวไปสู่ตัวชี้ในหลาย ๆ สถานการณ์ การส่งผ่านตัวแปรไปยังฟังก์ชัน C โดยการอ้างอิงทำได้โดยตัวชี้ ไม่มีความจำเป็นอย่างมากสำหรับอาร์เรย์และตัวแปรที่ส่งผ่านโดยการอ้างอิงในรูปแบบที่ภาษาร่วมสมัยอื่น ๆ มีดังนั้น C จึงไม่ได้รับสิ่งเหล่านั้น

ดังนั้นคำตอบก็คือในทุกวันนี้ภาษาส่วนใหญ่คุณใช้พอยน์เตอร์อย่างต่อเนื่องโดยไม่เตือนความจริง ใน C และ C ++ ในระดับที่น้อยกว่าคุณใช้พอยน์เตอร์เพื่อทำสิ่งต่าง ๆ ในระดับต่ำหรือทำสิ่งที่สำเร็จระดับสูงกว่าซึ่งไม่มีสัญลักษณ์พิเศษ


คำตอบที่ดีมาก
Kate Gregory

1
ฉันยอมรับคำตอบนี้เพราะอธิบายความแตกต่างได้ดีที่สุดที่ฉันไม่สามารถเข้าใจระหว่างพอยน์เตอร์ใน C / C ++ และ Reference ใน Java
OliverS

มันเป็นการดีที่จะเพิ่มคำอธิบายสั้น ๆ ว่าทำไม Java ไม่ใช้พอยน์เตอร์เพื่ออธิบายการรับรู้ที่ผิดพลาดโดย Gosling (ผู้สร้างหลักของ Java)
Guido Anselmi

10

โครงสร้างข้อมูลที่ซับซ้อน คุณไม่สามารถสร้างบางสิ่งบางอย่างเช่นรายการที่เชื่อมโยงหรือต้นไม้ไบนารีโดยไม่มีตัวชี้

ไม่มี "ข้อดี" และ "ข้อเสีย" ของพอยน์เตอร์ พวกเขาเป็นเพียงเครื่องมือเช่นค้อน


5
ใน Java ไม่มีพอยน์เตอร์ แต่มันเป็นไปได้ที่จะสร้างรายการที่เชื่อมโยงและต้นไม้ไบนารี มีความแตกต่างระหว่างการอ้างอิง (เช่นใน Java) และตัวชี้ (เหมือนใน C)
StartClass0830

7
ไม่มีความแตกต่างระหว่างการอ้างอิงและพอยน์เตอร์ เลขคณิตของตัวชี้คือ C-specific มีภาษาอื่น ๆ ที่มีพอยน์เตอร์ แต่ไม่มีพอยน์เตอร์ทางคณิตศาสตร์ (เช่น Pascal)
zvrba

1
ตัวชี้และการอ้างอิงนั้นไม่มีความหมายเหมือนที่คุณคิด อ่านสิ่งนี้เพื่อดูความแตกต่าง stackoverflow.com/questions/57483/…
StartClass0830

4
ในการจัดการกับสองรายการแรกของรายการนั้น: การอ้างอิง Java สามารถกำหนดใหม่ได้และสามารถอ้างอิงได้เป็นโมฆะ คุณลักษณะที่แตกต่างของตัวชี้คือให้คุณอ้างอิงวัตถุอื่นทางอ้อม การทดสอบสารสีน้ำเงินของฉันคือ: ถ้าคุณสามารถสร้างโครงสร้างข้อมูลแบบวงกลม (ซึ่งคุณสามารถใช้กับการอ้างอิง Java) มันเป็นตัวชี้ (โปรดทราบว่าคุณไม่สามารถสร้างโครงสร้างข้อมูลแบบวงกลมด้วยการอ้างอิง C ++)
zvrba

1
มีความแตกต่างระหว่างตัวชี้และการอ้างอิง C # เช่นมีทั้ง ( blogs.msdn.com/b/ericlippert/archive/2009/02/17/ … )
Steven Evers

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

การอ้างอิงใน C ++, Java และภาษาประเภทเดียวกันอื่น ๆ เป็นเพียง 'ตัวชี้ความปลอดภัย' และการอ้างอิงเหล่านี้ถูกใช้อย่างมากใน Java


1
การอ้างอิงใน C ++ ไม่ใช่ตัวชี้ที่ปลอดภัย การอ้างอิงใน C ++ ไม่มีส่วนเกี่ยวข้องกับพอยน์เตอร์เลย อ้างอิงใน C ++ เป็นนามแฝง ไม่สามารถกำหนดให้กับNULLและไม่สามารถแก้ไขได้หลังจากสร้างแล้ว
Billy ONeal

@Billy: การอ้างอิง C ++ มักจะนำมาใช้โดยใช้พอยน์เตอร์และทำงานคล้ายกันในบางสิ่งดังนั้นผู้คนมักคิดว่ามันเป็นตัวชี้ที่ จำกัด
David Thornley

2

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


2

char*เป็นตัวอย่างของตัวชี้ crummy คุณอาจจะดีกว่าการใช้std::string(หรือบางประเภทที่ดีกว่าที่จับ Unicode / ANSI / สัญลักษณ์ specialness ของคุณ) char*กว่า เกือบ ๆ ตัวอย่างอื่น ๆ ของตัวชี้ ( Employee*, PurchaseOrder*, ... ) แต่มีข้อดี:

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

ในความเป็นจริงพอยน์เตอร์มีความสำคัญอย่างยิ่งที่ภาษาส่วนใหญ่ที่ดูเหมือนจะไม่ให้พวกเขามีเพียงพวกเขาเท่านั้น ประเภทการอ้างอิงใน C # และ Java เป็นตัวชี้ที่ปลอมตัวเป็นวัตถุที่เป็นของแข็ง

ตอนนี้การจัดการตัวชี้ ( p++บนตัวชี้หรือp += delta) เป็นเรื่องราวทั้งหมด บางคนคิดว่ามันอันตรายบางคนคิดว่ามันยอดเยี่ยม แต่นั่นก็ยิ่งไปกว่านั้นจากคำถามของคุณ


1

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

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

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

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

บ่อยครั้งที่สิ่งที่ทำให้ตัวชี้ "แข็ง" ไม่เพียง แต่เข้าใจว่าเกิดอะไรขึ้นในระดับฮาร์ดแวร์ มันไม่มีอะไรมากไปกว่าการอ้อมไป

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

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

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

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


0

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


-1

พอยน์เตอร์ให้การมองเห็นเครื่องที่จำเป็นสำหรับการโปรแกรมที่น่าสนใจที่สุด ภาษาสมัยใหม่ส่วนใหญ่จะซ่อนบิตที่เป็นกรวดไว้จากคุณ

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