对于C语言开发人员来说,sizeof应该不陌生吧。此次我主要写的是sizeof对各变量长度的计算方式。
sizeof这个函数主要是对各数据类型的长度进行计算,入参为数据类型,返回值计算结果。但由于不同OS的系统架构下,sizeof计算的结果会存在一定的差异。下文主要基于32位系统,讨论sizeof的计算方式。
比较常见的场景是基本数据类型长度的计算结果如下:
类型
32位系统(bytes)
64位系统(bytes)
bool
1
1
char
1
1
short
2
2
int
4
4
long
4
8
long long
8
8
char *
4
8
float
4
4
double
8
8
long double
12
16
说明:char*代表指针变量,不管什么类型的指针,指针变量长度都是一样的。
为了加快CPU取数速度,C标准规定变量存放地址一定为自身长度的整数倍。因此变量间就会出现缝隙空间,这时编译器在编译期间就会对这些缝隙进行填充,叫做变量的对齐与补齐规则。接下来我会举例说明各种场景下的对齐与补齐方式:
例1:
#include <stdio.h>
struct st
{
char a;
int b;
short c;
long d;
};
int main(void)
{
struct st tmp;
printf("&tmp.a=%p\n",&(tmp.a));
printf("&tmp.b=%p\n",&(tmp.b));
printf("&tmp.c=%p\n",&(tmp.c));
printf("&tmp.d=%p\n",&(tmp.d));
printf("sizeof(tmp)=%d\n",sizeof(tmp));    
return 0;
}
执行结果:
&tmp=0xbfe6e960
&tmp.a=0xbfe6e960
&tmp.b=0xbfe6e964
&tmp.c=0xbfe6e968
&tmp.d=0xbfe6e96c
sizeof(tmp)=16
从结果可以出成员变量的存放地址都是自身长度的整数倍。但结构体有所不同,结构体变量的地址应该为其最大成员变量长度的整数倍,且各成员变量遵守对齐与补齐规则,包括最后一个成员变量。所以 st结构体的大小为:1(a)+3(填充)+4(b)+2(c)+2(填充)+4(d)=16
例2:
struct st
{
    char a;
    int b;
    short c;
    long d;
    static int e;
};
结果:
sizeof(tmp)=16
在C++中可能会见到结构体中定义静态成员的代码,由于静态成员在定义时就已经分配的内存空间,所以用sizeof来计算结构体大小时,是不计算在内的。
例3:
struct st1
{
}tmp1;
结果:
sizeof(st1)=0
空结构体的大小为0,该类型不占用任何的地址空间。
例3:
void fun(void)
{
}
printf("sizeof(void)=%d\n",sizeof(void));
printf("sizeof(fun)=%d\n",sizeof(fun));
printf("sizeof(fun())=%d\n",sizeof(fun()));
结果:
sizeof(void)=1
sizeof(fun)=1
sizeof(fun())=1

void类型的大小为1,sizeof也可以用来计算函数的大小以及返回值。
从执行文件的头部信息来看:
Num:    Value  Size Type    Bind   Vis      Ndx Name
48: 080483c4     5 FUNC    GLOBAL DEFAULT   13 fun

函数fun应该是占用5个字节的,这里不知道为什么打印出来只有1个字节?不过一般不会用sizeof来计算函数大小,没有什么意义。
例4:
struct st2
{
    char a:1;
    char b:4;
    char c:5;
    short d:10;
};

结果:
sizeof(st2)=4
这个例子结合位变量来说明字节对齐与补齐的规则,结构体中各成员变量存放如下:
|0|1234|567 01234567 01234567 01234567|   //4个字节长度
|a|   b   |       |   c    |      |        d          |                //4个变量存放
首先a占用了第一个字节的最低位,b占用了第1到第4位,由于c所占的位数超过了上一字节空闲的位数,所以c从下一字节的地址开始算起,占用第0到第4位。变量d由于是short型变量,需要以2字节对齐,所以地址从第3个字节的低位开始算,长度为10,余下6个位自动补齐。最终,该结构体大小为4字节。
例5:
union st2
{
    char a;
    shot b;
    int c;
};
结果:
sizeof(union)=4
联合体中成员是共享内存的,所以长度为最大成员变量的大小。
例6:
struct st
{
    char a;
    int b;
    short c;
    long d;        //最大长度为4
};
struct st2
{
    char a;
    short d;        //最大长度为2
    char e;
};
struct st4
{
    struct st a;          //16个字节
    struct st2 b;        //6个字节
};
结果:
sizeof(st4)=24
在st4结构体中,成员a占用16个字节,成员b占用6个字节,为什么 最终st4会占用24个字节呢?原因是a中变量最大长度为4,所以a以4字节对齐,b中变量最大长度为2,所以b以2字节对齐,但对于st4结构体来说,它内部基本数据类型最长为4字节,所以st4结构体以4字节对齐,最后会在后面填充2个字节。
总之,sizeof计算规则如下:
1、基本数据类型变量地址为自身长度的整数倍
2、对于结构体,sizeof会把编译器自动填充的字节算在内。
3、sizeof不计算静态变量的长度
C语言提供了#pragma宏可以指定字节对齐的长度:
例7:
#include <stdio.h>
#pragma pack(2)        //强制以2字节对齐
struct st
{
    char a;
    int b;
};
void main(void)
{
    printf("sizeof(struct st)=%d\n",sizeof(struct st));
}
结果:
sizeof(struct st)=6
st结构体中成员b的初始地址不再是4的位数,而是2的倍数。

