คำอธิบายที่ดีสำหรับตัวชี้คืออะไร [ปิด]


72

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

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

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


Update:ฉันชอบคำตอบจริงๆ โปรดให้พวกเขามา มีมุมมองที่ดีมากมายที่นี่ แต่ฉันคิดว่าหลายคนมีคำอธิบาย / คำขวัญที่ดีสำหรับตัวเราเองหลังจากที่เราใช้แนวคิดนี้ ฉันกำลังมองหารายละเอียดบริบทและสถานการณ์เมื่อเริ่มต้นกับคุณ

ตัวอย่างเช่น:

ฉันแค่เข้าใจพอยน์เตอร์ syntactically ใน C. ฉันได้ยินเพื่อนของฉันสองคนอธิบายพอยน์เตอร์ให้เพื่อนอีกคนหนึ่งซึ่งถามว่าทำไม a ถึงstructถูกส่งผ่านด้วยพอยน์เตอร์ เพื่อนคนแรกพูดคุยเกี่ยวกับวิธีการที่จะต้องมีการอ้างอิงและแก้ไข แต่มันเป็นเพียงความเห็นสั้น ๆ จากเพื่อนคนอื่น ๆ ที่มันตีฉัน: "มันมีประสิทธิภาพมากขึ้นด้วย" การส่งผ่าน 4 ไบต์แทนที่จะเป็น 16 ไบต์เป็นการเปลี่ยนแนวคิดขั้นสุดท้ายที่ฉันต้องการ


16
วิธีการ 'ปืนลูกซอง': โยน * ทุกที่จนกว่าจะใช้งานได้
Michael K

15
@Michael: ใช่โชคดีกับสิ่งนั้น
Robert Harvey

8
คำถามนี้เกิดขึ้นไม่นานหลังจากเริ่มภาคการศึกษาทุกภาคการศึกษา การจุติใหม่ล่าสุดอยู่ที่นี่: stackoverflow.com/questions/4118647/…
Tim Post

10
คำอธิบายที่ดีสำหรับตัวชี้คืออะไร Brian Kernhigan และ Dennis Ritchie เกลียดวิศวกรซอฟต์แวร์
Adam Crossland

3
มันเป็น "คลิก" สำหรับฉันหลังจากใช้เวลาสักครู่หนึ่งรหัสเครื่องในโปรแกรมดีบั๊ก ใช่ฉันคุ้นเคยกับพื้นฐานของสถาปัตยกรรมคอมพิวเตอร์ - ฉันเรียนรู้การชุมนุมใน Commodore 64 และ x86 ASM ค่อนข้างตรงไปตรงมาหลังจากนั้น ดังนั้นฉันจึงรู้แนวคิดของ "ที่อยู่" ฉันก็ไม่เข้าใจว่ามันถูกแมปกับโครงสร้างทางไวยากรณ์ของ C อย่างไร
zvrba

คำตอบ:


25

ไดอะแกรมหน่วยความจำ -a-a-Grid

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

โดยปกติแล้วมันเป็นช่วงเวลา "ohhhh" สำหรับนักเรียนส่วนใหญ่ของฉัน

สัญลักษณ์การเล่นกล

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

พิมพ์ไปยังหน่วยกู้ภัย

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

มีความกว้างขวาง

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

จากนั้นเริ่มคำนวณตัวชี้


ภาคผนวก: การเรียกซ้ำ

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

มักจะมี "สิ่งที่ ... ?" สักครู่และเมื่อคุณเพิ่มพารามิเตอร์อื่นลงใน printf ของคุณเพื่อพิมพ์ค่าตัวเลขและเยื้องขั้นตอนมันจะโล่งใจ


ทางเลือก: รุ่น Play-Doh และถ้วยน้ำ

