sizeof的用法(附strlen函数)

news/2024/7/3 14:51:15 标签: alignment, class, fun, 存储, 编译器, compiler
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

一、由几个例子说开去。

第一个例子:

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 class="tags" href="/tags/ALIGNMENT.html" title=alignment>alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data class="tags" href="/tags/ALIGNMENT.html" title=alignment>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给出其指针的大小。


 

sizeof的总结:
  基本类型:
   sizeof(bool)=1;
   sizeof(char)=1;
   sizeof(short)=2;
   sizeof(long)=4;
   sizeof(int)=4;
   sizeof(float)=4;
   sizeof(double)=8;
   sizeof(string)=16;
   sizeof(vector<elemType>)=16;
  元素类型为T,个数为n的数组array:
  sizeof(array)=n*sizeof(T);
  
  指针和引用:
   sizeof作用于指针变量class="zoominoBgImage" alt="" src="http://static.zoomino.cn/static-ox/images/blank.gif" width="1" height="1" style="padding-bottom:0px; margin:0px; padding-left:0px; width:12px; padding-right:0px; display:inline; float:none; height:14px; padding-top:0px" />时,结果总是为4,而作用于引用变量class="zoominoBgImage" alt="" src="http://static.zoomino.cn/static-ox/images/blank.gif" width="1" height="1" style="padding-bottom:0px; margin:0px; padding-left:0px; width:12px; padding-right:0px; display:inline; float:none; height:14px; padding-top:0px" />时,结果等于所引用的变量的size。如:
  double a; double* b=&a; double& c=a;
  则sizeof(b)=4;sizeof(c)=8。
  类:
  1)无父类的类 : 其size原则上等于其非静态成员变量class="zoominoBgImage" alt="" src="http://static.zoomino.cn/static-ox/images/blank.gif" style="padding-bottom:0px; margin:0px; padding-left:0px; width:12px; padding-right:0px; display:inline; float:none; height:14px; padding-top:0px" />的size之和:
  class CTest1{
   public:
   int a,b
   static double c;
   double d;
  };
  sizeof(CTest1)=sizeof(a)+sizeof(b) +sizeof(d)=4+4+8=16;
  为什么说原则上等于呢?因为变量只能在内存中一个字的开头存储,所以定义成员变量的顺序可能会影响到类的size,如将上面的CTest1改为
  class CTest2{
   public:
   int a;
   static double c;
   double d;
   int b;
  };
  sizeof(CTest2)=24; 可以看出类中成员变量的定义顺序会影响到内存的利用率,这是跟编译器的对齐方式有关。
  2)派生类class="zoominoBgImage" alt="" src="http://static.zoomino.cn/static-ox/images/blank.gif" width="1" height="1" style="padding-bottom:0px; margin:0px; padding-left:0px; width:12px; padding-right:0px; display:inline; float:none; height:14px; padding-top:0px" />:需要加上其基类的size
  class CTest3:CTest1{
  public:
   int e;
  }; sizeof(CTest3)=24
  3)class CTest4{}; //sizeof(CTest4)=1
   class CTest5{virtual ~CTest5(){}};//sizeof(CTest5)=4


