提问人:Virgil G. 提问时间:7/21/2023 最后编辑:Virgil G. 更新时间:7/22/2023 访问量:94
如何在 C 中转储变量的位?[复制]
How to dump a variable's bits in C? [duplicate]
问:
我正在尝试对函数进行编码:
void memdump(void *p, size_t nmemb, size_t size);
其目的是以正确的顺序显示 所指向的变量中包含的位。不检查是否是故意的。也使用。p
p
NULL
write()
问题是我希望显示器是正确的,无论机器的长度如何。
这是我的代码:
#include <unistd.h>
#include <stdint.h>
void memdump(void *p, size_t nmemb, size_t size)
{
size_t total_bits = nmemb * size * 8;
unsigned char *ptr = (unsigned char *)p;
for (size_t i = 0; i < total_bits; i++) {
unsigned char bit = (ptr[i / 8] >> (7 - (i % 8))) & 0x01;
char c = bit ? '1' : '0';
write(STDOUT_FILENO, &c, sizeof(char));
if ((i + 1) % 8 == 0)
write(STDOUT_FILENO, " ", 1);
}
write(STDOUT_FILENO, "\n", sizeof(char));
}
int main(void)
{
int i = 0;
int j[2] = {1, 0};
char c = 'a';
char *s = "za";
uint64_t size = 213213;
memdump(&i, 1, sizeof(int));
memdump(j, 2, sizeof(int));
memdump(&c, 1, sizeof(char));
memdump(s, 2, sizeof(char));
memdump(&size, 1, sizeof(size_t));
return 0;
}
因此,我期望以下结果:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000
01100001
01111010 01100001
00000000 00000000 00000000 00000000 00000000 00000011 01000000 11011101
但我明白了:
00000000 00000000 00000000 00000000
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01100001
01111010 01100001
11011101 01000000 00000011 00000000 00000000 00000000 00000000 00000000
你可以帮我吗?
下面是一个可重现示例的链接:https://onlinegdb.com/4e5Ei2OUS
提前致谢
[更新]
我不知道如何考虑内延性,这是我的问题。 我的 memdump 函数应该具有上面指定的预期行为。
我不检查指针是否为 NULL 的原因很简单,因为这个函数是基于标准 C 库及其原理的库的一部分(即开发人员对他们的代码负责,所以将 NULL 字符串传递给 strlen(),你不会收到任何警告)。
我的函数应该按照字节插入变量示例的顺序显示字节:
int test[2] = {0 , 1};
预期结果是:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
机器的无端序并不重要。
答:
预期结果是:
1 00000000 00000000 00000000 00000001
最重要的位在左边。左边是地址最低的字节。这意味着最大(即“大”)有效位具有最低地址。所以这是大端序。阅读 https://en.wikipedia.org/wiki/Endianness 。
如何考虑内延性
应用动态规划。两个步骤:
- 您的机器有什么弹性?
- 如何将机器字节序转换为目标字节序?
- https://man7.org/linux/man-pages/man3/endian.3.html
- 如何在不使用库函数的情况下将 C 中的 big endian 转换为 little endian?
- 以及一个简单的“If machine endian == target endien then do no else convert fi”。
- 请注意,必须对每个 .我会先遍历,然后遍历字节,然后遍历位。
nmemb
nmemb
nmemb * size * 8;
考虑使用 limits.h 中的CHAR_BITS
memdump(&i, 1, sizeof(int));
请考虑使用 和 以防更改变量类型。sizeof(i)
sizeof(*j)
char *s = "za";
请注意,endianess 对 和 的顺序没有影响。 总是首先(具有最低地址),然后是 ,然后是零字节。您可以考虑选择性地应用字节变换。z
a
z
a
而且,还要注意,在 linux 和 C23 中使用最新的 glibc,我们必须打印二进制文件!耶!printf("%b", 123);
评论
NULL
memdump
nmemb
size