ทำไมสั้น, int และคิดค้นมานานใน C?


16

ฉันมีปัญหาในการทำความเข้าใจสิ่งที่เป็นวัตถุประสงค์ที่แน่นอนของการสร้างshort, intและlongชนิดข้อมูลใน C?

เหตุผลที่ผมถามคือมันไม่ได้ดูเหมือนขนาดของพวกเขาจะกระโดด - พวกเขาอาจจะมีขนาดใดตราบใดที่shortมีขนาดเล็กกว่าintเช่น

ในสถานการณ์ใดที่คุณควรใช้unsigned intหรือunsigned longตัวอย่างเช่น a แทนsize_tเมื่อคุณทำเช่นนั้นจะไม่มีความหวังของความเข้ากันได้ของไบนารี?

(หากคุณไม่ทราบขนาดคุณจะรู้ได้อย่างไรว่าจะเลือกขนาดไหน)


2
ชำระเงิน<stdint.h>
BlackJack

1
@Backack Jack: ฮ่าฮ่าใช่แล้วฉันมี - แต่ฉันเดาคำถามของฉันคือทำไมประเภทเหล่านั้นไม่ได้กำหนดไว้โดยกำเนิดแทน? เป็นปัญหา "การเข้าใจถึงปัญหาหลังรวม 20/20" หรือมีเหตุผลเฉพาะหรือไม่?
user541686

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

@ SK-logic: ไม่แม้ว่าพวกเขาจะพูดsizeof(short) == 2 * sizeof(char)หรือคล้ายกัน?
user541686

1
มีแพลตฟอร์มที่ไหนsizeof(char) == sizeof(short)และมันสมเหตุสมผล แต่น่าเสียดายที่มีวิธีการระบุชนิดจำนวนหนึ่งว่าวิธีการที่พวกเขาจะพอดีไม่มีทุก แพลตฟอร์มที่เป็นไปได้และที่มีอยู่
SK-logic

คำตอบ:


12

มันจะถูกกำหนดโดยสถาปัตยกรรมที่คุณใช้ บนชิป Zilog z80 (ชิปฝังตัวทั่วไป) พวกเขาจะมีขนาดเดียวในขณะที่พวกเขาอาจมีขนาดแตกต่างกันโดยสิ้นเชิงในชิปเซ็ต x86 อย่างไรก็ตามขนาดตัวเองเป็นอัตราส่วนคงที่ซึ่งกันและกัน เป็นหลักสั้นและยาวไม่ได้เป็นประเภท แต่มีคุณสมบัติสำหรับประเภท int ints สั้นจะเป็นหนึ่งในลำดับความสำคัญขนาดเล็กกว่า (ปกติ) int และ ints ยาวจะเป็นลำดับของขนาดที่สูงขึ้น ดังนั้นสมมติว่า Int ของคุณมีขอบเขตถึง 4 ไบต์ตัวระบุแบบสั้น จำกัด ขอบเขตไว้ที่ 4 ไบต์แม้ว่า 2 ไบต์จะพบได้บ่อยมากและตัวขยายแบบยาวจะเพิ่มความน่าจะเป็น 8 ไบต์แม้ว่ามันจะน้อยลงถึง 4 ไบต์ โปรดทราบว่านี่อาจมีความยาวของคำเช่นกันดังนั้นในระบบ 32 บิตคุณจะได้สูงสุดที่ 4 ไบต์ต่อ int อย่างไรก็ตามทำให้ยาวเหมือนกับ int ปกติ ดังนั้นสั้น≤ Int ≤ยาว

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

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

C อาจเป็น "ชุดประกอบแบบพกพา" แต่คุณยังต้องรู้ฮาร์ดแวร์ของคุณ


11
นี่ไม่ถูกต้องกางเกงขาสั้นไม่ต้องเล็กกว่า ints พวกเขาไม่สามารถใหญ่กว่า ints
jk ได้

ฉันจะแก้ไขให้ถูกต้อง
วิศวกรโลก

2
ในทำนองเดียวกันความยาวต้องไม่เล็กกว่า ints
Donal Fellows

1
แน่นอนฉันเชื่อว่ามีเครื่องจักรที่สั้น, int และยาวที่เหมือนกัน
jk

6

แม้ว่าวันนี้ "ไบต์" หมายถึง "8 บิต" ซึ่งไม่ได้เป็นจริงเสมอไป เครื่องจักรใช้ชิ้นส่วนแอดเดรสที่อยู่ได้ 4 บิต, 8 บิต, 12 บิต, 16 บิต, 32 บิตและ 36 บิต (และอาจมีขนาดอื่น ๆ ด้วย) หนึ่งในความตั้งใจออกแบบของ C คือการใช้งานบนเครื่องที่มีขนาดหน่วยความจำและการกำหนดค่าต่างกัน

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

