แก้ไข: microtherion ให้คำตอบที่ดีซึ่งแก้ไขบางจุดของฉันที่นี่โดยเฉพาะเกี่ยวกับการใช้หน่วยความจำ
ตามที่คุณระบุมีบางสถานการณ์ที่คุณถูกบังคับให้ใช้#define
เพราะคอมไพเลอร์จะไม่อนุญาตให้ใช้const
ตัวแปร ในบางสถานการณ์คุณถูกบังคับให้ใช้ตัวแปรเช่นเมื่อคุณต้องการอาร์เรย์ของค่า (เช่นคุณไม่สามารถมีอาร์เรย์ได้#define
)
อย่างไรก็ตามมีหลายสถานการณ์ที่ไม่จำเป็นต้องมีคำตอบ 'ถูกต้อง' เพียงคำเดียว นี่คือแนวทางบางส่วนที่ฉันจะทำตาม:
ความปลอดภัยของประเภท
จากมุมมองการเขียนโปรแกรมทั่วไปconst
ตัวแปรมักจะเป็นที่นิยม (หากเป็นไปได้) เหตุผลหลักสำหรับเรื่องนี้คือความปลอดภัยประเภท
A #define
(มาโครตัวประมวลผลล่วงหน้า) คัดลอกค่าตัวอักษรไปยังแต่ละตำแหน่งในโค้ดโดยตรงทำให้การใช้งานทุกครั้งเป็นอิสระ สิ่งนี้อาจส่งผลให้เกิดความคลุมเครือในเชิงสมมุติฐานเนื่องจากรูปแบบอาจจบลงด้วยการแก้ไขแตกต่างกันไปขึ้นอยู่กับวิธี / ตำแหน่งที่ใช้
const
ตัวแปรเดียวที่เคยชนิดหนึ่งซึ่งจะถูกกำหนดโดยการประกาศของตนและได้รับการแก้ไขในช่วง initialisation มันมักจะต้องใช้การส่งที่ชัดเจนก่อนที่มันจะทำงานแตกต่างกัน (แม้ว่าจะมีสถานการณ์ต่าง ๆ ที่มันสามารถได้รับการส่งเสริมประเภทโดยนัย) อย่างน้อยที่สุดคอมไพเลอร์สามารถ (หากกำหนดค่าอย่างถูกต้อง) ส่งคำเตือนที่เชื่อถือได้มากขึ้นเมื่อเกิดปัญหาประเภท
#define
การแก้ปัญหาที่เป็นไปได้สำหรับเรื่องนี้คือการรวมทีมนักแสดงอย่างชัดเจนหรือชนิดคำต่อท้ายภายใน ตัวอย่างเช่น:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
วิธีการดังกล่าวอาจทำให้เกิดปัญหาไวยากรณ์ในบางกรณีขึ้นอยู่กับวิธีการใช้งาน
การใช้หน่วยความจำ
แตกต่างจากการคำนวณด้วยคอมพิวเตอร์ทั่วไปหน่วยความจำมีความชัดเจนเมื่อใช้งานกับ Arduino การใช้const
ตัวแปร vs. #define
อาจส่งผลต่อการจัดเก็บข้อมูลในหน่วยความจำซึ่งอาจบังคับให้คุณใช้อย่างใดอย่างหนึ่ง
const
ตัวแปรจะ (ปกติ) ถูกเก็บไว้ใน SRAM พร้อมกับตัวแปรอื่น ๆ ทั้งหมด
- ค่าตัวอักษรที่ใช้ใน
#define
มักจะถูกเก็บไว้ในพื้นที่โปรแกรม (หน่วยความจำแฟลช) พร้อมร่างภาพตัวเอง
(โปรดทราบว่ามีหลายสิ่งหลายอย่างที่สามารถส่งผลกระทบต่อวิธีการและสิ่งที่เก็บไว้เช่นการกำหนดค่าคอมไพเลอร์และการเพิ่มประสิทธิภาพ)
SRAM และ Flash มีข้อ จำกัด ที่แตกต่างกัน (เช่น 2 KB และ 32 KB ตามลำดับสำหรับ Uno) สำหรับแอพพลิเคชั่นบางอย่างมันค่อนข้างง่ายที่จะหมด SRAM ดังนั้นมันจะมีประโยชน์ในการเปลี่ยนบางสิ่งเป็น Flash การย้อนกลับยังเป็นไปได้แม้ว่าอาจพบได้น้อยกว่าทั่วไป
PROGMEM
เป็นไปได้ที่จะได้รับประโยชน์จากความปลอดภัยประเภทขณะเดียวกันก็เก็บข้อมูลไว้ในพื้นที่โปรแกรม (Flash) สิ่งนี้จะทำโดยใช้PROGMEM
คำหลัก ใช้งานไม่ได้กับทุกประเภท แต่มักใช้กับอาร์เรย์ของจำนวนเต็มหรือสตริง
แบบฟอร์มทั่วไปที่ให้ไว้ในเอกสารมีดังนี้:
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
ตารางสตริงค่อนข้างซับซ้อนกว่าเล็กน้อย แต่เอกสารประกอบมีรายละเอียดครบถ้วน