ขนาดของ C“ int” 2 ไบต์หรือ 4 ไบต์หรือไม่


169

ตัวแปรเลขจำนวนเต็มใน C ใช้ 2 ไบต์หรือ 4 ไบต์หรือไม่ อะไรคือปัจจัยที่ขึ้นอยู่กับอะไร

หนังสือเรียนส่วนใหญ่บอกว่าตัวแปรจำนวนเต็มมี 2 ไบต์ แต่เมื่อฉันรันโปรแกรมที่พิมพ์ที่อยู่ต่อเนื่องของอาร์เรย์จำนวนเต็มมันจะแสดงความแตกต่างของ 4



1
intเป็นเพียงหนึ่งในจำนวนเต็มหลายชนิด คุณถามเกี่ยวกับขนาดของ "จำนวนเต็ม"; intคุณอาจหมายถึงการถามเกี่ยวกับขนาดของ
Keith Thompson

3
และคุณควรหาแบบเรียนที่ดีกว่า หนังสือเรียนที่บอกว่ามีintขนาด 2 ไบต์ (a) อาจหมายถึงระบบเก่าและ (b) ล้มเหลวในการทำให้ชัดเจนว่าขนาดจะแตกต่างจากระบบหนึ่งไปอีกระบบหนึ่ง หนังสือที่ดีที่สุดใน C คือ "ภาษาการเขียนโปรแกรม C" โดย Kernighan และ Ritchie แม้ว่ามันจะถือว่าประสบการณ์การเขียนโปรแกรมบางอย่าง ดูเพิ่มเติมคำถาม 18.10 ของcomp.lang.c คำถามที่พบบ่อย
Keith Thompson

2
ลองใช้#define int int64_tแพลตฟอร์ม 64 บิตเช่นกัน sizeofใช้เพียงแค่ ;-)
netcoder

มีความเป็นไปได้ที่ซ้ำกันของมาตรฐาน C ++ ระบุขนาดของ int และ long type ว่าเป็นอะไร
phuclv

คำตอบ:


183

sizeof(int)ฉันรู้ว่ามันเท่ากับ ขนาดของintคอมไพเลอร์ขึ้นอยู่กับมันจริงๆ ย้อนกลับไปในวันนี้เมื่อโปรเซสเซอร์มีขนาด 16 บิตและintเท่ากับ 2 ไบต์ ทุกวันนี้มันมักจะเป็น 4 ไบต์ในระบบ 32- บิตและ 64- บิต

ถึงกระนั้นการใช้sizeof(int)เป็นวิธีที่ดีที่สุดในการรับขนาดของจำนวนเต็มสำหรับระบบเฉพาะที่ใช้งานโปรแกรม

แก้ไข:แก้ไขคำผิดที่intเป็น 8 ไบต์ในระบบ 64 บิตส่วนใหญ่ ตัวอย่างเช่นมันคือ 4 ไบต์ใน GCC 64- บิต


31
@RajivPrathap: มันขึ้นอยู่กับคอมไพเลอร์ แต่คอมไพเลอร์ตัดสินว่ามันขึ้นอยู่กับเครื่องด้วยหรือไม่ :)
user541686

2
หากคุณต้องการขนาดสำหรับตัวประมวลผลล่วงหน้าคุณสามารถตรวจสอบมาโครที่กำหนดไว้ล่วงหน้าเช่น INT_MAX หากค่าไม่ใช่ค่าที่คาดหวังจากโค้ดของคุณขนาดไบต์ของ int จะแตกต่างกันในการรวมกันของคอมไพเลอร์ / แพลตฟอร์มปัจจุบัน
Walt Sellers

3
ไม่เพียง แต่ขึ้นอยู่กับเครื่องเท่านั้น แต่ยังขึ้นอยู่กับระบบปฏิบัติการที่รันบนเครื่องด้วย ตัวอย่างเช่นยาวใน Win64 คือ 4 ไบต์ในขณะที่ยาวใน Linux64 คือ 8 ไบต์
Cem Kalyoncu

