sizeof:是一个关键字,不是函数。(计算对象所占空间的字节数,包括'\0')
举例证明sizeof是关键字而不是函数:
①int i; printf("%d\n",sizeof i);
②sizeof(fun());fun函数没有调用,因为sizeof是在预编译期间完成的。
字节对齐的好处:有助于加快计算器的取数速度,否则就会多花指令周期。
其实就是提高程序的性能,也就是让处理器少访问一次内存。
sizeof的三种正确的用法:
①sizeof (int);
②sizeof(i);
③sizeof i;
错误的用法:sizeof int;
注意:用sizeof计算结构体时,指针时占用四个字节的(和类型无关)。
如:
struct Test
{
intNum;
char*Pc;//这里是4,不是1,特别注意一下。
shortsDtate;
charch[2];
shortS[4];
}*p;
sizeof和strlen的注意点对比:
1.测试一
func(char *str)
{
printf("%d",sizeof(str));//这里是4,指针
printf("%d",strlen(str));//这里是9
}
int main(void)
{
chara[]="123456789";
printf("%d",sizeof(a));
printf("%d",strlen(a));
func(a);
}
结果: 10 9 4 9
2.测试二
void Func ( char str[100] )
{
sizeof(str ) = ?
}
void *p = malloc(100 );
sizeof ( p ) = ?
解答:
sizeof( str ) = 4
sizeof ( p ) = 4
3.测试静态数组的大小
sizeof(str)/sizeof(str[0])
以下测试函数里动态数组是错误的做法。
void Func ( char str[] )
{
int a = sizeof(str)/sizeof(str[0]);//这里计算出来是4/1=4,不是想要的结果。
}
数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,
如:
fun(char [8])
fun(char [])
都等价于 fun(char *)
复杂测试:
测试一:
union data1
{
doubled;
inti;
charc1;
charc2[9];
};
sizeof(uniondata1)的值为16;本身最大是9,所以按照8字节对齐为16;
如果是:
struct data1
{
doubled;
inti;
charc1;
charc2[9];
};
sizeof(structdata1)的值为24, 首先按照存储大小, 该结构体所占存储空间为: 8+4+1+9=22字节, 这个结构体也是以8对齐, 因此实际分配的是24字节。只是这里的情况可以快速的计算。下面会有差异性的例子。
这就是结构体和共用体大小的区别。注意下。
计算方法总结:
共用体:先找出最大占用字节数和最大字节对齐数。然后占用最大占用字节是必须是对齐字节的倍数。
结构体:先找出最大占用字节数和最大字节对齐数。先相加然后是对齐字节的倍数。
小检测一:
union data2
{
inti;
charc1;
charc2[9];
};
sizeof(uniondata2)的值为12, 该共用体占内存空间最大的基本数据类型为int,其长度为4, 所以该共用体以4来对齐。 该共用体的长度取决于字符c2, 其长度为9,9不是4的倍数, 要进行对齐, 因此实际分配的存储空间为12.
struct data2
{
inti;
charc1;
charc2[9];
};
sizeof(structdata2)的值为16, 与上面共用体一样, 该结构体以4对齐。 按照存储大小, 该结构体所占存储空间为: 4+1+9=14, 14不是4的倍数, 进行对齐,对齐后的值为16.
小检测二:
union data3
{
charc1;
charc2[3];
};
sizeof(uniondata3)的值为3, 该共用体占内存空间最大的基本数据类型为chart,其长度为1, 所以该共用体以1来对齐。 该共用体的长度取决于字符c2, 其长度为3,因此分配的存储空间为3.
struct data3
{
charc1;
charc2[2];
};
sizeof(structdata3)的值为3, 与上面共用体一样, 该结构体以1对齐。 按照存储大小, 该结构体所占存储空间为: 1+2=3字节。
差异性来了
测试二:
struct inner
{
charc1;
doubled;
charc2;
};
这个结构体显然是8字节对齐的,在给c1分配存储空间时, 考虑到对齐, 分配给c1的字节数就是8, 然后给d分配8字节, 最后给c2分配时, 因为也要以8对齐,所以也分配了8个字节的存储空间。 所以sizeof(struct inner)值为24.
如果是:
struct inner
{
charc1;
charc2;
doubled;
};
当然这个结构体也是以8字节对齐的,编译器编译程序时, 给c1、 c2分配存储空间没有必要各自给它们分配8字节, 只要8字节就可以了。 给d分配8字节, 所以sizeof(structinner)值为16.
测试三:
struct data
{
inta;
long b;
double c;
float d;
char e;
short f;
}d;
这个结构体所占的字节数是多少呢?这里假设long所占字节数为4字节, short占2字节。 这个结构体与示例4中第二个struct inner类似。 首先这个结构体是以8字节对齐的,因为最长基本数据类型为double, 它占8字节, d、 e、 f、 总和为7个字节。 分配存储空间时, 成员 a和b各分配4字节, d分配4字节,f分配2字节, e也分配2字节。 d、 e、 f总和刚好占8个字节, 所以sizeof(struct data)值为24.
struct data
{
int a;
long b;
double c;
float d;
chare[3];
short f;
}d;
sizeof(structdata)值为32
测试四:
已知运行这个程序的主机中数据类型long占8字节, 请分析程序的运行结果。
#include<stdio.h>
int main()
{
structdata
{
longl;//8
char*s;//4,注意
shortint i;//2
charc;//1+1
shortint a[5];//10
}d;
structdata *p=&d;
printf("%d\n",sizeof(d));
printf("%x\t%x\n",p,p+1);
printf("%x\t%x\n",p,(char*)p+1);
printf("%x\t%x\n",p,(long*)p+1);
return0;
}
运行结果:
linux测试是:32 //VC测试是24