ปัญหาการเขียนโปรแกรมใดที่แก้ไขได้ดีที่สุดโดยใช้พอยน์เตอร์? [ปิด]


58

โดยทั่วไปฉันเข้าใจวิธีใช้พอยน์เตอร์ แต่ไม่ใช่วิธีที่ดีที่สุดในการใช้เพื่อทำให้โปรแกรมดีขึ้น

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


ถามเกี่ยวกับปัญหาการเขียนโปรแกรมที่แก้ไขได้ดีที่สุดโดยใช้ตัวชี้ไม่ใช่โครงการ / โปรแกรม คุณสามารถเขียนโปรแกรมโดยใช้ตัวชี้หรือไม่ - พวกเขา (โครงการ) นั้นใหญ่เกินไปสำหรับคำตอบที่มีความหมาย
Oded

37
ปัญหาการเขียนโปรแกรมถูกสร้างขึ้นโดยใช้ตัวชี้, ไม่ได้รับการแก้ไข :)
xpda

4
อันที่จริงฉันสงสัยว่าปัญหาใดที่สามารถแก้ไขได้โดยไม่ใช้ตัวชี้ น้อยมากอย่างแน่นอน
deadalnix

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

3
เอ่อคำตอบบางคำเหล่านี้แย่มาก

คำตอบ:


68

การจัดการข้อมูลจำนวนมากในหน่วยความจำคือจุดที่ตัวชี้ส่องแสงจริงๆ

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


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

44

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

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

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

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

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

ตัวอย่างสามารถพบได้ในหลายสถานที่เช่น:

โพสต์ต่อไปนี้อาจมีความเกี่ยวข้องในบางวิธี:


14
ฉันจะไม่พูดว่า C # ไม่สนับสนุนการใช้พอยน์เตอร์ แต่ไม่สนับสนุนการใช้พอยน์เตอร์ที่ไม่ได้รับการจัดการ - มีสิ่งต่าง ๆ มากมายใน C # ที่ได้รับการอ้างอิงแทนค่า
Blakomen

คำอธิบายที่ดี
Sabby

5
ต้อง downvote สำหรับความคิดเห็น C # C # "การอ้างอิง" นั้นเทียบเท่ากับพอยน์เตอร์มันเป็นเพียงแค่ C # ที่คุณไม่ต้องรู้ว่าจริงๆแล้วคุณกำลังติดต่อกับพอยน์เตอร์ไปยังวัตถุในฮีปที่ได้รับการจัดการ
MattDavey

1
@MattDavey: การอ้างอิง C # ไม่ใช่ตัวชี้ คุณไม่สามารถเพิ่มจากพวกเขาใช้พวกเขาเพื่อสร้างดัชนีอาร์เรย์ใช้หลายทางอ้อมเป็นต้นคุณไม่สามารถอ้างอิงถึงการอ้างอิงได้
Billy ONeal

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

29

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

รายการที่เชื่อมโยง (เดี่ยว, ทวีคูณ, และเชื่อมโยงเป็นวงกลม), ต้นไม้ (แดงดำ, AVL, trie, ไบนารี, การแบ่งช่องว่าง…) และกราฟเป็นตัวอย่างทั้งหมดของโครงสร้างที่สามารถสร้างขึ้นตามธรรมชาติในแง่ของการอ้างอิงมากกว่าค่า .


