现在的位置: 首页 > 综合 > 正文

谈谈sizeof这个运算符(union+struct+数组)

2013年08月30日 ⁄ 综合 ⁄ 共 2206字 ⁄ 字号 评论关闭

谈谈sizeof这个运算符

我们在C编程的时候经常要用到sizeof,特别是在考试的时候,这往往是一个必考的知识点。

下面,我就我在编程中的理解,浅谈一下sizeof的一些问题,让朋友们在遇到它的时候,知道它到底是怎么一回事。不过在讲之前,先熟悉一下这个公式。

A % ( min(B,C) ) == 0         /*此公式不是我总结的,但文章是我根据这个公式写的*/

A:变量存放的地址     (Address)

B:变量所占的字节数 (Bytes)

C:现行的字节对齐数  (Current alignment modules)

 

还有一点需要主要的是,计算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的倍数(主要是为了保证当定义一个DATE数组的话,数组的第二个元素存放的起始位置正确)。

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’

抱歉!评论已关闭.