前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言——结构体类型(二)【结构体内存对齐,结构体数组】

C语言——结构体类型(二)【结构体内存对齐,结构体数组】

作者头像
用户11029137
发布2024-03-19 15:49:06
1450
发布2024-03-19 15:49:06
举报
文章被收录于专栏:编程学习编程学习

一,结构体内存对齐

1,基本知识

🔍问题引导: 我们都知道sizeo(变量类型))可以得到一个变量所占内存的大小,那么,请看下面这串代码👇🏻

代码语言:javascript
复制
#include<stdio.h>
struct stu1
{
    char a;
    int b;
    char c;
};
struct stu2
{
    int b;
    char c;
    char a;
};
int main()
{
    printf("%d\n", sizeof(struct stu1));
    printf("%d\n", sizeof(struct stu2));
    return 0;
}

输出结果是什么呢? 猜测:两个结构体里面都是两个char,一个int,那他们的内存大小应该一样吧 但是,输出结果👇🏻

很显然,尽管这两个结构体变量的成员差不多,但是这两个结构体变量的大小却不一样。 这就是因为结构体类型的变量在开辟内存的时候,要遵循结构体内存对齐,只有对齐到符合的地址处时,才会开始为成员分配内存

在了解如何对齐前,我们先来了解对齐数这个概念👇🏻

① 一个变量的对齐数 = 编译器默认的对齐数 与 该成员变量大小之间的较小值 ②如果嵌套了结构体类型的成员,则这个成员的对齐数就是 这个嵌套的结构体的自身成员中的最大对齐数 ●VS中默认的对齐数是8 ●Linuxgcc没有默认对齐数(即对齐数就是成员变量的自身大小)

🔍接下来我们就来介绍一下结构体内存对齐的规则: 1,结构体的第一个成员对齐到与结构体变量起始位置的偏移量为0的地址处(简单来说就是第一个成员变量的内存从起始位置开始分配) 2,其他成员变量要对齐到 与起始位置的偏移量为这个变量的对齐数的整数倍的地址处,然后再开始分配内存 3,结构体的总大小应该为 所有成员中最大对齐数 的整数倍

2,例子分析

我们计算结构体的大小的一般流程如下👇🏻

了解了上面的知识以后,我们再来分析几个例子: 例1:(为什么:stu1是12,stu2是8?)

代码语言:javascript
复制
struct stu1
{
    char a;
    int b;
    char c;
};
struct stu2
{
    int b;
    char c;
    char a;
};

我们用上面步骤对stu1进行分析:

具体分配(stu1):

同理,我们可以得到stu2的分配情况:

例2(当有结构体成员):

代码语言:javascript
复制
#include<stdio.h>
struct date
{
    int year;
    int month;
    int day;
};
struct stu
{
    char name[10];
    int age;
    char sex;
    struct date birthday;
};
int main()
{
    printf("%d", sizeof(struct stu));
    return 0;
}

运行结果:

要注意的有以下两点: 1,嵌套的结构体成员birthday的对齐数 2,birthday成员的大小,birthday也是一个结构体,也要用结构体内存对齐的方式来计算大小 具体分配如下:

二,结构体数组

1,什么是结构体数组

结构体数组,顾名思义就是数组元素是结构体的数组

结构体类型的数组的定义形式: struct 结构体类型名 数组名[数组长度];

例如(定义一个能保存3个学生信息的结构体数组)👇🏻

代码语言:javascript
复制
struct student
{
    char name[10];
    int age;
    char sex;
};
struct student stu[3];

其数组元素各成员的引用形式为:

代码语言:javascript
复制
stu[0].name[i], stu[0].age, stu[0].sex //引用第一个
stu[1].name[i], stu[1].age, stu[1].sex //引用第二个

2,结构体数组的初始化

数组总的元素用花括号{ }括起来,在括号内再用花括号{}对单个结构体元素的多个成员进行初始化,每个数组元素之间用逗号隔开 (多成员初始化就用:花括号{}) ●在定义的时候初始化

代码语言:javascript
复制
    struct student stu[3] ={{"zhangsan",18,'B'},{"lisi",20,'G'},{"wangwu",30,'B'}};

最外层的{}代表数组里面有多个元素,内层的{}代表一个结构体里面有多个成员

●利用.操作符进行初始化

代码语言:javascript
复制
struct student stu[3] ={{.name="zhangsan",.age=18,.sex='B'},{.name="lisi",.age=20, .sex='G'},{.name="wangwu",.age=30,.sex='B'}};

●如果是部分初始化,未被初始化的就会被默认初始化为0

代码语言:javascript
复制
int main()
{
struct student stu[3] ={{.name="zhangsan",.age=18,.sex='B'},{.name="wangwu",.age=30,.sex='B'}};
        printf("%s\n", stu[2].name);
        printf("%d\n", stu[2].age);
        printf("%c", stu[2].sex);
    return 0;
}

运行结果:

stu[3]的初始化情况:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,结构体内存对齐
    • 1,基本知识
      • 2,例子分析
      • 二,结构体数组
        • 1,什么是结构体数组
          • 2,结构体数组的初始化
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档