c - 在 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");

对于第二种方法,输出为 0000000202000000。我还尝试了其他数字,似乎字节在两者中交换了。哪一个是正确的?

最佳答案

欢迎来到充满异国情调的字节序世界。

因为我们首先写入数字的最高有效位,所以您可能会认为最高有效字节存储在较低地址。

制造计算机的电气工程师更有想象力。

有时他们首先存储最高有效字节,但在您的平台上它是最不重要的。

甚至有些平台有点困惑 - 但您在实践中很少遇到。

所以我们大部分时间都在谈论大端和小端。这是关于格列佛游记的一个笑话,其中有一场关于从煮鸡蛋的哪一端开始的毫无意义的 war 。这本身就是对基督教会中一些争论的讽刺。但我离题了。

因为您的第一个代码段将值视为它遇到的一系列字节,然后按字节顺序排列。

但是因为 >>> 被定义为对位进行操作,所以它被实现为“逻辑上”工作,而不考虑实现。

C 不定义字节顺序是正确的,因为不支持 C 选择的模型的硬件将承受无休止和毫无意义的改组字节的开销。

遗憾的是,没有内置标识符告诉您模型是什么 - 尽管可以找到可以找到的代码。

如果 (a) 如上所述,您希望将整数类型分解为字节并对其进行操作,或者 (b) 您收到包含多字节结构的其他平台的文件,这将与您相关。

Unicode 在 UTF-16 和 UTF-32 中提供了一种称为 BOM(字节顺序标记)的东西。 事实上,使用 UTF-8 的一个很好的理由(在许多理由中)就是问题消失了。因为每个组件都是一个字节。

脚注: 评论中已经相当公正地指出我没有讲完整个故事。 C 语言规范接受不止一种整数表示,特别是有符号整数。特别是符号大小、二进制补码和个数补码。

它还允许不代表值的一部分的“填充位”。

因此原则上,除了解决字节顺序问题,我们还需要考虑表示。

原则上。所有现代计算机都使用二进制补码,而使用其他任何东西的现存计算机非常罕见,除非您确实需要支持此类平台,否则我建议您假设您使用的是二进制补码系统。

关于c - 在 C 中打印整数的实际位表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51517322/

相关文章:

将包含二进制表示的字符串转换为数字 - C

c - 寻找变量

c - 通过scanf读取c中的两个数组时,第二个以某种方式修改了第一个

c - 使用 C API (Windows) 注册 Linphone 和调用电话

c - 在 LCD 上显示 float

c - 如何用Matlab或C控制鼠标指针?

c - 在 c 中使用 scandir() 按升序打印目录

c++ - 从守护进程中的 exec()'ed 进程读取 stdout/stderr

c - 在不使用 libpcap 的情况下在 Linux 中嗅探数据包

c - 在C二叉树中插入函数?