First:sizeof是C++中的关键字,它是一个运算符,此关键字作用是取一个对象(数据类型或者结构对象)的长度,以byte为单位,
可以计算的对象包括:基本类型(当然不包括void)、用户自定义类型(结构体、共用体、类等)、函数类型。
十大特性:
0:sizeof是运算符,不是函数;
1:sizeof不能求得void类型的长
度;
2:sizeof能求得void类型的指针的长度;
3:sizeof能求得静态分配内存的数组的长度;
4:sizeof不能求得动态分配内存的大小;
5:sizeof不能对不完整的数组求长度;
6:sizeof当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值;
7:sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不能执行函数体;
8:sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和;
9:sizeof不能用于求结构体的维域成员的大小,但是可以求得包含维域成员的结构体的大小;
逐条说明:
0:sizeof是运算符,不是函数;
例如:
#include<iostream>
using namespace std;
int main()
{
char i[3]= {'a','b','c'};
int j;
//i = "abc";
j = sizeof(i);
cout<<"j="<<j<<endl;
return 0;
}
在本例子中,由于sizeof不是函数,因此并没有所谓的入口参数,习惯性叫i为操作数。
1:sizeof不能求得void类型的长度
例如函数:
#include<iostream>
using namespace std;
int main()
{
//char i[3]= {'a','b','c'};
//int j;
//i = "abc";
//j = sizeof(i);
//cout<<"j="<<j<<endl;
//return 0;
int i;
i = sizeof(void);
return 0;
}
本例中用sizeof求空类型所占的字节数,编译出现警告。
C:\Users\Administrator\Desktop\CodeLite\CodeLite\variable.cpp|12|warning: invalid application of 'sizeof' to a void type [-Wpointer-arith]|
2:sizeof能求得void类型的指针的长度
#include<iostream>
using namespace std;
int main()
{
int i,j,m,n;
i = sizeof(int*);
j = sizeof(void*);
m = sizeof(char*);
n = sizeof(double*);
cout<<"i="<<i<<endl;
cout<<"j="<<j<<endl;
cout<<"m="<<m<<endl;
cout<<"n="<<n<<endl;
return 0;
}
例如本例:返回结果如图:
几乎所有的类型编译平台都把指针的大小看做4byte。
3:sizeof能求得静态分配内存的数组的长度
非常需要注意的是对函数的形参数组使用sizeof的情况,举例:
#include<iostream>
using namespace std;
void fun(int array[10])
{
int n = sizeof(array);
cout<<"n="<<n<<endl;
}
int main()
{
//void fun(int array[10]);
//int n;
//int a[10];
int a[10];
fun(a);
//cout<<"n="<<n<<endl;
return 0;
}
结果返回4。如图:
4:sizeof不能求得动态分配内存的大小
这个不做过多的解释。
5:sizeof不能对不完整的数组求长度
如图:编译出现错误。
6:sizeof当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值
#include<iostream>
using namespace std;
int main()
{
char ch = 1;
int num = 4;
ch = ch+num;
int n1 = sizeof(ch+num);
int n2 = sizeof(ch);
cout<<"n1="<<n1<<endl;
cout<<"n2="<<n2<<endl;
return 0;
}
返回结果:
由于sizeof只关心类型大小,它自然不会对表达式求值,尽量不要在sizeof中直接对表达式求值,以免出现错误。
7:sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不能执行函数体
#include<iostream>
using namespace std;
double fun(int& num, const int& inc)
{
float div = 2.0;
double ret = 0;
num = num + inc;
ret = num/div;
return ret;
}
int main()
{
//int a= 3; b =5;
//fun(3,5);
int a = 4,b =9;
double c;
cout<<sizeof(fun(a,b))<<endl;
c =fun(a,b);
cout<<"c = "<<c<<endl;
return 0;
}
返回结果如图:
8:sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和
规则:1、结构体的大小等于结构体内最大成员大小的整数倍;
2、结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,ex:double型数据成员相对于结构体首地址的地址偏移量应该是8的整数倍。
3、为了满足规则1和规则2编译器在结构体成员之后进行字节补充。
#include<iostream>
using namespace std;
struct A
{
int num1;
int num2;
double num3;
};
struct B
{
int num1;//0-3,补4-7
double num3;//8-15
int num2;//16-19
};
int main()
{
//int a= 3; b =5;
//fun(3,5);
cout<<"A="<<sizeof(A)<<endl;
cout<<"B="<<sizeof(B)<<endl;
return 0;
}
返回结果:
9:sizeof不能用于求结构体的维域成员的大小,但是可以求得包含维域成员的结构体的大小
#include<iostream>
using namespace std;
struct A
{
bool b:1;
char ch1:4;
char ch2:3;
};
struct B
{
int num1;//0-3,补4-7
double num3;//8-15
char num2;//16-19
};
int main()
{
//int a= 3; b =5;
//fun(3,5);
cout<<"A="<<sizeof(A)<<endl;
cout<<"B="<<sizeof(B)<<endl;
return 0;
}
返回结果: