sizeof 操作符的作用是返回一个对象或类型名的长度,返回值的类型是size_t。size_t是标准库中的类型,定义在cstddef头文件中,该文件是C标准库的头文件stddef.h的C++版本,它是一个与机器相关的unsigned类型,其大小足以保证存储内存中的对象的大小。
(1)sizeof 操作符的用法
sizeof的结果是编译时常量,它的使用有三种形式:
a. sizeof (type name)
b. sizeof (expr)
c. sizeof expr
b,c中返回的结果都不是expr的值,而是expr的结果的类型的长度,因此,对于sizeof *p,即使p指向一个无效地址,结果也是合法的,因为他计算的是p指向的对象对应的类型长度。
sizeof的结果与类型的关系:
i. 对char类型或者值为char类型的表达式做sizeof的结果都为1;
ii. 对引用类型做sizeof操作的结果将返回存放此引用类型对象所需的内存空间的大小;
iii. 对指针做sizeof操作将返回存放指针所需的内存大小;如果要获取指针所指向对象的类型大小,则必须对指针解引用;
iv. 对数组做sizeof操作等效于对其元素类型做sizeof的结果乘上数组元素的个数。
示例代码如下:
1 #include<iostream> 2 using namespace std; 3 #include<cstdlib> 4 5 void GetLengthInnerType() 6 { 7 size_t cRes = sizeof (char); 8 size_t bRes = sizeof (bool); 9 size_t wcRes = sizeof (wchar_t); 10 size_t iRes = sizeof (int); 11 size_t lRes = sizeof (long int); 12 size_t fRes = sizeof (float); 13 size_t dRes = sizeof (double); 14 size_t ldRes = sizeof (long double); 15 16 17 cout<<"char:"<<cRes<<endl<<"bool:"<<bRes<<endl<<"wchar_t:"<<wcRes<<endl<<"int:"<<iRes<<endl 18 <<"long:"<<lRes<<endl<<"float:"<<fRes<<endl<<"double:"<<dRes<<endl<<"long double:"<<ldRes<<endl; 19 } 20 21 void main() 22 { 23 GetLengthInnerType(); 24 25 int a = 2; 26 double b = 4.1; 27 28 int& aa = a; 29 double& bb = b; 30 31 cout<<"sizeof aa:"<<sizeof aa<<endl; 32 cout<<"sizeof bb:"<<sizeof bb<<endl; 33 34 int* pa = &a; 35 double* pb = &b; 36 37 cout<<"sizeof pa:"<<sizeof pa<<endl; 38 cout<<"sizeof pb:"<<sizeof pb<<endl; 39 40 cout<<"sizeof *pa:"<<sizeof *pa<<endl; 41 cout<<"sizeof *pb:"<<sizeof *pb<<endl; 42 43 system("pause"); 44 }
上面的代码执行结果:
char:1 bool:1 wchar_t:2 int:4 long:4 float:4 double:8 long double:8 sizeof aa:4 sizeof bb:8 sizeof pa:4 sizeof pb:4 sizeof *pa:4 sizeof *pb:8 View Code
(2)sizeof和strlen的区别
strlen执行的是一个计数器的工作,它从内存的某个位置开始扫描,直到碰到第一个字符串结束符' '为止,然后返回计数器值。
sizeof是操作符,它以字节的形式给出了其操作数的存储大小,操作数可以是类型也可以是表达式,操作数的存储大小由操作数的类型决定。
二者的区别可以概括如下:
a. sizeof 后如果是类型,则必须加括号,如果是表达式,则不需要;strlen是函数,必须有括号。
b. sizeof 返回值为size_t,它在头文件中typedef为unsigned int类型,该类型保证能够容纳所建立的最大对象的字节大小;strlen返回值为int类型。
c. sizeof 的操作数可以为类型,或者函数,为函数时返回的是函数返回值类型的大小;而strlen参数则必须为以' '结束的char*类型的字符串。
d. 用数组名做sizeof 参数时不退化,而如果作为strlen参数就退化为指针,如下的代码:
1 char a[10] = {'c'}; 2 size_t m = sizeof a;//result:10 3 int n = strlen(a);//result:1
e. sizeof 在编译的时候计算,因而可以用sizeof(expr)定义数组维数,而strlen则是在运行期计算。
f. sizeof 不能返回动态数组的大小,strlen只关心数组实际的内容,如下代码:
1 char* parr = new char[10]; 2 cout<<"strlen(parr):"<<strlen(parr)<<endl; 3 cout<<"sizeof parr:"<<sizeof parr<<endl; 4 cout<<"sizeof *parr:"<<sizeof *parr<<endl;
得到的结果如下,根据strlen计算的原理,不能确定strlen(parr)的值,因为无法确定字符串终止的位置,所以得到的是一个随机值;而使用sizeof parr时,parr为指针,故而结果为4;parr解引用得到的是第一个字符,所以sizeof *parr返回的是第一个字符的类型大小,即为1.
strlen(parr):24
sizeof parr:4
sizeof *parr:1