C++ 转二进制时发现一个很有趣的现象

原代码 :

int main() {
    int i = 0;
    char j;
    string bin;
    cout << int(aaa) << endl;
    cin >> i;
    for (int x = BIT; x >= 0; x--) {
        j = (i >> x) & 1;
        bin = bin + j;//存到字符串里面
    }
    for (int n = 0; n < bin.size(); n++) {
        if (n % 4 != 0 || n == 0) {
            cout << (int)bin[n];
        }
        else
            cout << " " << (int)bin[n];
    }
}

转化原理:

由于c++内是无法直接输出数的二进制的,所以得我们自己来操作。

思路是将目标数移位与1进行&操作,来获取各个位的0,1的值然后一一输出。

比如:

bin(8)= 0000 1000 //8的二进制 bin(1)= 0000 0001

8 >> 7 = 0000 0000 &0000 0001 = 0 //将8的二进制右移7位

8 >> 6 = 0000 0000 0

8 >> 5 = 0000 0000 0

8 >> 4 = 0000 0000 0

8 >> 3 = 0000 0001 &0000 0001 = 1

8 >> 2 = 0000 0000 0

8 >> 1 = 0000 0000 0

8 >> 0 = 0000 0000 0

将他们的值一一与1(0000 0001)进行&操作 一一输出可以得出8的二进制0000 1000

输出:(ps:可以把BIT改值来支持更高位)

调试:(输入为8)

可以发现bin里面存储的都是'\0'与'\x1'!

如果我们不强制转换(int)bin[]的话会造成同下面一样结果。(右边的窗口)

所以我们将其强制转换为int后输出才得到我们想要答案。

为什么不转换会是这个结果?

大家有注意到这个语句吗?

j = (i >> x) & 1;

我们可以看到前面的定义j是char型 而i是int型的。我们这样其实就是在强制转换了。

什么是强制转化?

众所周知int型在内存中占4个字节,而char型为1个字节。那么我们强制转换系统要去掉高位的3个字节。

比如进行下列操作

int x=255;

char y=(char)x;

cout << int(y) ;

输出为-1 (255-256)

char型数据的范围是-128~127(256),你可以把他想象成一个圆盘,最上面是0,向右+1,向左-1,最下面是127和-128相邻。当你将一个大于127的正数转换时,可以理解成从零出发绕圈,最终结果就是停留的格子。

同样的如果x为512的话那么会被转化为0。

但在这里我们发现我还是使用了cout << int(y) 才能输出。

我想知道的是为什么一定得 (int)y 才能输出呢?

我发现0与1被转化为了'\0'与'\x1'。

而‘/0’是字符常量,0是整型常量。其中字符常量也可以用转义序列来表示。

什么是转义序列?

在C++里面有两类字符不能直接使用,转义序列泛化转义序列

转义序列为\r \n \t \b等之类的(大家可以自己查查)

而我们的问题出现在这其中的泛化的转义序列。

泛化的转义序列的形式有两种:

1.\后紧跟3个八进制数(最多只能3个,超过的算其他字符):

如\12表示换行符,\40表示空格,\124表示大T,\1243则表示T3。

2.\x后面紧跟着1个或多个十六进制数:

如\xa表示换行符,\x20表示空格,\x54表示大T,由于字符只占8位,所以最多只能有两个16进制位,多了会报错。

结论

原来在j = (i >> x) & 1;这个语句中,我们的结果被转化为了'\0' '\x1'这样转义序列,使得我们的输出出现了问题,所以我们需要再次强制转化为int型才能输出我们想要的答案!

如有错误欢迎大家指出,互相学习会让我们一起成长!

部分资料参考来自
https://blog.csdn.net/qq_50351157/article/details/110499630
(C语言:int型数据向char型数据的强制类型转换原理)
https://blog.csdn.net/weixin_43744293/article/details/116520817
(C++中的转义序列(\r \n \t \b)和泛化转义序列)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值