C/C++ 深入理解计算机各种类型大小(sizeof)
2016-12-24 17:18
447 查看
1.用法
1.1 sizeof和new、delete等一样,是关键字,不是函数或者宏。
1.2 sizeof返回内存中分配的字节数,它和操作系统的位数有关。例如在常见的32位系统中,int类型占4个字节;但是在16位系统中,int类型占2个字节。
1.3 sizeof的参数可以是类型,也可以是变量,还可以是常量。对于相同类型,以上3中形式参数的sizeof返回值相同。
int a; sizeof(a); // = 4 sizeof(int); // = 4 sizeof(1); // = 4
1.4 C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算s
izeof值,即下面这些写法都是错误的。
sizeof(fn); // error:函数 sizeof(fn()); // error:不能确定类型 struct S { int a : 3; }; S sa; sizeof( sa.a ); // error:位域成员
1.5 sizeof在编译阶段处理。由于sizeof不能被编译成机器码,所以sizeof的参数不能被编译,而是被替换成类型。
int a = -1; sizeof(a=3); // = sizeof(a) = sizeof(int) = 4 cout<<a<<endl; // 输出-1。由于“=”操作符返回左操作数的类型,赋值操作没有执行。
2. 在32位系统中不同类型的内存分配
2.1 基本类型
sizeof(int); // = 4 sizeof(double); // = 8 sizeof(char); // = 1 sizeof(bool); // = 1 sizeof(short); // = 2 sizeof(float); // = 4 sizeof(long); // = 4
2.2 指针
指针在32位系统中占4个字节。
sizeof(int *); // = 4 sizeof(double *); // = 4 sizeof(char *); // = 4
2.3 数组
2.3.1 数组的sizeof返回整个数组所占的字节数,即(数组元素个数×每个元素所占字节)。
int ai[] = {1, 2}; sizeof(ai); // = 2*4 = 8
2.3.2 常量字符串与字符数组的内存分配方式相同。
char ac[] = "abcd"; //注意数组末尾的字符串终结符'\0' sizeof(ac); // = 5*1 = 5 sizeof("abcd"); // = 5*1 = 5
2.3.3 数组和指针所占的字节数不同,应注意区分。
int *pi = new int[10]; //这是指针 sizeof(pi); // = 4 int ai[10]; int *p = ai; //这还是指针 sizeof(p); // = 4 double* (*a)[3][6]; //看成(double *) (*a)[3][6],即一个3×6的二维数组,数组元素为指针,指向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 函数形式参数中的数组会蜕变为指针,原因是数组参数“传址调用”,调用者只需将实参的地址传递过去。有一种情况例外,那就是参数是指向数组的指针。
void acf(char p[3]) //参数类型是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 *p[6]) //参数类型是int *[],表示指向int指针的指针 { sizeof( p ); // = 4 sizeof( *p ); // = 4 }
2.4. 类和结构体的内存分配。
2.4.1 空类或空结构体占一个字节。
class CEmpty { }; sizeof(CEmpty); // = 1 struct SEmpty { }; sizeof(SEmpty); // = 1
2.4.2 非空类和结构体所占字节为所有成员占字节的和,但是不包括成员函数和静态成员所占的空间。
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)。
struct SByte1 { double d; // 偏移量0~7 char j; // 偏移量8 int a; // 偏移量12~15,由于9不能整除4,故先填充9~11 }; sizeof(SByte1); // = 16 struct SByte2 { char j; // 偏移量0 double d; // 偏移量8~15,由于1不能整除8,故先填充1~7 int a; // 偏移量16~19 }; sizeof(SByte2); // = 24,为了凑成8的倍数,填充20~23
另外,可以通过#pragma pack(n)来设定变量以n字节对齐方式。
#pragma pack(push) //保存对齐状态 #pragma pack(4) //设定为4字节对齐 class CByte { char c; //偏移量0 double d; //偏移量4~11,由于1不能整除4,故先填充1~3 int i; //偏移量12~15 }; #pragma pack(pop) //恢复对齐状态 sizeof(CByte); // = 16
相关文章推荐
- 深入理解计算机各种类型大小(sizeof)
- 深入理解计算机各种类型大小(sizeof)
- 深入理解计算机各种类型大小(sizeof)
- 深入理解计算机各种类型大小(sizeof)
- [深入理解C++(一)]类型转换(Type Casting)
- C++:深入理解sizeof
- 深入理解C++浮点数(float、double)类型数据比较、相等判断
- 深入理解 C++ 指针(六)---指针和结构类型的关系
- [深入理解C++(一)]类型转换(Type Casting)
- 有关sizeof 数组名的问题 数组名和指针的深入理解(C++)
- C++主要数据类型在计算机中所占字节大小
- 深入理解2层的各种vlan端口类型
- C++——深入理解sizeof
- 深入理解C++浮点数(float、double)类型数据比较、相等判断
- 深入理解C语言-----各数据类型大小
- 深入理解C++标准类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- 【笔试面试知识点查缺补漏深入理解之C与C++篇】C/C++语言中的sizeof 深入理解
- 【转】c++各种数据类型所占存储空间大小
- C++中各种空类以及继承空类后的sizeof大小
- sizeof()的使用及各种数据类型的字节大小