C语言位段的应用:统计二进制的位数

位段是C语言中使用较少的一种特殊的结构体,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。

信息的存取一般以字节为单位。实际上,有时存储一个信息不必用一个或多个字节,例如,“真”或“假”用0或1表示,只需1位即可。在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占一个字节中的一个或几个二进制位,常常在一个字节中放几个信息。

怎样向一个字节中的一个或几个二进制位赋值和改变它的值呢?可以用以下两种方法:

(1)可以人为地将一个整型变量data分为几部分。

但是用这种方法给一个字节中某几位赋值太麻烦。可以位段结构体的方法。

struct packed-data
{
          unsigned a:2;
          unsigned b:6;
          unsigned c:4;
          unsigned d:4;
          int i;
}data;

其内存分配的结构如下所示

利用位段结构体,可以实现数据的统计信息。

参考题目:1的个数

题目分析,本题很显然就是要求统计输入整数的1的个数问题,当然,这题也可以使用位运算进行统计,在这里,我们使用位段进行结题。

可知,输入的数据N<=1000<2^16,所以设计16位的结构体位段

typedef struct A
{
	unsigned short a0:1;
	unsigned short a1:1;
	unsigned short a2:1;
	unsigned short a3:1;
	unsigned short a4:1;
	unsigned short a5:1;
	unsigned short a6:1;
	unsigned short a7:1; 

	unsigned short a8:1;
	unsigned short a9:1;
	unsigned short a10:1;
	unsigned short a11:1;
	unsigned short a12:1;
	unsigned short a13:1;
	unsigned short a14:1;
	unsigned short a15:1;
}DATATYPE;

为每一个位取一个名字ai 0<=i<16

接着,就想办法将整数转换到位段中去,直接赋值肯定是错的,使用每一位赋值,要求用到位运算,复杂而为容易出错,这里,我们要使用一个内存拷贝函数memcpy(void*,void*,size_t)

其实无论是结构体、数组、还是int变量,归根结底还是要在内存中连续表示,memcpy函数能实现数据得拷贝,是基于内存级别的。

参考源码:

#include <memory.h>
#include <iostream>

using namespace std;
#define  sums(b) b.a0+b.a1+b.a2+b.a3+b.a4+b.a5+b.a6+b.a7+	b.a8+b.a9+b.a10+b.a11+b.a12+b.a13+b.a14+b.a15

typedef struct A
{
	unsigned short a0:1;
	unsigned short a1:1;
	unsigned short a2:1;
	unsigned short a3:1;
	unsigned short a4:1;
	unsigned short a5:1;
	unsigned short a6:1;
	unsigned short a7:1; 

	unsigned short a8:1;
	unsigned short a9:1;
	unsigned short a10:1;
	unsigned short a11:1;
	unsigned short a12:1;
	unsigned short a13:1;
	unsigned short a14:1;
	unsigned short a15:1;
}DATATYPE;

int main(int argc ,char** argv)
{
	DATATYPE p;
	int c;
	int n;
	//scanf("%d",&n);
	cin>>n;
	while(n)
	{
		unsigned short b;
		n--;
		cin>>b;
		memcpy(&p,&b,sizeof(short));
		c=sums(p);
		cout<<c<<endl;
	}
	return 0;
}
时间: 2024-08-07 13:52:17

C语言位段的应用:统计二进制的位数的相关文章

C语言中字符串如何转换为二进制、八进制、十进制、十六进制

在C语言某个程序当中需要把文本16进制转换成对应的16进制数,比如字符串"0x1a"转换成10进制的26,可以用以下函数来实现 相关函数: atof, atoi, atol, strtod, strtoul表头文件: #include <stdlib.h>定义函数: long int strtol(const char *nptr, char **endptr, int base):函数的解释说明 这个函数会将参数nptr字符串根据参数base来转换成长整型数.参数base

获得两个整形二进制表达位数不同的数量

这是一道小米校招真题 题目描述 世界上有10种人,一种懂二进制,一种不懂.那么你知道两个int32整数m和n的二进制表达,有多少个位(bit)不同么? 输入例子: 1999 2299 输出例子: 7 1 class Solution { 2 public: 3 /** 4 * 获得两个整形二进制表达位数不同的数量 5 * 6 * @param m 整数m 7 * @param n 整数n 8 * @return 整型 9 */ 10 11 int countBitDiff(int m, int

蓝桥杯 算法训练 ALGO-151 6-2递归求二进制表示位数

算法训练 6-2递归求二进制表示位数 时间限制:10.0s   内存限制:256.0MB 问题描述 给定一个十进制整数,返回其对应的二进制数的位数.例如,输入十进制数9,其对应的二进制数是1001,因此位数是4. 样例输入 一个满足题目要求的输入范例.9 样例输出 与上面的样例输入对应的输出. 数据规模和约定 输入数据中每一个数的范围. 例:输入在int表示范围内. 题目解析: 在 Java 的 Integer 类的方法中,有将十进制数转换为二进制.八进制和十六进制的三个方法.若参数为正整数,则

统计二进制展开中数位1的个数的优化

问题: 对于任意的非负整数,统计其二进制展开中数位1的总数. 解决: 相关Blog:http://www.cnblogs.com/maples7/p/4324844.html 在看这篇之前可以先看看上述这篇,这篇主要讨论其优化问题. 常规解法: O(logn): 1 int countOnes(unsigned int n) 2 { 3 int ones = 0; 4 while (0 < n) 5 { 6 ones += (1 & n); 7 n >>= 1; 8 } 9 re

用C语言实现十进制转化为二进制

这是个很简单代码,我直接黏上去 int main(int argc, const char * argv[]) { int num = 0; int y = 0; int tow[20]; printf("请输入一个十进制的数:"); scanf("%d",&num); while (num !=0) { tow[y] = num % 2; num = num / 2; y++; } for (; y>0; y--) { printf("二进

【C语言】获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列

#include<stdio.h> int main() { int arr[32]; int m=0,i=0,count=0; printf("请输入一个十进制数:\n"); scanf("%d",&m); for(i=0;m!=0;i++)     {          arr[i]=m%2;         m=m/2;         count=i+1;     }     for(;count<32;count++) {    

【c语言】将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数

// 将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数 #include <stdio.h> // 从原数拿出最低位,放到mid中,mid左移,原数右移 int reverse(int a) { int mid = 0; int bit; int n = 31; for (; n > 0; --n) { bit = a & 1; mid |= bit; mid <<= 1; a >>= 1; } return mid; } int main

R语言第三章 统计绘图表示第二节

R语言 第2节 1. 散点图 plot(x$x1,x$x2, main="数学分析与线性代数成绩的关系", xlab="数学分析", ylab="线性代数", xlim=c(0,100), ylim=c(0,100), xaxs="i",#Setx axis style as internal yaxs="i",#Sety axis style as internal col="red"

c语言:编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果

编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果. 解:程序: #include<stdio.h> struct Person { char name[20]; int count; }leader[3] = {"li",0,"zhang",0,"yao",0}; int main() { int i, j; char leader_name[20]; for (i = 1; i <= 10; i++) { sc