1.10sizeof关键字

来源:互联网 发布:网络高科技犯罪电视剧 编辑:程序博客网 时间:2024/06/06 02:14

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