P4.C语言学习-数据的类型与存储

1.计算一个数的二进制表示形式下1的个数

例如:35=2^5+2+1,35的32位二进制表示为00000000 00000000 00000000 00010011      共3个1

思路:
1.1 不断%2,计算出现1的个数

设置计数器count,每次取模得到1后count++

1.2 先用二进制表示,然后转换为字符串格式,遍历查找1的个数

我们知道对十进制进行八进制、十六进制转换的时候,可以在采用打印格式"%#o"、"%#x",而二进制没有一个直接的打印格式。但是itoa函数可以实现进制转换,(还有另外一种atoi函数)可以大概了解一下:

char *itoa(int value/*要转换的数*/,char *buffer/*存放转换结果的字符串*/,int radix/*转换进制*/);
//“itoa”可以理解为“int to array”的缩写,把10进制数转换为其它进制数然后存放到字符串数组中
//同样atoi()函数中“atoi”可以理解为“array to int”的缩写,可大致了解一下

转换之后就可以对字符串进行查找,找1的个数。

1.3 移位运算,判断个位是否为1
    int count = 0, num = 126;
    for (int i = 0; num >> i; i++) {
        if ((num >> i) & 1 == 1)//将数的二进制形式位移每一位然后与1相与,判断其个位是否为1
            count++;
    }

此方法还可以求两个整数二进制不同位的个数。

1.4 与上一个数进行按位与运算

我们发现,一个数(num)与它的上一个数(num-1)进行逻辑与运算之后,总可以使该数二进制中1的个数-1,例如1001 0000(160)&100001111(159)的结果为1000 0000,可以发现,进行一次运算后1001 0000中1的个数少了一个,再进行一次1000 0000&0111 1111=0000 0000,1的个数又少了一个,因此我们只需要统计与操作进行了多少次,就能得出有多少个1了

count=0;
while(num) {
    num = num & (num - 1);
    count++;
}

因为相邻两个数的高位往往相等,与的结果不变。我们只用判断低位,低位大概有这些情况(x...x表示有若干个二进制位的二进制数)

         x...x1&x...x0=x...x0,少了一个1

         x...x10...0&x...x01...1=x...x00...0,少了一个1

2.验证当前系统存储数据是采用大端存储还是小端存储

2.1 大小端存储的概念

我们知道,数据是以字节为单位存取的,而存储一个int类型的整数需要四个字节。在内存中如何存储这四个字节呢?通常有两种方式,即大端存储小端存储

在大端存储中,高位字节存储在低位地址,而低位字节存储在高位地址。在小端存储中,低位字节存储在低位地址,而高位字节存储在高位地址

 当我们在VS的x86平台下中定义了一个int类型的变量x并赋值时,调试查看内存,输入取x的地址,如图:

左侧0x00B9FEA4是x的首地址(虚拟地址),而右侧是该地址下(连续四个地址)存储的四个字节的数据值,为3。而整形3用16进制显示为00 00 00 03(实际是用2进制存储,四个字节即32位二进制序列),可以发现,系统采用的是小端存储。

那么如何不查看内存,通过程序验证是小端存储呢?

2.2 通过程序验证小端存储

在这个例子中,小端存储有效数值在第一个字节,而大端存储有效数值在最后一个字节。因此我们可以只改第一个字节的内容,比如改成1,然后输出x,判断x是否改为了1。如果x为1则采用的是小端存储,否则十六进制序列为01 00 00 03,此时x是一个比较大的数,为大端存储。

由上图可以看到x被改为了1,说明x是按照小端方式来存储的。应当注意的是,(char)x=1是指将1赋值给“将x强制类型转换为char类型的变量”,x自身还是int类型;我们可以用256来验证:

        256的32位二进制序列为00000000 00000000 00000001 00000000,其小端存储16进制表现样式为00 01 00 00,执行(char)x=1后该序列变为01 01 00 00,数值为257。如果x变成了char类型,那么x只占1个字节,即第一个字节,值为1,而由输出结果可以看出x并未变为char类型。

事实上,无论是64位系统还是32位系统,大多数计算机架构都采用小端存储(Little-endian)。然而,某些特定的计算机架构可能采用大端存储(Big-endian)。例如,某些RISC体系结构中,如MIPS和PowerPC,支持可配置的字节序,可以选择使用大端或小端存储。

拓展

除了上述方法,我们还可以利用联合体的特性来判断,也是同样的方法。(插入链接)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值