C++中常见数据类型的sizeof值,以及计算struct和union的详细方法

#include <iostream>
#include <cstdio>
#include <cstdlib>
/*sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。*/
using namespace std;
//1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
//2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
//3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
struct ss{
    char a;     //size=1 + 对界偏移+7
    double b;   //size=8
    int c;      //size=4
    char d;     //size=1
};  //根据第三条规则(sizeof(ss)应为8的整数倍):对界偏移+3,所以总大小1+7+8+4+1+3=24;
//union sizeof计算规则:sizeof(union)=最宽基本成员变量的字节数
union uu{
    int i;
    char c;
    long l;
};
int main()
{
    cout << "Hello world!" << endl;
    int i;          cout<<"sizeof(int)="<<sizeof(i)<<endl;
    int8_t i8;      cout<<"sizeof(int8_t)="<<sizeof(i8)<<endl;
    int16_t i16;    cout<<"sizeof(int16_t)="<<sizeof(i16)<<endl;
    int32_t i32;    cout<<"sizeof(int32_t)="<<sizeof(i32)<<endl;
    int64_t i64;    cout<<"sizeof(int64_t)="<<sizeof(i64)<<endl;

    short st;       cout<<"sizeof(short)="<<sizeof(st)<<endl;
    double d;       cout<<"sizeof(double)="<<sizeof(d)<<endl;
    long l;         cout<<"sizeof(long)="<<sizeof(l)<<endl;
    long long ll;   cout<<"sizeof(long long)="<<sizeof(ll)<<endl;

    char c;         cout<<"sizeof(char)="<<sizeof(c)<<endl;

    struct ss s;    cout<<"sizeof(struct_int_char_long)="<<sizeof(s)<<endl;
    union uu u;     cout<<"sizeof(union_char_double_int_char)="<<sizeof(u)<<endl;
    return 0;
}

输出结果:


Hello world!
sizeof(int)=4
sizeof(int8_t)=1
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int64_t)=8
sizeof(short)=2
sizeof(double)=8
sizeof(long)=8
sizeof(long long)=8
sizeof(char)=1
sizeof(struct_int_char_long)=24
sizeof(union_char_double_int_char)=8

上面可以看到C++中常见的数据类型的sizeof大小,只有1,2,4,8 总共4中情况所以还是比较好记的

下面说一下计算结构体大小的方法:

结构体大小的计算需要满足下面3条规则:

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

看来比较抽象是吧,结合程序来看就容易一些了

根据规则1,定义结构体时可以将结构体变量的首地址都看成是0。就算在结构体的定义的前面还有代码,导致结构体变量的首地址不是0,其也不会影响结构体的size。

结构体定义的初始偏移是0,char占用一个字节


第二个成员变量是一个double,占8个字节

根据规则2,b的偏移地址应是8的整数倍,所以应该在a的后面加上7个空字节(也叫对界),这样b的偏移就是8,满足了规则2


第三个成员变量是一个int,占4个字节

变量c的偏移是16,满足规则2,不用进行对界了


第三个成员变量是一个char,占1个字节

此时变量d的偏移是20,char占1个字节,20也是1的倍数,所以不用对界


现在结构体占用21个字节,但是程序显示的结果是24,原因就是用到了规则3

结构体ss中的最宽基本类型是double,8个字节

所以结构体ss的大小应该是8的整数倍,需要进行对界操作,填充3个空字节

所以最后结构体ss的大小是24字节!!


Tips:因为结构体涉及复杂的对界操作,所以结构体中的成员变量发生变化,结构体的大小也会发生变化。


计算union的大小就很容易了,因为union的成员变量占用最宽成员变量的字节长度

共用体uu中的最宽成员变量是long,占8个字节,所以共用体uu的大小就是8个字节!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言所有关键字的意思及用法: auto:自动变量关键字,用于定义自动变量。 break:跳出循环语句或switch语句。 case:switch语句的分支标签。 char:字符类型关键字,用于定义字符变量。 const:常量关键字,用于定义常量。 continue:继续循环语句执行。 default:switch语句的默认分支。 do:循环语句关键字,用于执行循环体。 double:双精度浮点数类型关键字,用于定义双精度浮点数变量。 else:条件语句关键字,用于表示条件不成立时的执行操作。 enum:枚举类型关键字,用于定义枚举类型。 extern:外部变量或函数关键字,用于引用其他文件的变量或函数。 float:单精度浮点数类型关键字,用于定义单精度浮点数变量。 for:循环语句关键字,用于执行循环体。 goto:无条件跳转关键字,用于跳转到指定标签处。 if:条件语句关键字,用于表示条件成立时的执行操作。 int:整型类型关键字,用于定义整型变量。 long:长整型类型关键字,用于定义长整型变量。 register:寄存器变量关键字,用于定义寄存器变量。 return:函数返回关键字,用于从函数返回。 short:短整型类型关键字,用于定义短整型变量。 signed:带符号类型关键字,用于定义带符号类型变量。 sizeof计算数据类型大小关键字,用于计算数据类型所占的字节数。 static:静态变量或函数关键字,用于定义静态变量或函数。 struct:结构体类型关键字,用于定义结构体类型。 switch:多分支选择语句关键字,用于根据不同的条件执行不同的操作。 typedef:类型定义关键字,用于定义新的数据类型union:共用体类型关键字,用于定义共用体类型。 unsigned:无符号类型关键字,用于定义无符号类型变量。 void:空类型关键字,用于表示无返回或无参数的函数。 volatile:易变变量关键字,用于定义易变变量。 while:循环语句关键字,用于执行循环体。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值