1.为什么需要内存
(1)计算机为什么需要编程?为什么要写新的程序?
计算机编程主要注重两点,结果和过程。比如下面的代码看重的是结果
int add(int a,int b)
) { return a+b; }
下面的代码看重的是过程
void add(int a,int b) { printf("%d",a+b); }
而下面的代码既看重过程也看重结果
int add (int a,int b) { printf("%d",a+b); return a+b; }
(2)计算机程序运行过程
计算机运行过程其实就是多个函数相继运行的过程,程序的本质就是函数,函数的本质是数据的加工。
(3)冯诺依曼结构和哈佛结构
冯诺依曼结构:数据和代码放在一起
哈佛结构:数据和代码分开存放
例如在常见的单片机中比如51或32他们都是通过烧录将程序烧录进ROM中而程序执行后的产生的数据存储在RAM中故其输入哈佛结构。而在linux系统中代码和数据都存储在同一个存储器中故其属于冯诺依曼结构。
(4)DRAM和SRAM
对于RAM ROM DRAM SRAM不熟悉的同学可以看 这里
(5)总结
程序运行过程中可变数据是必不可少的,而可变数据(局部变量、全局变量等)都存储在内存中。故在计算机中内存也是必不可少的。
(6)如何管理内存
操作系统中:操作系统控制所有的硬件内存,因为内存很大所以操作系统会通过将其分为页面进行管理,页面内用更细小的方式进行管理。(在此省略)操作系统提供了很多API,我们调用即可。
无操作系统时:裸机程序中,需编程者自己计算、使用和安排
2.位、字节、半字、字的概念和内存位宽
(1)什么是内存
硬件角度:内存是电脑的一个硬件比如内存条
逻辑角度:内存可以随机访问并且可以读写。在编程中用来存放变量
(2)内存位宽
硬件角度:硬件内存的实现本身就是有宽度的,也就是说有些是8位、16位的,有些是32位的
逻辑角度:内存位宽是任意的,
(3)位和字节
内存单元的大小大单位,位(1)->字节(8)->半字(一般为16)->字(一般为32)
所有计算机中位都是1bit 字节为8bit
(4)字和半字
字和半字根据不同平台有所不同。编程时一般用不到这几个概念,但文档中会用到。
3.内存的编址和寻址、内存对齐
(1)内存编制方法
内存在逻辑上就是一个个的格子,这些格子可以用来储存数据,每个格子都有一个编号,这个编号就是内存地址。
程序运行时,计算机cpu只认识内存地址,并不关心这个地址所代表的空间在哪里,由硬件来保证按照这个地址一定能找到这个空间
(2)内存编址是以字节(8bit)为单位的
(3)内存和数据类型的关系
c语言中数据类型有:char short int long float double
int 整型(整数类型)如32机中int为32位
数据类型是用来定义变量的,而变量需要储存、运算在内存中。数据类型必须和内存相匹配才能获得最好的性能。
在32位系统中变量最好用int,因为这样效率高。(其实应该是使用unsigned int效率会更高,少了符号判断的一个过程)
(4)内存对齐
内存分配策略:
第一种:0 1 2 3 对齐访问
第二章:2 3 4 5 非对齐访问
内存的对齐访问不是逻辑问题,是硬件问题。对齐访问很配合硬件效率很高,非对齐访问和硬件不搭配因此效率不高。有时为了节省空间会采用非对齐的方式。
(5)从内存编址看数组
数组b[10],b即指的是b[0]字节的的首地址
4.C语言如何操作内存
(1)C语言中对内存地址的封装
如 int a; a=5;编译器帮我们申请了1个int类型的内存格子,并将符号a和之和内存格子绑定。a的地址只有编译器知道,我们不需要知道。
函数就是一段代码的封装。函数名的实质就是这一段代码的首地址。所以说函数名本质也是一个内存地址
(2)用指针来间接访问内存
int a和int *p 本质上没有任何区别,int a是内存中某一个格子,而int *p也是内存中某一个格子,不过int *p这个格子内存的是内存地址。也就是说解析方式不同
(3)数组管理内存
数组管理内存本质上和变量没有区别,只是符号的解析方式不同。
数组的第一个元素a[0]成为首元素;每一个元素类型都是int,长度都为4,其中第一个字节的地址就是首地址;首元素a[0]的地址也就是首元素首地址。
举例:
int a; int *p; int *q; int b[4]; //以上都是申请内存地址用与储存变量 a=5; //a所关联的地址的数值写为5 b=[1,2,3,4];//b所关联的4个字节的内存地址每个字节分别写为1 2 3 4 p=&a;//p所关联的内存地址写为a的内存地址 q=b;//q所关联的内存地址写为b的内存地址 printf("%d",*p) //p指向a的地址,*p即为a的内存即输出 5 printf("%s",*q) //q指向的为b的首地址,输出为[1,2,3,4] printf("%d"**q); //*q为b的首地址,**q即为*b即输出 1
...
标签:精通,语言,int,地址,内存,对齐,内存地址,字节 From: https://www.cnblogs.com/foorun/p/17623481.html