C/C++ 大小端、位域、内存详解

前言
面试时遇到关于大小端、位段(或者叫位域)和内存对齐的考题,然后就不知所措了。这部分对于嵌入式底层工作者是必须要掌握的,其他方面不是必须的;但还是很有必要学习理解这些知识点,因为它可以让你更了解C++的,了解程序在内存的运行情况,也能加深对计算机系统的理解。

1、大小端
         在现代的“冯.诺依曼体系结构”计算机中,计算机内的数制都是采用二进制来存储,并且是以8位,一个字节为单位,产生内存地址系统。数据在内存中有如下三种存在方式:

           1、从静态存储区分配:此时的内存在程序编译的时候已经分配好,并且在程序的整个运行期间都存在。全局变量,static变量等在此存储。

           2、在栈区分配:在程序的相关代码执行时创建,执行结束时被自动释放。局部变量在此存储。栈内存分配运算内置于处理器的指令集中,效率          高,但容量有限。

            3、在堆区分配:动态分配内存。用new/malloc时开辟,delete/free时释放。变量的生存期由用户指定,灵活,但会有内存泄露等问题。

          一般涉及到大小端问题都是针对的float、int、long等等非一个字节类型的数据类型,像C/C++中的char这样的数据类型,它本身就是占用一个字节的大小,不会产生什么问题。例如 int数据类型,在32位系统中,占4个字节,那这样4个字节存放空间地址是什么样的顺序呢,这就涉及到了大小端的原理了。

          常用的x86结构都是小端模式,而大部分DSP,ARM也是小端模式,不过有些ARM是可以选择大小端模式,KEIL C51是大端的。

        大端:数值的高字节放在内存的低地址处,数值的低字节放到高低址处;就是高位在前。

        小端:数值的低字节放在内存的低地址处,数值的高字节放到高低址处;就是低位在前。

        总结一句话:按内存地址增长的顺序,先放高位就据就是大端,先放低位数据就是小端。

  示例:

        int Height = 0x12345678,&Height = 0x0042ffc4

  

2、位域
       在计算机中,是采用0 ,1表示数据的,每一个0或者1占用1位(bit)存储空间,8位组成一个字节(byte),为计算机中数据类型的最小单位,如char在32bit系统中占用一个字节。但有的时候,我们只需要bool类型的数据量,但C/C++里面没有bool类型的数据,那如何使用bool类型的数据量呢,这就涉及到了位域的概念;并且使用位域(有的叫做位段)可以节省空间。

       具体的语法就是在变量名字后面,加上冒号(:)和指定的存储空间的位数。具体的定义语法如下:

struct A{
    char a:2;
    char b:3;
    char c:2;
    int  d;
};
      A.a = 2;

      A.b = 4;

      A.c = 1;

      A.d = 18;

      sizeof(A) = 8;

      假如 A 的地址为0x0004b80,则


       在这里讲解位域的时候,涉及到了内存对齐或者叫字节对齐的概念,在下面讲解到。

3、内存
       内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址)、访问数据(表现为CPU读取数据)的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐 。

       具体详细的请看我另外三篇专门讲解字节对齐的博客:

       #Pragma Pack(n)内存分配:https://mp.csdn.net/postedit/93205993

      C语言 字节对齐问题 详解: https://mp.csdn.net/postedit/92686850

      #pragma pack(push,1)与#pragma pack(1)的区别:https://mp.csdn.net/postedit/93206004

 
 

发布了339 篇原创文章 · 获赞 46 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u014644594/article/details/103886642