1.定义
sizeof是C/C++中的一个操作符,其作用就是返回一个类型和对象在内存中占的字节数。
返回值的类型为size_t 定义为 typedefunsignedint size_t;
2.语法
sizeof有三种语法:
(1)sizeof(类型)
(2)sizeof(对象)
(3)sizeof 对象
int i;
cout<<sizeof(int)<<endl; //4
cout<<sizeof(i)<<endl; //4
cout<<sizeof i <<endl; //4
//cout<<sizeof int<<endl; //error
sizeof可以作用于表达式,但是不会对表达式求值
cout<<sizeof(2)<<endl; //4
cout<<sizeof(2+3.14)<<endl; //8,编译器不会进行计算
sizeof可以作用与函数,但是函数必须要有明确的返回类型,不能是void,sizeof作用于函数时并不会调用函数
char foo1()
{
cout<<"foo1"<<endl;
return 'a';
}
int foo2()
{
return 1;
}
void foo3()
{
}
cout<<sizeof(foo1())<<endl; //1,计算其返回值的类型
cout<<sizeof(foo2())<<endl; //4,不会调用函数
//cout<<sizeof(foo3())<<endl; //error,没有返回值类型
//cout<<sizeof(foo1)<<endl; //error函数要有()
3.sizeof的常量性
int n=10;
//int a[n]; //error
int a[sizeof(n)]; //ok,说明sizeof的常量性
4.基本数据类型的sizeof
和系统有关,下面是在vs2010-32bit下运行的结果
cout<<sizeof(int)<<endl; //4
cout<<sizeof(short)<<endl; //2
cout<<sizeof(char)<<endl; //1
cout<<sizeof(bool)<<endl; //1
cout<<sizeof(float)<<endl; //4
cout<<sizeof(double)<<endl; //8
cout<<sizeof(long)<<endl; //4
5.指针变量的sizeof
在32位系统中,指针占4个字节,在64位系统中,指针占8个字节
char *pc="abc";
int *pi;
string *ps;
char **ppc = &pc;
void (*pf)(); //函数指针
cout<<sizeof(pc)<<endl; //4
cout<<sizeof(pi)<<endl; //4
cout<<sizeof(ps)<<endl; //4
cout<<sizeof(ppc)<<endl; //4
cout<<sizeof(pf)<<endl; //4
6.数组的sizeof
注意数组作为函数参数时,传递的地址,这是数组名是指针而不代表数组
char a1[] = "abc";
int a2[3];
cout<<sizeof(a1)<<endl; //4,最后还有一个'\0'结束符
cout<<sizeof(a2)<<endl; //12=3*4
void foo4(char a[3])
{
cout<<sizeof(a)<<endl; //4,a在这里是一个指针,并不代表数组
}
void foo5(char a[])
{
cout<<sizeof(a)<<endl; //4
}
7.结构体的sizeof
这是sizeof考察的重点,主要涉及到内存对其的问题,详细参考上篇日记,c++-内存对齐
8.位域的sizeof
位域的成员不能单独求sizeof
使用位域的主要目的就是为了压缩存储,其规则如下:
(1)如果相邻位域的类型相同,并且两者内存之和小于其sizeof(类型),则后面的字段紧跟着前一个字段存储,直至不能容纳为止
(2)如果相邻位域的类型相同,并且两者内存之和大于其sizeof(类型),则后面的字段要从新的一个新的存储单元开始,其偏移量为此类型大小的整数倍
(3)如果相邻位域的类型不同,各编译器的具体实现不同,vc采取不压缩的方式
(4)如果位域字段之间穿插着非位域字段,则不进行压缩
(5)整个结构体的总大小为最宽基本类型成员大小的整数倍
struct bf1
{
char f1:3;
char f2:4;
char f3:5;
};
struct bf2
{
char f1:3;
short f2:4;
char f3:5;
};
struct bf3
{
char f1:3;
char f2;
char f3:5;
};
cout<<sizeof(bf1)<<endl; //2
cout<<sizeof(bf2)<<endl; //6,不压缩
cout<<sizeof(bf3)<<endl; //3,不压缩
9.联合体的sizeof
联合体共享一块内存,其sizeof值为最宽的数据类型的大小。复合类型成员要作为整体考虑
struct s1
{
int a;
double b;
};
union u1
{
char a;
int b;
double c;
};
union u2
{
char a;
s1 s;
};
cout<<sizeof(u1)<<endl; //8
cout<<sizeof(u2)<<endl; //16 要整体考虑s
10.枚举的sizeof
enum e{A,B,C,D};
cout<<sizeof(e)<<endl; //4,相当于一个int
11.类的sizeof
空类:值为1,因为空类要用能够实例化,要实例化就必须在内存中占有一定的空间
非空:只考虑成员变量的空间,static变量不考虑,成员函数不考虑,满足内存对齐原则
考虑虚函数,有虚函数就会有一个指向虚表的指针,只要有虚函数不管多少个就+4
主要规则:
class student
{
};
cout<<sizeof(student)<<endl; //1,空类为1,需要声明该类型的实例,就必须在内存中占有一定的空间
12.string的sizeof
cout<<sizeof(string)<<endl; //32
//cout<<sizeof()<<endl; //error
//cout<<sizeof(void)<<endl; //error
为什么还不清楚,没有找到string类的具体定义。