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

📝前言:
上一讲结构体类型(一)中,我们讲述了有关结构体定义,创建,初始化和引用的内容,这一讲,我们进一步学习结构体的相关知识:
1,结构体内存对齐
2,结构体数组

🎬个人简介:努力学习ing
📋个人专栏:C语言入门基础
🎀CSDN主页 愚润求学
🌄每日鸡汤:山高路远,看世界,也找自己!

文章目录

  • 一,结构体内存对齐
    • 1,基本知识
    • 2,例子分析
  • 二,结构体数组
    • 1,什么是结构体数组
    • 2,结构体数组的初始化

一,结构体内存对齐

1,基本知识

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

#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?)

struct stu1
{
    char a;
    int b;
    char c;
};
struct stu2
{
    int b;
    char c;
    char a;
};

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

具体分配(stu1):

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

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

#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个学生信息的结构体数组)👇🏻

struct student
{
    char name[10];
    int age;
    char sex;
};
struct student stu[3];

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

stu[0].name[i], stu[0].age, stu[0].sex //引用第一个
stu[1].name[i], stu[1].age, stu[1].sex //引用第二个

2,结构体数组的初始化

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

    struct student stu[3] ={{"zhangsan",18,'B'},{"lisi",20,'G'},{"wangwu",30,'B'}};

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

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

struct student stu[3] ={{.name="zhangsan",.age=18,.sex='B'},{.name="lisi",.age=20, .sex='G'},{.name="wangwu",.age=30,.sex='B'}};

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

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]的初始化情况:

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

版权声明:本文为博主作者:愚润求学原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/tan_run/article/details/135506419

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2024年1月16日
下一篇 2024年1月16日

相关推荐