- sizeof操作符:
sizeof是一个操作符,返回一条表达式或一个类型名字所占的字节数。返回值一个常量表达式,类型为size_t。
size_t sizeof(type)
size_t sizeof expr
在sizeof的运算对象中解引用一个无效指针仍然是一种安全的行为,因为指针实际上并没有被真正使用,sizeof并不需要真的解引用指针也能知道它所指对象的类型。
sizeof对C++的所有内置类型求其所占空间的大小:
环境:win7 64-bits, Code::Blocks 16.01, GUN GCC Compiler with C++11 ISO Standard
Type |
Number of bytes |
bool |
1 |
char |
1 |
wchar_t |
2 |
char16_t |
2 |
char32_t |
4 |
short |
2 |
int |
4 |
long |
4 |
long long |
8 |
float |
4 |
double |
8 |
long double |
12 |
std::string |
4 |
1. sizeof对数组
传入数组头指针,返回每个元素所占的字节数乘以数组的长度。
2. sizeof对C风格字符串
传入头指针,返回的是字符串长度加上末尾结束符’\0’的总长度。
C风格字符串有两种,一种是指针形式:const char* s = “hello”; 将s传入给sizeof,会认为s为一个指针,返回的是指针所占的字节数。
另一种是数组形式:const char c_str[] = “hello”; 将头指针c_str传给sizeof,是按数组形式的计算所占字节数,返回的是字符串长度加上末尾结束符的总长度。
3. sizeof对指针
传入任意类型的指针,返回值由计算机内存地址总线的宽度决定,32-bits的操作系统返回4,64-bits的操作系统返回8。
4. sizeof对结构体(类)
空的结构体(没有任何成员),返回1,表示仅含占位符;对含有多个数据成员的结构体,所有成员所占的内存字节要与所占内存最长的成员进行对齐,不足的进行内存补齐,例如结构体内最长的成员为double,占8个字节,另一成员为char,原本占1个字节,因此char类型的成员需进行内存与double类型对其,在1字节后补齐7个字节,形成8个字节,因此整个结构体所占的总字节数即为最长的成员字节数乘以数据成员数;另外,不考虑函数成员所占的内存,函数成员会储存在代码区,而不是栈区,所以不考虑。
5. sizeof对联合体(union)
union在内存中储存是层叠式的,各成员共享一段内存,因此返回的是所占字节数最长的成员的字节数。例如最长的成员为double,其它无论还有多少个成员且任意小于double的类型,返回的值均为8。
6. sizeof对函数
sizeof对函数操作实际上是求其返回值类型所占的字节数。求值时必须完整地写出函数调用的形式,但并不实际调用函数。
示例程序:
//测试C++中的sizeof() #include <iostream> using std::cout; using std::cin; using std::endl; size_t getPtrSize(char* cptr) { return sizeof(cptr); } struct NoMember { }; struct S_int_char { char c; int i; }; struct S_int_short { short s; //sizeof(short) == 2 int i; }; struct S_int_func { int i; double ret_i() //不考虑 { return i; } }; struct S_ONLY_func { double func() { return 0; } }; //联合体 union my_u { int a; float b; double c; char d; }; //函数 short func_short() { return 0; } float func_float(int a, int b) { return 1.1; } int main() { //C风格字符串的测试 char c_str[] = "Hello!"; cout << sizeof(char) << " " << sizeof(c_str) << " " << getPtrSize(c_str) << endl; //数组测试 double d_arr[20]; cout << sizeof(d_arr) << endl; //返回值为80,4*10 == 80 //指针的测试 char* p; cout << sizeof(p) << endl; //返回值是4,由计算机内存地址总线的宽度决定 //与所指对象无关 //结构体的sizeof测试 NoMember nm; cout << sizeof(nm) << endl; S_int_char sic; cout << sizeof(sic) << endl; //int是4,char是1, //为了c与i的空间对齐,对c往后相邻的3个内存加入填充字节 //是空间对齐,则总的空间为i的4加上c的4,得到8 S_int_short sis; cout << sizeof(sis) << endl; //同样需要内存对齐,返回的也是8 S_int_func sif; cout << sizeof(sif) << endl; //返回值为4,不考虑成员函数所占的空间 S_ONLY_func sof; cout << sizeof(sof) << endl; //返回值为1,不考虑成员函数所占的空间 //联合体的测试 my_u u; cout << sizeof(u) << endl; //返回值为最大的成员所占空间长度,最大为double,返回8 //函数的测试 cout << sizeof(func_short()) << endl; cout << sizeof(func_float(1, 2)) << endl; return 0; }
- strlen函数:
strlen函数定义在头文件cstring.h中,用于计算字符串的长度,但空字符’\0’不计算在内。参数为C风格字符串的头指针,返回值是字符串的长度,空字符不计算在内。计算原理是顺着头指针向后找,直到遇到空字符才停下来。注意,如果字符数组没有以空字符结尾,调用strlen()函数可能产生重大错误,因为会不断向前找直到遇到空字符。例如:
char ca[] = {‘a’, ‘b’, ‘c’}; //不以空字符结束 cout << strlen(ca) << endl; //严重错误
示例程序:
#include <iostream> #include <cstring> int main() { //腾讯实习软开 2016-04-03 const char* s = "hello tencent.\0"; const char c_str[] = "hello tencent.\0"; cout << sizeof(s) << " " << strlen(s) << " " << sizeof(c_str) << endl; return 0; }
测试输出: