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

如果您希望它不签名,请在数字末尾添加u0x23FEu

【讨论】:

这个答案似乎与 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 > 0x7000int 进行比较,否则0x8000unsigned0x7000 提升为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中的无符号十六进制常量?的主要内容,如果未能解决你的问题,请参考以下文章

C中的无符号字符连接

C ++十六进制字符串到无符号整数[重复]

C基础数据类型进制运算符语句

将 Long/ULong 转换为带有填充零的无符号十六进制字符串

C基础数据类型进制运算符语句

c 语言常量