18-结构体的简单使用------结构体的声明、定义与结构体成员的引用以及赋值
文章目录
- 18-结构体的简单使用------结构体的声明、定义与结构体成员的引用以及赋值
-
- 一、结构体的声明
-
- [1.1 声明语法](#1.1 声明语法)
- [1.2 示例](#1.2 示例)
- 二、结构体的定义与初始化
-
- [2.1 普通成员初始化](#2.1 普通成员初始化)
- [2.2 指定成员初始化](#2.2 指定成员初始化)
- 三、结构体成员的引用
-
- [3.1 引用语法](#3.1 引用语法)
- [3.2 示例](#3.2 示例)
- 四、对结构体的堆内存进行赋值
-
- [4.1 示例](#4.1 示例)
结构体的概念 :
在实际开发中,单一的基础数据类型如 int
、float
、double
等不足以描述复杂的实体。比如描述一本书时,需要记录书名、作者、定价和版本等信息。C语言允许开发者将基础数据类型组合成一个新的数据类型,称为结构体(struct
)。
一、结构体的声明
结构体的声明使用 struct
关键字,并定义结构体标签和成员。成员可以是任何基础数据类型或其他结构体。
1.1 声明语法
c
struct 结构体标签
{
成员1;
成员2;
成员3;
...
};
注意:
struct
: 关键字 , 用来告诉编译器 我要声明的东西是一个自定义的类型*(结构体)结构体标签
:用来区分不同的结构体类型成员
:指结构体内部由哪些基础数据类型所构成, 可以是任何的数据类型
1.2 示例
c
#include <stdio.h>
// 声明一个结构体类型 Book--> 不占用内存空间
struct Book
{
char title[50]; // 书名
char author[50]; // 作者
float price; // 定价
int edition; // 版本
};
二、结构体的定义与初始化
定义结构体变量时,可以同时进行初始化。初始化可以通过普通成员初始化和指定成员初始化两种方式。
2.1 普通成员初始化
c
// 定义 与 初始化 实际为结构体分配内存空间 栈
struct Book book1 = { "C Programming Language", "Brian W. Kernighan, Dennis M. Ritchie", 45.99, 2 };
2.2 指定成员初始化
c
struct Book book1 = {
.title = "C Programming Language",
.author = "Brian W. Kernighan, Dennis M. Ritchie",
.price = 45.99,
.edition = 2
};
注意:
普通成员初始化
: 写起来方便一点,但是用起来麻烦一点,不利于代码的更新于迭代。指定成员初始化
:写起来麻烦一点,但是用起来比较轻松, 有利于后期代码的更新迭代,不会照成成员与成员之间初始化错位的问题。
三、结构体成员的引用
结构体相当于一个数据集合
,里面由多个不同类型的数据组合而成,每一个成员都可以通过成员引用符来单独引用,可以通过成员引用符 .
单独引用成员。对于结构体指针,使用 ->
操作符引用成员。
3.1 引用语法
c
结构体变量名.成员 // 普通结构体变量
结构体指针变量->成员 // 结构体指针
3.2 示例
c
#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 示例
c
#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
关键字声明一个新的数据类型,可以包含多个成员。
- 结构体定义与初始化:定义结构体变量并进行初始化,初始化可以通过普通成员初始化和指定成员初始化。
- 结构体成员引用 :通过
.
操作符引用结构体成员,通过->
操作符引用结构体指针的成员。- 堆内存处理:结构体指针的成员指向堆内存时,需在释放结构体内存前释放指针所指向的内存。