จริง ๆ แล้วฉันมีเพื่อนร่วมงานในมหาวิทยาลัยที่แสดงให้นักเรียนเห็นวิดีโอที่อธิบายตัวชี้และการเข้าถึงหน่วยความจำโดยใช้ play-doh paste มันฉลาดและทำได้ดีมาก แต่ฉันก็ไม่เคยใช้เทคนิคนั้นด้วยตัวเองยกเว้นผู้เรียนที่อายุน้อยมากที่สนใจการเขียนโปรแกรม (แต่โดยทั่วไปแล้วฉันจะไม่นำพวกเขาไปสู่ภาษาโดยใช้พอยน์เตอร์เร็วเกินไป) โดยทั่วไปใช้ play-doh ลูกเล็ก ๆ ซึ่งคุณสามารถแนบไปกับ ball-doh ที่ใหญ่กว่าซึ่งเป็นตัวแทนของพื้นที่หน่วยความจำและคุณสามารถรวมเข้าด้วยกันเพื่อเชื่อมโยงพวกเขา (เช่นในโครงสร้างข้อมูลที่เชื่อมโยง) หรือผสานเข้าด้วยกัน พื้นที่หน่วยความจำ) การใช้สีที่แตกต่างกันสำหรับพื้นที่หน่วยความจำที่ชี้ไปและตัวชี้ช่วยเช่นกัน แต่ฉันยังคงคิดว่าสิ่งที่ Memory-as-a-Grid ใช้งานได้ดีกว่า ในขณะที่คุณสามารถแสดงให้เห็นได้อย่างชัดเจนว่าการชี้นั้นเป็นเรื่องของ "การพูดถึง" เช่นเดียวกับใน "แผนที่ / กริด" ในขณะที่โหมด Play-doh ยังคงสับสนพวกเขาคิดว่าสิ่งที่ "สัมผัส" กันในหน่วยความจำ

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


ว้าวขอบคุณสำหรับความกรุณา ดีใจที่ได้รับคำตอบ
เฮย์เล็ม

วาดออก: | ฟังดูเหมือนการสอนที่ดี!
Spooks

80

บางคนฉลาดกว่าที่ฉันเคยพูดไว้:

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

ปรมาจารย์ตอบว่า "ฉันไม่รู้หนังสือได้โปรดอ่านตัวละครให้ฉันฟังและบางทีฉันอาจจะสามารถอธิบายความหมายได้"

ภิกษุณีกล่าวว่า "คุณไม่สามารถจำตัวละครต่าง ๆ ได้คุณจะเข้าใจความหมายได้อย่างไร"

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


13
+1 สำหรับการอ้างอิงดวงจันทร์ +1 สำหรับ koan ถ้าทำได้
Tim Post

14
เสียงของการเลื่อนนิ้วหนึ่งนิ้วคืออะไร?
Adam Crossland

3
@ อดัมที่ขึ้นอยู่กับว่าคุณกำลังใช้เมาส์หรือแทร็คแพด
แดเนียลโจเซฟ

7
@ Frank มันเป็นคำพูดที่ยอดเยี่ยม ยังฉันคิดว่ามันจะไม่ช่วยให้เข้าใจความคิด พิเศษสำหรับคนที่ยังใหม่กับพอยน์เตอร์
Gulshan

11
นี่เป็นเรื่องราวที่สวยงาม ... แต่ฉันสงสัยว่าผู้คนโหวตเพราะเรื่องนั้นมากกว่าที่จะอธิบายตัวชี้ได้ดี
Kyralessa

46

ฉันพบว่าไดอะแกรมมีประโยชน์มาก ตัวอย่าง:

ไดอะแกรมตัวชี้


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


4
ค่าภายใน "พอยน์เตอร์" ควรเป็น 4 หรือดัชนีอาเรย์ (หรือที่อยู่หน่วยความจำ) ควรเริ่มจาก 0 มิฉะนั้นตัวชี้ที่เก็บค่า 3 ชี้ไปที่ตำแหน่ง 4 จะเป็นอย่างไร
MAK

++ นี่คือสิ่งที่ฉันจะอธิบาย ฉันเริ่มที่ฟอร์แทรน (ดีขึ้นหรือแย่ลง!) ใน Fortran ย้อนกลับไปตอนนี้เราใช้อาร์เรย์แบบขนานแทนที่จะเป็นอาร์เรย์ของ structs (ไม่มีสิ่งใหม่ ) หากอาร์เรย์หนึ่งมีดัชนี "อีกแถวหนึ่ง" ในอาร์เรย์เราเรียกมันว่า "ตัวชี้" และนี่น่าตื่นเต้น เราสร้างรายการต้นไม้คุณตั้งชื่อมัน
Mike Dunlavey

2
ฉันพบตัวชี้ที่อธิบายได้ดีที่สุดโดยใช้รูปภาพที่ระบุว่าเก็บไว้ที่ไหนและลูกศรเพื่อระบุตำแหน่งที่ตัวชี้ชี้
gablin

32

