我使用 Arduino Uno(16 位 int )并且:
#define DT 49
#define DT_MICRO ((DT) * 1000)
...
while (val<DT_MICRO){/*something*/}
哪个给
49
-16536
如果我使用Serial.print(DT);
打印它们。为什么?我期望 49000。为什么有负数?如果我(在代码内)使用 Serial.print(DT*1000)
,也会发生同样的情况。
使用
DT 49L
and DT_MICRO (DT*1000L)
按预期工作。感谢您的澄清。
最佳答案
除了#if
指令之外,预处理器不执行算术运算,仅执行文本替换。在编译器的后续阶段看到它之前,代码中出现的任何 DT_MICRO
都会被序列 ((49) * 1000)
替换。
常量49
和1000
的类型为int
。 (更一般地,整数常量的类型为 int
、long int
或 long long int
,具体取决于其值;49
和 1000
保证适合 int
,所以这就是它们的类型。)
因此,表达式 ((49)*1000)
也是 int
类型。对于表达式(与常量相反),类型不受值的影响。如果 49,000 太大而无法放入 int
,则表达式会溢出。
类型 int
要求至少为 16 位,上限至少为 32767。现在更常见的是 32 位,上限为 2,147,483,647 ( 231-1)。因此,如果 int
是 16 位,则 DT_MICRO
具有未定义的行为,但很可能评估为 -16536
,这就是您所看到的。如果 int
为 32 位,则 DT_MICRO
的计算结果恰好为 49000
。
至于为什么您会看到该负值,您没有向我们提供足够的信息来确定。你说你“打印”了这个值,但是怎么打印呢?正确的打印方法是:
printf("%d\n", DT_MICRO);
但是您还可以做很多其他事情。
如果您需要确保 DT_MICRO
的类型足够大以保存其值,您可以将定义更改为:
#define DT 49L
#define DT_MICRO (DT * 1000L)
(请注意,只要 DT
定义正确,DT
周围的额外括号就不是必需的)。这会导致它的类型为 long
,至少为 32 位,您可以使用以下命令打印它:
printf("%ld\n", DT_MICRO);
关于c - 预处理器常量溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25098959/