一.sizeof,是个运算符不是一个函数,字节数的计算在程序编译时进行,而不是在程序执行的过程中才计算出来。
1.sizeof操作符的结果的类型为size_t,在头文件中使用typedef重新定义的,它的原始数据类型为unsigned int类型(无符号整形),该类型保证能容纳实现所建立的最大对象的字节数。
2.和strlen的区别
strlen是个函数而sizeof是运算符;sizeof可以使用数据类型做参数,strlen只能使用char *类型指针做参数,并且必须是要以"\0"来结尾.
另外sizeof 还可以使用函数做参数,例:
short func();
printf(“%d\n”, sizeof(func()));
结果为sizeof(short) = 2;
数组做sizeof的参数不退化,传递给strlen就退化为指针。
char a[20] = "0123456789";
printf("%d\n", sizeof(a));
printf("%d\n", strlen(a));
打印的结果为20、10.
strlen的结果要运行的时候才能计算出来,用来计算字符串的长度,而不是数据类型所占内存空间的大小。
当使用了一个结构体类型或变量时,sizeof返回实际大小,当使用一静的空间数组时,sizeof返回全部数组的尺寸,sizeof不能返回动态分配的数组或外部数组的尺寸。
数组作为参数传给函数时,传的是指针,也就是数组的首个元素的地址;如func(char a[8])、func(char a[]) ,等价于func(char *)
计算结构体大小就必须讨论数据数据对齐,为了使CPU存取的速度最快,C++在处理数据时经常把结构体中的成员变量按4或8 的倍数计算,这就是数据对齐。
二.结构体,共同体大小计算。
1.在计算结构体大小时要4或8的倍数计算,就是上面说数据对齐;
例子:
/*32位机上计算以下结构体的大小*/
struct ss
{
short a;
char b;
int c;
char d;
};
printf("%d\n", sizof(struct ss));
打印结果为 12.
解析: 第一个成员a是结构体的首地址,short类型所占的空间大小为2个字节,所以偏移量为0,所以从0开始偏移
偏移量 补充字节 成员大小
0 0 2
2 0 1 //第二个成员b为char类型,偏移量 = 上一个成员偏移量 + 补充字节 + 成员大小;因为2能被1整除所以不用补充字节,中间为0
3 1 4 //第三个成员的偏移量 = 上一个成员偏移量 + 补充字节 + 成员大小=2+0+1=3,;因为3不是4的倍数不能被4整除所以加1
8 0 1//计算方法同上
结构体大小 sizeof(struct ss) = 8 + 0 + 1 = 9,但是上面已经说过,在计算结构体大小时要4或8的倍数计算,就是上面说数据对齐;所以9要再加3也就是12,才能被4整除
最终结构体大小sizeof(struct ss) = 8 + 0 +1 = 9; 9+3 = 12.最终结构体大小为12个字节。
2.共同体
在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共同体”类型结构,简称共同体,也叫联合体。
union{
char value[10];
int size;
double type;
};
这个共同体的大小为10,因为共同体的大小就是变量覆盖,以最大的成员为主;上面结构体中第一个成员 value = 10 * 1= 10字节;第二个成员 size = sizeof(int) = 4;第三个type = sizeof(long) = 8;最大的成员会覆盖所有成员,所以最终共同体的大小为10字节,
再看下面的例子:
/*32位机上,计算以下几个数据类型的大小*/
struct ss
{
short a;
char b;
int c;
union{
char value[10];
int size;
double type;
};
char d;
};
以上代码要是sizeof(ss) 会等于多少呢?
解析:同上面的计算。
偏移量 补充字节 成员大小
0 0 2 //第一个成员
2 0 1 //第二个成员方法同上
3 1 4 //第三个成员
8 2 10 //第四个成员共同体,大小以最大的成员为主。
20 0 1 // 第五个成员d
sizeof(ss) = 20 +1 = 21.但21不能被4整除所以要加上3 最终sizeof(ss) = 20 + 1+ 3 = 24.