《C语言内核深度解析》笔记(1):c语言与内存

《嵌入式Linux与物联网开发——C语言内核深度解析》这本书很适合新人嵌入式工程师学习,这本书有两个推荐的点:第一个是以嵌入式的视角重新解读C语言,在实际硬件和应用场景下重新讲解相关概念;第二个是补充了很多关于嵌入式c语言的细节,这些细节在工作中常见,但在课堂上不会讲。接下来一段时间我会把之前做的笔记陆续整理发出来,当作个人一次复习的小结。

第01章 c语言与内存

1.2 程序:数据+算法

静态内存SRAM和动态内存DRAM:
SRAM:性能高,速度快,昂贵,如CPU的一级缓冲、二级缓冲
DRAM:慢,便宜,DDR是一种改进型的RAM,可以在一个时钟读写两次数据。


冯诺依曼结构和哈佛结构:
按照数据(全局变量和局部变量)和代码(函数)的存储方式不同:
冯诺伊曼:数据和代码放在一起,共用一条传输总线
哈佛:数据和代码分开,中央处理器首先到程序指令存储器钟读取指令内容,得到数据地址,再到相应的数据存储器中读取数据。

1.3 位、字节、半字、字的概念和内存位宽

三总线:地址总线、数据总线、控制总线。
如向内存中写入数据,则控制总线上传输写命令,地址总线上传输内存地址,数据总线传输要写入内存的数据。
多少位CPU指的就是数据总线位数。数据位数越多,一次传输处理的数据就越多

内存位宽(内存数据线的数量)是指在一定时间(时间指的是一个时钟周期)内所能传送数据的位数,位数越大,则所能传输的数据量就越大。


1.4 内存编址和寻址、内存对齐


内存编址以字节为单位
写程序时尽量要配合硬件特点

内存对齐:计算机系统对基本类型数据在内存中存放的位置有限制,
它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。

1.5 c语言如何操作内存

c语言中数据类型的本质含义,是表示一个内存格子的长度和解析方法。
假如有一个内存地址,可以通过给这个内存地址不同的类型来指定这个内存单元格子中二进制的解析方法。
在C语言中,函数就是一段代码的封装,函数名的实质就是这一段代码的首地址,所以说函数名的本质也是一个内存地址。

指针是一个变量,且这个变量是专门用来存放地址的。
指针变量和普通变量没有任何区别,类型只是对其所修饰的数字或者符号所代表内存空间的长度和解析方法的规定。

数组定义就是在内存中开辟一块连续的内存空间,数组名就是其开辟的内存空间的首地址,即数组名就相当于一个指针,放着这个数组的首元素地址。

1.6 内存管理之结构体

结构体属于聚合数据类型,提供一种把各种相关且类型可能不同的数据组合到一起的手段。
结构体变量在被定义后,编译器在编译的时候回为所有成员分配空间。
向函数传递结构时,实际上时传递结构成员的值,即都是值传递方式。
但直接值传递整个结构体变量存在很大的缺陷,因为当执行函数调用时,数据压栈需要开销,因此解决方案是传递结构体
变量的指针。

题外话:结构体内嵌指针实现面对对象
structs
{
    int age;
    void (*pFunc)(void);        //函数指针
}

1.7 内存管理之栈

栈是一种数据结构,C语言中使用栈来保存局部变量。本质是一种维护内存的机制。

栈特点:入口即出口,先进后出。
队:有入口有出口,先进先出

栈应用:局部变量和函数调用
当我们在C语言中定义一个局部变量时,编译器会在栈中分配一段空间(4字节)给这个局部变量用。
对应操作为入栈,栈指针的移动和内存分配时自动完成的,不需要程序参与。
函数退出的时候,局部变量会被释放,对应操作时出栈。

栈大小不灵活,怕溢出,要避免定义局部变量太多导致溢出。

1.8 内存管理值堆


堆:一种动态内存管理方式。malloc和free申请的内存来源于堆内存。
需要内存容量比较大时,以及需要反复使用及释放时(动态特性),很多数据结构的实现都要使用内存。

特点:容量不限,动态分配;申请和释放需要手工进行(注意避免内存泄漏)。

void *malloc(size_t size);
void *calooc(size_t nmemb, size_t size);    //nmemb个单元,每个的单元size字节
void *realloc(void *ptr, size_t size);      //改变原来申请的空间的大小

局部变量存在栈(stack)中,全局变量存在静态数据区中,动态申请数据存在于堆(heap)中。

静态局部变量和全局变量存储在静态存储区,编译器在编译程序时就确定了静态存储区的大小。

你可能感兴趣的:(c语言笔记,c语言,单片机,物联网,mcu)