sizeof


sizeof的常量性

  • 常量性的概念:简单的说就是编译的时候就可以确定他的值了,就好像是const一样

    在一些老式的编译器里面你是不能够声明一个不确定大小的数组的,也就是说以下写法是错误的:
    int n = 10; int a[n] = {};
    这样子却是可以的:
    const int n = 10; int a[n] = {};
    原因就是const声明的变量是在编译的时候就已经确定好了,大小不允许改变,就是说经过了编译期之后,你的代码变成了这个样子:
    int a[10] = {}
    那么又回到了上面的问题,sizeof在编译的时候就确定了他的值,所以:
    int a[sizeof(int)] = {};
    这句话是完全没有错误的


sizeof基本数据类型

在一般的32位操作系统中
sizeof(bool)->1
sizeof(char)->1
sizeof(short)->2
sizeof(int)->4
sizeof(float)->4
sizeof(double)->8


sizeof数组和指针

  • 数组

    sizeof(数组)就是这个数组的所有元素占用内存空间的总和
    在32位操作系统中,
    int a[10] = {}; // sizeof(a)->10*sizeof(int)->40

  • 指针

    指针和数组很多新手一开始混淆两者的概念,来个比较简单形象的解释就是指针就是指向了某段内存但没有包含这段内存,而数组包含了整段内存
    所以sizeof(指针)仅仅是这个指针在内存中占有的空间,不包括指针指向的整段内存所占用的空间
    在32位操作系统中?????
    int* a; bool** b; // sizeof(a) = sizeof(b) = 4

这里看一个坑:(网上找来的)

int myfun(int a[10]) {return sizeof(a);
}
int main() {int a[10] = {};printf("%d\n", myfun(a));
}

如果你会觉得返回10,那你就错咯,编译器会输出8。8是怎么来的呢,很简单,就是在64位操作系统下的指针占用内存大小,这个时候你大概有点明白了吧~myfun函数传进去的参数实际上不是整个数组吧,而只是一个指向数组头的指针,这个指针大小仅仅是8而已。

结构体

这大概能算是sizeof里面比较难的的了

offsetof(struct, vari)是返回vari离struct的偏离量
先看一个例子

    #include<stdio.h>#include<stddef.h>#define s sizeofstruct student {char a;short a2;int b[10];float c;double d;short d2;} stu1;int main() {printf("%d\n", s(stu1));printf("\n");printf("%d\n", s(stu1.a));printf("%d\n", s(stu1.a2));printf("%d\n", s(stu1.b));printf("%d\n", s(stu1.c));printf("%d\n", s(stu1.d));printf("%d\n", s(stu1.d2));printf("\n");printf("%d\n", offsetof(struct student, a));printf("%d\n", offsetof(struct student, a2));printf("%d\n", offsetof(struct student, b));printf("%d\n", offsetof(struct student, c));printf("%d\n", offsetof(struct student, d));printf("%d\n", offsetof(struct student, d2));}// 输出如下641240482024444856

估计看了这个还是一脸蒙蔽(什么!明明是看了才会一脸MB)
为了更好的理解struct这个东西的内部构造,你首先要知道对齐这个概念,就是说struct里面的结构不会是一沓书那样堆积起来,而是有些书会悬浮,没错,你可以理解为悬浮。这种效果在struct里面就叫做对齐
好的,接下来,我引入百科到的对齐规则:
1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2. 结构体每个成员相对于结构体首地址的偏移量(offset)都是每个成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
最宽基本类型是看单个的,也就是说数组只会看一个元素,结构体会打散看最大的哪个元素
现在尝试分析上面的例子,一开始char是1字节,偏移量为0;第二个short是2字节,那么根据第二条规则,偏移量是2;第三个是int[10]数组,占用4*10字节,根据最宽基本类型是看单个的原则,偏移量就是int的整数倍,那就是4;float占用4个字节,偏移量是44;double占用8个字节,偏移量是48;short占用2的字节,偏移量是56,那最后64是怎么得到的?56+2=58并不能整除最宽成员大小8,所以取最接近的64就ok啦。

再来看一个结构体包含结构体的例子把~

    struct S1{char c;int i;};struct S2{char c1;S1 s;char c2};

这时候sizeof(S2)->16
首先sizeof(s)->8,然后注意了,S2里面的最宽类型大小不是sizeof(s)而是S1里面最宽的一个元素int->4。S2第一个元素:c1偏移量为0,大小是1。s偏移量是4,大小是8。c2偏移量是12,大小是1。12+1=13不能整除4,所以取最接近的16。

然而事情并没有你想的那么简单,编译器算出的sizeof还与另外一个东西有关,那就是pack指令,pack指令可以控制偏移量,那么偏移量就会取pack指令的那个标准偏移量和item字节大小的较小的那个
offsetof( item ) = min( n, sizeof( item ) )

#pragma pack(push) // 将当前pack设置压栈保存
#pragma pack(2)// 必须在结构体定义之前使用
struct S1
{char c;int i;
};
struct S3
{char c1;S1 s;char c2
};
#pragma pack(pop) // 恢复先前的pack设置

