sizeof的概念  

  sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。

    它并不是函数。
    sizeof操作符以字节形式给出了其操作数的存储大小。
    操作数可以是一个表达式或括在括号内的类型名。
    操作数的存储大小由操作数的类型决定。 

sizeof的使用方法  

  1、用于数据类型    
  sizeof使用形式: sizeof(type)
  数据类型必须用括号括住: sizeof(int)

  2、用于变量    
  sizeof使用形式: sizeof(var_name) 或 sizeof var_name    
  变量名可以不用括号括住.如sizeof (var_name),sizeof var_name等都是正确形式

    带括号的用法更普遍,大多数程序员采用这种形式。    
  注意:sizeof操作符不能用于函数类型,不完全类型或位字段。
     不完全类型指具有未知存储大小的数据类型,
     如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。    
    例如: sizeof(max)     --若此时变量max定义为int max();
      sizeof(char_v)    --若此时char_v定义为char char_v[MAX]且MAX未知,
      sizeof(void)      
     以上都是不正确形式。

sizeof的结果

1、ANSI C正式规定字符类型为1字节。    
    sizeof(char)= 1;
    sizeof(unsigned char) = 1;
    sizeof(signed char)= 1;
  
  2、其他类型在ANSI C中没有具体规定,大小依赖于实现。
    sizeof(int)= 4;
    sizeof(unsigned int)= 4;
    sizeof(short int)= 2;
    sizeof(unsigned short) = 2;
    sizeof(long int)= 4;
    sizeof(unsigned long)= 4;
    sizeof(float)= 4;
    sizeof(double)= 8;
    sizeof(long double)= 12; //gcc 32-bit 编译器
    sizeof(long double)= 16; //gcc 64-bit 编译器

  3、当操作数是指针时,sizeof依赖于编译器。
    学过数据结构的你应该知道指针是一个很重要的概念,它记录了另一个对象的地址。既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以字节为单位),在64位系统中指针变量的sizeof结果为8。
       例如: char *p;      
           sizeof(p) = 4;//gcc 32-bit 编译器
           sizeof(p) = 8;//gcc 64-bit 编译器     
 
  4、当操作数具有数组类型时,其结果是数组的总字节数。
    例如: char a[5];
        int  b[5];
        sizeof(a) = 5;
        sizeof(b) = 20;
   
  5、当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。
      例如: sizeof(8)    = 4;  //自动转化为int类型
          sizeof(8.8)  = 8;  //自动转化为double类型,注意,不是float类型
          sizeof("ab") = 3   //自动转化为数组类型,
                                   
  6、当操作数是联合类型时,sizeof是其最大字节成员的字节数。当操作数是结构类型时,sizeof是其成员类型的总字节数,包括补充字节在内。还是拿例子来说话:
   union u{             //对union来说
       char c;
       double d;
     }u;
    sizeof(u) = max(sizeof(c),sizeof(d)) = sizeof(1,8) = 8;
  struct a{             //对struct来说
       char b; 
       double x;
    }a;   
   sizeof(a) = 16;  而一般sizeof(char) + sizeof(double) = 9; 
  这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。但如果全对齐的话,sizeof(a) = 16, 这是因为b被放到偏移量为0的地址,占1个字节;在存放x时,double类型长度为8,需要放到能被8整除的偏移量上,这时候需要补7个空字节, 达到8个,这时候偏移量为8,放上x后长度为16。

