ความแตกต่างระหว่าง size_t และ int ที่ไม่ได้ลงชื่อ


109

ฉันสับสนเกี่ยวกับsize_t. ฉันได้ค้นหาบนอินเทอร์เน็ตและทุกที่ที่กล่าวถึงว่าsize_tเป็นประเภทที่ไม่ได้ลงนามดังนั้นจึงสามารถแสดงได้เฉพาะค่าที่ไม่เป็นลบ

คำถามแรกของฉันคือถ้ามันถูกใช้เพื่อแสดงเฉพาะค่าที่ไม่ใช่ค่าลบทำไมเราไม่ใช้unsigned intแทนsize_t?

คำถามที่สองของฉันคือsize_tและunsigned intใช้แทนกันได้หรือไม่? ถ้าไม่แล้วทำไม?

และใครช่วยให้ฉันเป็นตัวอย่างที่ดีsize_tและสั้น ๆ เกี่ยวกับการทำงานของมัน?


5
typedef /*This part is implementation dependent */ size_t;
P0W

คำตอบ:


89

หากใช้แทนค่าที่ไม่ใช่ค่าลบดังนั้นทำไมเราไม่ใช้unsigned intแทนsize_t

เนื่องจากunsigned intไม่ใช่ชนิดจำนวนเต็มที่ไม่ได้ลงชื่อเท่านั้น size_tอาจจะเป็นใด ๆunsigned char, unsigned short, unsigned int, unsigned longหรือunsigned long longขึ้นอยู่กับการดำเนินการ

คำถามที่สองคือการที่size_tและunsigned intสามารถใช้แทนกันได้หรือไม่และถ้าไม่ได้แล้วทำไม?

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

และใครช่วยยกตัวอย่าง size_t และการทำงานสั้น ๆ ให้ฉันได้บ้าง

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

โบนัส: นี่คือบทความดีๆเกี่ยวกับsize_t(และptrdiff_tประเภทที่เกี่ยวข้องอย่างใกล้ชิด) เป็นเหตุผลที่ดีว่าทำไมคุณควรใช้


1
วิธีการว่าสามารถsize_tจะเป็นunsigned char? สิ่งนี้อยู่ในมาตรฐานที่อนุญาตหรือไม่ ฉันหมายถึงความคิดนั้นจะคาดหวังให้ใครใช้calloc()(และครอบครัว) strlen()ฯลฯ ได้อย่างไร? ดูเหมือนว่าฉันจะไร้สาระ
Pryftan

ผมคิดว่าsize_tถูกกำหนดไว้ในมาตรฐานที่จะเป็น "ชนิดจำนวนเต็มไม่ได้ลงนาม" unsigned {char, short, int, long, long long}แต่ไม่จำเป็นต้องว่ามันจะเป็นเช่นเดียวกับการใด
Paul Hankin

82

C มีจำนวนเต็มมาตรฐานที่ไม่ได้ลงนาม 5 ประเภท:

  • unsigned char
  • unsigned short
  • unsigned int
  • unsigned long
  • unsigned long long

ด้วยข้อกำหนดที่หลากหลายสำหรับขนาดและช่วง (สั้น ๆ ช่วงของแต่ละประเภทเป็นส่วนย่อยของช่วงประเภทถัดไป แต่บางส่วนอาจมีช่วงเดียวกัน)

size_tเป็นtypedef(กล่าวคือนามแฝง) สำหรับประเภทที่ไม่ได้ลงนาม (อาจเป็นหนึ่งในประเภทข้างต้น แต่อาจเป็นประเภทจำนวนเต็มที่ไม่ได้ลงนามเพิ่มเติมแม้ว่าจะไม่น่าเป็นไปได้ก็ตาม) เป็นประเภทที่ได้รับจากตัวsizeofดำเนินการ

ในระบบหนึ่งอาจเหมาะสมที่จะใช้unsigned intเพื่อแสดงขนาด อีกก็อาจทำให้รู้สึกมากขึ้นที่จะใช้หรือunsigned long unsigned long long( size_tไม่น่าจะเป็นอย่างใดอย่างหนึ่งunsigned charหรือunsigned shortแต่ได้รับอนุญาต)

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

รหัสที่ถือว่าsizeofให้ผลตอบแทนunsigned intจะไม่สามารถพกพาได้ รหัสที่ถือว่าให้ผล a size_tมีแนวโน้มที่จะพกพาได้มากกว่า


6
ฉันคิดว่านี่ควรเป็นคำตอบที่ยอมรับได้เพราะมันอธิบายได้ว่าทำไมคุณควรใช้ size_t
kuchi

