按位存储

在编程中遇到处理位的运算时,一般用结构体定义位长度;比如在发送邮件程序中,数据必须由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个位段后面,从而在两个内存位置的边界上形成重叠。

由上面的论述可见,位段在内存中的表示没有统一的标准,各家编译器厂商实现的方式可能不一样。 注意内存大小端表示的不同





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值