谈谈sizeof这个运算符
我们在C编程的时候经常要用到sizeof,特别是在考试的时候,这往往是一个必考的知识点。
下面,我就我在编程中的理解,浅谈一下sizeof的一些问题,让朋友们在遇到它的时候,知道它到底是怎么一回事。不过在讲之前,先熟悉一下这个公式。
A % ( min(B,C) ) == 0 /*此公式不是我总结的,但文章是我根据这个公式写的*/
A:变量存放的地址
B:变量所占的字节数
C:现行的字节对齐数
还有一点需要主要的是,计算struct的sizeof,如果最后一个成员变量没有占满字节对齐要求的地址数时,要知道补几个padding。
先看下面一题:
/****************************************************/
union A
{
long i;
short int k[5];
char c;
}DATE;
struct B
{
short int cat;
char sheep;
DATE cow;
double dog;
}too;
DATE max;
求:sizeof(struct date)+sizeof(max)的值。
/****************************************************/
我们来一步步的拆分。
union A
{
long i;
short int k[5];
char c;
}DATE;
首先要声明一点,计算机默认情况下是4字节对齐的。
我们知道,i占4个字节,k占10个字节,c占一个字节,由于AA是一个union,它的成员都是共用内存的,所以A的大小应该取决于数组k的大小,那么,A的大小具体是多少呢?是10吗?显然不是,因为字节要对齐的原因,且系统默认为4字节对齐,所以A实际上为12字节,也就是在10的基础上还要补上2个padding,以保证A中的long型的成员变量正确对齐4的倍数。
union的sizeof表示该类型中所有成员所需的存储空间量,包括成员和成员后面未用的填充空间,规则是联合要填充到该类型数组的元素可能占用的长度(对任何类型,包括union,其n个元素组长度的n倍)。
struct B
{
short int cat;
char sheep;
DATE cow;
double dog;
}too;
这里,cat占2个字节,sheep占1个字节,cow占12个字节,dog占8个字节,struct和union不一样,它的大小是所有成员大小之和,由于要对齐的原因,它绝对不是简单的23(2+1+12+8)字节了。下面看实际情况。
字节数 |
× |
× |
× |
○ |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
存放地址 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
×:代表变量占的1个字节;
○:代表字节对齐时的字节补位
为什么会这样呢?
1. 变量cat,占2字节。字符都是从0开始存放的,所以0,1字节理所当然的存放变量cat;
2. 变量sheep,占1字节。它的存放就要参考公式“A % ( min(B,C) ) == 0”了。此时A=2,B=1,C=4,min(B,C)=1,2%1==0,满足条件,不需要字节补位,所以2字节存放变量sheep;
3. 变量cow,占12字节。此时A=3,B=12,C=4,min(B,C)=4,3%4 != 0,所以需要字节补位,补1位之后,A=4,4%4 == 0,满足条件,然后cow就存放在4至15字节;
4. 变量dog,占8字节。此时A=16,B=8,C=4,min(B,C)=4,16%4 == 0,不需要字节补位,dog放在16至23字节。
所以,sizeof(struct B)=24,由此可见,sizeof(struct B)+sizeof(max)的值为24+12=36。
再看下面的代码:
union AAA
{
struct
{
char a;
short b;
char c;
}half;
long d;
}number;
我们运行之后,得到下面结果
sizeof(union AAA)=8
sizeof(number.half)=6
结构体成员的大小为6,而union的大小为8。
char a占1个字节;short b占2个字节;char c占1个字节,利用公式“A % ( min(B,C) ) == 0”得知:
字节数 |
× |
○ |
× |
× |
× |
○ |
存放地址 |
0 |
1 |
2 |
3 |
4 |
5 |
三个成员只占用了5个字节,但是要保证占2字节的short b字节对齐,也就是必须是2的倍数,所以必须补一个padding,因此sizeof(number.half)=6。
对union而言,有两个成员,一个是6字节struct,另外一个是4字节的long d,union的大小取决于struct,还是刚刚的原因,必须在6字节后面在补2个padding,成为4的倍数,以保证d能够字节对齐。
char *p=”world cup”;
char a[]=”world cup”;
strlen(p)=9
strlen(a)=9
sizeof(p)=4
sizeof(a)=10
sizeof(*p)=1
strlen()是函数,包含在string.h里,计算字符串的长度,不包含’\0’
sizeof()是运算符,运算字符串所占的空间大小,包含’\0’