เมื่อครั้งแรกที่ฉัน "เรียนรู้" เกี่ยวกับพอยน์เตอร์ฉันก็เลยอยากลอง มหาวิทยาลัยของฉันตัดสินใจมานานก่อนที่ฉันจะลงทะเบียนเพื่อวางหลักสูตรไว้ที่ Java ดังนั้นเมื่อโครงสร้างข้อมูลของฉันให้การบรรยายหนึ่งครั้งบน C และขอให้เรานำ XOR-List มาใช้ร่วมกับตัวชี้ฉันรู้สึกว่าฉันกำลังจะทำอะไรทางเหนือหัวของฉัน

ฉันเข้าใจคำจำกัดความ:

ตัวชี้เป็นตัวแปรที่มีที่อยู่ของตัวแปร

แต่ฉันก็ยังไม่เข้าใจแนวคิดส่วนใหญ่ มองย้อนกลับไปฉันคิดว่ามันมีศูนย์กลางอยู่ที่สามสิ่ง:

  1. สิ่งที่ว่าเป็นที่ตั้งของหน่วยความจำหรือไม่? (ในตอนนั้นฉันไม่เรียนวิชาคอมพิวเตอร์)

  2. ไวยากรณ์ที่น่าอึดอัดใจ (อืม ... ทำไมมันถึงถูกกำหนดเช่น "int * ip" แต่แล้วฉันก็อ้างถึงตัวแปรเป็น "ip"?)

  3. มันจะมีประโยชน์อย่างไรในการเก็บที่อยู่ของตัวแปรมากกว่าแค่ใช้ตัวแปร?

มันไม่ได้จนกว่าฉันจะซื้อหนังสือ K&R และทำทุกปัญหาที่ฉันเข้าใจสำหรับตัวชี้ นอกจากความจริงที่ว่าฉันเรียนคอมพิวเตอร์มานานแล้ว (ซึ่งฉันคิดว่าควรจะต้องเรียนก่อนที่จะเรียน C) ส่วนหนึ่งเกี่ยวข้องกับข้อเท็จจริงที่ฉันรู้ว่าสามารถใช้พอยน์เตอร์สำหรับฟังก์ชั่น, อาร์เรย์, struct ... เพื่อทำสิ่งที่มีประโยชน์และไม่เพียงเป็นที่เก็บข้อมูลสำหรับที่อยู่ของตัวแปรสามัญ

แต่ช่วงเวลา "aha" ของฉันในตอนนั้นคือวิธีที่ K&R อธิบายไวยากรณ์ที่น่าอึดอัดใจของการกำหนดตัวชี้แบบง่าย ฉันจดบันทึกตลอดทั้งเล่ม (ซึ่งฉันใช้ถ้อยคำใหม่ที่ทำขึ้นโดยหนังสือเล่มนี้เป็นคำพูดของตัวเองเพื่อความเข้าใจที่มากขึ้น) และนี่คือสิ่งที่เกี่ยวข้องกับสิ่งนั้น:

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

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

ฉันมักจะรู้สึกว่าฉันไม่สามารถเข้าใจแนวคิดขั้นสูงของพอยน์เตอร์ได้อย่างเต็มที่จนกว่าฉันจะมีอะไรบางอย่างฝังแน่นอยู่ในหัวของฉัน มันรบกวนฉันอย่างไม่สิ้นสุดหลังจากการบ้านนั้น (ซึ่งฉันทำได้ไม่ดีนักตาม);) ทำไม "* ip" ไม่ได้อยู่หลังจากฉัน (คิดว่าฉัน) กำหนด "* ip" การเรียนรู้สิ่งนี้เป็นสิ่งจำเป็นสำหรับแนวคิดขั้นสูงเพิ่มเติมที่เกี่ยวข้องกับพอยน์เตอร์เช่นตัวชี้ฟังก์ชั่นและคำจำกัดความที่ซับซ้อนมากขึ้นเช่นนี้:

char (*(x())[])()

โดยสรุปฉันคิดว่าแนวคิดของพอยน์เตอร์ต้องการ:

  1. ความเข้าใจพื้นฐานเกี่ยวกับวิธีการจัดวางหน่วยความจำในคอมพิวเตอร์ (และหน่วยความจำคืออะไร)

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

  3. การถอดรหัสอักษรอียิปต์โบราณที่รู้จักกันเรียกขานว่า "นิยามของตัวชี้"

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