@ คี ธ อมป์สันดังนั้นนี้หมายความว่าประเภทที่เฉพาะเจาะจง (เช่นunsigned int, unsigned longฯลฯ ) ที่size_tสอดคล้องกับการขึ้นอยู่กับเครื่องที่รหัสจะทำงาน? เช่นบนสถาปัตยกรรมเครื่องหนึ่งมันสอดคล้องกับunsigned intแต่ในสถาปัตยกรรมอื่นมันจะสอดคล้องกับunsigned longฯลฯ ?
Richie Thomas

1
@RichieThomas: มันขึ้นอยู่กับการใช้งาน C คอมไพเลอร์ที่แตกต่างกันสองตัวในสถาปัตยกรรมเดียวกันอาจเลือกประเภทที่แตกต่างกันsize_tโดยเฉพาะอย่างยิ่งถ้าเช่นunsigned longและunsigned long longมีขนาดเท่ากัน
Keith Thompson

@RichieThomas นั่นเป็นส่วนหนึ่งของมันเช่นกัน นั่นคือจะบอกว่าสูงสุดของlong, long longฯลฯ ไม่ขึ้นอยู่กับระบบ: ถ้าคุณดูที่limits.hคุณจะได้อย่างน้อยภายใต้ Unices เห็นได้ว่าค่าสูงสุดสำหรับ ints ขึ้นอยู่กับขนาดคำของระบบ
Pryftan

1
@Pryftan ดู Motorola 68000 series ซึ่งเป็น Intel x86 series รุ่นเก่า (ย้อนกลับไปที่ 8086 และ 8088)
Keith Thompson

10

size_t มีข้อ จำกัด เฉพาะ

อ้างจากhttp://www.cplusplus.com/reference/cstring/size_t/ :

นามแฝงของประเภทจำนวนเต็มพื้นฐานที่ไม่ได้ลงชื่อ

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

ไม่สามารถใช้แทนกันได้unsigned intเนื่องจากขนาดของintถูกระบุโดยโมเดลข้อมูล ยกตัวอย่างเช่น LLP64 ใช้ 32 บิตintและ ILP64 ใช้ int64


5
ใบเสนอราคานั้นมาจากไหน? (ไม่ได้มาจากมาตรฐาน C)
Keith Thompson

2
คำถามถูกแท็ก . มาตรฐาน C ++ ไม่มีผลบังคับใช้กับ C.
II ระบุได้

7

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


4

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


จุดดี. appleเป็นแอปเปิ้ลที่size_tเป็นขนาด ...
dom_beau

2

ชนิด size_t เป็นประเภทเลขฐานจำนวนเต็มของภาษา C / C ++ ที่ไม่ได้ลงชื่อ เป็นประเภทของผลลัพธ์ที่ส่งคืนโดยตัวดำเนินการ sizeof ขนาดของประเภทถูกเลือกเพื่อให้สามารถจัดเก็บขนาดสูงสุดของอาร์เรย์ประเภทใดก็ได้ในทางทฤษฎี บนระบบ 32 บิต size_t จะใช้ 32 บิตบน 64 บิตหนึ่ง 64 บิต กล่าวอีกนัยหนึ่งตัวแปรประเภท size_t สามารถจัดเก็บตัวชี้ได้อย่างปลอดภัย ข้อยกเว้นคือตัวชี้ไปยังฟังก์ชันคลาส แต่เป็นกรณีพิเศษ แม้ว่า size_t สามารถจัดเก็บตัวชี้ได้ แต่จะดีกว่าถ้าใช้ uintptr_t ประเภทจำนวนเต็มอื่นที่ไม่ได้ลงชื่อเพื่อจุดประสงค์นั้น (ชื่อแสดงถึงความสามารถ) ประเภท size_t และ uintptr_t เป็นคำพ้องความหมาย ประเภท size_t มักใช้สำหรับตัวนับลูปการสร้างดัชนีอาร์เรย์และเลขคณิตที่อยู่ ค่าสูงสุดที่เป็นไปได้ของประเภท size_t คือค่าคงที่ SIZE_MAX


1
size_tสามารถจัดเก็บขนาดของวัตถุใด ๆ ตัวชี้สามารถชี้ไปที่ไบต์ของวัตถุใดก็ได้ ตัวอย่างเช่นคุณสามารถมีระบบที่มีพื้นที่แอดเดรส 64 บิตซึ่ง จำกัด ขนาดของอ็อบเจ็กต์ใด ๆ ไว้ที่ 2 ** 32-1 ไบต์ ไม่มีการรับประกันว่าไม่เป็นsize_tและuintptr_tเป็นประเภทเดียวกัน
Keith Thompson

2

พูดง่ายๆว่า size_t คือแพลตฟอร์มและการใช้งานขึ้นอยู่กับการใช้งานในขณะที่ int ที่ไม่ได้ลงชื่อจะขึ้นอยู่กับแพลตฟอร์มเท่านั้น

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