ปัญหาที่ใหญ่ที่สุดของซีแมนทิกส์แบบซีของจำนวนเต็มคือในบริบทบางอันพวกเขาเป็นตัวแทนของตัวเลขเชิงตัวเลขหรือจำนวนเต็มทางคณิตศาสตร์ในขณะที่บริบทอื่น ๆ พวกเขาใช้เพื่อเป็นตัวแทนสมาชิกของแหวนพีชคณิตนามธรรมของจำนวนเต็ม ค่าที่สามารถแทนได้สูงสุดจาก 0 ถูกกำหนดให้เป็น 1] แต่พฤติกรรมจะถูกระบุเพิ่มเติมบนพื้นฐานของสิ่งที่คอมไพเลอร์ดูเหมือนจะทำในวันที่ขนาดคำคอมพิวเตอร์ประมาณ 16 บิต (และขนาดของคำ 36 บิตจะมีขนาดใหญ่มาก ) แทนที่จะใช้พื้นฐานของสิ่งที่เหมาะสมบนเครื่อง 64 บิต ดังนั้นผลลัพธ์ของการลบค่าที่ไม่ได้ลงนาม 32- บิตจากค่าที่ไม่ได้ลงนามที่มีขนาดเล็กกว่าอาจเป็นค่าที่ไม่ได้ลงนาม 32- บิตขนาดใหญ่หรือจำนวนลบ 64- บิต


4

/programming/589575/size-of-int-long-etc

ดังนั้นในสถาปัตยกรรมที่ใช้กันมากที่สุดถ่านคือ 1 ไบต์สั้นและ int อย่างน้อย 2 ไบต์และยาวอย่างน้อย 4 ไบต์

และตั้งใจว่า 'int' ควรจะเป็นตัวแทนที่เป็นธรรมชาติ / ปกติ / มีประสิทธิภาพมากที่สุดสำหรับ CPU ปัจจุบัน

ดังนั้นกฎทั่วไปคือใช้ 'int' ยกเว้นว่าค่าของคุณเกิน +/- 32K ทำให้คุณ (บน CPU ที่เก่ากว่า) ใช้ 'long' ... หรือถ้าคุณกำลังสร้างอาร์เรย์ขนาดใหญ่ที่มีค่าน้อย (<32K) และหน่วยความจำก็เป็นปัญหาดังนั้นคุณต้องใช้ 'สั้น' เพื่อบันทึกหน่วยความจำ (หรืออาจเป็น 'ถ่าน' หรือ 'ไบต์')


2
แต่ด้วย 64- บิตintเป็นตัวเลือกที่ดีใช่ไหม? ฉันมักจะจบลงด้วยการใช้size_t(หรือแม้แต่ptrdiff_t!) ต่อไปเพื่อหลีกเลี่ยงปัญหาเกี่ยวกับการย้ายรหัส
user541686

@ Merhdad - int ใช้กับตัวเลือกที่ดีที่สุดมันเป็น defn 'หน่วยมาตรฐาน' ของ HW และโดยทั่วไปจะมีขนาดของตัวชี้ ทุกวันนี้ใช้ size_t เพื่อความปลอดภัย
Martin Beckett

1

C ถูกออกแบบมาเพื่อจัดการกับหน่วยความจำในระดับต่าง ๆ อย่างแข็งขัน มีบางกรณีที่ความแตกต่างระหว่าง short, int และ long และระหว่าง float และ double มีความสำคัญเนื่องจากข้อ จำกัด ด้านหน่วยความจำสถาปัตยกรรมและอื่น ๆ ถึงแม้ว่าตอนนี้มันจะมีความสำคัญน้อยกว่า แต่ก็ยังมีสภาพแวดล้อมที่มันทำอยู่ กรณีที่ข้อมูลมีขนาดใหญ่มาก) และการเปลี่ยนจากสถาปัตยกรรม 32 บิตเป็น 64 บิตเป็นปัญหาอีกครั้ง (ในสิบหรือยี่สิบปีที่เราเปลี่ยนไปใช้สถาปัตยกรรม 128 บิตและ C / C ++ ยังคงเป็นที่นิยมก็จะเป็นปัญหาอีกครั้ง) คุณถูกต้องแล้วแม้ว่าความเข้ากันได้แบบไบนารีนั้นมีความทุกข์ซึ่งเป็นเหตุผลว่าทำไมคุณไม่ต้องการใช้ขนาดประเภทตัวแปรเหล่านี้ในกรณีที่สำคัญ

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

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