SIZEOF 及 结构体联合体大小计算方法.doc_第1页
SIZEOF 及 结构体联合体大小计算方法.doc_第2页
SIZEOF 及 结构体联合体大小计算方法.doc_第3页
SIZEOF 及 结构体联合体大小计算方法.doc_第4页
SIZEOF 及 结构体联合体大小计算方法.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SIZEOF 及 结构体联合体大小计算方法2010-09-06 16:30Cpp代码 / Example of the sizeof keyword size_t i = sizeof( int ); struct align_depends char c; int i; ; size_t size = sizeof(align_depends); / The value of size depends on / the value set with /Zp or / #pragma pack int array = 1, 2, 3, 4, 5 ; / sizeof( array ) is 20 / sizeof( array0 ) is 4 size_t sizearr = / Count of items in array sizeof( array ) / sizeof( array0 ); / Example of the sizeof keywordsize_t i = sizeof( int );struct align_depends char c; int i;size_t size = sizeof(align_depends); / The value of size depends on / the value set with /Zp or / #pragma packint array = 1, 2, 3, 4, 5 ; / sizeof( array ) is 20 / sizeof( array0 ) is 4 size_t sizearr = / Count of items in array sizeof( array ) / sizeof( array0 ); 1. 用法1.1 sizeof和new、delete等一样,是关键字,不是函数或者宏。1.2 sizeof返回内存中分配的字节数,它和操作系统的位数有关。例如在常见的32位系统中,int类型占4个字节;但是在16位系统中,int类型占2个字节。1.3 sizeof的参数可以是类型,也可以是变量,还可以是常量。对于相同类型,以上3中形式参数的sizeof返回值相同。Cpp代码 int a; sizeof(a); / = 4 sizeof(int); / = 4 sizeof(1); / = 4 int a;sizeof(a); / = 4sizeof(int); / = 4sizeof(1); / = 41.4 C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算s izeof值,即下面这些写法都是错误的。Cpp代码 void fn() sizeof(fn); / error:函数 sizeof(fn(); / error:不能确定类型 struct S int a : 3; ; S sa; sizeof( sa.a ); / error:位域成员 void fn() sizeof(fn); / error:函数sizeof(fn(); / error:不能确定类型struct Sint a : 3; S sa; sizeof( sa.a ); / error:位域成员1.5 sizeof在编译阶段处理。由于sizeof不能被编译成机器码,所以sizeof的参数不能被编译,而是被替换成类型。Cpp代码 int a = -1; sizeof(a=3); / = sizeof(a) = sizeof(int) = 4 coutaendl; / 输出-1。由于“=”操作符返回左操作数的类型,赋值操作没有执行。 int a = -1;sizeof(a=3); / = sizeof(a) = sizeof(int) = 4coutaendl; / 输出-1。由于“=”操作符返回左操作数的类型,赋值操作没有执行。2. 在32位系统中不同类型的内存分配2.1 基本类型Cpp代码 sizeof(int); / = 4 sizeof(double); / = 8 sizeof(char); / = 1 sizeof(bool); / = 1 sizeof(short); / = 2 sizeof(float); / = 4 sizeof(long); / = 4 sizeof(int); / = 4sizeof(double); / = 8sizeof(char); / = 1sizeof(bool); / = 1sizeof(short); / = 2sizeof(float); / = 4sizeof(long); / = 42.2 指针指针在32位系统中占4个字节。Cpp代码 sizeof(int *); / = 4 sizeof(double *); / = 4 sizeof(char *); / = 4 sizeof(int *); / = 4sizeof(double *); / = 4sizeof(char *); / = 42.3 数组2.3.1 数组的sizeof返回整个数组所占的字节数,即(数组元素个数每个元素所占字节)。Cpp代码 int ai = 1, 2; sizeof(ai); / = 2*4 = 8 int ai = 1, 2;sizeof(ai); / = 2*4 = 82.3.2 常量字符串与字符数组的内存分配方式相同。Cpp代码 char ac = abcd; /注意数组末尾的字符串终结符0 sizeof(ac); / = 5*1 = 5 sizeof(abcd); / = 5*1 = 5 char ac = abcd; /注意数组末尾的字符串终结符0sizeof(ac); / = 5*1 = 5sizeof(abcd); / = 5*1 = 52.3.3 数组和指针所占的字节数不同,应注意区分。Cpp代码 int *pi = new int10; /这是指针 sizeof(pi); / = 4 int ai10; int *p = ai; /这还是指针 sizeof(p); / = 4 double* (*a)36; /看成(double *) (*a)36,即一个36的二维数组,数组元素为指针,指向double类型。 sizeof(a); / = 4,a为指向上述二维数组的指针 sizeof(*a); / = sizeof(double *)*3*6 = 72,*a表示上述二维数组 sizeof(*a); / = sizeof(double *)*6 = 24,*a即*(*a),表示double*6,是元素为double指针的一维数组。 sizeof(*a); / = sizeof(double *) = 4,表示上述一维数组中的第一个元素,元素类型为double指针。 sizeof(*a); / = sizeof(double) = 8,表示上述数组首元素指向的double类型。 int *pi = new int10; /这是指针sizeof(pi); / = 4int ai10;int *p = ai; /这还是指针sizeof(p); / = 4double* (*a)36; /看成(double *) (*a)36,即一个36的二维数组,数组元素为指针,指向double类型。sizeof(a); / = 4,a为指向上述二维数组的指针sizeof(*a); / = sizeof(double *)*3*6 = 72,*a表示上述二维数组 sizeof(*a); / = sizeof(double *)*6 = 24,*a即*(*a),表示double*6,是元素为double指针的一维数组。sizeof(*a); / = sizeof(double *) = 4,表示上述一维数组中的第一个元素,元素类型为double指针。sizeof(*a); / = sizeof(double) = 8,表示上述数组首元素指向的double类型。2.3.4 函数形式参数中的数组会蜕变为指针,原因是数组参数“传址调用”,调用者只需将实参的地址传递过去。有一种情况例外,那就是参数是指向数组的指针。Cpp代码 void acf(char p3) /参数类型是int,表示指向int的指针 sizeof( p ); / = 4 void aif(int p) /参数类型是int,表示指向int的指针 sizeof( p ); / = 4 void pif(int (*p)6) /参数类型是int (*)6,表示指向int数组的指针 sizeof( p); / = 4 sizeof( *p ); / = sizeof(int)*6 = 24 void ppf(int *p6) /参数类型是int *,表示指向int指针的指针 sizeof( p ); / = 4 sizeof( *p ); / = 4 void acf(char p3) /参数类型是int,表示指向int的指针 sizeof( p ); / = 4void aif(int p) /参数类型是int,表示指向int的指针 sizeof( p ); / = 4void pif(int (*p)6) /参数类型是int (*)6,表示指向int数组的指针 sizeof( p); / = 4 sizeof( *p ); / = sizeof(int)*6 = 24void ppf(int *p6) /参数类型是int *,表示指向int指针的指针 sizeof( p ); / = 4 sizeof( *p ); / = 42.4. 类和结构体的内存分配。2.4.1 空类或空结构体占一个字节。class CEmpty ; sizeof(CEmpty); / = 1 struct SEmpty ; sizeof(SEmpty); / = 1 class CEmpty ;sizeof(CEmpty); / = 1struct SEmpty ;sizeof(SEmpty); / = 12.4.2 非空类和结构体所占字节为所有成员占字节的和,但是不包括成员函数和静态成员所占的空间。Cpp代码 class CInt : public CEmpty int i; ; sizeof(CInt); / = 4; class CFunc void f() ; sizeof(CFunc); / = 1; struct SInt : SEmpty static int i; ; sizeof(SInt); / = 1; class CInt : public CEmpty int i;sizeof(CInt); / = 4;class CFunc void f() ;sizeof(CFunc); / = 1;struct SInt : SEmpty static int i;sizeof(SInt); / = 1;2.4.3 字节对齐为了加快计算机的取数速度,编译器默认对内存进行字节对齐。对结构体(包括类)进行字节对齐的原则是:1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。Cpp代码 struct SByte1 double d; / 偏移量07 char j; / 偏移量8 int a; / 偏移量1215,由于9不能整除4,故先填充911 ; sizeof(SByte1); / = 16 struct SByte2 char j; / 偏移量0 double d; / 偏移量815,由于1不能整除8,故先填充17 int a; / 偏移量1619 ; sizeof(SByte2); / = 24,为了凑成8的倍数,填充2023 struct SByte1double d; / 偏移量07char j; / 偏移量8int a; / 偏移量1215,由于9不能整除4,故先填充911; sizeof(SByte1); / = 16struct SByte2 char j; / 偏移量0double d; / 偏移量815,由于1不能整除8,故先填充17int a; / 偏移量1619; sizeof(SByte2); / = 24,为了凑成8的倍数,填充2023另外,可以通过#pragma pack(n)来设定变量以n字节对齐方式。Cpp代码 #pragma pack(push) /保存对齐状态 #pragma pack(4) /设定为4字节对齐 class CByte char c; /偏移量0 double d; /偏移量411,由于1不能整除4,故先填充13 int i; /偏移量1215 ; #pragma pack(pop) /恢复对齐状态 sizeof(CByte); / = 16 #pragma pack(push) /保存对齐状态#pragma pack(4) /设定为4字节对齐class CBytechar c; /偏移量0double d; /偏移量411,由于1不能整除4,故先填充13int i; /偏移量1215;#pragma pack(pop) /恢复对齐状态sizeof(CByte); / = 162.4.4 位域有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。2.4.4.1 位域以比特位作为单位,其长度不能大于一个字节。一个位域必须存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。Cpp代码 struct SBit1 char a : 3; char b : 4; char c : 5; ; sizeof(SBit1); / = (3+4+1+5+3) bits = 2 bytes struct SBit1 char a : 3; char b : 4; char c : 5;sizeof(SBit1); / = (3+4+1+5+3) bits = 2 bytesSBit1:| a 3+ b 4 + # 1 | c 5 + # 3 |2.4.4.2 使用空域可以有意使某位域从下一单元开始,但是空域不能使用。Cpp代码 struct SBit2 char a : 3; char : 0; / 空域 char b : 4; char c : 5; ; sizeof(SBit2); / = (3+4+1+5+3) bits = 3 bytes struct SBit2 char a : 3; char : 0; / 空域 char b : 4; char c : 5;sizeof(SBit2); / = (3+4+1+5+3) bits = 3 bytesSBit2:| a 3 + # 5 | b 4 + # 4 | c 5 + # 3 |2.4.4.3 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C+采取压缩方式。Cpp代码 struct SBit3 char a : 3; short b : 4; char c : 5; ; sizeof(SBit3); / = 6 bytes,由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C+中为2。 struct SBit3 char a : 3; short b : 4; char c : 5;sizeof(SBit3); / = 6 bytes,由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C+中为2。SBit3(不压缩):| a 3 |

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论