首先我们要了解sizeof它的本质用处在什么地方?
sizeof的作用是:返回一个对象或者类型的长度。说白了就是计算长度的。
问题1:sizeof与strlen的区别是什么?
分析:在比较二者区别之前,首先来看看strlen的作用是什么?
strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值。
区别:
(1)sizeof操作符的结果类型是size_t,实际上就是unsigned int 类型,因为在头文件中有typedef unsigned int size_t
(2)sizeof是运算符,strlen是函数
(3)sizeof可以用类型做参数,strlen只能用char*做参数(可参考strlen的函数原型),且必须以”\0“结尾的,sizeof还可以用函数做参数。
----->strlen函数原型:extern unsigned int strlen(char *s),所以说strlen只能用char *做参数
e.g.1:char *ss = "0123456789"
sizeof(ss)结果是4,因为指针的长度就是4
sizeof(*ss),*ss指的是第一个字符,所以结果是1
e.g.2:char ss[]="0123456789"
sizeof(ss),ss是数组,计算到"\0"的位置,因此是11
sizeof(*ss),结果是1,*ss指的是第一个字符
e.g.3: char ss[100]="0123456789"
sizeof(ss)结果为100,因为在内存中预分配了大小
strlen(ss),结果为10,它内部的实现是用一个循环计算字符长度。直到”\0“over
e.g.4:int ss[100] = "0123456789"
sizeof(ss)的结果是400
strlen(ss)的结果是错误,因为strlen参数智能是char *
e.g.5
class X
{
int i;
int j;
char k;
};
X x;
cout <<sizeof(X)<<endl;
cout <<sizeof(x)<<endl;
结果都是12,理由是内存补齐。
(4)数组做sizeof的参数不退化,传递给strlen就退化为指针
(5)大部分编译程序在运行的时候就把sizeof计算过了,是类型或变量的长度。这就是sizeof(x)可以用来定义数组维数的原因,但是strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型所占内存的大小。
(6)sizeof后如果是类型必须加括号,如果是变量名可以不加括号。这是因为sizeof是操作符不是函数。
(7)当使用一个结构类型或者变量时,sizeof返回实际大小。当使用一静态的空间数组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。
——>关于数组的长度计算问题:
e.g.2:char ss[]="0123456789"
sizeof(ss),ss是数组,计算到"\0"的位置,因此是11
sizeof(*ss),结果是1,*ss指的是第一个字符
(8)数组作为参数传给函数传的是指针而不是数组,传递的是数组的首地址
(9)计算结构变量的大小就必须讨论数据对齐的问题。
———>关于内存补齐的问题可以参考:http://blog.youkuaiyun.com/gzbaishabi/article/details/38520959
(10)sizeof操作符不能用于函数类型、不完全类型或位字段。
问题2:sizeof、strlen以及length()的区别。
上面已经说了sizeof、strlen的区别,那么length又有什么用呢?
length是计算针对字符串而言的,C语言的库函数中并没有,只是存在于C++的string类中。
length是数组变量的元素个数,是个数,每一个不一定刚好一个字节。
具体的用法可参考:
#include <string.h>
#include <iostream>
using namespace std;
int fun(char num[])//传递过来是一个指针
{
//int n=strlen(num);
int n=sizeof(num);//数组作为参数传递过来的是指针,是首地址,所以此处应该是4
printf("%d\n",n);//4
char *p=num;
int j=strlen(p);
int g=strlen(num);
printf("%d\n",j);//13
printf("%d\n",g);//13
if(13==n){
if((*p==8)&&(*(p+1)==6))
while(*p!='\0'){
if(*p>='0'&&*p<='9')
p++;
else return 2;
if(*p='0')
return 0;}
else return 3;
}
else return 1;
}
int main()
{
char num[]="87139a3887671";//字符串长度为13
//char num[13];
//scanf("%s",num);
//char num[13];
//gets(num);
int m=sizeof(num);
int j=strlen(num);
printf("%d\n",m);//14
printf("%d\n",j);//13
int k;
k=fun(num);
cout << k <<endl;
return 0;
}
问题3:sizeof具体用在什么地方?
(1)sizeof的一个主要用途是:与存储分配和I/O系统那样的例程进行通信。
e.g.1:
void *malloc(size_t size) ;
size_t fread (void *ptr,size_t size,size_t nmemb,FILE *stream);
其实就是利用sizeof获取了长度,在把长度运用到对文件的操作上去。
(2)用它可以查看某种类型的对象在内存中所占的单元字节。
e.g.2:
void *meset(void *s,int c,sizeof(s))
说明:注意meset函数的意义。作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。sizeof(s)获取了s的长度,并全部用c代替,同时返回给s。若把c全部改成了0,即可达到了清零的作用。
(3)在动态分配一对象的时,可以让系统知道要分配多少内存。
(4)便于一些类型的扩充。在windows中有很多结构类型就有一个专用的字段来存放类型的字节大小。
(5)由于操作室的字节数在实现时可能出现变化,建议在涉及操作数字节大小时用sizeof代替常量计算。
(6)如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。