สวัสดีและยินดีต้อนรับกลับ ในการบรรยายนี้ ฉันต้องการสาธิตการท้าทายครั้งก่อนของเรา
ซึ่งทำให้คุณเข้าใจวิธีจัดสรรหน่วยความจำแบบไดนามิกโดยใช้
malloc
เราจะอ่านง่ายๆ จากแป้นพิมพ์แล้วแสดงสตริง
แต่เราจะใช้กับพอยน์เตอร์ที่จัดสรรแบบไดนามิก
พอยน์เตอร์อักขระ
มาสร้างบล็อคโค้ดสร้างโปรเจ็กต์ใหม่กัน
และเราจะตั้งชื่อตัวอย่างการจัดสรรหน่วยความจำแบบไดนามิก
และสิ่งแรกที่คุณต้องทำเมื่อจะใช้การจัดสรรหน่วยความจำแบบไดนามิกคือ
คุณต้องแน่ใจว่าได้รวม lib มาตรฐานไว้ด้วย
โชคดีที่คุณสร้างโปรเจ็กต์ในบล็อคโค้ด โปรเจ็กต์จะรวมโปรเจ็กต์ให้คุณโดยอัตโนมัติ
แต่เหตุผลที่เราต้องรวม lib มาตรฐานไว้ก็เพราะว่า malloc ฟังก์ชัน
malloc อยู่ในนั้น และอย่าลืมว่า malloc เป็นหน้าที่หลักในการจัดสรรหน่วยความจำ
มีแคลล็อคด้วย
Calloc มีความสำคัญมากเพราะ calloc
จะทำการคำนวณที่ดีว่าคุณต้องการกี่ไบต์เพราะนั่นเป็นสองพารามิเตอร์
แต่ข้อดีที่แท้จริงเกี่ยวกับ calloc ก็คือมันเริ่มต้นข้อมูลทั้งหมดให้เป็นศูนย์หากพวกมันเป็น
int และอื่นๆ ฟังก์ชันที่ดีจริงๆ
คุณมี realloc Realloc จะขยายหน่วยความจำที่ได้รับการจัดสรรแล้ว
ดังนั้นคุณจึงส่งผ่านในตัวชี้
จากตัวชี้นั้นจะกำหนดจำนวนหน่วยความจำที่จัดสรรให้กับมันและจะคัดลอกทุกอย่างที่อยู่ในนั้นไปยังตำแหน่งหน่วยความจำใหม่
จากนั้นคุณยังระบุจำนวนไบต์ที่คุณต้องการจัดสรรเพียงแค่เพิ่มลงในตำแหน่งหน่วยความจำใหม่จริงๆ
คุณลักษณะที่ดี
แต่จำไว้ว่าเมื่อคุณจัดสรรหน่วยความจำสำหรับจำนวนเต็มโดยใช้ malloc
คุณต้องกำหนดจำนวนหน่วยความจำที่คุณต้องการจัดสรรไบต์ แต่โดยปกติคุณต้องการใช้ตัวดำเนินการ
sizeof
ทีนี้มาดูเรื่องนั้นกัน
ในวิธีหลักของฉัน ฉันจะสร้างจำนวนเต็ม และจะบอกว่า
มันคือขนาดเท่านั้น จะป้อนขนาดจำนวนไบต์ที่ต้องการจัดสรร
ณ รันไทม์ เพื่อที่จะเก็บขนาดไว้
อีกสิ่งหนึ่งที่ฉันต้องการสร้างคือฉันต้องการสร้างตัวชี้ถ่าน
และนี่เป็นเพียงข้อความ และฉันจะเริ่มต้นสิ่งนี้ให้เป็นโมฆะเพราะมันไม่ได้ชี้ไปที่สิ่งใดทันที
ตอนนี้สิ่งแรกที่ฉันต้องการทำคือฉันต้องการขอให้ผู้ใช้ป้อนขนาด
ฉันจะบอกว่า printf ฉันจะบอกว่า
enter limit ของข้อความ
และพวกเขาจะป้อนตัวเลขสำหรับจำนวนไบต์ที่ต้องการจัดสรร
จริงๆ แล้วจำนวนอักขระ
แล้วฉันจะอ่านมันโดยใช้ scanf
Scanf พารามิเตอร์แรกคือประเภทของตัวระบุรูปแบบสำหรับประเภทของข้อมูล
นี่จะเป็นเปอร์เซ็นต์ d เพราะผมกำลังอ่านจำนวนเต็ม
จากนั้นจำไว้ว่า scanf ใช้ตัวชี้
ตอนนี้เราทราบแล้วว่าฟังก์ชันที่ใช้พอยน์เตอร์
คุณต้องมีที่อยู่เพื่อส่งผ่าน
ดังนั้นถ้าฉันจะผ่านในขนาด ขนาดไม่ใช่ที่อยู่ เว้นแต่ว่าฉันจะใช้ที่อยู่ของโอเปอเรเตอร์
ผมจะใส่เครื่องหมายและจะบอกว่าขนาด,
นั่นจะอ่านเป็นจำนวนไบต์
เมื่อฉันมีจำนวนไบต์แล้ว ฉันสามารถจัดสรรหน่วยความจำโดยใช้ฟังก์ชัน malloc ได้
และ malloc กำลังจะส่งคืนตัวชี้เป็นโมฆะ
และตัวชี้จะเป็นที่อยู่แรกสำหรับหน่วยความจำที่จัดสรรใหม่นั้น
เพื่อให้คุณสามารถกำหนดให้ข้อความถูกต้อง
เพราะจำไว้ว่าข้อความเป็นตัวชี้
เราต้องการชี้ข้อความไปยังที่อยู่ใหม่นี้ซึ่งกำลังถูกส่งกลับ
เนื่องจาก malloc ส่งคืนตัวชี้เป็นโมฆะ เราจึงต้องส่งมัน
ประเภทของข้อมูลที่เราชี้ไปนั้นเป็นอักขระ เราจึงต้องการบอกว่า char
star แล้วเราก็เรียกฟังก์ชัน malloc ได้
ฟังก์ชัน malloc ใช้จำนวนไบต์
ดังนั้นจำนวนไบต์ ถ้าคุณเพิ่งส่งผ่านจำนวนไบต์ มันจะจัดสรรจำนวนไบต์นั้นเท่านั้น
แต่ขึ้นอยู่กับชนิดของข้อมูล
ชนิดของข้อมูลอาจเป็นสองหรือสี่ไบต์
ดังนั้น หากคุณต้องการจัดสรรอักขระ
10 ตัว คุณต้องแน่ใจว่าคุณคูณ 10
อักขระด้วยขนาดของอักขระ
ตอนนี้เราจะบอกว่า
n คูณ sizeof ตัวดำเนินการ sizeof มักใช้ในฟังก์ชัน malloc เนื่องจากเป็นเครื่องที่ไม่ขึ้นกับเครื่อง
และจะบอกให้คุณทราบว่าคุณจำเป็นต้องจัดสรรจริงจำนวนเท่าใด
ตอนนี้จะมีความเกี่ยวข้องมากขึ้นเมื่อคุณมีจำนวนเต็ม โปรดจำไว้ว่า จำนวนเต็ม ขึ้นอยู่กับระบบที่คุณใช้งาน
สถาปัตยกรรมที่คุณใช้งาน จำนวนเต็มสามารถแสดงด้วยสี่ไบต์
สองไบต์ โดยปกติสองหรือสี่ไบต์
ถ้าคุณจะบอกว่าฉันต้องการเก็บจำนวนเต็มหนึ่งจำนวน
ดังนั้นฉันจะสร้างหน่วยความจำสี่ไบต์ นั่นอาจไม่ถูกต้อง
เพราะถ้าหากเป็นสองไบต์
ดังนั้นคุณจึงต้องการสร้างจำนวนเต็มหรือจำนวนอักขระที่คุณต้องการสร้างเสมอ
แล้วคูณด้วยขนาดของอักขระในระบบของคุณ
ตัวดำเนินการ
Sizeof จะให้จำนวนไบต์ที่อักขระใช้ ดังนั้น ถ้าคุณต้องการสร้างอักขระ
10 ตัว แสดงว่ามีขนาดอักขระ 10 เท่า หากคุณต้องการสร้างจำนวนเต็ม
10 ตัวเพื่อเก็บจำนวนเต็ม
10 ตัว คุณบอกว่าขนาด int เป็น 10 เท่า นั่นสำคัญมาก
ด้วยฟังก์ชัน calloc คุณไม่จำเป็นต้องทำอย่างนั้น Calloc ใช้พารามิเตอร์สองตัวจริง
ๆ และพารามิเตอร์ตัวแรกคือตัวชี้ที่ฉันคิด
จากนั้นพารามิเตอร์ตัวที่สองคือขนาดของไบต์
ดังนั้นถ้าคุณพูดว่า 24 int สิ่งที่คุณต้องทำก็คือคุณต้องผ่าน
24 int และจัดสรรให้คุณโดยอัตโนมัติ
ดังนั้น calloc จึงเป็นเครื่องมือที่ดีมากเพราะคุณไม่ต้องคูณมัน
ดังนั้นสำหรับ calloc พารามิเตอร์แรกคือขนาด
ดังนั้นหากคุณต้องการสร้าง 10 int คุณก็จะผ่าน 10
จากนั้นพารามิเตอร์ที่สองคือขนาดของไบต์
จะได้ไม่ต้องคูณ ช่วยให้คุณประหยัดขั้นตอนเล็กน้อย
ตอนนี้เราจัดสรรหน่วยความจำแล้ว คุณต้องแน่ใจว่าข้อความนั้นไม่เป็นค่าว่างก่อนที่คุณจะพยายามยกเลิกการอ้างอิงข้อความ
ดังนั้น คุณจึงต้องการตัดสิ่งนี้รอบ ๆ ข้อความที่ไม่ใช่ข้อความ และนั่นจะบอกว่าไม่ใช่ค่าว่าง
หรือคุณสามารถระบุให้ชัดเจนและบอกว่าข้อความไม่เท่ากับค่าว่างหรือไม่
ฉันต้องการทำอย่างนั้นเสมอเพราะมันอันตรายมากที่จะพยายามยกเลิกการอ้างอิงตัวชี้
อะไรก็เกิดขึ้นได้. คุณอาจจะสามารถเขียนข้อมูลลงไปได้
เข้าไปในนั้น มันจะเขียนไว้ที่อื่นในความทรงจำ ดังนั้นมันจะทำให้โปรแกรมของคุณเสียหายหรือคุณอาจมีข้อผิดพลาดในการแบ่งส่วนและโปรแกรมอาจหยุดทำงาน
แต่ตราบใดที่คุณจัดสรรหน่วยความจำนั้นจริงๆ
คุณก็สามารถอ่านข้อมูลบางส่วนได้แล้ว
คุณสามารถใช้ git s หรือคุณสามารถใช้ scanf ได้ที่นี่
แต่สิ่งที่คุณต้องการทำคือ
คุณต้องการพิมพ์ออกมา ป้อนข้อความ และเราต้องการเพิ่มการป้อนบรรทัดที่นี่เพื่อให้อ่านง่าย
และเราจะใช้ scanf เพราะนั่นคือสิ่งที่เราคุ้นเคย
และ scanf ก็แค่อ่านเป็นเปอร์เซ็นต์
อันที่จริงฉันจะแสดงเคล็ดลับให้คุณดู
ฉันจะใช้ scanf เพื่ออ่านในอักขระถัดไป ดังนั้นมันจึงหยุดชั่วคราว
จากนั้นฉันจะใช้ get s เพื่ออ่านในข้อความ
และ gets ก็เป็นอีกฟังก์ชันหนึ่งที่ปกติคุณสามารถใช้ f gets ได้ คุณเพียงแค่ต้องตั้งค่าเป็นตั้งค่าให้เป็นสตรีมอินพุต
แต่ gets จะอ่านจากสตรีมอินพุตมาตรฐาน ซึ่งโดยค่าเริ่มต้นคือคีย์บอร์ด
และได้รับกำลังจะใช้ตัวชี้ สิ่งที่เราต้องทำคือส่งข้อความเพราะมันเป็นตัวชี้อยู่แล้ว
เราไม่ต้องใส่ที่อยู่ของโอเปอเรเตอร์
และสิ่งที่ดีในการถามคือคุณสามารถอ่านได้หลายสตริงโดยคั่นด้วยช่องว่าง
เมื่อเราอ่านจริงแล้ว เราสามารถพิมพ์ออกมาได้
ดังนั้นเราจึงสามารถพูดได้ว่าข้อความที่ป้อนเข้ามา
หากป้อนเป็นเครื่องหมายแบ็กสแลชของคำ เปอร์เซ็นต์ n แล้วตามด้วยข้อความจุลภาค
ข้อความเป็นตัวชี้
Printf ใช้ตัวชี้ เราไม่จำเป็นต้องยกเลิกการอ้างอิง
เพราะถ้าคุณเพียงแค่แสดงข้อความ
ข้อความจะแสดงค่าของตัวชี้ซึ่งจะเป็นที่อยู่
เราต้องการแสดงค่าของข้อความที่ชี้ไป
แล้วเราก็เสร็จแล้ว ไม่นะ เราไม่จบแน่นอน เราต้องการโทรหาเราฟรี
เราต้องการปล่อยตัวชี้ของเรา
แม้ว่าเมื่อเราออกจากหน่วยความจำจะว่าง เรายังต้องการให้แน่ใจว่าเราปล่อยให้มันว่าง
จากนั้นเราอาจต้องการเพียงเพื่อความปลอดภัย เราต้องการตั้งค่าข้อความให้เป็นโมฆะ
ไปข้างหน้าและสร้างสิ่งนี้และดูว่าเกิดอะไรขึ้น
และฉันมีปัญหาเพราะฉันไม่ได้อ่านตัวแปรที่ถูกต้อง
ดังนั้นที่นี่ฉันไม่ได้ใช้ตัวแปรที่ถูกต้อง ฉันต้องการใช้ขนาดและดูเหมือนว่าเราจะดี
ต่อไปนี้ ความแตกต่างอย่างหนึ่งที่นี่คือ คุณไม่จำเป็นต้องอ้างอิงข้อความเพราะข้อความเป็นตัวชี้อักขระ
คุณจะต้องยกเลิกการอ้างอิงหากอยู่ในตัวชี้และอื่นๆ ดังนั้นเมื่อคุณใช้เปอร์เซ็นต์
s มันจะรู้โดยอัตโนมัติเพื่อยกเลิกการอ้างอิงตัวชี้อักขระ
นั่นเป็นข้อแตกต่างอย่างหนึ่งเมื่อคุณใช้พอยน์เตอร์อักขระกับพอยน์เตอร์อื่นๆ
ตัวชี้อื่น
ๆ ที่คุณต้องยกเลิกการอ้างอิงเพื่อรับค่าเพราะคุณไม่สามารถคัดลอกสตริงไปยังอาร์เรย์สตริงและอื่น
ๆ ได้
คุณจะไม่สามารถทำข้อความติดดาวได้เท่ากับ
คุณต้องใช้ str copy เสมอหากต้องการคัดลอกข้อความ
เนื่องจากจำจากการบรรยาย คุณไม่สามารถกำหนดข้อมูลให้กับอาร์เรย์ได้จริง
และตัวชี้อักขระคืออาร์เรย์
นี่จึงดูถูกต้อง ไม่มีเหตุผลที่จะยกเลิกการอ้างอิง
เราต้องการสร้างสิ่งนี้ และเราต้องการที่จะเรียกใช้มัน
และคุณจะสังเกตเห็นว่าเราใส่ขีด จำกัด ของข้อความ
สมมุติว่าเราใส่ 5, 6 สำหรับ jason และมันพิมพ์ว่าอินพุตคือ
jason
และคุณสามารถเล่นกับโปรแกรมนี้ได้ แต่อีกครั้ง สิ่งที่ได้จากสิ่งนี้รวมถึง
lib มาตรฐานเมื่อคุณทำ malloc
เริ่มต้นตัวชี้อักขระของคุณให้เป็นโมฆะ ทำ scanf ใช้เครื่องหมายและเพราะขนาดไม่ใช่ตัวชี้
เมื่อคุณกำลังคลุ้มคลั่ง malloc จะส่งกลับตัวชี้เป็นโมฆะ ดังนั้นคุณต้องแคสต์
คุณต้องการเข้าไปใน malloc ของคุณเสมอ ทำตัวดำเนินการ sizeof
สำหรับสิ่งที่คุณต้องการจัดสรร ครั้ง จำนวนอักขระจริงหรือจำนวนเต็มมีกี่ตัว
สิ่งนี้ใช้ได้กับจำนวนเต็มและประเภทข้อมูลดั้งเดิมในทางเทคนิคสำหรับอักขระมากกว่า
คุณสามารถทำขนาดได้ซึ่งน่าจะใช้ได้ดี
คุณต้องการตรวจสอบค่า null เสมอ ตรวจสอบให้แน่ใจว่าไม่ใช่ค่า null
เมื่อคุณใช้สตริงอักขระ
จากนั้นเราก็ป้อนข้อความ เก็บไว้ในกระเป๋าของเราแล้วพิมพ์ออกมา
และสุดท้ายแต่ไม่ท้ายสุด เราต้องการปลดปล่อยตัวชี้ของเราเสมอ เพื่อที่เราจะสามารถคืนสิ่งนั้นให้กับกองได้
หวังว่านี่จะช่วยได้ ขอขอบคุณ.