sizeof的用法(一)
1. 基本类型:
sizeof(bool)=1;
sizeof(char)=1;
sizeof(short)=2;
sizeof(long)=4;
sizeof(int)=4;
sizeof(float)=4;
sizeof(double)=8;
sizeof(string)=16;
sizeof(vector<elemType>)=16;
元素类型为T,个数为n的数组array:sizeof(array)=n*sizeof(T);
2. 数组、指针和引用:
注:sizeof作用于指针变量时,结果总是为4,而作用于引用变量时,结果等于所引用的变量的size。
如:double a; double* b=&a; double& c=a;
则sizeof(b)=4;sizeof(c)=8。
3. 结构和类:
1)无父类的类 : 其size原则上等于其非静态成员变量的size之和:
class CTest1
{
public:
int a,b
static double c;
double d;
};
sizeof(CTest1)=sizeof(a)+sizeof(b) +sizeof(d)=4+4+8=16;
为什么说原则上等于呢?因为变量只能在内存中一个字的开头存储,所以定义成员变量的顺序可能会影响到类的size,如将上面的CTest1改为:
class CTest2
{
public:
int a;
static double c;
double d;
int b;
};
sizeof(CTest2)=8+8+8=24; 可以看出类中成员变量的定义顺序会影响到内存的利用率,这是跟编译器的对齐方式有关。
2)派生类:需要加上其基类的size
class CTest3:CTest1
{
public:
int e;
};
3)空类:
class CTest5
{
};
class CTest6{virtual ~CTest5(){}};//sizeof(CTest6)=4
4.参数为其他。下面举例说明:
}
1.
2. cout<<sizeof(1==2)<<endl;
3. cout<<sizeof(unsigned int)<<endl;
4. int a = 0;
结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。
[补充]:C++中sizeof与strlen函数的区别
char* ss = "0123456789";
cout<<sizeof(ss)<<endl;
cout<<sizeof(*ss)<<endl;
cout<<strlen(ss)<<endl;
char ss1[] =
cout<<sizeof(ss1)<<endl;
cout<<sizeof(*ss1)<<endl;
cout<<strlen(ss1)<<endl;
char ss2[100] =
cout<<sizeof(ss2)<<endl;
char ss3[] = "0123456789\n";
cout<<sizeof(ss3)<<" "<<strlen(ss3)<<endl;
char ss4[] = "0123456789/n\t\0";
cout<<sizeof(ss4)<<" "<<strlen(ss4)<<endl;
char ss5[] = "0123456789/n";
cout<<sizeof(ss5)<<" "<<strlen(ss5)<<endl;
char p[]="a\m%23";
cout<<sizeof(p)<<" "<<strlen(p)<<endl;
int n[4] = {1,2,3,4};
cout<<sizeof(n)<<endl;
int arr[]={1,2,3,4,5};
cout<<sizeof(arr)<<endl;
int n1= 1234;
cout<<sizeof(n1)<<endl;
char c[2][3] = {"aa", "bb"};
cout<<sizeof(c)<<endl;
int arr[4][5];
cout<<sizeof(arr)<<endl;
sizeof的用法(二)
一、由几个例子说开去
第一个例子:
char* ss = "0123456789";
sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针
sizeof(*ss) 结果 1 ===》*ss是第一个字符
char ss[] = "0123456789";
sizeof(ss) 结果 11 ===》ss是数组,计算到\0位置,因此是10+1
sizeof(*ss) 结果 1 ===》*ss是第一个字符
char ss[100] = "0123456789";
sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1
strlen(ss) 结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前
int ss[100] = "0123456789";
sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4
strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''\0''结尾的
char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 4 3 3 2
第二个例子:
class X
{
int i;
int j;
char k;
};
X x;
cout<<sizeof(X)<<endl; 结果 12 ===》内存补齐 4+4+1+3=12
cout<<sizeof(x)<<endl; 结果 12 同上
第三个例子:
char szPath[MAX_PATH]
如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小)
二、sizeof深入理解。
1.sizeof是运算符,strlen是函数。
2.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
3.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
4.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
5.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8])
fun(char [])
都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小,需要这样做:进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
}
有关内容见: C++ PRIMER?
6.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。
7.sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式
三、结束语
sizeof使用场合:
1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:
void *malloc(size_t size),
size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
2.用它可以看看一类型的对象在内存中所占的单元字节。
void * memset(void * s,int c,sizeof(s))
3.在动态分配一对象时,可以让系统知道要分配多少内存。
4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。