1、ANSI C正式规定字符类型为1字节。
sizeof(char)= 1;
sizeof(unsigned char) = 1;
sizeof(signed char)= 1;
2、其他类型在ANSI C中没有具体规定,大小依赖于实现。
sizeof(int)= 4;
sizeof(unsigned int)= 4;
sizeof(short int)= 2;
sizeof(unsigned short) = 2;
sizeof(long int)= 4;
sizeof(unsigned long)= 4;
sizeof(float)= 4;
sizeof(double)= 8;
sizeof(long double)= 12; //gcc 32-bit 编译器
sizeof(long double)= 16; //gcc 64-bit 编译器
3、当操作数是指针时,sizeof依赖于编译器。
学过数据结构的你应该知道指针是一个很重要的概念,它记录了另一个对象的地址。既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以字节为单位),在64位系统中指针变量的sizeof结果为8。
例如: char *p;
sizeof(p) = 4;//gcc 32-bit 编译器
sizeof(p) = 8;//gcc 64-bit 编译器
4、当操作数具有数组类型时,其结果是数组的总字节数。
例如: char a[5];
int b[5];
sizeof(a) = 5;
sizeof(b) = 20;
5、当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。
例如: sizeof(8) = 4; //自动转化为int类型
sizeof(8.8) = 8; //自动转化为double类型,注意,不是float类型
sizeof("ab") = 3 //自动转化为数组类型,
6、当操作数是联合类型时,sizeof是其最大字节成员的字节数。当操作数是结构类型时,sizeof是其成员类型的总字节数,包括补充字节在内。还是拿例子来说话:
union u{ //对union来说
char c;
double d;
}u;
sizeof(u) = max(sizeof(c),sizeof(d)) = sizeof(1,8) = 8;
struct a{ //对struct来说
char b;
double x;
}a;
sizeof(a) = 16; 而一般sizeof(char) + sizeof(double) = 9;
这是因为编译器在
时,在结构中插入空位以控制各成员对象的地址对齐。但如果全对齐的话,sizeof(a) = 16, 这是因为b被放到偏移量为0的地址,占1个字节;在存放x时,double类型长度为8,需要放到能被8整除的偏移量上,这时候需要补7个空字节, 达到8个,这时候偏移量为8,放上x后长度为16。
struct S1 { char c; double d; }; union u { //对union来说 char c; double d; } u; int a; char b; short c; double d; float f; int *p; char a1[]="abcd"; int a2[3]; printf("int=%d\n",sizeof(a)); printf("char=%d\n",sizeof(b)); printf("short=%d\n",sizeof(c)); printf("double=%d\n",sizeof(d)); printf("float=%d\n",sizeof(f)); printf("指针=%d\n",sizeof(p)); printf("数组=%d\n",sizeof(a1)); printf("数组=%d\n",sizeof("ab")); printf("结构体=%d\n",sizeof(S1)); printf("联合类型=%d\n",sizeof(u));
gcc 64-bit 编译器,指针=8;
类的sizeof
面试中遇到面试官让我求一个类的sizeof,里边有各种类型的变量,还有虚函数(但是不懂什么是虚函数)。如果有虚函数就要加上一个指向虚表的指针,4字节大小(32 位 编译器),64位编译器是8字节大小。 1、空类 class A{}; sizeof(A)=1; 求sizeof的结果是1,因为即使是没有成员之类的,一个类存在,至少都要给他一个空间,不然就没有存在的意义了。 class A{ int a; double b;};
本来sizeof(A.a)+sizeof(A.b)=12;结果=16,说明类的大小也遵守类似struct字节对齐的补齐规则,补齐为double类型8字节,所有为16 3、含虚函数的类 class A{ int a; virtual fun();};
//sizeof(A)=8+8=16 (gcc-64bit编译器,指针大小为8字节)+补齐规则 //sizeof(A)=4+4=8 (gcc-32bit编译器,指针大小为4字节) class Base{public: Base(); virtual ~Base(); //每个实例都有虚函数表 void set_num(int num) //普通成员函数,为各实例公有,不归入sizeof统计 { a=num; }private: int a; //占4字节 char *p; //4字节指针};class Derive:public Base{public: Derive():Base(){}; ~Derive(){};private: static int st; //非实例独占 int d; //占4字节 char *p; //4字节指针};
sizeof(Derive)=sizeof(Base)+sizeof(Derive.d)+sizeof(Derive.p) 的指针即可; sizeof(Derive)=sizeof(Base)+sizeof(Derive.d)+sizeof(Derive.p) 因为普通继承,子类和父类的虚函数存放在同一个虚表中,所以,只需要存一个指向虚表 4.子类虚继承、父类含虚函数 class Base{public: Base(); virtual ~Base(); //每个实例都有虚函数表 void set_num(int num) //普通成员函数,为各实例公有,不归入sizeof统计 { a=num; }private: int a; //占4字节 char *p; //4字节指针};class Derive:virtual public Base{public: Derive():Base(){}; ~Derive(){};private: static int st; //非实例独占 int d; //占4字节 char *p; //4字节指针};
sizeof(Derive)=sizeof(Base)+虚函数指针(指示父类存放空间的起始偏移量)+sizeof(Derive.d)+sizeof(Derive.p) 虚继承时,父类和子类的虚函数表分开放,所以,分别存储两个指向对应续表的指针,因而不用减去sizeof(A)中续表指针的大小。 1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。 2.普通成员函数与sizeof无关。 3.虚函数由于要维护在虚函数表,所以要占据一个指针大小字节。 4.类的总大小也遵守类似struct字节对齐的,调整规则。 参考:http://blog.csdn.net/hairetz/article/details/4171769 http://blog.sina.com.cn/s/blog_728161840100u2ib.html