เหตุใดจึงมีเพียง 2 ไบต์เท่านั้น


9

เมื่อใช้ C / C ++ บนแพลตฟอร์มอื่น ๆintโดยทั่วไปจะเป็นประเภท 4 ไบต์ (หรือมากกว่านั้น) อย่างไรก็ตามบน Arduino มันมีเพียง 2 ไบต์

ทำไมถึงแตกต่าง มันส่งผลกระทบต่อประสิทธิภาพการทำงานหรือไม่ถ้าฉันใช้ 4 ไบต์longแทน


2
โปรดทราบว่าintเป็น 4 ไบต์บน Arduino Due shortจะมี 2 ไบต์ในทุก Ardunios ที่มีอยู่ แต่ผมเน้นคำแนะนำของผู้อื่นเพื่อการใช้งานหรือint16_t uint16_t
Ron

คำตอบ:


10

ATmega328 ที่ใช้ใน Arduinos เป็นไมโครคอนโทรลเลอร์ขนาด 8 บิต ซึ่งหมายความว่าการลงทะเบียนคือ 8 บิตบัสข้อมูลคือ 8 บิตพอร์ตเป็น 8 บิต มีบางแง่มุม 16 บิตขั้นต่ำสำหรับระบบ (เช่นหนึ่งในตัวนับ) แต่เกือบทุกอย่างคือ 8 บิต

ดังนั้นการดำเนินการส่วนใหญ่จัดการ 8 บิตในเวลา การทำงานกับอะไรก็ตามยกเว้น 8 บิต (เช่นจำนวนเต็ม 16 บิตหรือ 32 บิตและตัวเลขทศนิยม) จำเป็นต้องมีสิ่งที่สามารถอธิบายได้ว่าเป็นซอฟต์แวร์การจำลองซึ่งคอมไพเลอร์ใช้คำสั่งหลายคำสั่งเพื่อทำงานกับตัวแปรขนาดใหญ่เหล่านี้

เห็นได้ชัดว่า 8 บิตนั้นเพียงพอสำหรับการระบุที่อยู่พอร์ต 8 บิต นอกจากนี้ยังเพียงพอที่จะจัดการกับตัวนับลูปค่าส่งคืนและอักขระ ASCII จำนวนมาก มันไม่พอจริง ๆ เมื่อจัดการกับตัวเลข 8-bit int ที่ลงนามแล้ว (int8_t) สามารถแสดงได้เพียง -128 -> +127 ไม่ได้ลงชื่อ (uint8_t) สามารถแสดง 0 -> 255 เท่านั้น

จำนวนเต็ม 8 บิตค่อนข้าง จำกัด C / C ++ int ต้องแสดงอย่างน้อย -32,678 -> +32,767 ดังนั้นแมปกับ int16_t - ขนาดที่เล็กที่สุดที่จะทำ สิ่งนี้ให้สมดุลที่ดีของช่วงและประสิทธิภาพ สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อผู้เริ่มต้นเรียนรู้ - การมีน้ำล้นไม่ใช่สิ่งที่โปรแกรมเมอร์ไม่เข้าใจจริงๆ

มีผลกระทบต่อประสิทธิภาพการทำงานเนื่องจากการดำเนินการ 16 บิตส่วนใหญ่ใช้เวลาอย่างน้อยสองเท่าของการทำงาน 8 บิตและใช้การลงทะเบียนสองเท่า สิ่งนี้อาจหรือไม่อาจสร้างความแตกต่างให้กับคุณ

พวกเราหลายคนเปลี่ยนไปใช้ประเภทเนทิฟเช่น int8_t และ uint8_t เพราะมันช่วยให้คุณควบคุมได้มากขึ้น


3
เพียงทราบ: ไม่ใช่ทีม Arduino ที่แมป int ถึง int16_t "int" เป็นคำหลักที่สงวนไว้สำหรับ C / C ++ และการทำแผนที่ประเภทเป็นส่วนหนึ่งของ ABI ( gcc.gnu.org/wiki/avr-gcc ) ที่ นักพัฒนาคอมไพเลอร์ avr-gcc ตัดสินใจที่จะติดตาม ความแตกต่างที่เห็นได้ชัดเจนอีกอย่างหนึ่งก็คือประเภท "double" ที่มักจะเป็น 64 บิตแบบกว้างในขณะที่ avr-gcc 32 บิตเช่น "float"
cmaglie

ขอบคุณ ไม่แน่ใจว่าทำไมฉันถึงเขียนมัน ฉันรู้ว่า int ต้องเป็นตัวแทน 32,678 -> +32,767 (จริง ๆ แล้วฉันคิดว่ามีคอมไพเลอร์ที่เป็นกรรมสิทธิ์สำหรับหนึ่งในโปรเซสเซอร์ NEC ที่ไม่ได้ทำตามนี้) ฉันคิดว่าเป็นเพราะฉันไม่ชอบการซ่อนความกว้างของระบบฝังตัว - การใช้ int16_t นั้นชัดเจนกว่ามาก
Cybergibbons

1
+1 สำหรับการใช้งานประเภทเนทีฟล้าง! ใน Arduino เนื่องจากมีint32 บิต! arduino.cc/en/Reference/int
Ron

3

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

พวกเขาเพียงแค่กำหนดช่วงที่น้อยที่สุดและความสัมพันธ์ระหว่างช่วงเหล่านี้เช่น

range(short) <= range(int) < range(long)

ดังนั้นขนาดของเช่นintจะโดยทั่วไปจะขึ้นอยู่กับ:

  • แพลตฟอร์มเป้าหมาย (โปรเซสเซอร์)
  • คอมไพเลอร์เอง

คุณกำลังพูดว่าsizeof(short) == sizeof(int) == sizeof(long)เป็นไปได้?
Ron

@ ron-e ในทางทฤษฎีใช่ว่าจะเป็นไปได้ อย่างไรก็ตามในทางปฏิบัติฉันไม่เคยเห็นแบบนั้นมาก่อน ในคอมไพเลอร์ / แพลตฟอร์มส่วนใหญ่มีใครคาดหวังsizeof(short) < sizeof(long)ได้
jfpoilpret
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.