二、C语言小知识-指针和结构体究竟占几个字节

1、知识点:

  1. 我们在结构体这个整体中定义的成员变量是挨着的,这让我们容易误以为它们的存储方式也是挨着的,但其实并不是。
  2. 我们之前用sizeof测过,在gcc编译器下,不论什么类型指针,占用空间都是8字节;在VS编译器中,不论什么类型的指针,占用空间都是4字节。
  3. 在gcc编译器下,操作系统的1个操作字是8个字节(等于地址的存储范围,即寻址范围),因此每次存储、读取数据的都是按照8个字节来的。

1.指针:内存地址

16位机器的代码时,指针占2个字节。

32位机器的代码时,指针占4个字节。

64位机器的代码时,指针占8个字节。

2.结构体占用空间

特殊:大结构体的成员有小结构体 

原则:

①大结构体整体的空间=max{大结构体成员(不包括小结构体整体),小结构体成员}*n;

②大结构体中,前面的成员变量=max{成员变量}*n

同理,大结构体中,小结构体前面的变量占空间=max{小结构体成员}*n

1、规则一(根据成员变量类型确定为结构体开辟内存的基本单位):与成员变量类型相关

  • 知识点1【规则1制定的原因】:①能不能避免麻烦,直接给结构体分配一个很大的内存呢?当然不行,这是为了不造成过多的空置内存;②能不能对任意类型的结构体都规定一样的开辟基本单位?当然不行,这是为了针对不不同类型的结构体,制定不同的开辟速度,为了节省开辟时间;
  • 知识点2【确定方法】:确定每个成员变量的开辟内存大小后,取大的那一个作为结构体开辟内存的单位

确定不同类型成员变量的开辟内存大小:

  1. char类型的成员变量:以1字节为单位开辟内存
  2. short类型的成员变量:以2字节为单位开辟内存
  3. int类型的成员变量:以4字节为单位开辟内存
  4. float类型的成员变量:以4字节为单位开辟内存
  5. double类型的成员变量:以8字节为单位开辟内存
  6. 任意指针类型的成员变量:以8字节为单位开辟内存
  7. 数组成员变量:把它看成上述基本类型的成员变量的集合

2、规则二(内存对齐原则):与成员变量类型相关

  • 知识点【规则2制定的原因】:①能不能避免麻烦,在确定了结构体开辟内存的基本单位之后,直接在让成员变量挨着存储呢?当然不行,因为操作系统的1个操作字是8个字节,所以如果不规定字节对齐的话,对一个结构体成员取值,可能要取两遍,归纳起来就是用空间来换时间,提高CPU读取数据效率。
  • 内存对齐,跟谁对齐?答案是结构体变量的首地址,也就是结构体变量中第一个成员变量的地址。

确定不同类型成员变量的对齐方法:假设将结构体变量的首地址看作基准0,那么某个成员变量开始存放的地址编号是该成员的数据类型所占内存大小的倍数。

  1. char类型的成员变量:与结构体变量首地址的相对地址是1字节的倍数。
  2. short类型的成员变量:与结构体变量首地址的相对地址是2字节的倍数。
  3. int类型的成员变量:与结构体变量首地址的相对地址是4字节的倍数。
  4. float类型的成员变量:与结构体变量首地址的相对地址是4字节的倍数。
  5. double类型的成员变量:与结构体变量首地址的相对地址是8字节的倍数。
  6. 任意指针类型的成员变量:与结构体变量首地址的相对地址是8字节的倍数。
  7. 数组成员变量:把它看成上述基本类型的成员变量的集合

例:32位机器上,以下结构的sizeof(P)为()

A 26                    B 38                     C 40                    D 3

struct A {
    int a;       
    char b;     
    int c;        
    char d;       
};
 
 
struct P {
    struct A w[2];
    short b;
    struct A* p;
 
}

 

struct A {
    int a;        //4B
    char b;        //由原则2,b的大小必须是a的整数倍,4B
    int c;        //4B
    char d;       //由原则2,c的大小必须是a的整数倍,4B
};//4*4=16B
 
 
struct P {
    struct A w[2];//16*2=32B
    short b;//由原则2,b的大小必须是a的整数倍,4B
    struct A* p;//32位机,地址占4B
//由原则1,P的大小必须是max{A.a,A.b,A.c,A.d,P.B,P.p}=4的整数倍
//原大小=32+4+4=38,自动填充2B变为40B,
}

 

 


————————————————

参考原文链接:https://blog.csdn.net/lzh201864031/article/details/129900147

 参考原文链接:

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:C语言字节对齐问题详解中提到了C语言中的字节对齐问题。在结构体中,为了提高内存访问的效率,编译器会对结构体进行字节对齐。这意味着结构体的成员在内存中并不是紧凑排列的,而是按照一定的规则进行对齐。具体的对齐规则取决于编译器和编译选项。\[1\] 引用\[2\]:在C语言中,可以使用宏offsetof来获取结构体成员相对于结构体开头的字节偏移量。这个宏非常有用,可以帮助我们计算出每个结构体成员相对于结构体开头的偏移字节数。通过这个宏,我们可以更好地理解结构体的内存布局。\[2\] 引用\[3\]:在C语言中,指针结构体的组合常常用于处理复杂的数据结构。指针可以指向结构体的成员,通过指针可以方便地对结构体进行操作。指针结构体的组合可以实现更灵活的数据处理和内存管理。\[3\] 综上所述,C语言中的指针结构体组合可以用于处理复杂的数据结构,而字节对齐问题则是在结构体中为了提高内存访问效率而进行的优化。通过使用宏offsetof,我们可以更好地理解结构体的内存布局。 #### 引用[.reference_title] - *1* *3* [结构体指针C语言结构体指针详解](https://blog.csdn.net/weixin_34069265/article/details/117110735)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言结构体详解](https://blog.csdn.net/m0_70749276/article/details/127061692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值