我遇到了如下代码:
#define SOME_VALUE 0xFEDCBA9876543210ULL
这是稍后 SOME_VALUE
分配给一些人的。unsigned long long
问题:
- 在这种情况下是否需要有后缀
ULL
? - 什么情况下我们需要指定使用的整数类型?
- 在这种情况下,C 和 C++ 的行为是否不同?
在 C 中,十六进制文字获取第一种类型int
, unsigned int
, long
, unsigned long
,long long
或者unsigned long long
如果它没有后缀则可以表示其值。如果 C++ 有相同的规则,我不会感到惊讶。
如果您想为文字提供比默认情况下更大的类型,或者如果您想强制其签名,则需要一个后缀,例如考虑
1 << 43;
如果没有后缀,那(几乎可以肯定)是未定义的行为,但1LL << 43;
例如就可以了。
printf("%ld", SOME_VALUE);
如果SOME_VALUE
未指定 的整数类型,则可能会导致错误的输出。在 C++ 中使用指定后缀的一个很好的例子是重载函数。以以下为例:
#include <iostream>
void consumeInt(unsigned int x)
{
std::cout << "UINT" << std::endl;
}
void consumeInt(int x)
{
std::cout << "INT" << std::endl;
}
void consumeInt(unsigned long long x)
{
std::cout << "ULL" << std::endl;
}
int main(int argc, const char * argv[])
{
consumeInt(5);
consumeInt(5U);
consumeInt(5ULL);
return 0;
}
结果是:
INT
UINT
ULL
当您不提及任何后缀时,int
编译器会推断出整数文字的类型。由于如果将其类型推导出为 ,则某些整数文字可能会溢出int
,因此您添加后缀以告诉编译器将类型推导出为int
. 这就是你写作时所做的0xFEDCBA9876543210ULL
。
写浮点数时也可以使用后缀。1.2
是一个double
,1.2f
而是一个浮点数。
如果您的唯一目的是获得正确的数字值,则不需要后缀;C 会自动选择适合该值的类型。
如果你想强制表达式的类型,后缀很重要,例如为了它如何在表达式中交互。当您要执行会溢出较小类型(例如1ULL<<n
or x*10LL
)的算术运算时,可能需要将其设置为 long 或 long long,并且当您希望将表达式作为一个整体具有无符号语义(例如c-'0'<10U
, 或n%2U
)。