如何将变量中的值以二进制形式打印出来


如何将变量中的值以二进制形式打印出来

先看源码:

#include <stdio.h>
#include <string.h>

const char *uint64_to_binary(int n)
{
    static char str[33];
    str[0] = '\0';

    for (unsigned i = 0xffffffff / 2 + 1; i > 0; i >>= 1) {
        strcat(str, ((n & i) == i) ? "1" : "0");
    }
    return str;
}

int main()
{
    printf("%s\n", uint64_to_binary(1));
    return 0;
}

要打印出每个位的核心思想就是一个位一个位的去比较,如何该位为 1 就记录为 “1”,如果该位为 0 就记录为 “0”,比较一次记录一次。最后输出字符串中的结果。

0xffffffff / 2 + 1 就是将内存中最高位置为 1 其他位置为 0。如果电脑是小端处理器(数据低字节保存在内存的低地址中),那么内存中存储的应该就是 10000000 00000000 00000000 00000000,每一次循环就把该数右移一位,内存上体现的就是 1 在一格一格的向右移动。假如我们要输出的数它在内存中实际存储是这个样子 00000000 00000000 00000000 11111111

第 1 次循环:
10000000 00000000 00000000 00000000 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 00000000 所以 str = “0”。

第 2 次循环:
01000000 00000000 00000000 00000000 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 00000000
所以 str = “00”

……

第 25 次循环:
00000000 00000000 00000000 10000000 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 00000000
所以 str = “0000000000000000000000001”
……

这样就把内存中每个位的值打印出来了。如果要打印的是 1 个字节的变量,就得将 0xffffffff 修改成 0xff

引申

打印变量在内存的每个位是直观了解其在内存分布的方式,其实了解一个变量在内存中是怎么存储的,有利于我们解决异构 CPU 跨字节交互数据的问题。比如一台英特尔 CPU 的电脑(小端处理器)往一个 ESP32(大端处理器)上发送一个 4 字节的整型变量。电脑将 unsigned int a = 255, 内存中的数据(0x000000ff)直接发到 ESP32 上,ESP32 收到数据后直接内存拷贝到ESP32 中的 unsigned int b 变量上,则 b 的数值就为 4278190080,这样就很有可能造成程序运行错误。特别是这种跨平台跨字节交互数据的情况应该特别小心,做个大小端转换就没事了。说的容易,但是理解数据在内存中实际的存储情况才是关键。


文章作者: Caffreyfans
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Caffreyfans !
 上一篇
memmove 实现 memmove 实现
一次关于 memmove 实现的记录有一次面试嵌入式工程师,题目中有一题为“请不使用任何函数实现 memmove 源码”,这题我没做出来。 没做出来的原因1:我没使用过 memmove 函数不知道其作用,只知道字面意思。 没做出来原因2:就
2020-12-21
下一篇 
指针与下标 指针与下标
如何可以互换地使用指针表达式与表达式,应该使用哪种更为合适?对于大多数而言下标更容易理解,尤其在多维数组中。所以在可读性方面,下标更有优势。而我本人的编程习惯也倾向于使用下标,而且还一直以为下标与指针表达式等价。直到看了《C与指针》才知道,
2020-12-20
  目录