struct S1 {char c;double d;};union  u {            //对union来说char c;double d;} u;int a;char b;short c;double d;float f;int *p;char a1[]="abcd";int a2[3];printf("int=%d\n",sizeof(a));printf("char=%d\n",sizeof(b));printf("short=%d\n",sizeof(c));printf("double=%d\n",sizeof(d));printf("float=%d\n",sizeof(f));printf("指针=%d\n",sizeof(p));printf("数组=%d\n",sizeof(a1));printf("数组=%d\n",sizeof("ab"));printf("结构体=%d\n",sizeof(S1));printf("联合类型=%d\n",sizeof(u));

gcc 64-bit 编译器,指针=8;

gcc 32-bit 编译器,指针=4

类的sizeof

面试中遇到面试官让我求一个类的sizeof,里边有各种类型的变量,还有虚函数(但是不懂什么是虚函数)。如果有虚函数就要加上一个指向虚表的指针,4字节大小(32 位 编译器),64位编译器是8字节大小。
1、空类
class A{}; sizeof(A)=1;
求sizeof的结果是1,因为即使是没有成员之类的,一个类存在,至少都要给他一个空间,不然就没有存在的意义了。
2、简单的类
class A{int a;double b;
};

本来sizeof(A.a)+sizeof(A.b)=12;结果=16,说明类的大小也遵守类似struct字节对齐的补齐规则,补齐为double类型8字节,所有为16
3、含虚函数的类

class A{int a;virtual  fun();
};

//sizeof(A)=8+8=16   (gcc-64bit编译器,指针大小为8字节)+补齐规则
//sizeof(A)=4+4=8   (gcc-32bit编译器,指针大小为4字节)
3、子类继承父类,含虚函数
class Base
{
public:Base();                virtual ~Base();         //每个实例都有虚函数表void set_num(int num)    //普通成员函数,为各实例公有,不归入sizeof统计{  a=num;}
private:int  a;                  //占4字节char *p;                 //4字节指针
};class Derive:public Base
{
public:Derive():Base(){};     ~Derive(){};
private:static int st;         //非实例独占  int  d;                     //占4字节  char *p;                    //4字节指针};

gcc-32bit编译器
sizeof(Base)=12;
sizeof(Derive)=20
sizeof(Derive)=sizeof(Base)+sizeof(Derive.d)+sizeof(Derive.p) 的指针即可;
gcc-64bit编译器
sizeof(Base)=24; //补齐规则
sizeof(Derive)=40
sizeof(Derive)=sizeof(Base)+sizeof(Derive.d)+sizeof(Derive.p)
因为普通继承,子类和父类的虚函数存放在同一个虚表中,所以,只需要存一个指向虚表

4.子类虚继承、父类含虚函数

class Base
{
public:Base();                virtual ~Base();         //每个实例都有虚函数表void set_num(int num)    //普通成员函数,为各实例公有,不归入sizeof统计{a=num;}
private:int  a;                  //占4字节char *p;                 //4字节指针
};class Derive:virtual public Base
{
public:Derive():Base(){};     ~Derive(){};
private:static int st;         //非实例独占int  d;                     //占4字节char *p;                    //4字节指针};

sizeof(Derive)=sizeof(Base)+虚函数指针(指示父类存放空间的起始偏移量)+sizeof(Derive.d)+sizeof(Derive.p)
虚继承时,父类和子类的虚函数表分开放,所以,分别存储两个指向对应续表的指针,因而不用减去sizeof(A)中续表指针的大小。


类的sizeof总结:
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小字节。
4.类的总大小也遵守类似struct字节对齐的,调整规则。
参考:http://blog.csdn.net/hairetz/article/details/4171769
http://blog.sina.com.cn/s/blog_728161840100u2ib.html

c语言 sizeof详解相关推荐

  1. C语言sizeof 详解

    1.sizeof是C语言的一个操作符,类似于++.–等.sizeof能够告诉我们编译器为某一特定数据或者某一个类型的数据在内存中分配空间时分配的大小,大小以字节为单位.基本用法为: 1.sizeof( ...

  2. C语言中sizeof详解——面试C/C++

    C面试sizeof详解 1.定义 sizeof是C语言的一种单目操作符,它并不是函数.sizeof操作符以字节形式给出了其操作数所占存储空间的大小.操作数可以是一个表达式或括在括号内的类型名.操作数所 ...

  3. 链表的基本操作(C语言)详解(摘取自C语言学习网2.5)

    链表的基本操作(C语言)详解 #include <stdio.h> #include <stdlib.h>typedef struct Link{int elem;struct ...

  4. Go语言slice详解

    Go语言slice详解 Go语言中的slice表示一个具有相同类型元素的可变长序列,语言本身提供了两个操作方法: 创建:make([]T,len,cap) 追加: append(slice, T -) ...

  5. C#语言入门详解笔记(5)—P10、P11、P12 操作符详解_1_2_3

    C#语言入门详解_哔哩哔哩_bilibiliC#语言入门详解搬运,随youtube上进度更新.刘老师的C#视频教程到30集就告一段落了,感谢刘老师在这5年间的付出.能上youtube的同学可以去刘老师 ...

  6. C语言指针详解(全解)—— 前篇

    关于指针的基本概念及相关运算写在了上一篇博客 C语言指针详解(初级)_Seinrich的博客-CSDN博客 本篇博客来详细的解说一下指针,深入探讨指针 一.指针与const const修饰的变量为常变 ...

  7. Python的C语言接口 - 详解官方文档

    Python的C语言接口 - 详解官方文档 索引 Python的C语言接口 - 详解官方文档 介绍 / Introduce 代码标准 / Coding Standards 包含文件 / Include ...

  8. 归并排序过程实现c语言,C语言归并排序详解

    C语言归并排序详解 发布日期:2015-12-31 11:16 来源: 标签: 编程语言 C教程 C语言归并排序 C语言归并排序算法 本章我们主要学习C语言实现排序算法之归并排序,对归并排序的原理及实 ...

  9. c语言数组详解视频,C语言数组详解

    <C语言数组详解>由会员分享,可在线阅读,更多相关<C语言数组详解(55页珍藏版)>请在人人文库网上搜索. 1.就是一组具有固定数目的.有序的.类型相同的数据的集合.根据数组下 ...

最新文章

  1. uva 1613——K-Graph Oddity
  2. java date转sql date_java.util.Date和java.sql.Date转换(转)
  3. Python3 爬虫学习笔记 C06 【正则表达式】
  4. DAO层接口性能监控
  5. java + testng wsdl 测试_在测试中使用XPATH断言的策略
  6. L3-019 代码排版 (30 分)-PAT 团体程序设计天梯赛 GPLT
  7. 惠普1020打印机查看已打印页数
  8. 字符数组初始化c语言,C语言字符数组
  9. vs2015发布网站到IIS
  10. 网络对抗技术——实验四:恶意代码技术
  11. Fabric区块链开发详解
  12. C Runtime Library 与 STL
  13. Kalman Filter 通俗讲解
  14. python访问陌生人qq空间_python程序记录QQ空间条说说的访问详情
  15. 使用python编写的落网电台下载工具
  16. 通过室内LED光打造世界的标志
  17. 常见的几种浏览器问题以及解决方案
  18. VMware Esxi7.0增加硬盘存储
  19. 《pigcms v6.2最新完美至尊版无任何限制,小猪微信源码多用户微信营销服务平台系统》
  20. 极限理论总结06:样本矩与样本中心距

热门文章

  1. 11.11买电脑怎么选?请收下这份武极电脑爆款清单
  2. Django DRF 视图集
  3. 苹果x怎么关机_价值300元的苹果mac重装系统教程,免费赠送给你收藏起来
  4. 域名和服务器IP地址有什么关系?
  5. mysql快速导数脚本,shell实现半自动化导数
  6. 佳能ts9020墨盒不识别_感动常在!佳能ts9020打印机更换墨盒经验
  7. PHP中echo PHP_EOL和echo “<pre>“的区别
  8. 简单打开百度地图APP的方法,并可以直接检索出搜索的位置
  9. NoVNC—以Web方式交付VNC远程连接
  10. 星露谷物语联机开服务器的人不在线,《星露谷物语》多人联机细节曝光 雇佣好友来种田!...