9
ไม่ถูกต้อง. บนระบบ 64- บิตส่วนใหญ่ int ยังคงเป็น 4 ไบต์en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv

7
sizeof(int)สามารถเป็นค่าใด ๆ 1จาก ไบต์ไม่จำเป็นต้องเป็น 8 บิตและเครื่องบางเครื่องไม่มีหน่วยที่สามารถระบุตำแหน่งได้ 8 บิต (ซึ่งโดยทั่วไปคือคำจำกัดความของไบต์ในมาตรฐาน) คำตอบนั้นไม่ถูกต้องหากไม่มีข้อมูลเพิ่มเติม
ซื่อสัตย์เกินไปสำหรับไซต์นี้

103

นี่คือหนึ่งในจุดใน C ที่อาจทำให้เกิดความสับสนในตอนแรก แต่มาตรฐาน C ระบุช่วงขั้นต่ำสำหรับประเภทจำนวนเต็มที่รับประกันว่าจะได้รับการสนับสนุน intมีการรับประกันว่าจะสามารถถือ -32767 ถึง 32767 ซึ่งต้องใช้ 16 บิต ในกรณีintนั้นคือ 2 ไบต์ อย่างไรก็ตามการใช้งานมีอิสระที่จะก้าวไปไกลกว่าขั้นต่ำดังกล่าวเนื่องจากคุณจะเห็นว่าคอมไพเลอร์สมัยใหม่จำนวนมากสร้างint32- บิต (ซึ่งหมายถึง 4 ไบต์ที่ค่อนข้างแพร่หลาย)

สาเหตุที่หนังสือของคุณบอกว่า 2 ไบต์น่าจะเป็นเพราะมันเก่า ครั้งหนึ่งนี่เป็นบรรทัดฐาน โดยทั่วไปคุณควรใช้sizeofโอเปอเรเตอร์ทุกครั้งหากคุณต้องการทราบว่ามีกี่ไบต์บนแพลตฟอร์มที่คุณใช้

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


7
@Nevanking: บนเครื่องประกอบสอง (ซึ่งก็คือทุกเครื่องที่ฉันรู้จัก ... ) ใช่ แต่ C ไม่รับประกันว่าจะเป็นอย่างนั้น
FatalError

@ การลงทะเบียนฉันยังใหม่กับ C แต่มันไม่ใช่ 32767 เพราะไม่เช่นนั้นจะใช้ bit | byte อีกหรือเปล่า? ลองนึกภาพฉันสามารถเก็บ 3 หลัก (0 หรือ 1) ดังนั้นฉันสามารถไปจาก 000 ถึง 111 (ซึ่งเป็นทศนิยม 7) 7 ถูกต้องก่อนเลขชี้กำลัง 2 ถ้าฉันไปได้ถึง 8 (1,000) ฉันก็สามารถใช้ตัวเลข 4 หลักไปจนถึง 15! เช่น 32767 นั้นถูกต้องก่อนเลขชี้กำลัง 2 ซึ่งทำให้บิต | ไบต์ทั้งหมดมีอยู่หมด
RGS

3
@RSerrao ฉันไม่ใช่ผู้เชี่ยวชาญ C แต่เป็น AFAIK สำหรับจำนวนบวกมันเป็นน้อยกว่าจำนวนลบสูงสุด ดังนั้น -8 ถึง 7, -256 ถึง 255 และอื่น ๆ ตัวเลขติดลบไม่จำเป็นต้องนับศูนย์
nevan king

1
"16 บิตในกรณีนั้น int คือ 2 ไบต์" อาจผิดถ้า CHAR_BIT เป็น 16 ขนาดของ (int) สามารถเป็น 1 ไบต์ (หรือถ่าน)
12431234123412341234123

6
@nevanking: ถ้าคุณถือว่าเป็นตัวแทนที่สมบูรณ์ 2 intสำหรับการลงนาม C ไม่ได้ทำให้สมมติฐานนั้น 1 ระบบที่สมบูรณ์และขนาดสัญญาณไม่สามารถแสดงได้-32768ใน 16 บิต; ค่อนข้างพวกเขามีสองแนวทางสำหรับศูนย์ (บวกและลบ) นั่นเป็นเหตุผลที่ช่วงต่ำสุดของการเป็นint [-32767..32767]
John Bode

