码迷,mamicode.com
首页 > 其他好文 > 详细

C 学习之大小端

时间:2016-07-08 23:24:24      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:

题外话:如有误,请留言通知我。

 

大小端,是数值在内存中的排列方式:数值的高低位与内存地址的大小 的关系。

大/小端,英文Big/Little Endian。

注意:endian,就是字节序、字节存储顺序的意思,也有尾数的意思。这里取尾数的含义刚刚好,原因如下。

 

先说一个前提:内存地址的前xx位通常是系统保留区,用于运行内核程序。所以用户程序就从另一端开始占用 --- 这就是为什么用户程序是从高位地址开始往低位地址伸展。(另一种可能本文不考虑

在上面的前提下,我们已知int类型的长度是4 bytes,就是说它需要占用4 bytes的内存空间。

那么,它是如何占用的呢?

以 int i = 0x12345678; (见附注)为例说明,可以有两种方式,一种就是12 34 56 78,地址依次减小;另一种则是78 56 34 12,与前面的刚好相反。

两种方式都可以理解。但是,需要记住一点:int的地址永远是低位的(注意前提)。就是说,&i 获取的永远是低位的地址。

那么,第一种方式下,该地址应该是78所在的空间地址;同理,第二中方式下,该地址就是12所在的空间地址!

现在可以继续说尾数(endian)了,0x12345678的尾数自然就是78,该数字所在的端如果是低地址,就是小端对齐,反之,则是大端对齐!

 

代码验证windows下的大小端对齐方式

技术分享
#include <stdio.h>

//测试大小端对齐
int main(int argc, char const *argv[])
{
    int a=0x12345678;
    printf("%p, %x\n", &a, a);
    char *p=(char *)&a;
    char *p2=p;
    char *p3=p;

    //输出大小端
    for (int i = 0; i < sizeof a; ++i)
    {
        printf("%p, %x\n", p++, *p);
    }

    //如何反转大小端?
    for (int i = 0; i < sizeof(a)/2; ++i)
    {
        char tmp=*p2;
        *p2 = *(p2+sizeof(a)-1-2*i);
        *(p2+sizeof(a)-1-2*i)=tmp;
        ++p2;
    }
    printf("after transfer : %p, %x\n", &a, a);

    for (int i = 0; i < sizeof(a)/2; ++i)
    {
        (*p3) ^= (*(p3+sizeof(a)-1-2*i));
        (*(p3+sizeof(a)-1-2*i)) ^= (*p3);
        (*p3) ^= (*(p3+sizeof(a)-1-2*i));
        ++p3;
    }
    printf("after transfer again : %p, %x\n", &a, a);

    return 0;
}
View Code

 

 

附注

可能有的人不理解为什么要用这个数,或者说,为什么这个数可以说明问题。

这是基础的东西:

int4 bytes,1 byte8 bits,4 bits 刚好是一个16进制数字。

1 int == 4 bytes;
1 byte == 8 bits;
0x0 ~ 0xF == 4 bits; // ( 0000 ~ 1111 )
1 byte == 0x00 ~ 0xFF; //( 00000000 ~ 11111111 )
1 int == 0x00 00 00 00 ~ 0xFF FF FF FF; 

所以 1 byte 就是 2 个16进制数字,所以 int 就是 8 个16进制数字!

而为了区别每个byte的内容,将其设为不同的值是最佳选择!

C 学习之大小端

标签:

原文地址:http://www.cnblogs.com/larryzeal/p/5654779.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!