C++中sizeof与strlen函数的区别
本文来自: IT知道网(
http://www.itwis.com) 详细出处参考:http://www.itwis.com/html/c/ccc/20080826/2254.html

 

    1. sizeof 操作符的结果类型size_t,它在头文件中typedef为unsigned int类型: typedef unsigned int size_t.

    2. sizeof是是长度运算符, 获得数据类型或是变量的长度,如果是数据类型,则返回数据类型大小,如果是用数组,则   返回数组所占空间大小,strlen是计算字符串长度的函数,返回的是实际串长度,以char* 作参数 ,且必须是以'/0'结尾。

    3. sizeof在编译的时候就把计算过,strlen的结果要在运行的时候才能计算出来。

    4. 数组做长度运算符sizeof的参数不退化。数组做函数strlen的参数就退化为指针了,因为数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址。

class="dp-highlighter nogutter bg_cpp:nogutter">
class="bar">
class="tools"> [cpp:nogutter] view plain copy print ?
    class="dp-cpp">
  1. class="alt">class="datatypes">char* ss = class="string">"0123456789";  
  2. cout<<class="keyword">sizeof(ss)<<endl;class="comment">//4   
  3. class="alt">cout<<class="keyword">sizeof(*ss)<<endl;class="comment">//1   
  4. cout<<strlen(ss)<<endl;class="comment">//10   
  5. class="alt">  
  6. class="datatypes">char ss1[] =  class="string">"0123456789";  
  7. class="alt">cout<<class="keyword">sizeof(ss1)<<endl;class="comment">//11   
  8. cout<<class="keyword">sizeof(*ss1)<<endl;class="comment">//1   
  9. class="alt">cout<<strlen(ss1)<<endl;class="comment">//10   
  10.   
  11. class="alt">class="datatypes">char ss2[100] =  class="string">"0123456789";  
  12. cout<<class="keyword">sizeof(ss2)<<endl;class="comment">//100   
  13. class="alt">  
  14. class="datatypes">char ss3[] = class="string">"0123456789/n";  
  15. class="alt">cout<<class="keyword">sizeof(ss3)<<endl;class="comment">//12   
  16.   
  17. class="alt">class="datatypes">int n[4] = {1,2,3,4};  
  18. cout<<class="keyword">sizeof(n)<<endl;class="comment">//16   
  19. class="alt">  
  20. class="datatypes">int n1= 1234;  
  21. class="alt">cout<<class="keyword">sizeof(n1)<<endl;class="comment">//4  

附:C++ sizeof 使用规则及陷阱分析 http://dev.yesky.com/143/2563643.shtml

来源: http://blog.csdn.net/max_cpp/article/details/4268991

http://www.niftyadmin.cn/n/1736396.html

相关文章

MSM平台上的AMSS

AMSS的source实际上是QC BREW(Binary Runtime Environment For Wireless)平台的的底层部分&#xff0c;去掉了为应用程序提供接口的AEE(application execution environment)部分&#xff0c;高通在Dual Proc芯片上的其他平台基本上都是采用的这样的架构。所以如果要了解这套sou…

硬断点和软断点的区别

硬断点--break point 软断点--assert 简单的解释&#xff1a; 硬件断点&#xff1a;硬断点需要硬件寄存器提供支持&#xff0c;断点的数目受Embedded ICE中的Watchpoint数目的限制&#xff0c;但是可以在任何地方设置断点。 软件断点&#xff1a;软件断点通过在运行起来的程…

readelf命令的使用

readelf命令的使用 readelf命令是Linux下的分析ELF文件的命令&#xff0c;这个命令在分析ELF文件格式时非常有用&#xff0c;下面以ELF格式可执行文件test为例详细介绍&#xff1a; readelf -v 显示版本 readelf -h 显示帮助 readelf -a test 显示test的全部信息 readelf -…

objdump命令的使用

objdump命令的使用 objdump命令是Linux下的反汇编目标文件或者可执行文件的命令&#xff0c;它还有其他作用&#xff0c;下面以ELF格式可执行文件test为例详细介绍&#xff1a; objdump -f test 显示test的文件头信息 objdump -d test 反汇编test中的需要执行指令的那些sec…

xargs——维基百科

xargs是一条Unix和类Unix操作系统的常用命令。它的作用是将参数列表转换成小块分段传递给其他命令&#xff0c;以避免参数列表过长的问题。 例如&#xff0c;下面的命令&#xff1a; rm find /path -type f如果path目录下文件过多就会因为“参数列表过长”而报错无法执行。但改…

关于汇编ARM指令DCD

数据定义&#xff08; Data Definition &#xff09;伪指令 数据定义伪指令一般用于为特定的数据分配存储单元&#xff0c;同时可完成已分配存储单元的初始化。 — DCD &#xff08; DCDU &#xff09; 用于分配一片连续的字存储单元并用指定的数据初始化。 3、 DCD&#xff08…

电容屏原理

电容屏 电容技术的触摸屏是一块四层复合玻璃屏&#xff0c;如下图所示。玻璃屏的内表面和夹层各涂有一层ITO导电层&#xff0c;最外层是只有0.0015毫米厚的矽土玻璃保护层。内层ITO作为屏蔽层&#xff0c;以保证良好的工作环境&#xff0c;夹层ITO涂层作为检测定位的工作层&am…

有用的博客

1.http://www.cppblog.com/simmy2/ QQ的实现 2.http://www.cnblogs.com/technology/archive/2010/12/22/1913821.html UPNP穿透技术 UPnP协议统一即插即用英文是Universal Plug and Play 网络地址转换(NAT,Network Address Translation)属接入广域网(WAN)技术&#xff0c;是…