คุณลืมรายการเชื่อมโยง XOR [=
dan_waterworth

@dan_waterworth: ไม่ฉันรู้ว่ามนต์ดำก็ดีเหมือนกัน
Jon Purdy

8

วิธีหนึ่งที่ง่ายคือใน Polymorphism ความแตกต่างใช้งานได้กับพอยน์เตอร์เท่านั้น

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

for(int i = 0; i < size; i++)
   std::cout << array[i];

เท่ากับ

for(int i = 0; i < size; i++)
   std::cout << *(array + i);

ความรู้นี้ช่วยให้คุณทำสิ่งที่ยอดเยี่ยมเช่นคัดลอกอาร์เรย์ทั้งหมดในหนึ่งบรรทัด:

while( (*array1++ = *array2++) != '\0')

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

เพื่อให้เข้าใจพอยน์เตอร์ได้ดีขึ้น:

  1. ค้นหาโครงการบางอย่างที่เล่นด้วย c-strings และอาร์เรย์แบบดั้งเดิม
  2. ค้นหาบางโครงการที่ใช้การสืบทอด

  3. นี่คือโครงการที่ฉันตัดฟันของฉันเมื่อ:

อ่านเมทริกซ์ nxn สองตัวจากไฟล์และดำเนินการพื้นที่เวกเตอร์พื้นฐานกับพวกมันและพิมพ์ผลลัพธ์ไปที่หน้าจอ

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


2
"polymorphism ใช้ได้กับพอยน์เตอร์เท่านั้น" ไม่ถูกต้อง: ความแตกต่างยังทำงานร่วมกับการอ้างอิง ซึ่งในท้ายที่สุดตัวชี้ แต่ฉันคิดว่าความแตกต่างเป็นสิ่งสำคัญโดยเฉพาะกับมือใหม่
Laurent Pireyn

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

8

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

ต่อไปนี้เป็นตัวอย่างของการจัดสรรสแต็ก:

struct Foo {
  int bar, baz
};

void foo(void) {
  struct Foo f;
}

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

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

ตัวอย่างเช่นฟังก์ชั่นต่อไปนี้จะส่งผลให้สิ่งที่เรียกว่า "พฤติกรรมที่ไม่ได้กำหนด"

struct Foo {
  int bar, baz
};

struct Foo *foo(void) {
  struct Foo f;
  return &f;
}

หากคุณต้องการส่งคืนสิ่งที่ชอบstruct Foo *จากฟังก์ชันสิ่งที่คุณต้องการจริงๆคือการจัดสรรฮีป:

struct Foo {
  int bar, baz
};

struct Foo *foo(void) {
  return malloc(sizeof(struct Foo));
}

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

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

แก้ไข : ฉันไม่ได้สังเกตว่าคำถามนี้ถูกแท็กเป็นคำถาม C ++ c ++ ผู้ประกอบการnewและดำเนินการเช่นเดียวกับฟังก์ชั่นnew[] mallocผู้ประกอบการdeleteและมีความคล้ายคลึงกับdelete[] freeในขณะที่newและdeleteควรจะใช้เฉพาะในการจัดสรรและวัตถุ C ++ ฟรีการใช้งานmallocและfreeถูกกฎหมายในรหัส C ++


1
(+1) หรือที่เรียกว่า "ตัวแปรที่จัดสรรแบบคงที่" และ "ตัวแปรที่จัดสรรแบบไดนามิก" ;-)
umlcat

4

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

  • เว็บเซิร์ฟเวอร์ขนาดเล็กและเรียบง่าย
  • เครื่องมือบรรทัดคำสั่ง Unix (น้อยกว่า, cat, sort ฯลฯ )
  • โครงการจริงบางโครงการที่คุณต้องการทำเพื่อผลประโยชน์ของตนเองและไม่ใช่เพื่อการเรียนรู้

ฉันแนะนำอันสุดท้าย


ดังนั้นฉันเพียงแค่ไปสำหรับโครงการที่ฉันต้องการจะทำ (เช่นเกม 2D) และมันควรจะว่าฉันจะต้องและเรียนรู้พอยน์เตอร์?
dysoco

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

3

ปัญหาการเขียนโปรแกรมเกือบทั้งหมดที่สามารถแก้ไขได้ด้วยพอยน์เตอร์สามารถแก้ไขได้ด้วยการอ้างอิงประเภทที่ปลอดภัยกว่า(ไม่อ้างอิงการอ้างอิงC ++แต่แนวคิด CS ทั่วไปของการมีตัวแปรอ้างอิงถึงค่าของข้อมูลที่เก็บไว้ที่อื่น)

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

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

สำหรับสาเหตุที่คุณต้องการทางอ้อมรายการค่อนข้างยาว แต่โดยพื้นฐานแล้วแนวคิดหลักสองข้อคือ:

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

2

การปรับแต่งภาพระดับพิกเซลนั้นทำได้ง่ายและรวดเร็วกว่าโดยใช้ตัวชี้ บางครั้งมันอาจเป็นไปได้โดยใช้ตัวชี้


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

