C++中strlen与sizeof的区别

1.定义
 

   strlen与sizeof在MSDN上均有英文定义。下面只说一下我自己的理解。
    strlen是函数,是用来返回字符串长度的。在执行的过程中寻找结束标识符'\0',如果发现则返回之前的长度。而sizeof是内置运算符,返回变量的地址占用字节数。
    2.示例:
    char *ch=new char;
    cout<<sizeof(ch)<<endl;        //返回4,返回指针所占内存:4个字节
    cout<<strlen(ch)<<endl;        //返回5,因为ch是由new分配的,ch所指向的内存并没有初始化
                                   //所以它指向的内容是随机的;而strlen函数是查找到字符串结束字符
                                   //‘\0‘结束,所以strlen有可能等于任何值,这取决于你的编译器。
    cout<<strlen("abc\0d")<<endl;    //strlen寻找结束标志'\0',所以这里返回3

    char chs[40]="abcdef";
    cout<<sizeof(chs)<<endl;    //返回40,若是chs[]="abcdef"则返回7,算上'\0'。char[]每个元素恰好
                                //占一个字节
    int j[]={1,2,3,4,5,6};
    cout<<sizeof(j)/sizeof(*j)<<endl;        //sizeof(j)返回24

    string s="abcedf";
    cout<<sizeof(s[0])<<endl;                //返回1,转换成char数组了
    cout<<sizeof(s)/sizeof(s[0])<<endl;    //sizeof(s)返回32,这地方不能起到输出数组大小的作用
    cout<<s.size()<<endl;                    //返回6
    char pstr[] = "ABCD";
    cout<<sizeof(pstr)<<endl;            //返回5,加了结束标识符
    char* pstrs[] = { "ABCD","EFG" };
    cout<<sizeof(pstrs)<<endl;            // 两个指针,共八个字节

    下面是在网上搜到的一些例子,也有参考价值,先贴出:
    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
3、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);
     }
     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)都不是正确形式。
4、结束语
     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给出其指针的大小。
 
文章地址:http://blog.sina.com.cn/s/blog_6c02e0570100w41v.html

posted on 2012-09-17 10:54  互联网络  阅读(184)  评论(0编辑  收藏  举报

导航