一、由几个例子说开去。
第一个例子:
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 ===》内存补齐
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 操作符的结果类型是 size_t ,它在头文件中 typedef 为 unsigned int 类型。该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof 是算符, strlen 是函数。
3.sizeof 可以用类型做参数, strlen 只能用 char* 做参数,且必须是以 '/0' 结尾的。 sizeof 还可以用函数做参数,比如:
short f();
printf("%d/n", sizeof(f()));
输出的结果是 sizeof(short) ,即 2 。
4. 数组做 sizeof 的参数不退化,传递给 strlen 就退化为指针了。
5. 大部分编译程序 在编译的时候就把 sizeof 计算过了 是类型或是变量的长度这就是 sizeof(x) 可以用来定义数组维数的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); // 而 b=20;
6.strlen 的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
7.sizeof 后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为 sizeof 是个操作符不是个函数。 8. 当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
9. 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8])
fun(char [])
都等价于 fun(char *) 在 C++ 里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小, 需要这样做:进入函数后用 memcpy 拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
有关内容见: C++ PRIMER?
10. 计算结构变量的大小就必须讨论数据对齐问题。为了 CPU 存取的速度最快(这同 CPU 取数操作有关,详细的介绍可以参考一些计算机原理方面的书), C++ 在处理数据时经常把结构变量中的成员的大小按照 4 或 8 的倍数计算,这就叫数据对齐( data alignment )。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。 MS VC++ 中的对齐设定,有时候 sizeof 得到的与实际不等。一般在 VC++ 中加上 #pragma pack(n) 的设定即可 . 或者如果要按字节存储,而不进行数据对齐,可以在 Options 对话框中修改 Advanced compiler 页中的 Data alignment 为按字节对齐。
11.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 给出其指针的大小。
C++ strlen 与 sizeof 的深度认识
最新推荐文章于 2024-10-18 18:23:24 发布