字节序,字节内部顺序,位域,

940阅读 0评论2015-07-20 ggq1992
分类:C/C++

    关于字节序:是字节之间的事情,多字节数据类型,字节的排序问题,类似于在十进制数中,十位放在个位的左边还是右边的问题。例如int类型有4个字节,值为0x12345678,地址为0x000010~0x000013,那么在0x000010是存放0x12还是存放0x78.分下面两种情况:
    1)低地址放低位(小端字节序,小端即低位在前)。实际存储为0x78 56 34 12.  使用这种字节序的典型为x86机器,即intel和amd的cpu。
    2)低地址放高位(大端字节序)。实际存储为0x12 34 56 78. 其余的厂家一般使用这种字节序。sun,ibm等等。另外网络字节序也是这种,二进制文件如音视频文件中一般也为大端。
    在字节内部,一个字节的二进制排序,不存在大小端问题。就和平常书写的一样,先写高位,即低地址存储高位。如char a=0x12.存储从低位到高位就为0001 0010。
    字节内部二进制排序的特殊情况,字节被位域分割的话,不同位域会根据cpu的不同采用不同排序(大端或小端)。或者说一个字节内两个或多个位域的排练顺序:从左至右还是从右至左。
    例如,在流媒体协议rtp的头部格式为:版本(2bit),填充(1bit),扩展(1bit),csrc计数(4bit),标志(1bit),负载类型(7bit),序列号(16bit),时间戳(32bit)。在intel的机器中,定义头部类型时,应该如下:(intel为小端字节序,而网络流为大端字节序,相反
     
  1. typedef struct
  2. {
  3.     /**//* byte 0 此处,注意顺序与规定相反,在存储的时候,这个字节内部由低位到高位为version,padding,extension,csrc_len*/
  4.     uint8_t csrc_len:4;
  5.     uint8_t extension:1;
  6.     uint8_t padding:1;
  7.     uint8_t version:2;
  8.     /**//* byte 1 */
  9.     uint8_t payload:7;
  10.     uint8_t marker:1;
  11.     /**//* bytes 2, 3 */
  12.     uint16_t seq_no;
  13.     /**//* bytes 4-7 */
  14.     uint32_t timestamp;
  15.     /**//* bytes 8-11 */
  16.     uint32_t ssrc; /**//* stream number is used here. */
  17. } RTP_FIXED_HEADER;
    另外,上图,位域的顺序的说明,只在一个字节内有效。如果跨越字节,则按照声明的顺序分配。
    例2,程序如下:
  1. #include <stdio.h>
  2. int main()
  3. {
  4. struct bitfield {
  5. int ia:2;
  6. int ib:6;
  7. } field;
  8. field.ia=1;
  9. field.ib=4;

  10. char * c;
  11. c=(char *)&field;
  12. printf("%d\n",*c);
  13. getchar();
  14. return 1;
  15. }

在X86上运行结果是17(000100 01),而不是68(01 000100)
上一篇:SPI 的时钟配置
下一篇:IO端口 IO内存 IO映射方式 内存映射方式 (转载)