บางที ... ฉันไม่มีความรู้เกี่ยวกับภาษาที่มีทั้งหมด แต่ฉันไม่อยากเขียนกิจวัตรประจำวันเพื่อใช้ฟิลเตอร์ convolution กับรูปภาพโดยใช้ภาษาที่ไม่มีพอยน์เตอร์
Dave Nay

@Thomas ในขณะที่คุณถูกต้องคำถามนี้เกี่ยวกับ c ++ ซึ่งจะเป็นการชี้ให้ผู้พัฒนาเห็น
Jonathan Henson

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

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

1

พอยน์เตอร์ใช้ในภาษาการเขียนโปรแกรมจำนวนมากใต้พื้นผิว C / C ++ ช่วยให้คุณเข้าถึงได้

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


1

พอยน์เตอร์เป็นส่วนสำคัญในการใช้งานโครงสร้างข้อมูลใด ๆ ใน C และโครงสร้างข้อมูลเป็นส่วนสำคัญของโปรแกรมที่ไม่สำคัญ

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


+1 สำหรับการกล่าวถึงโครงสร้างข้อมูลการใช้อัลกอริทึมเป็นผลที่เกิดขึ้นตามธรรมชาติ
Matthieu M.

0

เป็นตัวอย่างในชีวิตจริงการสร้างหนังสือสั่งซื้อที่ จำกัด

ตัวอย่างเช่นฟีด ITCH 4.1 มีแนวคิดของคำสั่ง "แทนที่" ซึ่งราคา (และลำดับความสำคัญ) สามารถเปลี่ยนแปลงได้ คุณต้องการที่จะสามารถออกคำสั่งและย้ายไปที่อื่น การใช้คิวสองครั้งที่มีตัวชี้ทำให้การดำเนินการง่ายมาก


0

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

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

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


0

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

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

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

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

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


0

ขำ ๆ ฉันเพิ่งตอบคำถามเกี่ยวกับ C ++ และพูดคุยเกี่ยวกับพอยน์เตอร์

เวอร์ชั่นสั้นคือคุณไม่จำเป็นต้องมีพอยน์เตอร์เว้นแต่ว่า 1) ไลบรารี่ที่คุณกำลังใช้บังคับ 2) คุณต้องมีการอ้างอิงที่เป็นโมฆะ

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

คำถามของคุณอาจได้รับคำตอบในส่วนนี้

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

ptr=blah; func(ptr); //never use ptr again for here on out.

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

หมายเหตุเพิ่มเติม: ฉันสังเกตเห็นว่าฉันเขียน structs ของตัวเองและฉันจะส่งพวกเขาไปรอบ ๆ ดังนั้นฉันจะทำสิ่งนี้โดยไม่ใช้ตัวชี้ได้อย่างไร มันไม่ใช่คอนเทนเนอร์ STL ดังนั้นการส่งผ่านโดยอ้างอิงจะช้า ฉันมักจะโหลดรายการข้อมูล / deques / แผนที่และเช่น ฉันจำไม่ได้ว่าคืนวัตถุใด ๆ เว้นแต่เป็นรายการ / แผนที่บางประเภท ไม่แม้แต่สตริง ฉันดูโค้ดสำหรับวัตถุเดี่ยวและฉันสังเกตว่าฉันทำอะไรเช่นนี้{ MyStruct v; func(v, someinput); ... } void func(MyStruct&v, const D&someinput) { fillV; }ดังนั้นฉันจึงค่อนข้างคืนค่าวัตถุ (หลายรายการ) หรือ preallocate / pass ในการอ้างอิงเพื่อเติม (เดี่ยว)

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

ฉันหวังว่าคุณจะไม่ใช้พอยน์เตอร์: D ขอให้โชคดีในการจัดการกับ libs ที่บังคับให้คุณ


0

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


0

ฉันเห็นพอยน์เตอร์เป็นนิ้วชี้เราใช้ทำสองสิ่ง:

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

โปรดให้อภัยคำตอบที่ไม่ดีนี้


0

เมื่อคำถามของคุณถูกแท็ก C ++ ฉันจะตอบคำถามของคุณสำหรับภาษานั้น

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

1. ความแตกต่าง

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

2. การสร้างวัตถุถาวร

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

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


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