3.sizeof

3.sizeof

sizeofC/C++中的一种单目操作符,不是函数。 

作用就是返回一个对象或者类型所占的内存字节数。返回值类型为siz_t.

1.用于类型            sizeof(type)      数据类型必须用括号括住     例如sizeof(int)。

2.用于变量或对象    sizeof(object)或者sizeof  object       推荐使用括号形式,保持统一也为了防止错误

3.sizeof操作符不能用于函数类型,不完全类型或者位字段。

不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。

例如:     int fun(int a,int b){}    sizeof(fun(3,4));   相当于sizeof(int);

例如:     int max(int a,int b){}    sizeof(max);    错误      

int   a[MAX];     MAX大小未知        sizeof(a);      错误       sizeof(void)  ;  错误

sizeof操作符的结果类型是size_t,它在头文件中typedef为  unsigned int类型。 保证能容纳实现所建立的最大对象的字节大小。 
1、类型char、unsigned char或signed char在所有平台下,其sizeof的结果都为1。

                        32位机linux平台下             64位机linux平台下

int                                   4                                   4

unsigned int                    4                                   4

short int                          2                                   2

long int                           4                                   4

unsigned  long                4                                   8

float                                4                                   8

double                            8                                   8

long  double                   12                                 12

2.    sizeof的常量性

sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用。C99标准规定sizeof也可以在运行时刻进行计算

3.    指针变量的sizeof

指针变量的sizeof值与指针所指的对象没有任何关系

int  *p1;       char *p2 = "hello";      string* p3;       char** p4 = &p2;

sizeof(p1) == sizeof(p2) == sizeof(p3) ==sizeof(p4);     32位系统下为4,64位系统下为8

4.    数组的sizeof

char a1[]="hello";

int   a2[100];                   sizeof(a1) = 6;           sizeof(a2) = 400;

数组传参时,是传址方式,传的是数组的地址

操作数是函数中的数组形参或函数指针类型的形参,sizeof给出其指针的大小。

5.    联合体类型(union)的sizeof是其最大字节成员的字节数。

因为结构体在内存组织上是顺序式的,而联合体则是重叠式,各成员共享一段内存

 union   a{ int a;       char  b;       double  c;  };    sizeof(a) = 8;

6.结构体类型的sizeof要注意字节对齐

字节对齐的原因是:计算机组成原理告诉我们字节对齐有助于加快计算机的取数速度,否则就得多花指令周期了

三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
                   2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍, 如有需要编译器会在成员之间加上填充字节(internal adding);

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

struct   S2{

int i;

char c;

};

结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

例如,想要获得S2中c的偏移量,方法为

size_t pos = offsetof(S2, c);// pos等于4

关于三个对齐规则参考博客:  https://blog.csdn.net/u013057233/article/details/76573347

7. “空结构体”(不含数据成员)的大小不为0,而是1。

试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢

于是,“空结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。

8.含位域结构体的sizeof

位域成员不能单独被取sizeof值我们这里要讨论的是含有位域的结构体的sizeof。C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。使用位域的主要目的是压缩存储,其大致规则为: 
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字 
段将紧邻前一个字段存储,直到不能容纳为止; 
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字 
段将从新的存储单元开始,其偏移量为其类型大小的整数倍; 
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方 
式,Dev-C++采取压缩方式; 
4) 如果位域字段之间穿插着非位域字段,则不进行压缩; 
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍

例子: struct  a1{

char   f1:3;

char  f2:4;

char  f3:5;

};     3+4+5>8   所以  sizeof(a1) = 2;

struct  a2{

char   f1:3;

int    f2:4;

char f3:5;

} ;相邻位域类型不同, sizeof(a2) = 1+4+1;  VC++   

 struct  a3

{char f1:3;   

int f2;

char f3:5;
};非位域字段穿插在其中,不会产生压缩,在VCDev-C++中得到的大小均为3。

9.sizeof测类所占字节的大小

1.空类,使用sizeof求得其大小为1。

2.类里面的静态成员变量不计算,因为sizeof只能测堆栈区的数据字节数,无法测数据区的字节数

3.带虚函数的类

虚函数放在虚表中,类中定义了虚函数,需要存放一个指向虚表的指针。

        当有多个虚函数时,仍然只一个指向虚表的指针

        更多参考博客: https://blog.csdn.net/szchtx/article/details/10254007



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值