C语言第二篇:内存分析(一)(C语言)
上一节我们知道C语言中有很多种数据类型,这些数据类型在内存中是如何存储的呢?
下面我们来分析一下
一、int型基本数据类型变量在内存中的存储
上代码
模拟内存存储:
结论:
1、局部变量在内存中是由高地址向低地址的顺序存储的
2、地址的寻址方式也是从高到低
3、4个字节的int类型数据在内存中高地址存储高位
4、但变量的地址是由最低字节的地址确定
char、float等基本类型类似int的存储
注意:1、数据类型的长度和编译器有关糸
2、int型数据默认是有符号的
二、共用体构造类型数据变量在内存中的存储
结构体产生的原因:数组可以存储一组数据,但是这一组数据必须是同种类型,但现实生活中,很多事物都需要多种数据才能描述,例如 人,年纪是一个整型,但是身高却是一个浮点型,因此用数组就不能完整描述这个人的信息
1.结构体也是一种数据类型,和int、float一样代表一种数据类型,只不过,int、float等基本数据类型,编译器已经知道他们的类型,当使用他们进行定义时会分配相应的内存,以及把对应的变量名称和变量所在的内存的首地址关联,但是结构体数据定义前,编译器不知道它包含的数据,因此使用结构体之前必须定义机构体。
上代码
结论
1、结构体也是一种数据类型,参照int 数据类型来使用,扩展 共用体、指针乃至类 这种类推的悟性很重要,下面有彩蛋会讲一下类在内存中的存储
int、float、double等基本数据类型和数组、指针、结构体、枚举、乃至类等构造数据类型,看起来都不 太一样,其实我们要抓住他们的共同点,(就像矛盾的普遍性和特殊性一样),只有掌握了共同点,我们才能真正的理解他们,我们才不会被他们之间的差别所迷惑。他们的共同点就是都是数据类型,都是一种数据存储的结构,例如int类型是一种4字节的数据,编译的时候,编译器就会分配给他4个字节的存储空间,并且把其定义的变量名称和存储的地址绑定起来,这样编译器对这个变量访问的时候,就知道访问那个地址,以及包括几个字节。如果定义的是结构体(其实类的本质也是结构体,只不过它相比较只是多存储了一些方法而已),编译器根据结构体的定义例如上文的person类,就分配12个字节给这个结构体.既然是数据类型、那就都可以作为变量,函数返回值、形参来使用,当然在使用过程中要注意他们的不同
2、typedefine 好处
3、结构体指针的用法 —>
C语言 语法规定, 在通过指针来访问结构体变量时, 若想访问结构体变量中的属性, 要用 "->" 来访问
下图这也从侧面说明了 OC 中的类本质也是结构体
OC 语法规定,对象中的结构体属性中的属性是不允许作单独修改的
其实对象中的结构体属性中的属性是允许作单独修改的, 不过前提是能直接拿到这个结构体属性, 也就是说类要直接给外界暴露属性, 但这是非常不符合面向对象语言中封装特性的. 一般我们只会定义 @property 属性, 相当于生成了私有属性, 并且提供给外界 get 方法和 set 方法, 外界并不能直接拿到我们的属性, 所以说在一般开发中,对象中的结构体属性中的属性是不允许作单独修改的这句话虽然不正确, 但也能够解释大部分的问题了)
还有一个例子证明不用set/get方法而直接暴露属性是不好的 ,如在kvo中,kvo的原理是runtime生成NSKVONotifcation_xx类,xx类实例对象中的isa指向了NSKVONotication类对象,这样在xx.age = 10;执行该句代码时,实际上是到isa所指向的NSKVONotication类对象中的方法列表中找setage方法,如果age是直接暴露在外,则KVO也不能观察到属性的变化
(4) 结构体用名称 点语法
(5)结构体 内存大小按照最大成员变量的倍数 内存对齐
(6)sizeof 的妙用 num/int 数组中的个数
(7)结构体的名称不是首个成员的地址和数组有区别,机构体的地址就是第一个成员的地址