c - 在 C 中打印整数的实际位表示
问题描述
我想在 C 中打印整数的实际位表示。这是我发现的两种方法。
第一的:
union int_char {
int val;
unsigned char c[sizeof(int)];
} data;
data.val = n1;
// printf("Integer: %p\nFirst char: %p\nLast char: %p\n", &data.f, &data.c[0], &data.c[sizeof(int)-1]);
for(int i = 0; i < sizeof(int); i++)
printf("%.2x", data.c[i]);
printf("\n");
第二:
for(int i = 0; i < 8*sizeof(int); i++) {
int j = 8 * sizeof(int) - 1 - i;
printf("%d", (val >> j) & 1);
}
printf("\n");
对于第二种方法,输出是00000002
和02000000
。我还尝试了其他数字,似乎字节在两者中交换了。哪一个是正确的?
解决方案
欢迎来到异国情调的字节序世界。
因为我们先写数字的最高有效位,您可能会想象最高有效字节存储在较低地址。
制造计算机的电气工程师更有想象力。
有时他们首先存储最重要的字节,但在您的平台上它是最不重要的。
甚至有些平台有些混乱——但在实践中你很少会遇到这些。
所以我们大部分时间都在谈论大端和小端。这是一个关于格列佛游记的笑话,其中有一场关于煮鸡蛋从哪一端开始的毫无意义的战争。这本身就是对基督教会一些争论的讽刺。但我离题了。
因为您的第一个片段将值视为它遇到的一系列字节,然后按字节序排列。
但是因为它>>
被定义为对位进行操作,所以它被实现为“逻辑地”工作,而不考虑实现。
C 不定义字节顺序是正确的,因为不支持 C 选择的模型的硬件将背负无休止且毫无意义地移动字节的开销。
遗憾的是,没有内置标识符告诉您模型是什么——尽管可以找到确实的代码。
如果(a)如上所述,您希望将整数类型分解为字节并对其进行操作,或者(b)您接收包含多字节结构的其他平台的文件,那么它将与您相关。
Unicode 在 UTF-16 和 UTF-32 中提供了一种称为 BOM(字节顺序标记)的东西。事实上,使用 UTF-8 的一个很好的理由(其中很多)是问题消失了。因为每个组件都是一个字节。
脚注: 在评论中已经相当公平地指出我没有讲述整个故事。C 语言规范允许整数的一种以上表示,特别是有符号整数。具体来说,有符号幅度、二进制补码和二进制补码。
它还允许不代表值的一部分的“填充位”。
因此,原则上,除了解决字节序问题,我们还需要考虑表示。
原则上。所有现代计算机都使用二进制补码,而使用其他任何东西的现存机器非常罕见,除非您真正需要支持此类平台,否则我建议您假设您使用的是二进制补码系统。
推荐阅读
- r - 无法在 R 中打开 chrome 浏览器
- java - 为什么方法在声明之前在 Java 中可用?
- ruby-on-rails - froala rails 和图像上传到亚马逊 - 未定义的 url
- python - 为什么在 Django 视图中无法捕获异常以及如何调试
- php - PHP 选择下拉选项值数组
- laravel - laravel sendgrid 驱动程序中出现 cURL 错误 18 错误
- php - 将随机 URL 链接添加到随机背景图像
- javascript - 如何找到使用 Google Chrome 调试器调用 javascript 的位置?
- ios - 从多个视图控制器调用相同 API 的最佳方法是什么
- opengl-es - 需要一个关于鲁棒缓冲区访问何时有效的具体示例