33

ไม่มีคำตอบที่เฉพาะเจาะจง มันขึ้นอยู่กับแพลตฟอร์ม มันคือการดำเนินการที่กำหนดไว้ อาจเป็น 2, 4 หรืออย่างอื่น

แนวคิดเบื้องหลังintคือควรตรงกับขนาด "คำ" ตามธรรมชาติบนแพลตฟอร์มที่กำหนด: 16 บิตบนแพลตฟอร์ม 16 บิต, 32 บิตบนแพลตฟอร์ม 32 บิต, 64 บิตบนแพลตฟอร์ม 64 บิตคุณจะได้รับความคิด อย่างไรก็ตามเพื่อความเข้ากันได้ย้อนหลังคอมไพเลอร์บางคนชอบที่จะยึด 32- บิตintแม้บนแพลตฟอร์ม 64- บิต

เวลาของ 2 ไบต์intนั้นหายไปนานแล้ว (แพลตฟอร์ม 16 บิต?) เว้นแต่ว่าคุณกำลังใช้แพลตฟอร์มฝังตัวบางตัวที่มีขนาดคำ 16 บิต ตำราของคุณอาจเก่ามาก


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform- นี่คือสิ่งที่ฉันกำลังมองหา ความคิดใดเหตุผลอะไรอาจจะ? ในโลกเสรี int อาจครอบครองไบต์ต่อเนื่องจำนวนใดในหน่วยความจำใช่ไหม? 8, 16 อะไรก็ตาม
bholagabbar

19

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

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615

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

1
@ k06a การแก้ไขของคุณไม่ถูกต้อง คุณได้เปลี่ยนช่วงดั้งเดิมโดยเฉพาะเป็นช่วงเสริม 2 ช่วงซึ่งไม่ใช่ช่วงที่ระบุไว้ในมาตรฐาน C
Antti Haapala

@CodyGray สิ่งนี้มีความผันผวนไปมาเนื่องจากเป็นส่วนประกอบที่สมบูรณ์ของ 1 สำหรับ 3 ปีที่ผ่านมาและ OP ไม่ได้พูดอะไรดังนั้นฉันจึงเปลี่ยนการแก้ไขที่เปลี่ยนเป็นส่วนประกอบของ 2 ด้วย "ช่วงการแก้ไข" เนื่องจากมันบอกว่า "คุณเชื่อได้อย่างน่าเชื่อถือ" ซึ่งยังไม่เป็นความจริงอย่างแน่นอน
Antti Haapala

13

ตัวแปรเลขจำนวนเต็มใน C ใช้ 2 ไบต์หรือ 4 ไบต์หรือไม่

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


อะไรคือปัจจัยที่ขึ้นอยู่กับอะไร

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


sizeof, ไบต์และ CHAR_BIT

คำสั่งต่อไปนี้นำมาจากมาตรฐาน C (เชื่อมโยงกับด้านบน) อธิบายสิ่งนี้ในคำที่ฉันไม่คิดว่าสามารถปรับปรุงได้

ตัวsizeofดำเนินการให้ผลขนาด (เป็นไบต์) ของตัวถูกดำเนินการซึ่งอาจเป็นนิพจน์หรือชื่อวงเล็บชนิด ขนาดถูกกำหนดจากชนิดของตัวถูกดำเนินการ

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

เรามาสรุปกัน:

  • sizeof => ขนาดเป็นไบต์และ
  • CHAR_BIT => จำนวนบิตเป็นไบต์

ดังนั้นขึ้นอยู่กับระบบของคุณsizeof (unsigned int)อาจเป็นค่าใด ๆ ที่มากกว่าศูนย์ (ไม่ใช่แค่ 2 หรือ 4) ราวกับว่าCHAR_BITเป็น 16 แล้วไบต์เดียว (สิบหกบิต)มีบิตเพียงพอในนั้นเพื่อเป็นตัวแทนของจำนวนเต็มสิบหกบิตที่อธิบายโดย มาตรฐาน (ยกมาด้านล่าง) นั่นไม่ใช่ข้อมูลที่มีประโยชน์เสมอไปใช่ไหม มาเจาะลึกลงไป ...