联合体

联合体比较简单,就是取联合体内最大的那个元素占有的字节大小就好了

    union U {int i;char c;}; // sizeof(U)->sizeof(i)

以上内容属个人理解,难免会有错误,如有错误,请各位大神帮忙纠正,不甚感激!

转载于:https://www.cnblogs.com/PerdonLiu/p/6150337.html

对sizeof的一点点理解相关推荐

  1. 对Thrift的一点点理解

    对Thrift的一点点理解 这是一篇学习Thrift的笔记,包含了这样几点内容: 简单介绍Thrift 怎样使用Thrift Thrift整体架构 Thrift中的知识点 struct可以设置默认值 ...

  2. 重学概率论的一点点理解(持续更新)

    前言:这里是毕业N年后重学概率的一点点理解,因为上学的时候贪玩了,现在到了还的时候,要花费大量的时间,悲剧...所以请同学们抓紧在校时间,务必多夯实基础. 文章内容都是自己手工敲的,算是一点点学习笔记 ...

  3. HGMMs的一点点理解~

    Robust Ellipse Fitting Using Hierarchical Gaussian Mixture Models Motivation Related works Ellipse f ...

  4. javascript中函数参数以及函数中局部变量作用域一点点理解

    2019独角兽企业重金招聘Python工程师标准>>> 函数中局部变量如果与外部变量重名,则用的是函数内部局部变量,用完就会被释放.我的理解函数是一个function定义的代码段,以 ...

  5. 对线性时不变系统(LTI)中时不变(Time Invariant)的一点点理解

    这个博客又找回来了,重新恢复更新 ==========================================x 这个问题讨论的是一个系统对于一个随时间变化的输入信号x的一个处理问题. 时不变 ...

  6. 软件定义安全的一点点理解

    万事开头难,中间也难,最后也难.第一次写博客,内容.排版都不太好,请见谅.文章内容部分来源绿盟的<软件定义下的新型安全架构和实践>.<软件定义安全>以及<软件定义安全:S ...

  7. 强化学习(Reinforcement Learning)之策略梯度(Policy Gradient)的一点点理解以及代码的对应解释

    一.策略梯度算法推导以及解释 1.1 背景 设πθ(s)\pi_{\theta }(s)πθ​(s)是一个有网络参数θ\thetaθ的actor,然后我们让这个actor和环境(environment ...

  8. 网关是什么意思 这我对网关的一点点理解

    现在信息网络的发达,人们在使用电脑的过程中必然会遇到一些问题,而对于一些电脑的专用名词,如果你不是专业人士,可能在遇到这些问题时是一筹莫展的.其实网关有一个很简单的理解思路,就是当我们从一个空间到另一 ...

  9. 用我对HTML的点点理解来做个简单的百度首页

    为什么80%的码农都做不了架构师?>>>    在我心里,HTML一直以来都是一个新鲜而神秘的东西,好多次想静下心来研究研究,最终因为各种原因搁置下来.终于,最近终于有时间看看其中的 ...

最新文章

  1. Linux复制文件scp
  2. 257.二叉树的所有路径
  3. html 动画div右侧消失,使用animate.css时,动画一开始不隐藏,如何解决呢?
  4. python读取csv文件的方法-CSV文件在Python中的几种处理方式
  5. C++ leetcode 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外
  6. 如何用javac 和java 编译运行整个Java工程
  7. clientdataset 遍历字段_TClientDataSet[5]: 读取数据
  8. S3C2440 lds链接脚本解析
  9. 如何提高 Java 中锁的性能
  10. InstallShield安装过程介绍
  11. 算法(0)—— 打造一个C开发库
  12. Matlab Copula函数实现
  13. vue中index.html文件为什么可以使用模板语法
  14. 飞鸽传书——空号检测
  15. 祖籍-山西省洪洞县大槐庄
  16. C# 导出Excel解决Cannot get a text value from a numeric cell或者Cannot get a numeric value from a text cell
  17. 大众点评cat接入记录
  18. java null==null是否成立
  19. 客户无盘系统服务器内存,无盘服务器内存大小
  20. 争对让望对思野葛对山栀注解_中华经典名著《笠翁对韵》全文解释(上卷四支)...

热门文章

  1. 搭建php mysql平台,在windows7中搭建Apache+PHP+MySQL平台
  2. 我有个朋友叫大路,他满世界“平事儿”不含糊
  3. torch.Linear(input_size,output_size, bia = True/Flase)
  4. Web Storage知识点梳理,模拟后台管理系统部分功能
  5. PMI-ACP练习题(7)
  6. git学习之:如何将远程代码强制拉取同步(覆盖)到本地文件夹
  7. ACM-ICPC 2018 沈阳赛区网络预赛 G. Spare Tire
  8. verilog编写数字频率计
  9. 计算机操作系统保研面试题整理(自用)
  10. 使用A*算法解迷宫最短路径问题