研究 数据的 逻辑结构、(物理)存储结构 及 其算法。
线性关系(严格的一对一关系)
HEX表示十六进制 DEC表示十进制 OCT表示八进制 BIN表示二进制
练习:给定一个int数据,求出其二进制中的1的位数
#include <stdio.h>
int count_1(int num);
int nums_1(int num);
int main(void)
{
int n;
scanf("%d",&n);
printf("count = %d\n" , nums_1(n));
return 0;
}
输入:一个整数 num,其范围假设在0到15之间
功能:根据给定的num,从预定义数组count中返回对应的计数值
当输入为0时,返回0;输入为1时,返回1;输入为2时;输入为3时,返回2,以此类推。
int nums_1(int num)
{
int count[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
return count[num];
}
用switch语句列出所有可能的16位二进制数
int count_1(int num)
int count;
switch (num)
{
case 0x0:
count = 0;
break;
case 0x1:
case 0x2:
case 0x4:
case 0x8:
case 0x10:
case 0x20:
case 0x40:
case 0x80:
case 0x100:
case 0x200:
case 0x400:
case 0x800:
case 0x1000:
case 0x2000:
case 0x4000:
case 0x8000:
count = 1;
break;
case 0x3:
case 0x6:
case 0xc:
case 0x18:
case 0x30:
case 0x60:
case 0xc0:
case 0x180:
case 0x300:
case 0x600:
case 0xc00:
case 0x1800:
case 0x3000:
case 0x6000:
case 0xc000:
count = 2;
break;
case 0x7:
case 0xe:
case 0x1c:
case 0x38:
case 0x70:
case 0xe0:
case 0x1c0:
case 0x380:
case 0x700:
case 0xe00:
case 0x1c00:
case 0x3800:
case 0x7000:
case 0xe000:
count = 3;
break;
}
return count;
}
horse think 编程的华点在 n & 0b1111
& | 与 | 都为1时,才为1 |
| | 或 | 都为0时,才为0 |
^ | 异或 | 相同为0,相异为1 |
~ | 取反 | 0变1,1变0 |
定义一个大小为16的整形数组table,其初始化内容对应了0至15(二进制表示范围0000至1111)这16个数字中包含1的个数。
例,table[0] = 0 二进制0没有1;table[1] = 1 二进制1有一个1;table[3] = 2 二进制11有两个1。
初始化一个变量count为0,用于累加num二进制表示中1的数量。使用循环结构(虽然这里以连续四行代码的形式呈现),将num与掩码0b1111进行按位与(&)运算。这个操作会提取num的最低四位。然后通过table数组查询这四位中1的个数,并加到count上。
num & 0b1111:获取num的最低4位。num = num >> 4:将num右移4位,这样下一次迭代可以处理接下来的4位。重复四次,分别处理num的最低16位(即两个字节)。对于更大的num,超过16位的部分不会被计算在内。在所有迭代完成后,count中存储的就是num低16位中1的总个数。如果输入的num是一个16位或更小的整数,那么该函数能正确统计出所有位中的1的个数。对于32位或更大整数,只统计低16位中的1的数量。
例如10 Bin:1010 1010 & 1111 为 1010(会转换为DEC??? vscode 输出为 2 )
6 :1111 1111 & 1111 为 1111
table[num & 0b1111]= 2
至于循环四次:比如 17(0001 0111)挨个计数 四位记录一次