C语言sizeof的计算方式相关推荐

  1. c语言sizeof怎么计算字节数,理解c语言的sizeof

    c语言有很多用起来需要特别注意的地方,我们(计算机学习微信公众号:jsj_xx)以后会分析其中有使用价值的点.今天我们一起看看sizeof.c语言通过类型长度来达到指针的灵活性,我们觉得,某种意义上讲 ...

  2. c语言sizeof用法计算char,C语言里sizeof(char)是什么意思

    sizeof() 是一种内存容量度量函数,功能是返回一个变量或者类型的大小(以字节为单位). char是c语言中基本类型,一般char类型占1个字节. sizeof(char)的结果是,1. size ...

  3. 面试珠玑 C语言中union与struct的区别及sizeof的计算方式

    在C语言中结构体和联合具有细微差别,特别是使用sizeof()对其求大小时,许多刚刚接触C语言不久的朋友对此非常困惑,下面我将简单谈以下自己对union与struct之间的区别 联 合(union)  ...

  4. C语言中union与struct的区别及sizeof的计算方式

    C语言中union与struct的区别 2011-08-02 23:41 45人阅读 评论(0) 收藏 举报 在C语言中结构体和联合具有细微差别,特别是使用sizeof()对其求大小时,许多刚刚接触C ...

  5. java go md5_Go语言中三种不同md5计算方式的性能比较

    前言 本文主要介绍的是三种不同的 md5 计算方式,其实区别是读文件的不同,也就是磁盘 I/O, 所以也可以举一反三用在网络 I/O 上.下面来一起看看吧. ReadFile 先看第一种, 简单粗暴: ...

  6. C语言中短整型取值范围,以c语言中短整型(signed int)的取值范围为例说明各种数据类型取值范围的计算方式与原理...

    在开始我们的正文之前,你需要先了解一下原码.反码.补码这三个概念以及这三者之间的相互转换方式. 在有了一定的了解之后,我们开始我们的介绍.在本文中,我们以短整型为例,给大家介绍该类型的取值范围的计算方 ...

  7. c语言sizeof strlen,C语言中sizeof与strlen区别

    一.本质区别 sizeof 和strlen 有本质上的区别.sizeof 是C 语言的一种单目运算符,如++.--等,并不是函数,sizeof 的优先级为2 级,比/.% 等3 级运算符优先级高,si ...

  8. C语言 数组长度计算 - C语言零基础入门教程

    目录 一.计算数组长度 1.经典案例 2.计算数组长度 二.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.计算数组长度 1.经典案例 / ...

  9. C语言 sizeof 和 strlen 函数区别 - C语言零基础入门教程

    目录 一.sizeof 函数与 strlen 函数区别 1.获取字符串长度 – 针对字符串 2.获取指针/数组长度 – 针对指针/数组 3.sizeof 获取内存大小 4.经典案例 二.猜你喜欢 零基 ...

最新文章

  1. WebSocket 协议
  2. redis 常用配置
  3. 负载均衡算法-轮询均衡
  4. LBP(local binary pattern)
  5. RFID助力汽车零部件厂商识别冲压工具位置
  6. Windows10安装ubuntu 20双系统
  7. 谈软件测试---一年测试工作总结
  8. 通过CSS3 Media Query实现响应式Web设计
  9. 线性表接口的实现_Java
  10. Brother-MFC系列打印机 PDF双面打印设置
  11. 疯狂Java讲义(一)
  12. 磁盘管理压缩卷显示服务器异常,Win7分配盘符提示“磁盘管理控制台不是最新状态”错误怎么办...
  13. iPhone12、iPhone12 Pro、iPhone12 Max、iPhone12 Pro Max 详细参数配置
  14. 平台电子签章实现方法
  15. pg_receivewal实践
  16. 22套精致的用户界面 PSD 源文件素材
  17. 解决 system_stm32f0xx.o(.data) type RW incompatible with main.o type ZI in er RW_IRAM1.
  18. 威胁聚焦:Phobos勒索软件名不虚传
  19. Windows利用bat程序打开指定网址
  20. 简易局域网视频服务器

热门文章

  1. 重构碎片化知识_知识碎片化,思维导图重构你的思维体系
  2. Cocoapods制作pod时,依赖百度地图SDK的一些问题
  3. 好用的游戏机械键盘怎么选?精英选手挑选游戏机械键盘的入门指南
  4. HTML部分知识点整理
  5. 头歌实践-Java继承与多态
  6. Surfer13 自动实现网格化
  7. 光棍节程序员闯关秀第5关(总共10关)
  8. Python IDLE常用快捷键
  9. HTML +CSS制作QQ登录页面
  10. C++之substr函数