+1 สำหรับ 3 "อ่าฮ่า!" monents พอยน์เตอร์ Groking มาในเลเยอร์ ฉัน "เข้าใจ" จุดเป็นเวลานานก่อนที่ผมจะรู้ว่าผมเพียงประมาณครึ่งหนึ่งเข้าใจแนะนำให้คำแนะนำ :)
Binary Worrier

ฉันคิดว่าคุณถูกต้องทั้งหมดในส่วนที่ใหญ่มากของ 'ตัวชี้ที่ไม่เข้าใจ' กำลังสะดุดกับไวยากรณ์ C แปลก ๆ [คิด: ผมสงสัยว่ามันยากที่จะ grok กับชนิดของรูปแบบนี้: PointerTo<int> a]
Benjol

เห็นด้วย @Benjol ฉันประหลาดใจที่ไวยากรณ์int* ipไม่ธรรมดา ในที่สุดฉันก็เริ่มเข้าใจพอยน์เตอร์เมื่อฉันเห็นโค้ดที่จัดรูปแบบเช่นนี้ จากนั้นฉันก็อ่านมันได้ว่า "ip is of pointer int pointer"
Jacob

19

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

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

เมื่อกลุ่มเข้าใจพื้นฐานเบื้องหลังทางลัดคุณสามารถเริ่มอธิบายพอยน์เตอร์ได้ตามต้องการ พวกเขาอาจจะเข้าใจได้อย่างง่ายดาย


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

การเชื่อมโยงอย่างหนักนั้นเหมือนการอ้างอิงตัวชี้สมาร์ท
jk

1
+1 หนึ่งในการเปรียบเทียบที่ใช้งานได้จริงที่ดีที่สุดในการอธิบายพอยน์เตอร์ ฉันแน่ใจว่านักเรียนจะได้รับความคิดทันทีเนื่องจากฟังก์ชั่นนี้เป็นสิ่งที่ทุกคนใช้กันมากที่สุด
Karthik Sreenivasan

13

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

ฉันใช้การเปรียบเทียบของถ้วยกาแฟ (หรือแถวของพวกเขาสำหรับอาร์เรย์) เป็นตัวแปร (มันสามารถเก็บบางสิ่ง) จากนั้นฉันก็ใช้มือซึ่งอาจถือของบางอย่างหรือโดยการยืดนิ้วชี้ไปที่ "ชี้ไปที่" ถ้วยกาแฟ

มือที่ใกล้จะว่างเปล่านิ้วชี้ไปที่หัวของฉัน (เหมือนปืนจำลอง) เป็นตัวชี้ที่ห้อยต่องแต่ง

จากนั้นมีการสาธิตและการเดินทางผ่านดีบักเกอร์เพียงไม่กี่รายการจึงมีการคลิกมากที่สุด


3
คุณทำให้ฉันสับสนแล้ว
kirk.burleson

1
@ โบสถ์อย่างไรเหรอ? ให้ฉันดูว่าฉันสามารถล้างมันได้หรือไม่
DevSolo

4
++ ไม่มีอะไรที่เหมือนกับการสอนเพื่อให้คุณคิดถึงสิ่งเหล่านี้
Mike Dunlavey

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

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

10

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

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

ฉันได้รับจริงเหรอ? บางทีฉันไม่เคยทำ

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

เพียงแค่โยนความคิดนั้นออกไปที่นั่นแน่นอนโดยส่วนตัวแล้วฉันชอบแผนผังที่ดีและSteve Gibson ก็ทำหน้าที่ได้ยอดเยี่ยมในการอธิบายทุกอย่าง !


น่าสนใจ ... คุณใช้ภาษาอะไรในเวลานั้น? ฉันคิดว่าซินแท็กซ์ซินแท็คซ์มีผู้คนมากมาย หากคุณรู้ว่าการชุมนุมครั้งแรกฉันจะเห็นว่าเป็นหนึ่งในเหตุผล [BTW ฉันต้องการลงคะแนนนี้ แต่ฉันมาถึงขีดสูงสุดแล้ววันนี้]
Macneil

ที่น่าสนใจพอฉันไม่มีความรู้เกี่ยวกับตัวชี้ "อันตราย" มาเป็นเวลานานทำงานใน Python (และ Java ที่มหาวิทยาลัย) จากนั้นฉันก็ใช้โมดูล "วิธีการเชิงวัตถุ" ซึ่งใช้ภาษา C ++ เป็นภาษาที่ต้องการและตรงไปตรงมา
Marcus Whybrow