การเป็นตัวแทนจำนวนเต็ม

ซีระบุมาตรฐานขั้นต่ำที่มีความแม่นยำ / ช่วงสำหรับทุกประเภทจำนวนเต็มมาตรฐาน (และCHAR_BITมากเกินไป FWIW) ที่นี่ จากนี้เราสามารถได้รับมาอย่างน้อยกี่บิตจะต้องเก็บค่าแต่เราอาจได้เป็นอย่างดีเพียงแค่เลือกตัวแปรของเราขึ้นอยู่กับช่วง อย่างไรก็ตามรายละเอียดส่วนใหญ่ที่จำเป็นสำหรับคำตอบนี้อยู่ที่นี่ ตัวอย่างเช่นต่อไปนี้ที่มาตรฐานunsigned intต้องการ (อย่างน้อย) หน่วยความจำสิบหกบิต:

UINT_MAX                                65535 // 2¹⁶ - 1

ดังนั้นเราจะเห็นได้ว่าunsigned intต้องการ ( อย่างน้อย ) 16 บิตซึ่งเป็นที่ที่คุณได้รับสองไบต์ (สมมติว่าCHAR_BITเป็น 8) ... และต่อมาเมื่อขีด จำกัด นั้นเพิ่มขึ้น2³² - 1ผู้คนจะระบุ 4 ไบต์แทน สิ่งนี้อธิบายถึงปรากฏการณ์ที่คุณสังเกตได้:

หนังสือเรียนส่วนใหญ่บอกว่าตัวแปรจำนวนเต็มมี 2 ไบต์ แต่เมื่อฉันรันโปรแกรมที่พิมพ์ที่อยู่ต่อเนื่องของอาร์เรย์จำนวนเต็มมันจะแสดงความแตกต่างของ 4

คุณกำลังใช้ตำราโบราณและผู้แปลซึ่งสอนคุณแบบพกพา C; ผู้แต่งที่เขียนตำราเรียนของคุณอาจไม่รู้CHAR_BITตัว คุณควรอัพเกรดตำราเรียน (และคอมไพเลอร์) และพยายามจำไว้ว่าไอทีเป็นสาขาที่มีการพัฒนาตลอดเวลาที่คุณต้องอยู่ข้างหน้าเพื่อแข่งขัน ... เพียงพอสำหรับเรื่องนี้ เรามาดูกันว่าความลับที่ไม่ใช่แบบพกพาอื่น ๆ คืออะไรจำนวนเต็มไบต์ที่เก็บไว้ ...

บิตของค่าเป็นสิ่งที่ความเข้าใจผิดร่วมกันดูเหมือนจะนับ ตัวอย่างด้านบนใช้unsignedประเภทจำนวนเต็มซึ่งโดยทั่วไปจะมีเฉพาะค่าบิตดังนั้นจึงง่ายที่จะพลาดรายละเอียดมาร

Sign bits ... ในตัวอย่างข้างต้นฉันอ้างUINT_MAXว่ามันเป็นขีด จำกัด บนunsigned intเพราะเป็นตัวอย่างเล็กน้อยที่จะดึงค่า16จากความคิดเห็น สำหรับประเภทที่เซ็นชื่อเพื่อที่จะแยกแยะความแตกต่างระหว่างค่าบวกและลบ (นั่นคือเครื่องหมาย) เราต้องรวมบิตบิตด้วย

INT_MIN                                -32768 // -(2¹⁵)
INT_MAX                                +32767 // 2¹⁵ - 1

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


