用C语言写一个函数返回参数二进制中1的个数


首先,给出正确的C语言代码如下:

#include <stdio.h>

int count_one_bits(unsigned int value)

{

int count =0;

while(value)

{

if(value%2==1)

{

count++;

}

value=value/2;

}

return count;

}

int main()

{

unsigned int num=0;

int ret=0;

scanf("%d",&num);

ret=count_one_bits(num);

printf("count=%d\n",ret);

return 0;

}

运行结果如下图:

但是,当将函数里面的参数里的unsigned以及主函数里的unsigned去掉的时候,运行的结果变成了这样:

为什么会产生这样的结果呢?

先说说unsigned。unsigned是修饰int、char的类型说明符。表示被修饰的数据类型是一个无符号数,即最高位不表示符号位。整型的每一种都有无符号(unsigned)和有符号(signed)两种类型(float和double总是带符号的),在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned。无符号版本和有符号版本的区别就是无符号类型能保存2倍于有符号类型的数据,比如16位系统中一个int能存储的数据的范围为-32768~32767,而unsigned能存储的数据范围则是0~65535。

以上面的-1为例。如果去掉unsigned,说明需要考虑其符号位(0正1负)。因为负数在计算机中存储以补码存储。有符号的整形(整形)在计算机中占据4个字节(32位)存储空间。-1的补码为:1111 1111 1111 1111 1111 1111 1111 1111.最高位的1表示符号位。之所以最后count值为0,是因为没有执行“count++;”语句。

为什么会没有执行“count++;”语句呢?接下来,看一段代码及其运行结果:

通过上面的程序运行结果即就是说-1除以2取余得到仍是-1。结合上面给出的正确代码里面的函数部分,只有执行if(value%2==1)成立时,才会给count自加。而现在(以-1为例),表达式的左边为-1,右边为1,左右永远都不会相等,自然count不会自加,进而,最后输出的count为0。

怎么在不加unsigned的情况下,还能使得程序运行正确呢?

因为-1的补码含有32个1,我们巧妙的发现它“与”上1的二进制结果竟为1。所以,将代码改为如下:

#include <stdio.h>

int count_one_bits(int value)

{

int count =0;

int i=32;

while(i)

{

if(value&1==1)

{

count++;

}

value=value>>1;//每算完一位,左移,算下一位

i--;

}

return count;

}

int main()

{

int num=0;

int ret=0;

scanf("%d",&num);

ret=count_one_bits(num);

printf("count=%d\n",ret);

return 0;

}

编译执行程序,得到运行结果为:

第一篇博客,难免语言上有表达不到位的地方,望大家原谅。同时,欢迎批评指正。。谢谢。

时间: 2024-08-03 14:25:24

用C语言写一个函数返回参数二进制中1的个数的相关文章

写一个函数返回参数二进制中1的个数

分析: (1)输入一个数 (2)判断它是否为0. (3)如果不为0,就对它进行模2取余,模2的过程就相当于把这个数向右移除了一位,如果余数为1,则证明移除的这一位为1,就将其记录下来.如果余数为0,就证明移除的这一位为0,就不记录. (4)经过第3步以后,对这个数进行除2取整,再进入到第2步中.如此循环,直到第3步中判断为0. 注意: (1)对于负数,在内存中是以其补码形式存放的.例如-1,它的二进制中有32个1. (2)以下方法中对于函数形参的定义方式有两种,一种是无符号整型,一种是有符号整型

用一个函数返回参数二进制中1的个数

//题目:写一个函数返回参数二进制中的1的个数 //      比如:15    0000 1111  4个1 //     程序原型:  int count_one_bit(unsigned int value) //                {  //                        //返回1的个数 //                 }     #include<stdio.h> #include<stdlib.h> int count_one_bit

写一个函数返回参数二进制中 1 的个数

#include<stdio.h>int main(){   int num; int s=0,ys=0,count=0;  printf("请输入一个数字:");    scanf("%d",&num);     for(s=num;s>=1;)     {     ys=s%2;         s=s/2;         if (ys==1)      {    count++;         }     }    printf(

写一个函数返回参数二进制中 1 的个数 比如: 15 &nbsp; &nbsp; 0000 1111 &nbsp; &nbsp; 4 个 1

方法一: 程序: #include<stdio.h> int  count_one_bits(int t) { int i = 32; int count = 0; while (i>0) { if (t & 1 == 1) { count++; } //t=t/2 t = t >> 1; i -= 1; } return count; } int main() { int t = 0; printf("请输入一个整数:"); scanf(&quo

写一个函数返回参数二进制中 1 的个数(三种方法)

1.运用了除法,取余方式递推出结构2.运用右移符(>>)运算3.利用算术与(&)运算 三种方法效率越来越高,减少成本 #include<stdio.h> int Number1(int n) { int k; int count=0; while (n > 0) { k = n % 2; n /= 2; if (1 == k) { count++; } } return count; } int Number2(int n) { int count = 0; whil

说一说,求一个正整数的二进制中0的个数

昨天突然看到一个算法题:一个正整数a的二进制中0的个数: 话说这是个老题了,直观的算法就每次右移一位,直到0为止:代码就省略了: 仔细想想有更好的方案么? 就是这个题可以转换成一个正整数~a的二进制中1的个数: 求1的个数这个貌似就很熟悉了吧: int num = 0; b = ~a; while(b){ num++; b = b & (b-1); } 是不是容易了许多呢 另外像java和python这种没有unsigned的语言要自己去转 b = ~a & 0x0ffff

求一个整数的二进制中1的个数

题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 假设该整数为i.首先i和1做与运算,判断i的最低位是不是为1.接着把1左移一位得到2,再和i做与运算,就能判断i的次高位是不是1……这样反复左移,每次都能判断i的其中一位是不是1.基于此,我们得到如下代码 int NumberOf1_Solution(int i) { int count = 0; unsigned int flag = 1; while(flag) { if(

【C语言】统计一个数二进制中1的个数

//统计一个数二进制中1的个数 #include <stdio.h> int count_one(int num) { int count = 0; while (num) { count++; num = num&(num - 1); //每次消去最后面的一个1,直至没有 } return count; } int main() { printf("%d\n", count_one(12)); printf("%d\n", count_one(

ACM:每行输入一个正整数n,找出与它对应的比它大的最小的且它们对应的二进制中1的个数一样多的正整数.

#include<stdio.h> //每行输入一个正整数i,找出与他对应的比它大的最小的正整数且他们的二进制中1的个数一样多. /* 样例输入: 样例输出: 1 2 2 4 3 5 4 8 78 83 0 */ //78的二进制位1001110,有4个1:83比78大且83的二进制位1001011也是4个1. int main() { int count1,count2;//count1统计原数据对应的二进制中1的个数,count2... int a[100];//存输入的数字 int i=