นอกจากนี้ฉันคิดว่าการมีความเข้าใจเกี่ยวกับวิธีการแสดงโปรแกรมในหน่วยความจำสามารถช่วยได้อย่างแน่นอน แต่ฉันคิดว่าฉันค่อนข้างจะบอกว่าการทำความเข้าใจว่าทำไมพอยน์เตอร์จึงมีประโยชน์เพิ่มเติมกับภาษาเป็นมุมที่มีประสิทธิภาพมากที่สุด ดำเนินการในฐานะนักออกแบบดั้งเดิม
Marcus Whybrow

+1 ฉันไม่รู้ว่าทำไมคนคิดว่าตัวชี้นั้นยากหรือลึกลับ
ggambett

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

7

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


+1 สำหรับการปรับนามธรรมที่เป็นนามธรรมมากกว่าการพยายามใช้การเปรียบเทียบ
ประเภทไม่ระบุชื่อ

ในโรงเรียนมัธยมของฉันมีการเรียนวิชาคอมพิวเตอร์หนึ่งหน่วยเพื่อศึกษาคอมพิวเตอร์กลักไม้ขีดไฟซึ่งสามารถสอนได้จากกระดานดำโดยไม่ต้องสัมผัสหรือเกี่ยวข้องกับคอมพิวเตอร์จริง
rwong

@ แลร์รี่โคลแมนสมัชชา !!!!!!!!!!!! ฉันต้องการลองครั้งแรกก่อน C. กรุณาบอกฉันว่าจะเริ่มเรียนที่ไหนดี Ebooks ฟรี PDF ฟรี IDE? โปรด!!!!!!!!!!!!!!!!!!!
Spacez Ly Wang

7

ตัวชี้เป็นตัวแปรที่มีค่าเป็นที่อยู่หน่วยความจำของตัวแปรอื่น


สง่างามทำไมทำให้ซับซ้อนมากขึ้น
Bjarke Freund-Hansen

หากพอยน์เตอร์ดูเหมือนจะไม่เข้าใจง่ายและมีประโยชน์ในทันทีพวกเขาจะอธิบายผิด
Jon Purdy

6

ฉันเรียนรู้เกี่ยวกับพอยน์เตอร์ได้อย่างไร โดยการเขียนเรียบเรียงปีการศึกษาเรียบง่ายของวิทยาลัย

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


+1 สำหรับความทรงจำของหลักสูตร CS ของฉันที่ฉันมีคำอธิบายนั้นอย่างแน่นอน
Gary Rowe

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

+1 การเปรียบเทียบนั้นยังคงแนวคิดเดียวกันกับที่Barfieldmvอธิบายไว้แต่ด้วยวิธีการในชีวิตจริงที่มากขึ้น
Karthik Sreenivasan

5

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

  • มันเป็นตัวแปรด้วย แต่มีลักษณะแตกต่างกัน สมมติว่ามีสองชั้นในพื้นที่ตัวแปร ตัวแปรปกติของประเภทต่าง ๆ อยู่ในชั้นบนและพอยน์เตอร์ในชั้นล่าง ชอบรูปนี้

    ข้อความแสดงแทน

  • ตามที่ชื่อ 'ตัวชี้' แนะนำตัวชี้สามารถชี้ไปที่บางสิ่งบางอย่าง เช่นเดียวกับนิ้วของเราสามารถชี้ไปที่วัตถุบางอย่าง สิ่งที่พวกเขาชี้ไปคืออะไร? นี่คือตัวแปรปกติ กล่าวสั้น ๆ ว่า "พอยน์เตอร์ชี้ไปที่ตัวแปรปกติ"

  • เช่นเดียวกับตัวแปรปกติพอยน์เตอร์มีจำนวนประเภทเดียวกันเช่น int, char หรือ float และตัวชี้ชนิดเฉพาะสามารถชี้ไปที่ตัวแปรประเภทเดียวกันเท่านั้น
  • ตัวชี้สามารถชี้ไปที่ตัวแปรหนึ่งและต่อมาตัวชี้เดียวกันสามารถชี้ไปที่ตัวแปรอื่น เพียงประเภทควรจะเหมือนกัน ดังนั้นความสัมพันธ์ของตัวชี้กับตัวแปรบางตัวนั้นไม่ถาวรและสามารถเปลี่ยนแปลงได้
  • ดังนั้นวิธีการประกาศตัวชี้? เกือบเหมือนตัวแปรทั่วไป คุณต้องนำหน้าชื่อด้วยเครื่องหมายดอกจัน ( *) ชอบ-

    int *pointer;
    
  • จากนั้นตัวชี้เกี่ยวข้องกับตัวแปรอย่างไร การใช้&โอเปอเรเตอร์หน้าตัวแปรเช่นนี้

    pointer = &variable;
    
  • วิธีการใช้ตัวชี้โดยชี้ไปที่ตัวแปร? นอกจากนี้ยังสามารถทำได้โดยนำหน้าด้วยเครื่องหมายดอกจัน ( *) จากนั้นมันสามารถใช้แทนตัวแปรที่ชี้ไปตอนนี้ -

    *pointer = var1 + var2;
    

    แทน

    variable = var1 + var2;
    
  • ตอนนี้เล่นด้วยตัวชี้พร้อมรหัสบางส่วน เพิ่งคุ้นเคยกับลักษณะของพอยน์เตอร์นี้ เกินจุดนี้เรากำลังพูดถึงสิ่งที่ตัวชี้ทำ เมื่อคุณตกลงกับมันแล้วเริ่มศึกษาว่าตัวชี้ชี้ไปที่ตัวแปรบางตัวอย่างไรและพวกมันจะตอบสนองอย่างไรหากมีการใช้งานการคำนวณทางคณิตศาสตร์ตามปกติ จากนั้นไปที่ความสัมพันธ์ระหว่างพอยน์เตอร์กับอาร์เรย์และพอยน์เตอร์กับพอยน์เตอร์

