这两类作业(job)有什么不同?
uint16_t x = 0x002f;
uint16_t y = 47;
最终两个变量都是47,但这两个变量的位有什么不同吗?
是不是十六进制的更好,如果是,为什么?
这两类作业(job)有什么不同?
uint16_t x = 0x002f;
uint16_t y = 47;
最终两个变量都是47,但这两个变量的位有什么不同吗?
是不是十六进制的更好,如果是,为什么?
简短的答案是,在发布的代码中,两个初始化之间没有实际区别:
uint16_t x = 0x002f;
uint16_t y = 47;
右边的值是相同的,它们可以用uint16_t
类型表示,结果是x
和y
在初始化后都有相同的值.
有时,出于可读性的考虑,优先使用十六进制而不是十进制记数法是很方便的.一个典型的例子是 colored颜色 值通常被写成十六进制表示.RGB或RGBA colored颜色 值通常由无符号32位整数表示.这样的 colored颜色 可以写为0xCCDDEE
或0xCCDDEEFF
,其中CC
是红值,DD
是绿值,EE
是蓝值,以及FF
是阿尔法值.当被视为十六进制表示法而不是十进制表示法3437096703
时,更容易理解 colored颜色 的组成.一目了然地看到这个十进制数中的绿色值是221
,这是很有挑战性的.如果您想要编写用于从这样的 colored颜色 值提取 colored颜色 值的位掩码,则十六进制记法也很方便,例如,您可以使用0x00FF0000
作为位掩码,用于从0xCCDDEEFF
(或3437096703
)给出的RGBA值提取绿色值(0xDD
).并且同样地,写入位掩码0x00FF0000
比写下对应的十进制表示16711680
更容易.
尽管OP发布的代码中的初始化具有相同的效果,但这两行代码之间存在细微的差异.
47
是decimal constant,而0x002f
是hexadecimal constant.这两个都是integer constants.
对于没有后缀的小数常量,类型是int
、long int
或long long int
中可以表示常量值的第一个.
对于不带后缀的十六进制(或八进制或二进制)常量,类型是int
、unsigned int
、long int
、unsigned long int
、long long int
或unsigned long long int
中可以表示常量值的第一个.请注意,二进制整数常量是在C23中添加的;以前,一些实现支持它们(早期标准的实现不要求遵循C23中指定的二进制整数常量的类型化规则,但我怀疑它们是这样做的).
1001
实际上,这对已发送的初始化没有任何影响;重要的是,整数常量的value可以由左侧的类型表示,即在本例中为uint16_t
.如果不是这样,则C标准为无符号整型目标类型指定回绕转换,而有符号整型目标类型必须以实现定义的方式转换值,或者必须引发实现定义的信号.
整数常量可能是无符号的并不是理论上的;当无符号算术出现在意想不到的地方时,会有trap .考虑一下这个计划:
#include <stdio.h>
int main(void) {
long int x = 2147483647 - 0x80000000; // 2147483647 - 2147483648
long int y = 2147483647 - 2147483648;
printf("x = %ld\n", x);
printf("y = %ld\n", y);
}
注意,这里的行为并不是未定义的;它是由C标准很好地定义的.然而,整数转换规则可能会让粗心大意、甚至经验丰富的程序员措手不及.下面是程序在我的机器上的输出:
$ ./a.out
x = 4294967295
y = -1
由于整数常量0x80000000
和2147483648
具有相同的值,因此可以预期上述打印x
和y
的结果将是相同的.但在我的机器上,0x80000000
是unsigned int
(其中INT_MAX
是0x7FFFFFFF或2147483647,因此int
在这里不能代表0x80000000),而2147483648
是long int
.这两者都有相同的value,但不同的types.上面表达式中十进制常量2147483647
的值,在两种情况下都是int
,因为在我的机器上这个值可以用int
表示.
将常用的算术转换应用于表达式,以便在带有十六进制常量的表达式中将值2147483647的类型转换为unsigned int
.另一方面,在带有十进制常数的表达式中,值2147483647的类型被转换为long int
.
由于无符号算术的包裹性,unsigned值(2147483647-2147483648)相减得到的无符号结果是4294967295,它被赋值为x
(在我的机器上是UINT_MAX
).
但将signed值(2147483647-2147483648)相减,得到的有符号结果为-1,赋值为y
.
这个故事的寓意是,最好小心使用十六进制(或八进制,或二进制)常量.它们可以服务于清晰的目的,例如,当描述位模式或 colored颜色 代码时,但是当在表达式中使用时,它们可能是棘手的.
1 If the value of the integer constant cannot be represented by one of it's listed types, an extended integer type may be applied here if a suitable type is available. If no such type is available there is a constraint violation and the implementation must issue a diagnostic message.