sizeof()计算嵌套结构体

学习此资料指南

  • 不用看各种头文件
  • 先从test::run2()极其前后注释看起
  • 然后如果想要深入学习,可以看test::run()中的Variadic_template实现递归复合的sizeof()求解,太细的东西暂时看不懂没关系,其实只用看数据,他就相当于run2()中的struct嵌套struct

关键

对于嵌套的结构体,需要将其展开。对结构体求sizeof时,上述两种原则变为:

  • 展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。

  • 结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for(int i = int(a); i <= int(b); ++i)
#define per(i, b, a) for(int i = int(b); i >= int(a); --i)
#define mem(x, y) memset(x, y, sizeof(x))
#define SZ(x) x.size()
#define mk make_pair
#define pb push_back
#define fi first
#define se second
const ll mod=1000000007;
const int inf = 0x3f3f3f3f;
inline int rd(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;}
inline ll qpow(ll a,ll b){ll ans=1%mod;for(;b;b>>=1){if(b&1)ans=ans*a%mod;a=a*a%mod;}return ans;}

namespace test{
    template<typename... Values> class tuple;
    template<> class tuple<> { };

    template<typename Head,typename... Tail>
    class tuple<Head,Tail...>
    {
        typedef tuple<Tail...> composited;
    protected:
        composited m_tail;
        Head m_head;
    public:
        tuple() { }
        tuple(Head v,Tail... vtail)
         : m_tail(vtail...),m_head(v){ }

        Head head() { return m_head; }
        composited& tail() { return m_tail; }
    };

    void run(){
        tuple<int,float,string> t(41,6.3,"linmin");
        cout<< sizeof(t) <<endl;
        cout<< sizeof(int) <<endl;
        cout<< sizeof(float) <<endl;
        cout<< sizeof(string("linmin")) <<endl;

        cout<< t.head() << endl;
        cout<< t.tail().head() << endl;
        cout<< t.tail().tail().head() << endl;

        tuple<string,complex<int>,bitset<16>,double>
            it2("Ace",complex<int>(3,8),bitset<16>(377),3.141592453);
        cout<< sizeof(it2) <<endl;
        cout<< sizeof(string("Ace")) <<endl;
        cout<< sizeof(complex<int>(3,8)) <<endl;
        cout<< sizeof(bitset<16>(377)) <<endl;
        cout<< sizeof(double) <<endl;
        cout<< it2.head() <<endl;
        cout<< it2.tail().head() << endl;
        cout<< it2.tail().tail().head() << endl;
        cout<< it2.tail().tail().tail().head() << endl;
    }
    /*
这个size我无法理解,老师的输出第一个竟然是16,第二个也是40

卡了一个多小时...2020年4月10日17:34:09 去查资料
2020年4月10日18:02:03 按照run2的分析之后就能懂得了为什么
这里是32,首先是这里一开始填4bytes,但是根据后面展开的结构体最宽的对齐
所以填完第一个的偏移量是8,之后填入4又同样的原因第二个后偏移到16
之后8和最后展开的一个空的一起都各自为8,所以是32

之后的40同理解释
32
4
4
8
41
6.3
linmin
40
8
8
4
8
Ace
(3,8)
0000000101111001
3.14159
    */

/*
对于嵌套的结构体,需要将其展开。对结构体求sizeof时,上述两种原则变为:
       (1)展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。

       (2)结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。

例子1:

struct stru5  
{  
      short i;  
      struct   
      {  
           char c;  
           int j;  
      } tt;   
      int k;  
};

结构体stru5的成员tt.c的偏移量应该是4,而不是2。整个结构体大小应该是16。
————————————————
版权声明:本文为CSDN博主「海月汐辰」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37858386/article/details/75909852

*/

    void run2(){
        struct stru1
        {
            short i;
            struct
            {
                char c;
                int j;
            } tt;
            int kl;
        };
        struct stru2
        {
            short i;
            struct
            {
                char c;
                int j;
                struct{
                    // 估计多加4,事实确实
                } tt2;
            } tt;
            int kl;
        };
        struct stru3
        {
            string a;
            struct
            {
                // 估计加8
            } sT;
        };
        cout<< sizeof(stru1) <<endl;
        cout<< sizeof(stru2) <<endl;
        cout<< sizeof(stru3) <<endl;
        // 16
        // 20
        // 16
    }
}


int main(){
    test::run();
    test::run2();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第十二章 自定义数据类型 12.1 结构体 结构体(structure)又叫结构,是一种构造类型,由若干成员构成,成员可以是一个基本数据类型或一个构造类型。 12.1.1 结构体声明 声明结构体的形式: struct 结构名 { 成员表列; }; 成员表列由若干个成员组成,每个成员必须做类型说明,形式为: 类型说明符 成员名; 例1:声明学生结构: struct student { int iNum; char cArrName[20]; char cSex; float fScore; }; 注意不要忘记}后的分号(;)。 成员名可与程序中其他变量同名,互不干扰。 结构体声明并不分配空间,结构体声明是在说明一种数据类型,不是变量定义。例1中结构体student与int、float一样都是数据类型。 声明结构体后可定义结构体变量,这时分配空间。 12.1.2 结构体变量定义 声明结构体后可以定义结构体变量。 定义方法: a.先声明结构体,再定义结构体变量 struct student { int iNum; char cArrName[20]; char cSex; float fScore; }; struct student stu1,stu2; 可以用宏定义使用一个符号常量表示一个结构体类型。 b.在声明结构体同时定义结构体变量 struct student { int iNum; char cArrName[20]; char cSex; float fScore; }stu1,stu2; c.直接定义结构体变量 struct { int iNum; char cArrName[20]; char cSex; float fScore; }stu1,stu2; 第三种与第二种区别在于省去了结构体类型名,而直接给出结构体变量。这种方法结构体只能用一次,即使再声明成员完全相同的结构体类型,也和此次定义的结构体类型属于不同的结构体类型。 结构体变量在内存空间中是连续存储的,结构体类型大小为sizeof(struct student),为各成员大小之和,各编译系统为内存管理方便可能分配大一些的内存空间来存储结构体,保证字节对齐。在Dev中上述结构体类型student为32字节。 结构体成员可以又是一个结构体,即构成嵌套结构体。如: struct date { int year; int month; int day; }; struct student { int iNum; char cArrName[20]; char cSex; float fScore; struct date birthday; }; 12.1.3 结构体变量引用 1.结构变量初始化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值