อย่างที่คุณเห็นมาตรฐานดูเหมือนว่าจะสนับสนุนการพิจารณาช่วงเช่นINT_MIN.. INT_MAXและค่าต่ำสุด / สูงสุดอื่น ๆ จากมาตรฐานเมื่อเลือกประเภทจำนวนเต็มและกีดกันที่ขึ้นอยู่กับขนาดเนื่องจากมีปัจจัยที่ลึกซึ้งอื่น ๆ ที่น่าจะลืมเช่นCHAR_BITบิตรอง อาจส่งผลกระทบต่อค่าของsizeof (int)(เช่นความเข้าใจผิดที่พบบ่อยของจำนวนเต็มสองไบต์และสี่ไบต์ละเลยรายละเอียดเหล่านี้)


13

ร่างมาตรฐาน C99 N1256

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

ขนาดของintและประเภทจำนวนเต็มอื่น ๆ ทั้งหมดจะถูกกำหนดใช้งาน C99 ระบุเท่านั้น:

  • รับประกันขนาดขั้นต่ำ
  • ขนาดญาติระหว่างประเภท

5.2.4.2.1 "ขนาดของประเภทจำนวนเต็ม<limits.h>" ให้ขนาดต่ำสุด:

1 [... ] ค่าที่กำหนดโดยการนำไปปฏิบัติจะต้องเท่ากับหรือมากกว่าในขนาด (ค่าสัมบูรณ์) กับค่าที่แสดง [... ]

  • UCHAR_MAX 255 // 2 8 - 1
  • USHRT_MAX 65535 // 2 16 - 1
  • UINT_MAX 65535 // 2 16 - 1
  • ULONG_MAX 4294967295 // 2 32 - 1
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1

6.2.5 "ประเภท" จากนั้นพูดว่า:

8 สำหรับจำนวนเต็มสองชนิดที่มีการเซ็นชื่อเหมือนกันและลำดับการแปลงจำนวนเต็มแตกต่างกัน (ดู 6.3.1.1) ช่วงของค่าของประเภทที่มีอันดับการแปลงจำนวนเต็มน้อยกว่านั้นคือช่วงย่อยของค่าของประเภทอื่น

และ 6.3.1.1 "บูลีนอักขระและจำนวนเต็ม" เป็นตัวกำหนดอันดับการแปลงสัมพัทธ์:

1 ทุกประเภทจำนวนเต็มมีอันดับการแปลงจำนวนเต็มดังนี้:

  • อันดับของ long long int จะมากกว่าอันดับของ long int ซึ่งจะมากกว่าอันดับ int ซึ่งจะมากกว่าอันดับสั้น int ซึ่งจะสูงกว่าอันดับ char ที่ลงนาม
  • อันดับของประเภทจำนวนเต็มใด ๆ ที่ไม่ได้ลงนามจะเท่ากับอันดับของประเภทจำนวนเต็มที่ลงนามที่สอดคล้องกันถ้ามี
  • สำหรับประเภทจำนวนเต็มทั้งหมด T1, T2 และ T3 หาก T1 มีอันดับมากกว่า T2 และ T2 มีอันดับมากกว่า T3 แล้ว T1 จะมีอันดับมากกว่า T3

8

การรับประกันเพียงอย่างเดียวคือcharต้องมีความกว้างอย่างน้อย 8 บิตshortและintต้องมีความกว้างอย่างน้อย 16 บิตและlongจะต้องมีความกว้างอย่างน้อย 32 บิตและsizeof (char)<= sizeof (short)<= sizeof (int)= = = sizeof (long)(เหมือนกันสำหรับรุ่นที่ไม่ได้ลงนาม )

int อาจอยู่ที่ใดก็ได้ตั้งแต่ 16 ถึง 64 บิตขึ้นอยู่กับแพลตฟอร์ม


6

ขนาดของ C“ int” 2 ไบต์หรือ 4 ไบต์หรือไม่

คำตอบคือ "ใช่" / "ไม่" / "อาจจะ" / "อาจจะไม่"

ภาษาการเขียนโปรแกรม C ระบุสิ่งต่อไปนี้: ยูนิตที่สามารถระบุแอดเดรสที่เล็กที่สุดซึ่งรู้จักกันโดยcharและเรียกว่า"byte"คือCHAR_BITความกว้างบิตที่แน่นอนCHAR_BITอย่างน้อยโดยมีอย่างน้อย 8

