我使用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)
像预期的那样工作。谢谢你的澄清。
答案 0 :(得分:4)
除#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(2 31 -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);
答案 1 :(得分:1)
预处理器无法将常量解释为一种或另一种类型,它只能进行词法替换...所以你的程序将完全相同:
print(49*1000)
并且那些被视为.c文件中的裸常量,因此在不知道print()
的原型是什么的情况下,除了指示您远离预处理器之外,我无法提供更多帮助。
答案 2 :(得分:0)
数字为负的原因是您使用的是16位带符号数学运算。您可以表示的最大正数是32767.任何大于该值的数字都被视为负数。如果您想了解有关有符号整数数学的更多信息,可以在线获取大量资源。
要计算更大的值,您需要使用不同的变量类型。