zoukankan      html  css  js  c++  java
  • sizeof总结

    1.sizeof常用总结

    ①与strlen比较

          strlen  计算字符串的字符数,以""为结束判断,但不统计结束符。 
         sizeof  计算数据(数组、变量、类型、结构体等)所占内存空间,用字节数表示。

    ②指针与静态数组的sizeof操作

      指针均可看为变量类型的一种。因此:
          int *p; 
                        sizeof(p)=4;
                        sizeof(*p)=4;//相当于sizeof(int)      
    

      对于静态数组,sizeof可直接计算数组大小:
          例:int a[10];char b[]="hello";
                        sizeof(a)=40;//4*10=40;
                        sizeof(b)=6;
      数组做型参时,数组名称当作指针使用:
                 例: void  fun(char p[]);
                         sizeof(p)=4;

    ③格式的写法

        sizeof为操作符而非函数,对变量或对象可以不加括号,但若是类型,须加括号。

    ④操作string的注意事项

            string   str[]={"hello", "world", "CHB","
    "};
            cout<<sizeof(str)<<endl;//输出128
            cout<<sizeof(str[0])<<endl;//输出32,即对象的大小
            cout<<sizeof(str[0].c_str())<<endl;//输出4,c_str()返回 const char*指针,指向str[0]
            cout<<strlen(str[0].c_str())<<endl;//输出5,str[0]字符串的长度

    ⑤经典问题: 

            double* (*a)[3][6]; 
            cout<<sizeof(a)<<endl; // 4,a为指针
            cout<<sizeof(*a)<<endl; // 72 ,*a为一个有3*6个指针元素的数组
            cout<<sizeof(**a)<<endl; // 24, **a为行指针
            cout<<sizeof(***a)<<endl; // 4 ,***a为一维的第一个指针
            cout<<sizeof(****a)<<endl; // 8 ,****a为一个double变量
           解析a为指向double*[3][6]类型二维指针数组(数组元素为double* 指针类型)的指针。既然是指针,所以sizeof(a)就是4。*a就表示二维指针数组double*[3][6],因此sizeof(*a)=3*6*sizeof(double*)=72**a为行指针,指向一维指针数组double*[6]sizeof(**a)=6*sizeof  (double*)=24***a就表示行指针数组的第一个指针元素,也就是double*了,所以sizeof(***a)=4。至于****a,则是一个double类型,所以sizeof(****a)=sizeof(double)=8

         看看以下情况:
    	double**b[3][6]; 
            cout<<sizeof(b)<<endl; // 72,b为数组类型,数组元素为double**;
            cout<<sizeof(*b)<<endl; // 24,行指针
            cout<<sizeof(**b)<<endl; // 4,b[0][0]的值,double**类型
            cout<<sizeof(***b)<<endl; // 4,double* 
            cout<<sizeof(****b)<<endl; // 8 double
    	double (*c)[3][6];
    	cout<<sizeof(c)<<endl;//4,指针变量,指向double[3][6]
    	cout<<sizeof(*c)<<endl;//144,double[3][6]的数组类型
    	cout<<sizeof(**c)<<endl;//48,行指针,指向c[0],实际指向为&c[0][0]
    	cout<<sizeof(***c)<<endl;//8,c[0][0]的值
    	double* d[3][6];
            cout<<sizeof(d)<<endl; // 72,指针数组类型,元素为double*的[3][6]数组
            cout<<sizeof(*d)<<endl; // 24,行指针
            cout<<sizeof(**d)<<endl; // 4,d[0][0]的元素值,即double*
            cout<<sizeof(***d)<<endl; // 8

    ⑥操作struct的内存对齐问题

         (1)整体空间是占用空间最大的成员(的类型)所占字节数的整倍数
        (2)内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。
        (3)数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。

    例子1

    1. struct s1{  
    2.    char a;  
    3.    double b;  
    4.    int c;  
    5.    char d;};  
    6.      
    7. struct s2{  
    8.    char a;  
    9.    char b;  
    10.    int c;  
    11.    double d;};  
    12.      
    13. cout<<sizeof(s1)<<endl; // 24  
    14. cout<<sizeof(s2)<<endl; // 16  
             占空间的最大成员是double类型变量,故对齐空间大小为8。s1中的c和d,s2中a,b,c可以放进一个“8”位空间中。

    例子2

    1. struct s1  
    2. {char a[8];};  
    3.   
    4. struct s2  
    5. {double d;};  
    6.   
    7. struct s3{    
    8.   s1 s;  
    9.   char a;};  
    10.   
    11. struct s4{  
    12.   s2 s;  
    13.   char a; };  
    14.   
    15. cout<<sizeof(s1)<<endl; // 8  
    16. cout<<sizeof(s2)<<endl; // 8  
    17. cout<<sizeof(s3)<<endl; // 9  
    18. cout<<sizeof(s4)<<endl; // 16  
        虽然s1s2大小都是8,但是s1的对齐空间大小是1(char)s28double)所以定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。这里结构体中定义的数组可以当做多个同类数据顺序排列,以此确定对齐的空间大小。

    例子3

    1. struct s1 {   
    2.  int i: 8;   
    3.  int j: 4;   
    4.  double b;   
    5.  int a:3;};   
    6.   
    7. struct s2 {   
    8.  int i;   
    9.  int j;   
    10.  double b;   
    11.  int a;};   
    12.   
    13. struct s3 {   
    14.  int i;   
    15.  int j;   
    16.  int a;   
    17.  double b;};   
    18.   
    19. struct s4 {   
    20.  int i: 8;   
    21.  int j: 4;   
    22.  int a:3;   
    23.  double b;};   
    24.   
    25. cout<<sizeof(s1)<<endl; // 24   
    26. cout<<sizeof(s2)<<endl; // 24   
    27. cout<<sizeof(s3)<<endl; // 24   
    28. cout<<sizeof(s4)<<endl; // 16   
           在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。double存在会干涉到位域。所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。
        如上。以double--8字节为单位,分配位,以s1为例。i,j占据一个double长度,b自己占据一个double长度,a占据另外一个double。
        注意:计算结构体嵌套结构体的内存空间时,注意嵌套之结构体的对齐空间非所占空间,而是两者的最大size变量。数组并不作为一个整体变量计算内存。

    ⑦基本操作结果

    32位系统中

         sizeof  int:4
         sizeof  short:2
         sizeof  long:8
         sizeof  float:4
         sizeof  double:8
         sizeof  char:1
         sizeof  *p:4
         sizeof  WORD:2
         sizeof  DWORD:4

    64位系统中:

        指针一律为8字节

        


    2.其它

        如下:

    class A{
    	int i;
    	union U{
    		char buffer[13];
    		int i;
    	} u;
    	typedef int* (*p)(int,int);
    	enum{red,blue,white} e;
    };

              sizeof(A)为 4+16+0+4=24。注意,union设计到内存对齐,并且以最大的存储单元计算空间,此时应为16。enum类型变量大小为4。这里应该注意的是,typedef只是定义了一个类型,并没有定义变量,因此不占内存空间。反之,倘若A存在成员指针,不管是什么类型的,大小都为4.

     

             倘若用#pragma pack(2)约束以两个字节对齐,则结果为22.因为此时枚举类型大小为14.









  • 相关阅读:
    js -- use strict
    css布局—— 固定+自适应
    web前端安全问题(转载)
    清除float浮动
    源码核心动画01-CALayer-基本使用(了解)
    源码0308-画板
    源码0306-手势解锁
    源码0301-图片水印-裁剪-截屏-截取-擦除
    源码0309-雪花(定时器)-图形上下文状态栈-矩阵操作
    源码0308-模仿UIImageView
  • 原文地址:https://www.cnblogs.com/engineerLF/p/5393018.html
Copyright © 2011-2022 走看看