这两类作业(job)有什么不同?

uint16_t x = 0x002f;
uint16_t y = 47;

最终两个变量都是47,但这两个变量的位有什么不同吗?

是不是十六进制的更好,如果是,为什么?

推荐答案

简短的答案是,在发布的代码中,两个初始化之间没有实际区别:

uint16_t x = 0x002f;
uint16_t y = 47;

右边的值是相同的,它们可以用uint16_t类型表示,结果是xy在初始化后都有相同的值.

有时,出于可读性的考虑,优先使用十六进制而不是十进制记数法是很方便的.一个典型的例子是 colored颜色 值通常被写成十六进制表示.RGB或RGBA colored颜色 值通常由无符号32位整数表示.这样的 colored颜色 可以写为0xCCDDEE0xCCDDEEFF,其中CC是红值,DD是绿值,EE是蓝值,以及FF是阿尔法值.当被视为十六进制表示法而不是十进制表示法3437096703时,更容易理解 colored颜色 的组成.一目了然地看到这个十进制数中的绿色值是221,这是很有挑战性的.如果您想要编写用于从这样的 colored颜色 值提取 colored颜色 值的位掩码,则十六进制记法也很方便,例如,您可以使用0x00FF0000作为位掩码,用于从0xCCDDEEFF(或3437096703)给出的RGBA值提取绿色值(0xDD).并且同样地,写入位掩码0x00FF0000比写下对应的十进制表示16711680更容易.

尽管OP发布的代码中的初始化具有相同的效果,但这两行代码之间存在细微的差异.

整数常量的类型是什么?

47decimal constant,而0x002fhexadecimal constant.这两个都是integer constants.

对于没有后缀的小数常量,类型是intlong intlong long int中可以表示常量值的第一个.

对于不带后缀的十六进制(或八进制或二进制)常量,类型是intunsigned intlong intunsigned long intlong long intunsigned 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

由于整数常量0x800000002147483648具有相同的值,因此可以预期上述打印xy的结果将是相同的.但在我的机器上,0x80000000unsigned int(其中INT_MAX是0x7FFFFFFF或2147483647,因此int在这里不能代表0x80000000),而2147483648long 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.

C++相关问答推荐

使用sd-设备列举设备导致seg错误

来自stdarg.h的c中的va_args无法正常工作<>

如何解决C中的严格别名?

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

如何调试LD_PRELOAD库中的构造函数?

如果dim指定数组中的数据量,使用dim-1会不会潜在地导致丢失一个元素?

1处的解析器错误:yacc语法的语法错误

S在本文中的价值观到底出了什么问题?

指向不同类型的指针是否与公共初始序列规则匹配?

使用ld将目标文件链接到C标准库

Fprintf正在写入多个 struct 成员,并且数据过剩

条件跳转或移动取决于未初始化值(S)/未初始化值由堆分配创建(Realloc)

从整型转换为浮点型可能会改变其值.

在下面的C程序中,.Ap0是如何解释的?

如何在C中处理流水线中的a、n命令?

Linux memcpy 限制关键字语法

在 C 中传递参数时出现整数溢出

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

在带中断的循环缓冲区中使用 易失性

strided memcpy(3) 在 libvpx 中如何工作