《嵌入式LINUX与物联网软件开发 C语言内核深度解析》学习1——C语言与内存

什么是程序?

程序=数据+算法。

内存分类:

分静态内存SRAM、动态内存DRAM。
DRAM有好多代,比如DDR1、DDR2、DDR3、DDR4……。

内存结构:

1、冯诺依曼结构:代码和数据存储在同一个存储器中,并且共用一条传输总线,因此影响到了数据处理速度。
2、哈佛结构:指令和数据分开存储的结构。执行效率高。
这两种结构各有各的用处。

程序为什么要有内存

用来存储数据

几种语言对内存的管理

1、汇编:没有内存管理,直接操作地址(例如0xd0020010)。
2、c语言:编译器帮我们管理地址。通过编译器提供的变量名来访问内存。程序员可以通过API来申请,注意要自己释放。
3、C++:和C差不多
4、Java/C#:不直接操作内存,而是通过虚拟机来操作。程序员不需要关心内存的释放,虚拟机自己会做,但是虚拟机回收内存需要一定的代价。

内存是什么

内存在逻辑上就是一个个的格子,每个格子都有编号,这个编号就是内存地址。硬件保证了按照这个地址就一定能找到格子。
我们以多大空间来划分一个格子,并绑定一个地址呢?
以一个字节为基本单位对整个内存进行划分,并绑定地址。

linux C的内存映像

在这里插入图片描述

数据类型在开辟内存时的作用

c语言中有char、short、int、long、double这些基本数据类型。
当我们定义一个变量时,应该分配多大的空间,按照什么样的方式去解析该空间呢?数据类型就决定了分配的空间和解析方法。
(32位系统中最好使用int,因为硬件本身就是32位的,例如bool型如果定义成int,虽然浪费了31位,但是效率会高很多,所以有人说写程序要配合硬件特点)
那造成的浪费怎么办呢?现在内存很便宜,条件允许的话还是以效率为重。

为什么要内存对齐

内存以4字节对齐时效率比较高。

函数是怎么找到的

函数名就是一段代码的封装,函数名其实就是这段代码的首地址,也就是说函数名是一个指针。

数组名是什么

在内存中申请一块连续的空间。数据名相当于一个指针,里面存放的是这块空间的首地址(第一个字节的地址)。
对数据名的+操作,具体偏移多少字节,需要看数组的数据类型。

C实现面向对象(有趣的想法)

struct
{
	int age;    //成员变量
	void (*pFunc)(void);    //成员函数
};
linux系统就是用C写出来的,但是思想是面向对象的,所以有的人学了C但是看不懂linux内核代码。

堆栈的理解

堆和栈是两个东西。都是用于管理内存的。
栈的特点:先进后出,后进先出,空间小,自动分配和回收,存放局部变量。
堆:容量大,人工申请和释放(malloc,free)。因为需要人工,有的人记性不好忘记释放了就内存泄漏了。

内存的管理方式有哪些?

内存被分为栈、堆、数据段、bss段、text段(代码区)等不同管理方法的内存段。
有的分类是栈、堆、数据区(.data 和.bss)、常量区(.ro.data)。
1、栈特点
	- 空间自动管理,运行时空间自动分配,运行结束时空间自动回收。栈是自动管理的,程序员不需要手动干预。
	- 能够反复使用,栈内存在程序中使用的都是一块内存空间,程序通过自动开辟和自动释放会反复使用这一块空间。
	- 脏内存,栈内存由于反复使用,每次使用后程序不会去清空内容,因此当下一次该内存再次被分配时,上一次使用的值会还在。
	- 临时性,函数不能返回栈变量的指针,因为这个空间在函数运行结束后会被释放。
2、堆特点
	- 灵活
	- 内存量大
	- 程序手动申请和释放
	- 脏内存
	- 临时性,堆内存在free之后不能访问,否则会有不可预料的后果
3、数据区和.data和.bss
  	数据区,也叫静态数据区、静态区、全局静态区,存放静态变量、全局变量的空间。
   	.data存放的是显示初始化为非0的静态数据。
   	.bss存放的是显示初始化为0或未显示初始化的静态、全局数据。

程序中变量的存储

加入main.c文件的内容如下:
int a = 0; 				------全局初始化区 
char *p1; 				------全局未初始化区 
main() 
{ 
int b; 					------栈 
char s[] = "abc"; 		------栈 ,有人会觉得"abc"在常量区,其实在编译的时"abc"会拷贝到s所在的内存区域,拷贝完后就丢弃了
char *p2; 				------栈 
char *p3 = "123456"; 	------123456\0在常量区,p3在栈上。 
static int c =0; 		------全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得来的10和20字节的区域就在堆区。 
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 
}

malloc的一些细节

malloc(0),返回的是NULL还是一个有效指针呢?答案是不确定,由各malloc函数库的实现者来定义。
malloc(4), GCC中malloc默认最小是以16B为单位进行空间分配的。如果指定空间小于16B,也会按照16B来分配。
发布了38 篇原创文章 · 获赞 17 · 访问量 4321

猜你喜欢

转载自blog.csdn.net/qq_14877637/article/details/86932417