目录
《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介
1、结构体概念引入
C 语⾔已经提供了内置类型,如:char、short、int、long、float、double 等,但是只有这些内置类型还是不够的。
假设我想描述⼀个学生的信息,需要名字、年龄、学号、成绩、身高等,这时单⼀的内置类型是不⾏的。
为了解决这个问题,增加了结构体这种⾃定义的数据类型,让程序员可以自己创造适合的类型。
前面的教程中我们讲解了数组
[(2.24)数组入门 – 保证入门],它是一组具有相同类型的数据的集合
。
- 比如可以
描述一个班级里的所有学生姓名
。
但在实际的编程过程中,我们往往还需要一组类型不同的数据
。
- 比如描述⼀个学生的信息,姓名为字符串,年龄为整数,学号为整数,成绩为小数等,因为数据类型不同,
显然不能用一个数组来存放
。
总而言之:
数组:可存储相同类型数据
;
结构体:可存储不同类型数据
。
2、结构体声明
在 C 语言中,可以使用结构体来存放一组不同类型的数据。
结构体的定义形式为:
struct 结构体名 {
member1;
member2;
...
不同成员变量集合
} 结构体变量集合(可省略);
(1)第一行由关键字 struct 和结构体名组成。
(2)结构体内容是⼀些值的集合
,它们的类型可以相同,也可以不同,这些值称为成员变量。
(3)结构体中的成员变量可以是基本数据类型
(如 int、float、char 等),也可以是其他结构体类型,如:数组、指针
,甚⾄是其他结构体
。
如下举例:
结构体用于描述⼀个学生信息 Student 结构
的方式:
struct Student
{
char name[20]; //姓名
int age; //年龄
char id[20]; //学号
float score; //性别
}; //注意分号不能丢
结构体包含了 4 个成员,分别是 name、age、id、score。
注意大括号后面的分号
;
不能少,这是一条完整的语句。
结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。
3、结构体变量
既然结构体是一种数据类型,那么就可以用它来定义变量。例如:
struct Student stu1, stu2;
定义了两个变量 stu1 和 stu2
,它们都是 stu 类型,都由 4 个成员组成。注意关键字 struct
不能少。
Student 就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。
也可以在定义结构体的同时定义结构体变量:
struct Student
{
char name[20]; //姓名
int age; //年龄
char id[20]; //学号
float score; //性别
} stu1, stu2;
将变量放在结构体定义的最后即可。
如果只需要 stu1、stu2 两个变量,后面的代码不需要再使用结构体名定义其他变量
,那么在定义时也可以不给出结构体名
【不建议这么做】,如下所示:
struct
{
char name[20]; //姓名
int age; //年龄
char id[20]; //学号
float score; //性别
} stu1, stu2;
这样做书写简单,但是因为没有结构体名,后面就没法用该结构体定义新的变量
。
需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。
4、成员访问运算符(.)
为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。
结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。
- 数组使用下标
[ ]
获取单个元素
,结构体使用点号.
获取单个成员
。
使用方式:
结构体变量名.成员名;
通过这种方式可以获取成员的值,也可以给成员赋值!
5、结构体变量的初始化
和其它类型变量一样,对结构体变量可以在定义时指定初始值。
5.1、在定义时整体初始化
#include <stdio.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book = {"C 语言", "BoBo", "编程语言", 123456};
int main()
{
printf("title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book.title, book.author, book.subject, book.book_id);
}
不过整体赋值仅限于定义结构体变量的时候,在使用过程中只能对成员逐一赋值,这和数组的赋值非常类似。
5.2、使用时初始化
#include <stdio.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main()
{
struct Books book = {"C 语言", "BoBo", "编程语言", 123456};
printf("title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book.title, book.author, book.subject, book.book_id);
}
5.3、指定顺序初始化
#include <stdio.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main()
{
struct Books book = {.title="C 语言", .author="BoBo", .subject="编程语言", .book_id=123456};
printf("title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book.title, book.author, book.subject, book.book_id);
}
5.4、对成员逐一初始化
#include <stdio.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main()
{
book.title = "C 语言";
book.author = "BoBo";
book.subject = "编程语言";
book.book_id = 123456;
printf("title: %s\nauthor: %s\nsubject: %s\nid: %d\n", book.title, book.author, book.subject, book.book_id);
}
讲几种方法说明一个字:全!
6、成员访问运算符(->)
有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。为了访问指针成员
,我们使用成员访问运算符(->)。
使用方式:
结构体指针->成员名
如下所示:
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main()
{
struct Point p = {3, 4};
struct Point *ptr = &p;
ptr->x = 10;
ptr->y = 20;
printf("x = %d y = %d\n", ptr->x, ptr->y);
return 0;
}
7、综合举例
#include <stdio.h>
#include <string.h>
struct Stu
{
char name[15]; //名字
int age; //年龄
};
void print_stu(struct Stu s)
{
printf("%s %d\n", s.name, s.age);
}
void set_stu(struct Stu* ps)
{
strcpy(ps->name, "李四");
ps->age = 28;
}
int main()
{
struct Stu s = { "张三", 20 };
print_stu(s);
set_stu(&s);
print_stu(s);
return 0;
}
《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介
每日一更!
公众号、优快云等博客:小菜狗编程笔记
谢谢点赞关注哈!目前在飞书持续优化更新~
日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!