ดังนั้นหนึ่งไบต์ใน C ไม่จำเป็นต้องเป็นoctetเช่น 8 บิต ในอดีตหนึ่งในแพลตฟอร์มแรกที่รัน C code (และ Unix) มี 4 ไบต์int- แต่โดยรวมintมี 36 บิตเพราะCHAR_BITเท่ากับ 9!

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


ในขณะที่เครื่องจักรขนาด 36 บิตส่วนใหญ่ตายแล้วยังมีแพลตฟอร์มที่มีจำนวนไบต์ที่ไม่ใช่ 8 บิต เมื่อวานนี้มีคำถามเกี่ยวกับ Texas Instruments MCU ที่มี 16- บิตไบต์ที่มีคอมไพเลอร์ที่สอดคล้องกับ C99, C11

เมื่อวันที่TMS320C28xดูเหมือนว่าchar, shortและintมีทั้งหมด 16 บิตกว้างและด้วยเหตุหนึ่งไบต์ long intคือ 2 ไบต์และlong long int4 ไบต์ ความสวยงามของ C คือใครยังคงสามารถเขียนโปรแกรมที่มีประสิทธิภาพสำหรับแพลตฟอร์มเช่นนี้และทำได้ในลักษณะพกพา!


"เพราะ CHAR_BIT คือ 9!" - พวกเขามีการคำนวณแบบบิต 362880 แล้ว!? ประทับใจ
Josh Desmond

5

ส่วนใหญ่จะขึ้นอยู่กับแพลตฟอร์มที่คุณใช้มันขึ้นอยู่กับจากคอมไพเลอร์จะ compiler.Nowadays ในส่วนของคอมไพเลอร์intเป็น4 ไบต์ sizeof(int)หากคุณต้องการที่จะตรวจสอบสิ่งที่คอมไพเลอร์ของคุณใช้คุณสามารถใช้

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

สิ่งเดียวที่คอมไพเลอร์สัญญาไว้คือขนาดสั้นต้องเท่ากับหรือน้อยกว่า int และขนาดยาวต้องเท่ากับหรือมากกว่านั้นดังนั้นถ้าขนาดของ int เท่ากับ 4 ดังนั้นขนาดสั้นอาจเป็น 2 หรือ 4 แต่ไม่ใหญ่กว่า ดีกว่านั้นจริง ๆ แล้วเป็นเรื่องที่ยาวนานและไม่จริง นอกจากนี้ยังกล่าวว่าขนาดของสั้นและยาวไม่สามารถเหมือนกัน


1
การใช้%dสำหรับsize_tพารามิเตอร์คือ UB
พอล R

3

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

หากคุณต้องการตรวจสอบให้แน่ใจว่าคุณใช้ขนาดที่ระบุให้ใช้ประเภท <stdint.h>


2
#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

สิ่งนี้จะคืนค่า 4 แต่อาจขึ้นอยู่กับเครื่องจักร


1

ขนาดของ C“ int” 2 ไบต์หรือ 4 ไบต์หรือไม่

ตัวแปรเลขจำนวนเต็มใน C ใช้ 2 ไบต์หรือ 4 ไบต์หรือไม่

C อนุญาตให้ "ไบต์" เป็นอย่างอื่นที่ไม่ใช่ 8 บิตต่อ "ไบต์"

CHAR_BIT จำนวนบิตสำหรับวัตถุที่เล็กที่สุดที่ไม่ใช่บิตฟิลด์ (ไบต์) C11dr §5.2.4.2.1 1

คุณค่าของบางสิ่งที่มากกว่า 8 เป็นเรื่องธรรมดามากขึ้น สำหรับการพกพาสูงสุดใช้CHAR_BITมากกว่า 8. ขนาดของintในบิต ใน C sizeof(int) * CHAR_BITคือ

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

อะไรคือปัจจัยที่ขึ้นอยู่กับอะไร

intขนาดบิตเป็นปกติ 32 หรือ 16 บิต C ช่วงต่ำสุดที่ระบุ:

