栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言之什么是大小端,数组大小端,位域大小端,结构体大小端

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言之什么是大小端,数组大小端,位域大小端,结构体大小端

公众号:嵌入式不难

本文仅供参考学习,如有错误之处,欢迎留言指正。

理解大小端之前必须明白的三点
  1. 内存地址始终以字节为单位
  2. 大小端只针对基本数据类型
  3. 存在位域的情况下,小端模式下先定义的位域从LSB(最低有效位)开始,大端模式下先定义的位域从MSB(最高有效位)开始

首先解释下以上三点
第一点,内存地址存储的最小数据大小就是字节,例如一个变量char temp的地址0x10000000,temp值为0x55,由于char类型只占用一个字节,那么temp变量就只占用0x10000000这个内存地址,不会占用其他内存地址,那假如变量是个int型呢?占用的字节数可能是4字节,这个时候内存和内存值又是怎么分配的呢?这个有待后面分析。
第二点,大小端只针对基本数据单元类型,那么什么是基本数据类型单元呢,char, int, float, double,那什么不是基本数据类型呢?例如:数组,结构体,联合等等。
第三点,先定义的位域因大小端情况会表示最高位或者最低位。

大小端影响了什么?

当基本数据类型占用字节数超过了1字节后,大小端决定了数据按照什么顺序存储在内存里

既然字节数超过了1个字节才有影响,那么就会一个疑问,char型数据占用字节数为1个字节,那么char型数据在大小端的模式下,会有什么不同吗?答案是没有。

什么是大小端?
  1. 大端(Big-Endian):高地址存放低位
  2. 小端(Little-Endian):高地址存放高位

这里有几个概念:高地址,低地址,高位,低位,其中高地址,低地址是针对内存地址而言,高位,低位是针对数据类型的bit位的高低而言。

如何根据具体情况分析

分析步骤:

  1. 首先找出基本数据类型,明确数据占用字节数以及高位,低位情况
  2. 明确变量地址始终指向变量的低地址
  3. 根据大小端的特性来套表格
举例: 例1(基本数据类型):int temp = 0x12345678;

假设 temp 的地址为 0x10000000 ,按照上面的分析步骤来拆分解析

  1. int型占用字节数为4字节,将数据按照字节为单位的高位,低位分解如下:0x12(高位),0x34,0x56 ,0x78 (低位)
  2. 由1点可知,基本数据类型占用内存为4字节,所以内存地址范围为 0x10000000~ 0x10000003
  3. 根据大小端的特性来套表格如下
大端模式
内存地址内存值步骤
0x100000000x124.依次取值
0x100000010x343.依次取值
0x100000020x56 2.依次取值
0x100000030x78 1.高地址存放低位
小端模式
内存地址内存值步骤
0x100000000x78 4.依次取值
0x100000010x56 3.依次取值
0x100000020x34 2.依次取值
0x100000030x12 1.高地址存放高位
例2(数组):short int temp[2] = {0x1234,0x5678};

假设 temp 的地址为 0x10000000 ,按照上面的分析步骤来拆分解析

  1. short int型占用字节数为2字节,将数据按照字节为单位的高位,低位分解如下:0x12(高位),0x34(低位),0x56 (高位),0x78 (低位)
  2. 由1点可知,基本数据类型占用内存为2字节,但是由两个元素,所以内存地址范围为 0x10000000~ 0x10000003
  3. 根据大小端的特性来套表格如下
大端模式
内存地址内存值步骤
0x100000000x122.依次取值
0x100000010x341.高地址存放低位
0x100000020x56 4.依次取值
0x100000030x78 3.高地址存放低位
小端模式
内存地址内存值步骤
0x100000000x34 2.依次取值
0x100000010x12 1.高地址存放高位
0x100000020x784.依次取值
0x100000030x563.高地址存放高位
例3(位域结构体):struct {int b1:1; int b2:2; int b3:3; int b4:4; char b5:5;}temp = {.b1=1, .b2=2, .b3=3, .b4=4, .b5=5 };

假设 temp 的地址为 0x10000000 ,按照上面的分析步骤来拆分解析

  1. 首先分析位域情况

大端下temp的int值位域分布如下

bit位313029282726252423222120191817161514131211109876543210
b1b2b2b3b3b3b4b4b4b4
bit值1100110100----------------------

大端下temp的char值位域分布如下

bit位76543210
b5b5b5b5b5
bit值00101---
大端模式下,假设-表示0,则int值为0xCD000000,char值为0x28

小端下temp的int值位域分布如下

bit位313029282726252423222120191817161514131211109876543210
b4b4b4b4b3b3b3b2b2b1
bit值----------------------0100011101

小端下temp的char值位域分布如下

bit位76543210
b5b5b5b5b5
bit值---00101
小端模式下,假设-表示0,则int值为0x0000011D,char值为0x05
  1. int型占用字节数为4字节,char型占用字节数为1字节
  • 大端模式下将数据按照字节为单位的高位,低位分解如下:0xCD(高位),0x00,0x00,0x00(低位),0x28(字节)
  • 小端模式下将数据按照字节为单位的高位,低位分解如下:0x00(高位),0x00,0x01,0x1D(低位),0x05(字节)
  1. 由1,2点可知,基本数据类型占用内存为4字节+1字节,所以内存地址范围为 0x10000000~ 0x10000004
  2. 根据大小端的特性来套表格如下
大端模式
内存地址内存值步骤
0x100000000xCD4.依次取值
0x100000010x003.依次取值
0x100000020x002.依次取值
0x100000030x001.高地址存放低位
0x100000040x285.高地址存放低位
小端模式
内存地址内存值步骤
0x100000000x1D 4.依次取值
0x100000010x013.依次取值
0x100000020x002.依次取值
0x100000030x001.高地址存放高位
0x100000040x055.高地址存放高位
实验验证环境属于大端还是小端

测试代码如下:

#include 

int main(int argc, char *argv[])
{
    int temp1 = 0x12345678;
    short int temp2[2] = {0x1234, 0x5678};
    struct{
        int     b1:1;
        int     b2:2;
        int     b3:3;
        int     b4:4;
        int     bn:22;//这里是否需要占位根据编译器而定
        char    b5:5;
    }temp3={.b1=1, .b2=2, .b3=3, .b4=4, .bn=0, .b5=5};

    char *_p1, *_p2;
    int *_p3;

    _p1 = (char *)&temp1;
    if(*_p1==0x12) printf("基本数据类型测试:大端模式n");
    else if(*_p1==0x78) printf("基本数据类型测试:小端模式n");
    else printf("基本数据类型测试:测试错误n");

    _p1 = (char *)&temp2[0];
    _p2 = (char *)&temp2[1];
    if(*_p1==0x12 && *_p2==0x56) printf("数组类型测试:大端模式n");
    else if(*_p1==0x34 && *_p2==0x78) printf("数组类型测试:小端模式n");
    else printf("数组类型测试:测试错误n");

    _p3 = (int *)&temp3;
    _p1 = (char *)&temp3;   
    _p2 = (char *)(_p3+1);
    printf("temp3.int=0x%08Xn", *_p3);
    printf("temp3.char=0x%02Xn", *_p2);
    if(*_p1==0xCD && *_p2==0x28) printf("位域类型测试:大端模式n");
    else if(*_p1==0x1D && *_p2==0x05) printf("位域类型测试:小端模式n");
    else printf("位域类型测试:测试错误n");

    return 0;
}

实验结果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/943202.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号