Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161211
  • 博文数量: 24
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 206
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-24 11:08
文章分类

全部博文(24)

文章存档

2010年(4)

2009年(20)

分类: C/C++

2009-05-18 10:15:38

大端和小端
Endian表示数据在存储器中的存放顺序。
如果将一个32位的整数0x12345678存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。

地址偏移

大端模式

小端模式

0x00

12(OP0)

78(OP3)

0x01

34(OP1)

56(OP2)

0x02

56(OP2)

34(OP1)

0x03

78(OP3)

12(OP0)


由上表所知,采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将低位存放在低地址。

有的处理器系统采用了小端方式进行数据存放,如Intel的奔腾。有的处理器系统采用了大端方式进行数据存放,如IBM半导体和Freescale的PowerPC处理器。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。CP/IP也使用big-endian方法 big-endian方法也叫做网络编码)

判断大端小端:
 
    int main()
    {            int i = 1; 
        char *p = (char *)&i; 
        if(*p==1)   
            printf("1");
        else
            printf("2");
    }

联合体
union联的存放顺序是所有成员都从低地址开始存放:
    int checkCPU( )
    {
        {
            union w{ 
                    int a;
                char b;
            }c;
            c.a = 1;
            return(c.b ==1);
        }
    }

位域

所谓“位域”是把一个字节中的二进位划分为几 个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
    1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
    例如:
    struct bs{ 
      unsigned a:4 
      unsigned :0      /*空域*/ 
      unsigned b:4     /*从下一单元开始存放*/ 
      unsigned c:4 
    } 
    在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
    2.由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
    3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。
    struct k{ 
      int a:1 
      int :2      /*该2位不能使用*/ 
      int b:3 
      int c:2 
    }; 
    从以上分析可以看出,位域在本质上就是一种结构类型,      不过其成员是按二进位分配的。
位域使用:
    main()
    {
        struct bsi{
            unsigned a:1;
            unsigned b:3;
            unsigned c:4;
        }bit,*pbit;
        bit.a=1;
        bit.b=7;
        bit.c=15;
        printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
        pbit=&bit;
        pbit->a=0;
        pbit->b &= 3;
        pbit->c |= 1;
        printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);
    }
输出:
   [davy@local Work]$ ./a.out
     1,7,15
     0,3,15

网宿的一道笔试题目
    //假设硬件平台是intel x86(little endian)
    typedef unsigned int uint32_t;
    void inet_ntoa(uint32_t in)
    {
        char b[18];
        register char *p;
        p = (char *)∈
    #define UC(b) (((int)b)&0xff)
        sprintf(b, "%d.%d.%d.%d\n", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
        printf(b);
    }
    # int main()
    {
       inet_ntoa(0x12345678);
       inet_ntoa(0x87654321);
    }

阅读(1568) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~