自定义类型——结构体(如何计算结构体内存)

结构体类型

特点与定义

1,结构体(Structures)是 C 语言中一种用户自定义的数据类型,它可以包含不同类型的数据成员,这些成员可以按照用户的需求进行组织。结构体允许将多个不同类型的变量组合在一起,形成一个新的数据类型,从而更方便地描述和操作复杂的数据。

  • 下面是结构体的一些重要特点和用法:

2,结构体类型的关键字是 struct + 类型名

定义结构体

struct Person {
    char name[50];
    int age;
    float height;
};

上面的代码定义了一个名为 Person 的结构体,其中包含了三个成员:name、age 和 height,分别表示姓名、年龄和身高。

结构体变量的声明

struct Person person1;

这行代码声明了一个名为 person1 的 Person 类型的结构体变量。

访问结构体成员

strcpy(person1.name, "Alice");
person1.age = 25;
person1.height = 160.5;

可以使用 . 操作符来访问结构体变量的成员,对成员进行赋值或者取值操作。

结构体指针可以用 -> 来访问结构体中变量

struct preson* p1;
int a = p1->age;

结构体作为参数传递
结构体可以作为参数传递给函数,也可以作为函数的返回值。

结构体嵌套
结构体中可以包含其他结构体,从而实现更复杂的数据组织。

结构体变量创建和初始化

结构体变量的创建

1,在定义结构体时创建结构体变量。

struct Person {
    char name[50];
    int age;
}preson1,person2;
// preson1,person2为结构体变量

2,在函数内部直接创建。

struct Person {
    char name[50];
    int age;
};

int main()
{
	struct Person p;
}

结构体变量的初始化

  1. 声明结构体并初始化
struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person person1 = {"Alice", 25};
}

上面的代码中,首先定义了一个名为 Person 的结构体,然后在 main 函数中声明并初始化了一个 person1 结构体变量,指定了初始值。

  1. 逐个成员初始化
struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person person1;
    strcpy(person1.name, "Bob");
    person1.age = 30;
}

这种方式是逐个对结构体的成员进行赋值初始化。

  1. 使用结构体初始化器
struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person person1 = {.name = "Cathy", .age = 35};
}

使用结构体初始化器 {} 可以按照成员的顺序或者指定成员名称来初始化结构体变量。

  1. 动态分配内存并初始化
struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person *person1 = (struct Person *)malloc(sizeof(struct Person));
    if (person1 != NULL) {
        strcpy(person1->name, "David");
        person1->age = 40;
    }
}

这里通过动态分配内存来创建结构体变量,并可以在之后对其成员进行初始化。

结构体中的内存对齐

前提介绍

1,结构体中的内存并不是直接相加计算的,而是要遵循结构体内存对齐的规则。

比如:

struct MyStruct
{
    char c;
    int a;
    char v;
};

其sizeof求的大小为
(并不是简单的6)
在这里插入图片描述

结构体内存对齐规则

  • 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处

  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。
    -VS 中默认的值为 8
    -Linux中gcc没有默认对齐数,对齐数就是成员自身的大小

  • 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。

  • 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。

在这里插入图片描述

举例解释

1,例如这个结构体。

2, vs中的默认最大对齐数为8,下面为注释解释。

struct MyStruct
{
    char c;  // 第一个直接从0地址开始放 ,占了0地址位
    int a;   
    /* 4(a的大小) 8(默认对齐数) 更小的为4,对齐数为4,
    起始地址大小应该为4的倍数,1,2,3都不行,
    从4开始,占4,5,6,7四个位置。*/
    char v;
    /* 1 8 比较1更小,则内存从1的倍数放,8可以,直接放*/

	//总内存大小应该为三个变量中最大对齐数的整数倍,
	//现在的内存大小为8+1为9,则补充到12
};

画图解释:

在这里插入图片描述

结构体嵌套结构体

1, 不妨先自己试试s2的大小为多少。

struct MyStruct
{
    char c;
    int a;
    char v;
};


struct s2
{
    char c;
    struct MyStruct s;   
    //s中最大对齐数为4,比8小,
    //所以取4为它的对齐数
    int x;
};

结果
在这里插入图片描述

画图解释

在这里插入图片描述

总结

想要实验更多的可以自行探索。觉得有帮助就点个赞呗!画图还挺麻烦的来着~

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值