编辑:microtherion提供了一个很好的答案,它纠正了我在这里的一些观点,特别是关于内存使用情况。
如您所确定的,在某些情况下#define
,由于编译器不允许使用const
变量,因此您不得不使用。同样,在某些情况下,您被迫使用变量,例如,当您需要一个值数组时(即,您不能拥有的数组#define
)。
但是,在许多其他情况下,不一定有单个“正确”答案。这是我要遵循的一些准则:
类型安全性
从一般编程的角度来看,const
变量通常是可取的(可能的话)。这样做的主要原因是类型安全。
甲#define
(预处理宏)直接复制文字值成在代码中的每个位置,使得每次使用独立的。可能会导致模棱两可,因为根据使用方式/位置的不同,类型最终可能会以不同的方式解析。
甲const
变量是永远只一种类型,这是由它的声明来确定,并在初始化期间解析。它通常需要一个显式的强制转换才能表现出不同的行为(尽管在各种情况下都可以安全地隐式地对其进行类型提升)。至少,如果发生类型问题,编译器可以(如果配置正确)发出更可靠的警告。
可能的解决方法是在中包含显式强制转换或类型后缀#define
。例如:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
但是,在某些情况下,根据使用方式的不同,该方法可能会导致语法问题。
内存使用
与通用计算不同,内存在处理诸如Arduino之类的东西时显然很宝贵。使用const
变量vs.a #define
可能会影响数据在内存中的存储位置,这可能会迫使您使用其中一个。
const
变量(通常)将与所有其他变量一起存储在SRAM中。
- 所使用的文字值
#define
通常会与草图本身一起存储在程序空间(闪存)中。
(请注意,有多种因素可以准确影响事物的存储方式和存储位置,例如编译器配置和优化。)
SRAM和闪存具有不同的限制(例如,Uno分别为2 KB和32 KB)。对于某些应用程序来说,用尽SRAM很容易,因此将某些内容转移到闪存中可能会有所帮助。尽管可能不太常见,但相反的情况也是可能的。
PROGMEM
在将数据存储在程序空间(Flash)中的同时,可以获得类型安全的好处。这是使用PROGMEM
关键字完成的。并非所有类型都适用,但通常用于整数或字符串数组。
文档中给出的一般形式如下:
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
字符串表稍微复杂一点,但是文档中有完整的详细信息。