ค่าต่ำสุดสำหรับวัตถุประเภทint INT_MIN-32767
ค่าสูงสุดสำหรับวัตถุประเภทint INT_MAX+32767
C11dr §5.2.4.2.1 1

ช่วงต่ำสุดสำหรับintกองกำลังขนาดบิตที่จะเป็นอย่างน้อย 16 - แม้ว่าหน่วยประมวลผลก็คือ "8 บิต" ขนาดเช่น 64 บิตมีให้เห็นในโปรเซสเซอร์พิเศษ ค่าอื่น ๆ เช่น 18, 24, 36 เป็นต้นเกิดขึ้นบนแพลตฟอร์มประวัติศาสตร์หรืออย่างน้อยก็เป็นไปได้ในทางทฤษฎี การเข้ารหัสสมัยใหม่ไม่ค่อยกังวลเกี่ยวกับการไม่ใช้พลังงานของ 2intบิต

โปรเซสเซอร์และสถาปัตยกรรมของคอมพิวเตอร์เป็นตัวขับเคลื่อน intเลือกขนาดบิต

ถึงแม้จะใช้โปรเซสเซอร์ 64 บิตintขนาดคอมไพเลอร์อาจเป็น 32 บิตสำหรับเหตุผลด้านความเข้ากันได้เนื่องจากฐานโค้ดขนาดใหญ่ขึ้นอยู่กับintขนาด 32 บิต (หรือ 32/16)


-1

นี่เป็นแหล่งข้อมูลที่ดีสำหรับการตอบคำถามนี้

แต่คำถามนี้เป็นคำตอบที่จริงเสมอว่า "ใช่ทั้งคู่"

ขึ้นอยู่กับสถาปัตยกรรมของคุณ หากคุณกำลังจะทำงานกับเครื่อง 16 บิตหรือน้อยกว่านั้นจะไม่สามารถเป็น 4 ไบต์ (= 32 บิต) หากคุณกำลังทำงานกับเครื่อง 32- บิตหรือดีกว่าความยาวของมันคือ 32- บิต

เพื่อให้เข้าใจว่าโปรแกรมของคุณพร้อมที่จะแสดงผลสิ่งที่อ่านได้และใช้ฟังก์ชัน "sizeof" ที่ส่งคืนขนาดเป็นไบต์ของประเภทข้อมูลที่คุณประกาศ แต่ควรใช้ carfull กับอาเรย์

หากคุณประกาศint t[12];มันจะคืนค่า 12 * 4 ไบต์ sizeof(t)/sizeof(t[0])เพื่อให้ได้ความยาวของอาร์เรย์นี้เพียงแค่ใช้ หากคุณกำลังจะสร้างฟังก์ชั่นที่ควรคำนวณขนาดของอาร์เรย์ส่งให้จำไว้ว่าถ้า

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

ดังนั้นสิ่งนี้จะไม่ส่งคืนสิ่งที่แตกต่าง หากคุณกำหนดอาเรย์และลองรับความยาวหลังจากนั้นให้ใช้ sizeof หากคุณส่งอาร์เรย์ไปยังฟังก์ชันโปรดจำไว้ว่าค่าส่งเป็นเพียงตัวชี้ในองค์ประกอบแรก แต่ในกรณีที่หนึ่งคุณรู้อยู่เสมอว่าอาร์เรย์ของคุณมีขนาดเท่าใด กรณีที่สองสามารถหาได้โดยกำหนดฟังก์ชันสองฟังก์ชันและคิดถึงประสิทธิภาพบางอย่าง กำหนดฟังก์ชั่น (อาร์เรย์ t) และกำหนด function2 (อาร์เรย์ t, int size_of_t) Call "function (t)" วัดความยาวโดยการทำสำเนาและส่งผลให้ function2 ซึ่งคุณสามารถทำสิ่งที่คุณต้องการในขนาดอาเรย์ตัวแปร


ลิงค์ที่ให้นั้นเป็นแหล่งข้อมูลที่ไม่ดีเพราะมันจะถือว่าสิ่งต่าง ๆ ไม่จริงเสมอไป (เช่น charเสมอsigned)
Andrei Damian-Fekete
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.