ในหลายภาษา C ++ ตัวอย่างที่ผมเห็นการใช้งานของประเภทที่ที่ฉันจะได้ใช้ง่ายๆsize_t intความแตกต่างคืออะไรและทำไมจึงsize_tควรดีกว่า
ในหลายภาษา C ++ ตัวอย่างที่ผมเห็นการใช้งานของประเภทที่ที่ฉันจะได้ใช้ง่ายๆsize_t intความแตกต่างคืออะไรและทำไมจึงsize_tควรดีกว่า
คำตอบ:
ไฟล์ส่วนหัว stdlib.h และ stddef.h กำหนดประเภทข้อมูลที่เรียกว่าsize_tซึ่งใช้เพื่อแสดงขนาดของวัตถุ ฟังก์ชั่นห้องสมุดที่ใช้ขนาดคาดว่าพวกเขาจะเป็นประเภท size_t และผู้ประกอบการ sizeof ประเมินเป็น size_t
ขนาดจริงของ size_t ขึ้นอยู่กับแพลตฟอร์ม ข้อผิดพลาดทั่วไปคือสมมติว่า size_t เป็น int ที่ไม่ได้ลงนามซึ่งสามารถนำไปสู่ข้อผิดพลาดในการเขียนโปรแกรมโดยเฉพาะอย่างยิ่งเมื่อสถาปัตยกรรม 64- บิตกลายเป็นที่แพร่หลายมากขึ้น
ตรวจสอบด้วยเหตุใดจึงยังมีปัญหาเรื่อง size_t
/usr/include/stdlib.hได้รับคำนิยามจาก/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hนั้นมันเริ่มต้นlong unsigned intเว้นแต่ไฟล์ส่วนหัวอื่น ๆ พูดอย่างอื่น
size_t เป็นประเภทที่ใช้ในการแสดงขนาด (ตามชื่อของมันหมายถึง) แพลตฟอร์ม (และอาจมีการนำไปใช้) ขึ้นอยู่กับแพลตฟอร์มและควรใช้เพื่อจุดประสงค์นี้เท่านั้น เห็นได้ชัดว่าเป็นขนาด size_t ไม่ได้ลงนาม ฟังก์ชั่น stdlib จำนวนมากรวมถึง malloc, sizeof และฟังก์ชั่นการทำงานของสตริงต่างๆใช้ size_t เป็นประเภทข้อมูล
int จะถูกลงนามโดยค่าเริ่มต้นและแม้ว่าขนาดของมันจะขึ้นอยู่กับแพลตฟอร์มก็ตามมันจะเป็น 32 บิตคงที่ในเครื่องที่ทันสมัยที่สุด
ในการสรุป: ใช้ size_t เพื่อแสดงขนาดของวัตถุและ int (หรือยาว) ในกรณีอื่น ๆ
size_tประเภทถูกกำหนดให้เป็นประเภทหนึ่งได้รับการรับรองของsizeofผู้ประกอบการ ในโลกแห่งความเป็นจริงคุณมักจะเห็นการintกำหนดเป็น 32 บิต (สำหรับความเข้ากันได้ย้อนหลัง) แต่size_tถูกกำหนดเป็น 64 บิต (ดังนั้นคุณสามารถประกาศอาร์เรย์และโครงสร้างที่มีขนาดมากกว่า 4 GiB) บนแพลตฟอร์ม 64 บิต หาก a long intคือ 64- บิตสิ่งนี้เรียกว่าการประชุม LP64 ถ้าlong intเป็น 32 บิต แต่พlong long intอยน์เตอร์เป็น 64 บิตนั่นคือ LLP64 นอกจากนี้คุณยังอาจได้รับการย้อนกลับโปรแกรมที่ใช้คำแนะนำ 64 บิตสำหรับความเร็ว แต่ตัวชี้แบบ 32 บิตเพื่อบันทึกหน่วยความจำ นอกจากนี้ยังintมีการเซ็นชื่อและsize_tไม่ได้ลงนาม
นอกจากนั้นในอดีตจำนวนของแพลตฟอร์มอื่น ๆ intที่มีอยู่มีความกว้างขึ้นหรือสั้นกว่าขนาดของพื้นเมือง ในความเป็นจริงในยุค 70 และต้นยุค 80 นี่เป็นเรื่องธรรมดามากกว่า: คอมพิวเตอร์ 8 บิตที่ได้รับความนิยมทั้งหมดมีการลงทะเบียน 8 บิตและที่อยู่ 16 บิตและการเปลี่ยนระหว่าง 16 และ 32 บิตยังผลิตเครื่องจักรจำนวนมาก มีที่อยู่ที่กว้างกว่าการลงทะเบียน ฉันยังคงเห็นคำถามเกี่ยวกับ Borland Turbo C สำหรับ MS-DOS ที่มีโหมดหน่วยความจำขนาดใหญ่ซึ่งมีที่อยู่ 20 บิตที่เก็บไว้ใน 32 บิตบน CPU 16 บิต (แต่สามารถรองรับชุดคำสั่งแบบ 32 บิตของ 80386); Motorola 68000 มี ALU 16 บิตพร้อมการลงทะเบียนและที่อยู่ 32 บิต มีเมนเฟรมของ IBM พร้อมที่อยู่ 15 บิต 24 บิตหรือ 31 บิต คุณยังคงเห็น ALU และขนาดบัสที่แตกต่างกันในระบบฝังตัว
เมื่อใดก็ตามที่intมีขนาดเล็กกว่าsize_tและคุณพยายามจัดเก็บขนาดหรือออฟเซ็ตของไฟล์หรือวัตถุที่มีขนาดใหญ่มากในunsigned intนั้นมีความเป็นไปได้ที่มันจะล้นและทำให้เกิดข้อผิดพลาด ด้วยความintสามารถในการรับจำนวนลบ ถ้ามีintหรือunsigned intกว้างกว่าโปรแกรมจะทำงานอย่างถูกต้อง แต่หน่วยความจำไม่เพียงพอ
โดยทั่วไปคุณควรใช้ประเภทที่ถูกต้องเพื่อวัตถุประสงค์หากคุณต้องการพกพา ผู้คนจำนวนมากจะแนะนำให้คุณใช้คณิตศาสตร์ที่ลงนามแทนการไม่ได้ลงชื่อ (เพื่อหลีกเลี่ยงข้อบกพร่องที่น่ารังเกียจและบอบบางเช่น1U < -3) เพื่อที่การกำหนดมาตรฐานห้องสมุดptrdiff_tใน<stddef.h>เป็นชนิดลงนามในผลการลบตัวชี้จากผู้อื่น
วิธีแก้ปัญหาอาจเป็นการตรวจสอบที่อยู่และการหักล้างทั้งหมดINT_MAXและอย่างใดอย่างหนึ่ง0หรือINT_MINตามความเหมาะสมและเปิดคำเตือนคอมไพเลอร์เกี่ยวกับการเปรียบเทียบปริมาณที่ลงชื่อและไม่ได้ลงชื่อในกรณีที่คุณพลาด คุณควรตรวจสอบการเข้าถึงอาร์เรย์ของคุณใน C เสมอ
เป็นเพราะ size_t สามารถเป็นอย่างอื่นได้นอกจาก int (อาจเป็น struct) แนวคิดก็คือมันแยกงานของมันออกจากประเภทพื้นฐาน
size_tระบุเป็นประเภทจำนวนเต็มไม่ได้ลงนาม C11 §6.5.3.4 5 "ค่าของผลลัพธ์ของตัวดำเนินการทั้งสอง ( sizeof _Alignof) คือการกำหนดการนำไปใช้และประเภทของมัน (ชนิดจำนวนเต็มที่ไม่ได้ลงนาม) คือsize_t"
คำจำกัดความของSIZE_Tพบได้ที่:
https://msdn.microsoft.com/en-us/library/cc441980.aspxและhttps://msdn.microsoft.com/en-us/library/cc230394.aspx
การวางข้อมูลที่ต้องการที่นี่:
SIZE_Tเป็นULONG_PTRจำนวนสูงสุดของไบต์ที่ตัวชี้สามารถชี้
ประเภทนี้มีการประกาศดังนี้:
typedef ULONG_PTR SIZE_T;
A ULONG_PTRเป็นแบบยาวที่ไม่ได้ลงนามที่ใช้สำหรับความแม่นยำของตัวชี้ มันถูกใช้เมื่อชี้ตัวชี้ไปยังชนิดยาวเพื่อดำเนินการทางคณิตศาสตร์ตัวชี้
ประเภทนี้มีการประกาศดังนี้:
typedef unsigned __int3264 ULONG_PTR;
SIZE_Tไม่ใช่size_tสิ่งที่ OP ถามเกี่ยวกับ
SIZE_Tsize_tจะแตกต่างจาก SIZE_Tคุณไม่สามารถประกาศตัวแปรของชนิด