sizeof的特性
sizeof是运算符
看下面示例,可以看出,没有引入啥函数头文件,也没有啥函数声明,但仍能编译成功,说明 sizeof
是关键字(也可以认为是单目运算符,因此我们不把它括号中所要处理的对象叫参数),而不是函数。
int main(void)
{
int a=sizeof(int);
return 0;
}
结论:sizeof是关键字,不是函数也不是预定义标识符。
sizeof不能求得 void 类型的长度
void是空类型,编译器无法确定 void 类型的变量的存储大小
sizeof(void); //导致编译错误: illegalsizeof operand
void a; //编译器同样会报错: illegal use of type 'void'
sizeof能求得 void * 类型的长度
指针变量所占字节数取决于系统位数,这里我是64位,所以得到的是64bit/8=8byte;如果是32位系统,得到的会是4
#include<iostream>
using namespace std;
int main(int argc,char *argv[])
{
int x;
int a=1;
float b=1.0;
char c='y';
int* p1=&a;
float* p2=&b;
char* p3=&c;
void* p4;
cout<<sizeof(x)<<endl; //4
cout<<sizeof(p1)<<endl; //8
cout<<sizeof(p2)<<endl; //8
cout<<sizeof(p3)<<endl; //8
cout<<sizeof(p4)<<endl; //8
return 0;
}
求静态分配内存的数组长度
首先,我这里的数组长度等价于数组里的元素数量,下面是求数组的大小(所占空间):
int arr=[1,2,3];
char str[]="hello";
int len_arr = sizeof(arr); //12
int len_str = sizeof(str) //6 注意字符串数组末尾有'\0'
printf("len_a=%d,len_arr=%d,len_str=%d\n",len_a,len_arr,len_str)
以下为计算数组长度:C中char所占字节数为1,所以能省略 sizeof(char)
int arr[]={1,2,3};
for(int i=0;i<(sizeof(arr)/sizeof(int));i++){
printf("%d,",arr[i]);
}
char arr[]="hello";
for(int i=0;i<(sizeof(arr));i++){
printf("%d,",arr[i]);
}
【需要注意】对函数的形参数组使用sizeof的情况。举例来说,假设有如下的函数:
void fun(int array[10])
{
int n = sizeof(array); //8(64bit系统)
}
此时在fun内,n的值不为40,不管形参是int的型数组,还是float型数组,或者其他任何用户自定义类型的数组,也不管数组包含多少个元素,这里的n都是4。为什么呢?原因是在函数参数传递时,数组被转化成指针了:假如直接传递整个数组的话,那么必然涉及到数组元素的拷贝(实参到形参的拷贝),当数组非常大时,这会导致函数执行效率极低!而只传递数组的地址(即指针)那么只需要拷贝8byte。
不能求动态分配的内存大小
C/C++中,sizeof
只是运算符号,是编译的时候确定大小的。动态分配是运行过程中得到大小的(从堆中分配),也就是说C++中 new
出来的内存,sizeof
都无法统计的,退一步说,即使是new出来的空间也有可能失败,所以 sizeof
无法统计动态分配的内存大小。(最开始的c标准规定sizeof只能编译时求值,后来c99又补充规定sizeof可以运行时求值。【注意】但是,即便是在实现了c99标准的DEV C++中仍然不能用sizeof求得动态分配的内存的大小!这里我就是用的DEV C++进行测试)
#include<iostream>
using namespace std;
int main(int argc,char *argv[])
{
//使用new关键字,在堆区开辟一个int数组
int* arr = new int[5]{1,2,3,4,5};
//并不是计算数组arr所占用的内存空间大小,而是计算指针所占内存大小,32位系统指针占4字节,64位系统指针占8字节
cout << sizeof(arr) << endl; //8
//解指针,因为arr指针指向的时数组的首元素,所以实际计算的是int类型的数据所占用内存空间,int类型占4字节
cout << sizeof(*arr) << endl; //4
return 0;
}