นั่นคือทั้งหมดที่ฉันจะแนะนำเกี่ยวกับการเรียนรู้พอยน์เตอร์


ฉันต้องการติดตาม "ขั้นแรกว่ามันทำอย่างไร" Abstraction!
Gulshan

5

แก้ไขเพื่อรองรับการแก้ไขข้อกำหนดของคำถาม

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

char s[] = "Hello, world!";
printf("%s",s);

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

void print_str(char* p) {
  printf("%s",p);
}

เป็นสิ่งที่คู่มือพูด แต่สิ่งที่ * เกี่ยวกับ? อืมถ่าน * หมายถึง "ตัวชี้ไปยังถ่าน" ตกลง ... หลงทาง จากนั้นมันก็เริ่มที่ฉันว่าถ่าน * ทำให้ p เทียบเท่ากับ s [0] ตกลงฉันสามารถใช้สิ่งนั้นได้ แต่ฉันก็ยังไม่ได้เพิ่มว่าตัวชี้คืออะไร ฉันหมายถึงฉันจะตั้งค่าข้อมูลบางอย่างด้วยหนึ่งในสิ่งเหล่านี้ได้อย่างไร ออกไปด้วยตนเองอีกครั้ง ...

char* p = "Hello World!";

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

 s[2] = 'L'; 

แต่สิ่งที่เทียบเท่าใน "ตัวชี้พูด"? ปิดไปที่คู่มือนั้นอีกครั้ง ...

*(p+2) = 'L';

ฉันคิดว่า * ก็หมายความว่า "เนื้อหาของที่อยู่หน่วยความจำ" และเป็น(p+2) s[2]ซึ่งหมายความว่าตัวชี้ p คือ ... เพียงแค่ ... ที่อยู่ ... บ้อง!

นั่นคือเสียงแห่งการตรัสรู้ ทันใดนั้นฉันก็พอยน์เตอร์พอยน์เตอร์ (มันนานมาแล้วเราตัวนับอายุไม่ได้ "grok" จนกระทั่งในภายหลัง) มันเป็นเพียงการอ้อม


เดิม:

ตกลงมูลค่า 2c ของฉัน:

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

และคำตอบที่ขนาดใหญ่ที่ครอบคลุมทุกอย่างที่คุณเคยจะต้องรู้ - อ่านนี้


++ นั่นเป็นวิธีที่ฉันสอนมากขึ้นหรือน้อยลง
Mike Dunlavey

บทความที่แก้ไขเพื่อรองรับความต้องการ OP
Gary Rowe

คุณใช้ด้วยตนเองแบบไหนที่เพิ่มอักขระ NUL พิเศษไว้ที่ส่วนท้ายของสตริง
Rob Gilliam

@raimesh หนึ่งที่เก่ามาก (ประมาณปี 1991) จำไม่ได้ว่า
Gary Rowe

1991? นั่นไม่เก่าสำหรับคู่มือภาษา C - รุ่นที่ 1 ของ K&R ถูกตีพิมพ์ในปี 1978! เพิ่งทึ่งว่ามีคู่มือออกมาซึ่งแนะนำให้คุณใส่ \ 0 ที่ส่วนท้ายของค่าคงที่สตริงของคุณ (จริงๆแล้วลองดูอีกครั้งคุณตั้งใจจะใส่ \ n หรือเปล่า?)
Rob Gilliam

4

รับบล็อกไม้เล็ก ๆ

เพิ่มตะขอโลหะไว้ที่ปลายด้านหนึ่งและตาโลหะให้อีกข้างหนึ่ง

ตอนนี้คุณสามารถทำรายการเชื่อมโยงในสิ่งที่คุณสามารถเล่นกับ

ลองอธิบายด้วยอุปกรณ์ประกอบฉากทางกายภาพนี้ ฉันมักจะต้องการสิ่งนี้เมื่อสอนพอยน์เตอร์ให้กับนักเรียนชั้นปีที่หนึ่ง

ตะขอโลหะเล็ก ๆ คือตัวชี้บล็อกของไม้ที่ชี้ไป

ฉันต่อต้านทุกคนที่ไม่ได้รับหลังจากเล่นกับบล็อค


4

ฉันทำให้ชีวิตของฉันง่ายขึ้นเมื่อฉันเพิ่งลบขนปุยและเริ่มรักษาตัวชี้ว่าเป็นตัวแปรอื่น ๆ มากกว่าสิ่งมหัศจรรย์บางอย่าง (นานมาแล้วในระดับ 11) .. เพิ่งรู้ 3 สิ่ง:

  1. ตัวชี้เป็นตัวแปรที่เก็บที่อยู่ของตัวแปรอื่น (หรือที่อยู่ใด ๆ )
  2. * ใช้เพื่อรับค่าที่ตำแหน่งหน่วยความจำที่เก็บไว้ในตัวแปรพอยน์เตอร์
  3. & โอเปอเรเตอร์ให้ที่อยู่ของตำแหน่งหน่วยความจำ

ส่วนที่เหลือคือน้ำตาลประโยคและสามัญสำนึก .. เพียงแค่เขียนโปรแกรม C แบบง่าย ๆ (เช่นการนำไลบรารี่ลิสต์ที่เชื่อมโยง) ไปใช้โดยใช้พอยน์เตอร์เพื่อหยุดการทำงาน


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

2

ฉันไม่สามารถจำสถานการณ์รอบตัวชี้ - อา - ช่วงเวลาของฉันได้ แต่ฉันได้ปรับหน่วยความจำย้อนหลังเพื่อทำความเข้าใจเกี่ยวกับอาเรย์แบบ c (เช่นarr[3]เดียวกับ*(arr+3))

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


2

โดยทั่วไป @Gary Rowe แนะนำรุ่นที่ถูกต้อง หน่วยความจำเป็นชุดกล่องที่มีที่อยู่ (ตัวเลข) อยู่ แต่ละกล่องเก็บค่า (หมายเลข)

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

ถ้าvเป็นตัวแปร (กล่อง) คำสั่งนั้น

  • vหมายถึงค่าของvคือให้สิ่งที่อยู่ในกล่อง
  • *vหมายถึงการปฏิเสธค่าของv, คือให้สิ่งที่อยู่ในกล่องที่อ้างอิงโดยค่าของv
  • &vหมายถึงการอ้างอิงvคือให้ฉันอยู่ในกล่อง

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

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


2

คำอธิบายที่ฉันคร่ำครวญจริงๆก็คือ:

พิจารณากริดเมืองที่มีบ้านหลายหลังที่สร้างขึ้นบนชิ้นส่วนของที่ดิน ในมือคุณถือกระดาษแผ่นหนึ่ง บนกระดาษที่คุณเขียน:


บ้านของเดวิด

112 ถนนสายอื่น


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

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


2

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

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

ขั้นตอนถัดไป: ตั้งชื่อให้สี่เหลี่ยมบางอัน (เช่นตัวชี้) ตอนนี้คุณสามารถอธิบายการลงทะเบียน แค่นั้นแหละ.


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

2

