c语言 sizeof详解
来源:互联网 发布:mac相簿照片如何导出 编辑:程序博客网 时间:2024/06/08 14:06
sizeof的概念
sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。sizeof的使用方法
1、用于数据类型 sizeof使用形式: sizeof(type)
数据类型必须用括号括住: sizeof(int)
2、用于变量
sizeof使用形式: sizeof(var_name) 或 sizeof var_name
变量名可以不用括号括住.如sizeof (var_name),sizeof var_name等都是正确形式
注意:sizeof操作符不能用于函数类型,不完全类型或位字段。
例如: sizeof(max)
sizeof的结果
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。
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;
gcc 32-bit 编译器,指针=4
类的sizeof
面试中遇到面试官让我求一个类的sizeof,里边有各种类型的变量,还有虚函数(但是不懂什么是虚函数)。如果有虚函数就要加上一个指向虚表的指针,4字节大小(32 位 编译器),64位编译器是8字节大小。
1、空类
class A{}; sizeof(A)=1;
求sizeof的结果是1,因为即使是没有成员之类的,一个类存在,至少都要给他一个空间,不然就没有存在的意义了。
class A{}; sizeof(A)=1;
求sizeof的结果是1,因为即使是没有成员之类的,一个类存在,至少都要给他一个空间,不然就没有存在的意义了。
2、简单的类
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字节)
//sizeof(A)=4+4=8 (gcc-32bit编译器,指针大小为4字节)
3、子类继承父类,含虚函数
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字节指针};
gcc-32bit编译器
sizeof(Base)=12;
sizeof(Derive)=20
sizeof(Derive)=sizeof(Base)+sizeof(Derive.d)+sizeof(Derive.p) 的指针即可;
gcc-64bit编译器
sizeof(Base)=24; //补齐规则
sizeof(Derive)=40
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)中续表指针的大小。
类的sizeof总结:
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小字节。
4.类的总大小也遵守类似struct字节对齐的,调整规则。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小字节。
4.类的总大小也遵守类似struct字节对齐的,调整规则。
参考:http://blog.csdn.net/hairetz/article/details/4171769
http://blog.sina.com.cn/s/blog_728161840100u2ib.html
0 0
- C语言详解sizeof
- c语言详解sizeof
- C语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- C语言sizeof详解
- C语言sizeof详解
- c语言--sizeof详解
- c语言详解sizeof
- C语言详解 sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- c语言详解sizeof
- Spring 定时任务之 @Scheduled cron表达式
- <c:forEach> 循环<a> 标签 发送其他DELETE、PUT、POST请求
- nginx 配置去掉URL中工程名
- 如何完成一个有效的面试——善用STAR法则
- 使用maven搭建hadoop环境
- c语言 sizeof详解
- Dependencies 报错之 版本号
- 判断10个数互不相同模板
- Android ADB命令
- 尚硅谷java基础学习笔记之java语言概述
- win7下python2.7 ImportError: No module named 'MySQLdb'错误解决方法
- 测试(三)
- ajax的创建
- DataBase: oracle表字符数过长