c++ - 将 long 转换为 int 与使用按位 AND 以获得 4 个最低有效字节之间有什么区别?
问题描述
我知道,为了获得多种类型的 4 个最低有效字节,long
我可以将其转换为int
/unsigned int
或使用按位 AND ( & 0xFFFFFFFF
)。
此代码产生以下输出:
#include <stdio.h>
int main()
{
long n = 0x8899AABBCCDDEEFF;
printf("0x%016lX\n", n);
printf("0x%016X\n", (int)n);
printf("0x%016X\n", (unsigned int)n);
printf("0x%016lX\n", n & 0xFFFFFFFF);
}
输出:
0x8899AABBCCDDEEFF
0x00000000CCDDEEFF
0x00000000CCDDEEFF
0x00000000CCDDEEFF
这是否意味着使用的两种方法是等效的?如果是这样,无论平台/编译器如何,它们是否总是产生相同的输出?
此外,在投射到unsigned int
而不是int
为了这个问题的目的时是否有任何捕获或陷阱?最后,如果将数字改为 an
,为什么输出相同?n
unsigned long
解决方案
将 long 转换为 int 与使用按位 AND 以获得 4 个最低有效字节之间有什么区别?
类型。强制转换使值成为int
. And'ing 不改变类型。
范围。根据int,long
范围,强制转换可能根本不会改变值。
美洲开发银行和 UB。实现定义的行为和未定义的行为以混合符号存在。
要“获取” 4 个 LSByte,请使用& 0xFFFFFFFFu
或强制转换为uint32_t
.
OP的问题不必要地令人费解。
long n = 0x8899AABBCCDDEEFF;
--> 转换有符号整数类型范围之外的值是实现定义的。
否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。
C11 §6.3.1.3 3
printf("0x%016lX\n", n);
long
-->使用"%lX"
超出常见范围的a打印 along/unsigned long
是未定义的行为。
让我们继续unsigned long
:
unsigned long n = 0x8899AABBCCDDEEFF; // no problem,
printf("0x%016lX\n", n); // no problem,
printf("0x%016X\n", (int)n); // problem, C11 6.3.1.3 3
printf("0x%016X\n", (unsigned int)n); // no problem,
printf("0x%016lX\n", n & 0xFFFFFFFF); // no problem,
“没问题”即使是unsigned long
32 位或 64 位也可以。输出会有所不同,但还可以。
回想一下,int,long
并不总是 32,64 位。(16,32), (32,32), (32,64) 很常见。
int
至少为16位。至少
long
是32位的。int
推荐阅读
- r - 将可旋转输出导出为图像
- ios - Int 的默认大小可以改变吗?
- javascript - 异步函数阻止事件循环 - 调用 app.get 方法时不呈现页面
- python-3.x - 如何在 OS X Catalina 上使用 cron 调度 python 脚本
- spartacus-storefront - 刷新令牌功能
- iphone - 如何在 Flutter 中为 iOS 的 CupertinoPicker/CupertinoDatePicker 添加/启用自动收报机声音?
- c++ - 使用 std::function 映射对象方法
- python - Python没有将正确的内容写入csv
- javascript - 如何将返回数据中的值传递给 vue.js 中的另一个脚本 [mounted()]
- python - 添加和删除 QTreeWidgetItems 的复选框