C语言---求一个整数存储在内存中的二进制中1的个数--3种方法

简介: C语言---求一个整数存储在内存中的二进制中1的个数--3种方法
//编写代码实现:求一个整数存储在内存中的二进制中1的个数
//第一种写法
/*int count_bit_one(unsigned int n)
{
    int count = 0;
    while (n )//除到最后余数是0,那么这个循环就结束了
    {//这个题就是可以想成求15的二进制的过程
        //每次都除以2,余数为1的时候就count++
        if ((n % 2) == 1)//假设输入的是15
            count++;
        n = n / 2;//换下一个数继续除,直到所有的数除完
        //15/2=7  7/2=3  3/2=1  1/2=0,四次计算,每次计算的余数都为1
    }//15的二进制是1111
    return count; 
}
//对于这部分函数不理解的话可以自己画出自己一次计算的一个数的二进制的过程
 
 
int main()
{
    int num = 0;
    scanf("%d", &num);
    int ret = count_bit_one(num);
    printf("%d\n", ret);
 
 
    return 0;
}*/
但是我们输入-1,这个输出结果就有问题了
解决方法:传过去num,我们用unsigned int n来接收传过来的数,
使用 unsigned int 在这个函数中是恰当的,因为它确保了
 函数可以正确处理所有非负整数值,并且避免了有符号整数
 可能带来的问题。
 
 
 
 
//第二种算法--不考虑正负号
//-1在内存中的补码是全1
//11111111111111111111111111111111
//不关心符号的写法
 
 
//n&1==1   就说明n的二进制位的最低位是1
//n&1==0   就说明n的二进制位的最低位是0
 
//计算完这一位,想要计算下一位,那么就需要用到
//右移操作符了
//把n的二进制数的每一位都移到最低位
//00000000000000000000000000000001--1的补码
//因为&的用法是对应的二进制位,
// 有0则为0,两个同时为1才为1
//如果n的二进制数最低位和1的二进制数最低位产生反应,
//那么两个1就会场生一个1,
// 如果n的最低位数字是0,那么产生的数字仅仅是0
/*int count_bit_one(int n)
{
    int count = 0;
    for (int i = 0; i < 32; i++)
    {//有0则为0,两个同时为1才为1
        if ((n >> i) & 1 == 1)//i是从0开始的,也就是最开始的n的最低位
            //然后利用右移操作符依次变更最低位的数字
        {
            count++;//如果结果为1那么就++
        }   
    }
 
    return count;
}
 
 
int main()    
{    
    int num = 0;    
    scanf("%d", &num);  
    int ret = count_bit_one(num);   
    printf("%d\n", ret);    
 
 
    return 0;   
}    */
 
 
 
//第三种写法
//铺垫
/*
n=11   n=n&(n-1)
二进制
一开始:
n  = 1011
n-1= 1010
赋值后:   
n=n&(n-1),   &有 0就是0,两个1就是1
得到一个新的n
n  = 1010
n-1 =1001
再次用新得来的n和n-1来为新的n赋值
n=n&(n-1)
n   =    1000
n-1 =    0111
再次赋值
n=n&(n-1)
n=0000
 
 
n从最开始的1011不断赋值到0000,
n=n&(n-1)这个方程把n的二进制序列中的最右边的1去掉了
*/
 
 
//即通过反复应用 n = n & (n - 1); 直到 n 变为0,
// 每次操作清除一个1,计数器增加1,最后得到1的总数。
 
 
 
int count_bit_one(int n)
{
    int count = 0;
    int i = 0;
 
    while (n)//循环停下来的时候n就变成0了
    {
        n = n & (n - 1);//执行一次就会去掉一个1
        count++;
    }
 
    return count;
}
 
 
 
 
int main()
{
    int num = 0;
    scanf("%d", &num);
    int ret = count_bit_one(num);
    printf("%d\n", ret);
 
 
    return 0;
}    
 
 
 
每次执行 n = n & (n - 1); 都会减少 n 的二进制表示中1的个数,直到没有1剩下,此时 n 变为0,循环结束。
目录
相关文章
|
5月前
|
弹性计算 定位技术 数据中心
阿里云服务器配置选择方法:付费类型、地域及CPU内存配置全解析
阿里云服务器怎么选?2025最新指南:就近选择地域,降低延迟;长期使用选包年包月,短期灵活选按量付费;企业选2核4G5M仅199元/年,个人选2核2G3M低至99元/年,高性价比爆款推荐,轻松上云。
532 11
|
8月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
285 26
|
存储 安全 iOS开发
内存卡怎么格式化?6个格式化方法供你选
随着使用时间的增加,内存卡可能会因为数据积累、兼容性或是文件系统损坏等原因需要进行格式化。那么怎样正确格式化内存卡呢?格式化内存卡的时候需要注意什么呢?本文会给大家提供详细的步骤,帮助大家轻松完成格式化内存卡的操作。
|
8月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
396 15
|
9月前
|
存储 Windows
内存卡坏了还能修吗?4种常见修复方法
内存卡出现“无法保存”或“存储异常”等问题时,不一定是硬件损坏,可能是系统错误或文件系统异常导致。本文介绍几种亲测有效的修复方法:1) 更换读卡设备排除接触问题;2) 格式化修复文件系统(需先备份数据);3) 使用DiskGenius检测坏道;4) 借助厂商工具深度修复。同时提供日常保养建议,如避免高温环境、养成数据备份习惯,延长内存卡使用寿命。通过这些方法,多数问题可轻松解决,无需更换硬件。
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
673 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
428 6
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
566 1
|
8月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
2760 0