อาจเป็นเพียงฉัน แต่ฉันทำงานได้ดีกับการเปรียบเทียบ สมมติว่าคุณมีเพื่อน (ฟังก์ชั่น / คลาส) "Foo" ซึ่งต้องการมีคนอื่น (ฟังก์ชั่น / คลาสที่แตกต่าง), "บาร์" ติดต่อคุณด้วยเหตุผลบางอย่าง "Foo" อาจพาคุณไปดู "บาร์" แต่นั่นไม่สะดวกเลยย้ายสิ่งมีชีวิตทั้งหมด (อินสแตนซ์) ไปรอบ ๆ อย่างไรก็ตาม "Foo" สามารถส่ง "บาร์" หมายเลขโทรศัพท์ของคุณ (ตัวชี้) ด้วยวิธีนี้ไม่ว่าคุณจะอยู่ที่ไหน "ฟู" รู้วิธีติดต่อคุณโดยไม่ต้องไปหาคุณ

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


2

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


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

2

"aha!" ของฉัน ช่วงเวลาที่ผ่านมาในบทช่วยสอนนี้:

บทช่วยสอนเกี่ยวกับพอยน์เตอร์และอาร์เรย์ใน C

แน่นอนในบทนี้: บทที่ 3: พอยน์เตอร์และสตริง

เพื่อความแม่นยำยิ่งขึ้นมันมาพร้อมกับประโยคนี้:

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

เมื่อฉันอ่านสิ่งนั้นเมฆแยกจากกันและเหล่าทูตสวรรค์เป่าพัดผ่านแตรลำโพง

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

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


1

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


1

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


1

รับรหัส:

int v=42; // การประกาศและการเริ่มต้นตัวแปรอย่างง่าย

int *p = &v; // การสร้างจุด p ไปที่ตัวแปร v

ต่อไปนี้สามารถพูดเกี่ยวกับรหัสข้างต้น:

int * p // "int pointer p" ... นี่คือวิธีที่คุณประกาศตัวชี้ไปยังตัวแปรประเภท int

*p // "ชี้ไปที่ p" ... นั่นคือข้อมูลที่ p ชี้ไปเช่นเดียวกับ v

&v // "ที่อยู่ของตัวแปร v" ... นี่หมายถึงค่าตามตัวอักษรสำหรับ p


1

http://cslibrary.stanford.edu/

เว็บไซต์นี้มีบทเรียนที่ยอดเยี่ยมสำหรับการเรียนรู้พอยน์เตอร์และการจัดการหน่วยความจำ

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


1

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

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

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

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

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


0

ฉันจำหนังสือ "C puzzles" หรือคล้ายกันซึ่งฉันอ่านอย่างหมดจดเพราะเป็นหนึ่งในหนังสือที่เกี่ยวกับการเขียนโปรแกรม / คอมพิวเตอร์ที่มีอยู่ในห้องสมุดความเข้าใจของ C คือพื้นฐาน มันโยนตัวคุณ C ออกไปและขอให้คุณอธิบายให้มันซับซ้อนมากขึ้นเรื่อย ๆ


0

เมื่อตอนที่ฉันอยู่ในมหาวิทยาลัยอาจารย์ของฉันมีสไลด์ PowerPoint ที่เป็นระเบียบเรียบร้อยจริง ๆ วาดภาพจุดเป็นตัวแปรแยกต่างหากของมันเองพร้อมลูกศรไปยังตำแหน่งหน่วยความจำ (แสดงเหมือนอาร์เรย์) และเมื่อเราทำรายการที่เชื่อมโยงเขาจะทำ - ตามขั้นตอนการแสดงเมื่อลูกศรเปลี่ยนเมื่อตัวชี้ถูกปฏิเสธ ฯลฯ ... ไม่มีวิธีใดที่ไม่สามารถเข้าใจได้ภายในสองสามนาที แนวคิดนั้นง่ายมาก แต่การทำในสิ่งที่ถูกต้องหรือการนำไปใช้ในโปรแกรมที่ใช้งานจริงนั้นต้องการการฝึกฝนมากกว่า


0

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

ในที่สุดฉันอธิบายว่ามีชนิดข้อมูลและตัวแปรจำนวนเต็มชนิดข้อมูลสตริงและตัวแปร ... และอื่น ๆ จนกระทั่งอธิบายว่ามีชนิดข้อมูลพิเศษที่เก็บที่อยู่หน่วยความจำซึ่งมีค่าว่างเช่น 0 o "" เรียกว่าnull

และสุดท้ายคือตัวแปรที่จัดสรรแบบไดนามิกผ่านการใช้พอยน์เตอร์

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