一、概述

字节序用来表示数据在内存中的排布方式,它分为两种:高字节序和低字节序,也被称为大小字节序。

对于一个int类型的变量n=0x12345678,它在32位系统中占四个字节,假设这四个字节在内存中是0x00000001~0x00000004,则它以低字节序和高字节序存储的形式为:

在计算机中,一般都是采用低字节序,网络数据传输一般是高字节序。

我们可以通过以下代码片段来理解这个概念:

int main() {
    int n = 0x12345678;
    cout << "0x" << hex << (n&0xff) << endl; // 输出第一个字节
    cout << "0x" << hex << ((n>>1*8)&0xff) << endl; // 输出第二个字节
    cout << "0x" << hex << ((n>>2*8)&0xff) << endl; // 输出第三个字节
    cout << "0x" << hex << ((n>>3*8)&0xff) << endl; // 输出第四个字节
}

结果为:

0x78
0x56
0x34
0x12

二、相关面试题

2.1 下面程序的结果是多少

int main()) {
    unsigned int a = 0xfffffff7;
    unsigned char ch = (unsigned char)a;
    char* b = (char*)&ch;
    printf("%08x %08x\n", ch, *b);
}

int在内存中占四个字节,char占一个字节,所以int->char数据会被截断,ch只会取到a的第一个字节。而计算机中内存的分布方式是低字节序,所以ch的值是0xf7

printf中,对于无符号类型的数据,如果数据宽度不够,不够的位补会0,有符号的补f。所以ch输出0x000000f7*b输出0xfffffff7

2.2 题目二

在小端序的计算机中,有以下代码:

union X {
    int x;
    char y[4];
}

X a;
a.x = 0x11223344;

那么下面说法正确的是:

  1. a.y[0] = 0x11
  2. a.y[1] = 0x11
  3. a.y[2] = 0x11
  4. a.y[3] = 0x11
  5. a.y[3] = 0x22

正确的结果是第4个:低字节序,数据从低位开始排布,而栈区的地址是由高到低,因此内存分布如下所示:

y[0] = 0x44y[1] = 0x11,正确的是第4个选项。

测试代码:

#include <stdio.h>

union X {
    int a;
    char y[4];
};

int main() {
    int i;
    union X a;
    a.a = 0x11223344;
    for (i = 0; i < 4; i++) {
        printf("a.y[%d] = 0x%x, addr: %p\n", 
                i, a.y[i], &a.y[i]);
    }
    return 0;
}

结果:

a.y[0] = 0x44, addr: 0x7fffb1c7b580
a.y[1] = 0x33, addr: 0x7fffb1c7b581
a.y[2] = 0x22, addr: 0x7fffb1c7b582
a.y[3] = 0x11, addr: 0x7fffb1c7b583

最后修改:2019 年 04 月 29 日
如果觉得我的文章对你有用,请随意赞赏