C中的无符号十六进制常量?
Posted
技术标签:
【中文标题】C中的无符号十六进制常量?【英文标题】:Unsigned hexadecimal constant in C? 【发布时间】:2011-06-11 21:19:38 【问题描述】:C 是否处理十六进制常量(例如 0x23FE)和有符号或无符号整数?
【问题讨论】:
Type of integer literals not int by default?的可能重复 【参考方案1】:根据cppreference,十六进制字面量的类型是下面列表中第一个值可以适合的类型。
int
unsigned int
long int
unsigned long int
long long int(since C99)
unsigned long long int(since C99)
所以这取决于你的号码有多大。如果你的号码小于INT_MAX
,那么它的类型是int
。如果您的数字大于INT_MAX
但小于UINT_MAX
,则它的类型为unsigned int
,依此类推。
由于0x23FE
小于INT_MAX
(即0x7FFF
或更大),它的类型为int
。
如果您希望它不签名,请在数字末尾添加u
:0x23FEu
。
【讨论】:
这个答案似乎与 C++ 相关,而不是 C。它可能是正确的,但我认为应该更新参考链接以指向 C 参考,而不是 C++ 参考。 @RadonRosborough 我已经更新了答案以使用 C 参考并检查了它的其他部分以确保答案都是关于 C。感谢您指出。【参考方案2】:数字本身总是被解释为非负数。十六进制常量没有符号或任何固有的方式来表示负数。常量的类型是其中第一个可以表示其值的类型:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
【讨论】:
请注意,因此,0x8000 可能是有符号或无符号的,具体取决于 sizeof(int) 是 2 还是 4。哎呀!如果你真的需要unsigned
,只需附加u
。
@anatolyg:我不确定你所说的“恶心”是什么意思。它始终是正值,并且如果分配或提升到值仍在范围内的另一种类型,它将始终转换为正确的值,这对我来说似乎是相当明智和理想的行为。
@anatolyg:但0x8000
不是负面的。它可以适合int
,在这种情况下,0x8000 > 0x7000
与int
进行比较,否则0x8000
是unsigned
,0x7000
提升为unsigned
(值没有变化),比较是unsigned
的比较。无论哪种方式,结果都是正确的。
十进制和八进制常量也没有符号——如果你写-1
,你写的是一元-
,后面跟着一个十进制常量1
。在@anatolyg 的示例中,if (MYSIZE > -1)
可能会产生令人惊讶的结果,因为-1
可能会或可能不会被提升为无符号。
@caf: 0x8000 > -1
是一个更好的例子,说明哪些地方确实需要护理。【参考方案3】:
它将它们视为int
文字(基本上,作为有符号整数!)。要编写无符号文字,只需在末尾添加 u
:
0x23FEu
【讨论】:
我不认为你可以保留这样的声明。例如,假设int
的宽度是 32 位,则 0x8000
的值是 unsigned
(即 INT_MAX + 1
)而不是 signed
(和 INT_MIN
)。
@JensGustedt:大概你的意思是如果int
的宽度是16 位那么0x8000
将是unsigned
?
@Charles,可能。自己数位从来都不是我的强项:)
@JensGustedt 你说的不是真的。十六进制文字 0x8000
已签名,就像等效文字 32768
已签名一样。你说的没有道理。仅仅因为 16 位整数的文字值等于 INT_MAX + 1
并不会改变其类型的符号。 0x8000
已签名。如果您想要无符号,则需要将文字相应地限定为0x8000U
。
@Alex,没有。十六进制值是 int
,只要该值适合 int
,对于更大的值,它是 unsigned
,然后是 long
,然后是 unsigned long
等。请参阅 C 标准的第 6.4.4.1 节。正如公认的答案所述。以上是关于C中的无符号十六进制常量?的主要内容,如果未能解决你的问题,请参考以下文章