C语言学习之内存理解 文章目录 一、程序运行为什么要内存1.1 计算机的运行目的1.2冯洛伊曼结构和哈弗结构1.3动态内存DRAM,静态内存SRAM1.4为啥需要内存 二、位、字节、半字、字的概念和内存位宽2.1什么是内存2.2内存的大小2.3内存存放的模型2.4内存位宽2.5位,字节,半字、字的关系 三、内存的编址,寻址、对齐3.1 内存的编址方式3.2内存和数据类型的关系3.3内存对齐 四、如何操作内存4.1C 语言对内存地址的封装4.2 用数组访问内存4.3用指针访问地址 一、程序运行为什么要内存 1.1 计算机的运行目的 就像你打工是为了赚钱一样,所以计算机运行的目的也是为了得到一定的结果。再出及结果之前还有一个很重要的东西就是过程,有的人注重结果,有的人注重过程,有的人注重结果和过程。就类似于函数: 程序的本质就是很多函数相继运行的过程,如果程序不运行,那么就只是相当于一个一个字模和数字组合起来的占用内存的渣滓。只有程序运行起来,我们才能得到结果。 1.2冯洛伊曼结构和哈弗结构 冯诺依曼结构:数据和代码放在一起; 哈佛结构:数据和代码分开存放。 代码就是函数,单片机代码放在flash中。数据就是全局变量,和局部变量单片机放在RAM中。 1.3动态内存DRAM,静态内存SRAM 动态内存:就是程序员而分配的内存,malloc,需要程序员自己去释放,free。 静态内存:内存自己分配的,不需要我们自己去释放,比如定义的一个数组啊什么的。 1.4为啥需要内存 因为越大的程序越需要很多的数据来支撑,而数据是存放在内存的,所以需要内存。 同时管理内存也是一个很重要的过程,因为内存不是无限大的,循环利用才是一个优秀程序员应该必备的。 二、位、字节、半字、字的概念和内存位宽 2.1什么是内存 硬件角度:就是电脑的一个配件,需要他才能组成一个完整的计算机。 软件角度:就是一个一个随机访问的东西,只要你给地址,就可以访问这个地址的内存。就相当于你在超市,你付钱就可以买到东西,你付什么东西的钱,就可以买到什么东西。 2.2内存的大小 内存的大小在理论上是无穷大的,因为我们可以不停的加加,类似于数数,我可以从一不听的往后数,当然我们不可乱数,必须按照规矩来(也就是每个内存的地址都是唯一的不能改变)。 在实际上,我们的内存是有限的,就向你不可能修一座无线高的大楼,所以用操作系统来说,32位操作系统我们的的可以操作大小就是2的32次方(当然可能有部分偏差,很实际的例子就是我们8G的优盘,空间只有7个多G,没有8G) 2.3内存存放的模型 32位的内存存放方式:
16位内存:
8位内存
现在基本都是用的32位的芯片的。 2.4内存位宽 从上面几张图看来,内存位宽都是2的偶数倍,1,2,4,8… 从软件上来讲,我们的位宽可以是非0的任意整数,1,2,3,4.5…都可以,但是硬件做不出来的啊,所以我们再市场上看到不到这种奇数型的内存。 2.5位,字节,半字、字的关系 位:1 bit 字节:8位(8 bit) 半字:16位(16bit) 字:32位(32 bit) 双字:64位 (64 bit) 这个不是唯一性,因为有很多操作系统,window,Linux等等、但是他们的关系是不变的。 三、内存的编址,寻址、对齐 3.1 内存的编址方式 在理论上来说,内存的就是一个个的格子,这个格子有编号,这个格子有大小,可以装东西。这个格子的编号(唯一)和大小都是永久绑定的,这就是编址。 在程序运行的的时候,CPU不关心你的格子在哪里,有没有按照顺序来,CPU只关心你的地址在哪里(编号是多少 )。 这句话很重要: 内存的编址是以字节为单位的。 就是这格子占用了多大的空间?这个空间是固定的,都是1个字节。(可以看下面那张图,0123这个所有的格子都是1个字节的) 3.2内存和数据类型的关系 C语言的基本类型:int、char、short、long、float…等等 int 之所叫整形的数据,是因为他和CPU的位宽是一样的,比如32位的CPU,他的整形数据占用4个字节就是32位。 数据类型必须和内存相匹配才能获得最好的性能,否则可能效率低下甚至不工作。 在32位系统中,定义变量对好用int型,因为效率高,原因就是在32位系统中本身的内存也是32位的,与之相匹配。 当然char类型和short类型也可以执行,但是效率没有int类型高。 3.3内存对齐
以这张图为例子: 我们定义一个int类型的变量,我们给他分配内存的方式: 对齐:0123 这几个内存给他 非对齐:1234、2345、3456这几个内存都给他。 有什么区别呢,我们把这个内存编址看成一层一层的楼,如果0123这四个人住在一起,他们及交流不需要上下楼,是不是比起1234,2345、3456这几种方式来说快捷很多啊。 再举个极端的例子,假设我们定义了2个变量,一个char类型,一个int类型。char类型先入住,把0号房间占用了,那么接下来的int类型住那几个房间呢,答案是4567,那么是不是123这三个房间就空了呢,是的没错。但是我们不在乎,我们有钱,空着就空着。因为现在内存不像原来那么贵重,所以我们可以适当的浪费内存,保证效率。就像我们去卖电脑,你不会去买运行慢的但是拥有一个1T内存的电脑来打游戏,而是会选择一个运行起飞的256G的电脑。 四、如何操作内存 4.1C 语言对内存地址的封装 举个例子:上面程序来说,的实质就是编译器帮我们申请了1个int类型的内存格子,并且把这个符号a与这个内存绑定,以后我们用a的时候,编译器就会直接找到对应的内存。但是我们不知道这个内存的地址,也不需要知道。 C语言数据类型的本质含义:表示一个内存的长度和解析方法。 如何理解:
还是用这张图,首先地址里面有个地方存放的是0,我们就认为这个0从表格上的0号格子开始存储。 (int ) 0;首先int占用4个字节,从0开始存放0这个整形数,编译器看到这个0是一个整形数,需要占用4个格子,然后就把0123这四个格子一起给他,才能装下。 (char) 0;char占用一个字节,从0开始存放0这个整形数,编译器看到这个0是一个字符型,只要一个格子,所以就把0这个格子给他就好了。 (int *)0;这是一个整形指针,占用4个字节,从0开始存放0这个整形数,编译器看到这个0是一个指针,需要占用4个格子,然后就把0123这四个格子一起给他,才能装下。 (char *) 0;这是一个字符指针,占用4个字节,从0开始存放0这个整形数,编译器看到这个0是一个指针,需要占用4个格子,然后就把0123这四个格子一起给他,才能装下。 可以看到的是,0还是0他没变,只是他穿了不同马甲,但是他代表的是他对应的内存,让编译器认为他是那种类型。编译器不去刨根问底。看到他是什么类型,就给他分配对应类型需要占用的地址。 换个说法就是 int a;和char b;这两个定义a和b其实没有啥区别,你换成 int b和char a也是一样的,他的本质差距就是代表的地址不一样和编译器看待他的类型不一样(解析方法)。 4.2 用数组访问内存 区别在哪里: int a:内存给a这个家伙分配4个字节大小的地址,并把为首的地址和a绑定起来. int b[10]:内存给b这个家伙分配40个字节大小的地址,并把为首素的的首地址和b绑定起来. 4.3用指针访问地址 记住一句话,指针就是地址。 int a; int *p; a和p都代表一个地址(假设为0x); int a代表的是以0x这个地址开头的四个格子里面存放的一个整形数。 int *p代表的是以0x这个地址开头的四个格子里面存放的一个地址,这个地址代表的内存单里面存放的是一个整形数。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/28823.html