您的位置:首页 > 其它

按位存储

2015-08-08 15:13 281 查看
在编程中遇到处理位的运算时,一般用结构体定义位长度;比如在发送邮件程序中,数据必须由24位(3个字节)转化为4个字节(每个字节6位),这样才能被邮件服务器识别。

需要注意的是:

(1)数据在计算机中存储方式,比如:

数值: 0x99

存储:1001 1001

但是位段在内存中的存储是从右向左,看下面例程:

#include <stdio.h>
#include <stdlib.h>

union share
{
char val;
struct STR1
{
unsigned a : 3;
unsigned b : 2;
unsigned c : 3;
}str1;
struct STR2
{
unsigned b1 : 5;
unsigned b2 : 2;
}str2;
};

//0x99
// 1001 1001
int main(void)
{
union share m_struct;
m_struct.val = 0x99;   // 1001 1001
printf("sec1: %d\n", m_struct.str1.a);   //001
printf("sec2: %d\n", m_struct.str1.b);   //11
printf("sec3: %d\n", m_struct.str1.c);   //100

printf("b1: %d\n", m_struct.str2.b1);   //11001
printf("b2: %d\n", m_struct.str2.b2);   /00
}
程序运行结果:

sec1: 1
sec2: 3
sec3: 4
b1: 25
b2: 0


邮件发送代码的转换如下:

typedef struct Base64Cov
{
unsigned int sect1 : 6;
unsigned int sect2 : 6;
unsigned int sect3 : 6;
unsigned int sect4 : 6;
}BASE64COV_S;

int main(void)
{
int a = 0x030201; //10;

BASE64COV_S* pst;
pst = (BASE64COV_S*)&a;
//  0000 0011  0000 0010  0000 0001
printf("%d\n", pst -> sect1);
printf("%d\n", pst -> sect2);
printf("%d\n", pst -> sect3);
printf("%d\n", pst -> sect4);

}


结果:

1
8
48
0


(2)《C和指针》指出:

注重可移植性的程序应该避免使用位段。由于下面这些与实现有关的依赖性、位段在不同的系统中可能有不同的结果。

1、int位段被当作有符号数还是无符号数。

2、位段中位的最大数目。许多编译器把位段成员的长度限制在一个整形值的长度之内,所以一个能够运行于32位整数的机器上的位段声明可能在16位整数的机器上无法运行。(注:现在也有64位机器)

3、位段中的成员在内存中是从左向右分配的还是从右向左分配的。

4、当一个声明指定了两个位段,第2个位段比较大,无法容纳于第1个位段剩余的位时,编译器有可能把第2个位段放在内存的下一个字,也可能直接放在第1个位段后面,从而在两个内存位置的边界上形成重叠。

由上面的论述可见,位段在内存中的表示没有统一的标准,各家编译器厂商实现的方式可能不一样。注意内存大小端表示的不同
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: