18-结构体的简单使用——结构体的声明、定义与结构体成员的引用以及赋值

18-结构体的简单使用——结构体的声明、定义与结构体成员的引用以及赋值


结构体的概念

在实际开发中,单一的基础数据类型如 intfloatdouble 等不足以描述复杂的实体。比如描述一本书时,需要记录书名、作者、定价和版本等信息。C语言允许开发者将基础数据类型组合成一个新的数据类型,称为结构体(struct)。

一、结构体的声明

结构体的声明使用 struct 关键字,并定义结构体标签和成员。成员可以是任何基础数据类型或其他结构体。

1.1 声明语法

struct 结构体标签
{
    成员1;
    成员2;
    成员3;
    ...
};

注意:

  • struct : 关键字 , 用来告诉编译器 我要声明的东西是一个自定义的类型*(结构体)
  • 结构体标签:用来区分不同的结构体类型
  • 成员:指结构体内部由哪些基础数据类型所构成, 可以是任何的数据类型

1.2 示例

#include <stdio.h>

// 声明一个结构体类型 Book--> 不占用内存空间
struct Book
{
    char title[50];    // 书名
    char author[50];   // 作者
    float price;       // 定价
    int edition;       // 版本
};

二、结构体的定义与初始化

定义结构体变量时,可以同时进行初始化。初始化可以通过普通成员初始化和指定成员初始化两种方式。

2.1 普通成员初始化

// 定义  与 初始化   实际为结构体分配内存空间  栈
struct Book book1 = { "C Programming Language", "Brian W. Kernighan, Dennis M. Ritchie", 45.99, 2 };

2.2 指定成员初始化

struct Book book1 = {
    .title = "C Programming Language",
    .author = "Brian W. Kernighan, Dennis M. Ritchie",
    .price = 45.99,
    .edition = 2
};

注意

  • 普通成员初始化: 写起来方便一点,但是用起来麻烦一点,不利于代码的更新于迭代。
  • 指定成员初始化:写起来麻烦一点,但是用起来比较轻松, 有利于后期代码的更新迭代,不会照成成员与成员之间初始化错位的问题。

在这里插入图片描述

三、结构体成员的引用

结构体相当于一个数据集合,里面由多个不同类型的数据组合而成,每一个成员都可以通过成员引用符来单独引用,可以通过成员引用符 . 单独引用成员。对于结构体指针,使用 -> 操作符引用成员。

3.1 引用语法

结构体变量名.成员 // 普通结构体变量
结构体指针变量->成员 // 结构体指针

3.2 示例

#include <stdio.h>
#include <string.h>

struct Book
{
    char title[50];
    char author[50];
    float price;
    int edition;
};

int main()
{
    struct Book book1 = {
        .title = "C Programming Language",
        .author = "Brian W. Kernighan, Dennis M. Ritchie",
        .price = 45.99,
        .edition = 2
    };

    // 修改结构体成员的值
    book1.price = 49.99;

    // 打印结构体成员
    printf("Title: %s\n", book1.title);
    printf("Author: %s\n", book1.author);
    printf("Price: %.2f\n", book1.price);
    printf("Edition: %d\n", book1.edition);

    return 0;
}

四、对结构体的堆内存进行赋值

如果结构体成员是指针且指向堆内存,则在释放结构体内存时,需要先释放指针所指向的内存

4.1 示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Book {
    int num;
    char *title;
    float price;
    char author[32];
};

int main() {
    // 结构体变量定义与初始化--> 实际分配空间
    struct Book a = {123, "C Programming Language", 45.99, "Brian W. Kernighan"};

    // 结构体指针-->申请一个堆空间来存放结构体类型
    struct Book *p = calloc(1, sizeof(struct Book));
    if (p == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    
    // strdup函数用于分配足够的内存以保存给定字符串的副本,并返回指向该副本的指针。
    // 该函数不仅会复制字符串内容,还会在内存中为副本分配空间。
    // 这对于需要动态分配内存并进行字符串操作很有用
    p->title = strdup("C Programming Language1");
    if (p->title == NULL) {
        fprintf(stderr, "Memory allocation for title failed\n");
        free(p);
        return 1;
    }

    // 错误用法:直接赋值会导致悬空指针问题
    // p->title = tempTitle;

    // 修改结构体成员的值
    p->num = 250;

    // p->author = "李某"; 是错误的,因为 author 是数组,不能直接赋值
    // 对结构体中的数组进行重新赋值应该使用字符串拷贝
    strncpy(p->author, "李某", sizeof(p->author) - 1);
    p->author[sizeof(p->author) - 1] = '\0'; // 确保字符串以 null 结尾

    // 打印结构体成员
    printf("Num: %d\n", p->num);
    printf("Title: %s\n", p->title);
    printf("Author: %s\n", p->author);

    // 释放结构体指针所指向的内存
    free(p->title);
    free(p);

    return 0;
}

有:
在这里插入图片描述

在这里插入图片描述

总结:

- 结构体声明:使用 struct 关键字声明一个新的数据类型,可以包含多个成员。

  • 结构体定义与初始化:定义结构体变量并进行初始化,初始化可以通过普通成员初始化和指定成员初始化。
  • 结构体成员引用:通过 . 操作符引用结构体成员,通过 -> 操作符引用结构体指针的成员。
  • 堆内存处理:结构体指针的成员指向堆内存时,需在释放结构体内存前释放指针所指向的内存。
  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值