空结构体:对于空结构体,就是只有结构体这个模子,但里面却没有元素的结构体。数组
例:ide
typedef struct studenturl
{spa
}std;blog
这种空结构体的模子占一个字节,sizeof(std)=1。内存
柔性数组:get
结构体中最后一个元素能够是一个大小未知的数组,称做柔性数组成员,规定柔性数组前面至少有一个元素.it
typedef struct studentio
{class
int i;
char arr[]; //柔性数组成员
}std;
sizeof(std)=4;
sizeof求取该结构体大小是不包含柔性数组的大小,柔性数组无论有没有大小都不计入结构体的大小,能够经过动态内存为它实现内存分配。
内存对齐:
对于字(天然边界是偶数地址),双字(天然边界是能被4整除的地址),四字(天然边界是能被8整除的地址)自己就是对齐的。为何要对齐呢?这是由于对于对齐的内存只须要一次内存访问,对于未对齐的内存,处理器要两次内存访问。
未对齐:一个字或者双字跨越了4字节边界,或者双字跨越了8字节边界,须要两次内存访问。
对于结构体,联合体在计算其大小时要考虑其内存对齐,以结构中所占字节数最大的类型类型对齐。
例:
struct test
{
char a1;
short b2;
char c3;
int d4;
};
由于其中int类型所占字节最多,因此以4字节对齐,内存分配方式以下,总共占12个字节:
分析:由于以4字节对齐,首先char a1占一个字节存到00处,short b2 是字占两个字节 ,以偶数地址对齐,因此不能直接存到01 02 上,而应该存到02 03上,而空出来的01就会被浪费掉。同理,当char c3存到04上后,对于int i,双字必需要存到4的倍数的地址上,就只能存到08 09 0a 0b上,空出来的05 06 07会被浪费掉。
struct test
{
char a1;
char c3;
short b2;
int d4;
};
一样的,以4字节对齐,总共占8个字节:
这是由于a1存到00,c3存到01,b2恰好存到02 03上,以偶数地址对齐,d4也恰好从04开始存储,以4字节对齐,没有浪费内存。
大端字节序:高字节存储在低地址,低字节存储在高字节处
小端字节序:低字节存储在低地址,高字节存储在高地址处
计算机的最小存储单位是字节,一个字节占8bit位。
以int为例:
例如:1的二进制码是
00000000 00000000 00000000 00000001
写成十六进制形式 :00 00 00 01这就表明了4个字节,而内存是从低地址到高地址的,这样就产生了两种存储方式。
由于存储方式方式的不一样,读取时也就产生了两种方式。
通常读取是从低地址向高地址读取,为了将存储与读取统一取来,因此采用小端存储,这样的话,低字节存到低地址,高字节存到高地址。
验证方法:
一、能够声明一个int a=1,再声明一个char *p=&a;由于a占4个字节,char *一次向后访问一个字节,因此若是是小端的话在电脑上输出*p应该是1.
二、也能够用union,由于union是内存公用,因此声明一个int a,char c;对a赋值为1,输出c观察结果。
有些问题若是不考虑大小端的话是根本想不明白的。