嵌入式C语言之深谈内存

内存:

    计算机程序=代码+数据(数字)
    用函数来类比:函数的形参就是代加工的数据(函数内还需要一些局部变量),
                  函数本体就是程序,函数的返回值就是结果,函数体执行的过程就是过程。
    代码:函数
    数据:全局变量,局部变量。  
    
    内存管理:汇编语言:没有任何内存管理,汇编操作直接使用内存位置;
              C语言编译器帮我们直接管理内存,我们通过编译器的变量名访问内存
              c++对于内存进行分装,可以用new创建对象,为对象分派内存
              java c#不直接操作内存  通过虚拟机帮我们操作内存。
              
              看中程序的性能,例如操作系统内核的编写常用c/c++;
              在乎程序开发的速度时常用java/c#;
              
    从逻辑角度看内存:是一个东西,可以随机访问(给一个地址就可以访问这个内存的地址,)
                      可以读写(也可以设置为只读不写)
                       天然用来存放变量(有了内存,C语言才能定义变量),
                       C语言一个变量就对应内存中的一个单元
    内存由无线多个内存单元组成,每个内存单元叫做内存地址;
    每个内存地址的和这个内存单元唯一对应且永久绑定。
    
    字和位是内存单元大小的单位,位(1bit) 字节(8bit) 半字(一般是16bit) 字(一般是32bit)
    字  半字  双字具体多少位有赖于平台,不同的平台,其位数不同
    在linux+arm软硬件的系统内 字是32bit    

    内存的编址是以字节为单位的。内存的地址空间的大小是固定的  为一个字节(8bit)
    
    
数据类型:
    
    int类型的数据是整形数据,这个整体现在他和CPU本身的位宽是一样的;
    数据类型用来定义变量,而变量需要储存,运算在内存中,所以数据类型必须和内存相匹配才能最大程度上利用系统,得到最好的效率,最好的性能。即:32位系统中使用int
    类型的变量效率最高。    
    对齐访问很配合硬件,所以效率很高,
    
    C语言中数据类型的作用:表示一个内存格子的长度和解析方法
    
    数据类型决定长度:我们一个内存地址(0x30000000)本来代表一个字节长度,但是实际上我们可以通过给他一个类型(int),让它有了长度(4),这样本来这个内存地址的数字就从这个数字(0x30000000)就能代表以这个数字(0x30000000)开头的n(4)个字节的内存格子(0x30000000+0x30000001+0x300000002+0x300000003)。

   内存地址决定解析方法的含义:本身有一个内存地址,我们可以通过给这个内存地址不同的类型来指定这个内存单元格中二进制数字的解析方法。
   一定的内存地址,通过不同的数据类型定义后可以有不用的二进制解析方法,同时可以改变这个内存地址包括从改该内存格开始有多少个内存格,而存放的内容不会发生变化。
   
  关于类型(不管是普通的变量类型intfloat等,还是指针类型int*,float*等),类型只是对于后面的数字或者符号(代表的是内存地址)所象征的内存的一种长度规定和解析方法规定而已。

  
简单的数据结构:

  数组:
      数组管理内存和变量没有什么本质区别,只是符号的解析方法不一样
      例如:int a    //编译器分配4个字节给a,并且把首地址和符号a绑定起来
         int a[10]//编译器分配40个字节给a[10],并把首地址和首元素a[0]绑定
   
  结构体:
         
      结构体可以很好的解决数组内数据类型必须一致,且不能改变的缺陷,
      struct people   //people的的各种数据类型不同
      {
        int age;
        char name[20];
        int height;
      };
      含有不同的数据类型导致结构体不能直接访问地址,而是要通过.a来访问内存的地址。而数组的数据类型固定,可以通过计算算出数据的内存地址从而可以直接访问a[i]的内存地址。

  结构体内嵌指针实现面向对象:
  
      C语言是面向过程的,但是linux内核系统是面向对象的;
      sturct struct
      {
        int age ;     //普通变量
        void  (*pFunc)(void);   //函数指针  指向void Func (void)的函数
      }
      这样包含了函数指针的结构体就类似于面向对象中的class,结构体中的变量就类似于class中的成员变量,结构体的函数指针相当于class中的成员方法。

  栈(stack)
     用来保存局部变量,管理内存,自动为变量分配内存空间。
      遵循先进后出原则,bittom固定在首地址,而top始终在最后一个内存地址的下一个地址。
     相对应的队列:先进去的先出来,入口和出口都存在,从入口进入,出口出去
     
     局部变量的是通过栈实现的。    
     栈由于反复使用且不清零,所以定义局部变量之后如果不进行初始化则局部变量的值默认为上一次栈内的值。
  
  堆(heap):
     可以随时申请,随时释放,大小快随意的内存管理方式。
      堆内存是操作系统划归给堆管理器来管理的,然后向使用者(用户系统)提供API(malloc和free)来使用堆内存。
      堆内存的申请和释放都需要自己通过代码申请(malloc)和释放(free),如果自己申请内存使用后没有释放,则这段内存就会丢失。
  
复杂数据结构:
    链表:节点的插入(前插,后插),节点的删除,节点的查找,节点的遍历。


      


       
      

猜你喜欢

转载自blog.csdn.net/weixin_40647352/article/details/84075183