
C语言中的结构体认知升维:
(1)C语言中的基本数据类型定义的变量,比如字符变量,数组变量,数字类型的变量,布尔变量等由基本数据类型声明的变量,表达的抽象化数据比较有限,而数组只能存储同类型的数据,
其向系统申请的内存连续的区域;为表达更为复杂的数据类型,需要引入结构体类型,结构体类型是一种符合类型,它由基本的数据类型的各种语句指令组成一个完整的数据类型;
既然结构体是一种数据类型,那么久可以使用该结构体体声明变量,被声明的变量叫作结构体变量;
(2)结构体类型是一种构造类型,它由若干成员组成,其中的每一个成员可以是一个基本类型,它也可以是一个构造类型;
(3)声明结构体一般形式如下:
struct 结构体名称 {
成员1;
成员2;
成员..
成员n;
}; 末尾的分号不能省略;
(4)使用结构体作为数据类型来定义结构体变量,定义结构体变量通常有三种形式:
4.1: 先声明,在定义的方式
struct 结构体名 {
成员列表;
};
struct 结构体名称 变量名;
4.2: 声明同时定义结构体变量
struct 结构体名 {
成员列表;
}变量名列表;
4.2: 匿名结构体
struct {
成员类别;
}变量列表;
(5)结构体成员初始化通常有两种形式
5.1: 声明定义同时初始化
struct 结构体名 {
成员列表;
}变量名 = {以结构体成员顺序一致的值列表: 各成员值直接使用逗号分隔}; 注意:最后的分号不能省略;
5.2: 通过成员访问符来对结构体成员进行初始化
结构体变量名.成员名=成员值;
- #include
-
- /*
- C语言中的结构体认知升维:
- (1)C语言中的基本数据类型定义的变量,比如字符变量,数组变量,数字类型的变量,布尔变量等由基本数据类型声明的变量,表达的抽象化数据比较有限,而数组只能存储同类型的数据,
- 其向系统申请的内存连续的区域;为表达更为复杂的数据类型,需要引入结构体类型,结构体类型是一种符合类型,它由基本的数据类型的各种语句指令组成一个完整的数据类型;
- 既然结构体是一种数据类型,那么久可以使用该结构体体声明变量,被声明的变量叫作结构体变量;
- (2)结构体类型是一种构造类型,它由若干成员组成,其中的每一个成员可以是一个基本类型,它也可以是一个构造类型;
- (3)声明结构体一般形式如下:
- struct 结构体名称 {
- 成员1;
- 成员2;
- 成员..
- 成员n;
- }; 末尾的分号不能省略;
- (4)使用结构体作为数据类型来定义结构体变量,定义结构体变量通常有三种形式:
- 4.1: 先声明,在定义的方式
- struct 结构体名 {
- 成员列表;
- };
- struct 结构体名称 变量名;
- 4.2: 声明同时定义结构体变量
- struct 结构体名 {
- 成员列表;
- }变量名列表;
- 4.2: 匿名结构体
- struct {
- 成员类别;
- }变量列表;
- (5)结构体成员初始化通常有两种形式
- 5.1: 声明定义同时初始化
- struct 结构体名 {
- 成员列表;
- }变量名 = {以结构体成员顺序一致的值列表: 各成员值直接使用逗号分隔}; 注意:最后的分号不能省略;
- 5.2: 通过成员访问符来对结构体成员进行初始化
- 结构体变量名.成员名=成员值
- */
-
- // 定义结构体描述手机基本信息
- struct telephone { // 声明手机信息的结构体
- const char *brandName=""; // 品牌名称
- int price; // 报价
- const char *screen=""; // 主屏幕尺寸
- const char *processor=""; // 处理器
- int battery; // 电池容量
- }telephoneEntity01 = {"华为",99999,"曲面折叠屏","854-麒麟-10001A",10000};
-
- // 定义结构体变量
- struct telephone telephoneEntity; // 定义了数据类型为telephone结构体类型的变量telephoneEntity
- struct telephone* telephonePtr = &telephoneEntity; // 定义结构体类型的指针变量,并赋值telephoneEntity01变量的地址
-
- int main() {
- printf("========================结构体为显示初始化时,系统会默认给成员赋对应数据类型的初始化值====================\n");
- printf("手机名称: %s \n", telephoneEntity.brandName);
- printf("手机的报价: %d\n", telephoneEntity.price);
- printf("手机的电池容量: %d\n", telephoneEntity.battery);
- printf("手机主屏: %s \n", telephoneEntity.screen);
- printf("手机的处理器: %s\n", telephoneEntity.processor);
- printf("========================给结构体赋初始化值===========================");
-
- printf("========================赋值后显示的结构体成员值====================\n");
- printf("手机名称: %s \n", telephoneEntity01.brandName);
- printf("手机的报价: %d\n", telephoneEntity01.price);
- printf("手机主屏: %s \n", telephoneEntity01.screen);
- printf("手机的处理器: %s\n", telephoneEntity01.processor);
- printf("手机的电池容量: %d\n", telephoneEntity01.battery);
- printf("========================通过指针访问符访问成员并给成员赋值====================\n");
- telephonePtr->price = 2500;
- telephonePtr->brandName = "华为旗舰版Plus";
- telephonePtr->screen = "折叠屏";
- telephonePtr->processor = "高通 晓龙587";
- printf("手机名称: %s \n", telephonePtr->brandName);
- printf("手机的报价: %d\n", telephonePtr->price);
- printf("手机主屏: %s \n", telephonePtr->screen);
- printf("手机的处理器: %s\n", telephonePtr->processor);
- printf("手机的电池容量: %d\n", telephonePtr->battery);
-
- printf("C语言使用结构体定义字符串成员时,尽量使用字符串指针定义成员,避免使用字符数组定义字符串成员,否则赋值时容易参数错误;");
- printf("\n");
- return 0;
- }
运行效果:
========================结构体为显示初始化时,系统会默认给成员赋对应数据类型的初始化值====================
手机名称:
手机的报价: 0
手机的电池容量: 0
手机主屏:
手机的处理器:
========================给结构体赋初始化值===================================================赋值后显示的结构体成员值====================
手机名称: 华为
手机的报价: 99999
手机主屏: 曲面折叠屏
手机的处理器: 854-麒麟-10001A
手机的电池容量: 10000
========================通过指针访问符访问成员并给成员赋值====================
手机名称: 华为旗舰版Plus
手机的报价: 2500
手机主屏: 折叠屏
手机的处理器: 高通 晓龙587
手机的电池容量: 0
C语言使用结构体定义字符串成员时,尽量使用字符串指针定义成员,避免使用字符数组定义字符串成员,否则赋值时容易参数错误;D:\program_file\C++_workspace\ProjectCodeToStruct\x64\Debug\ProjectCodeToStruct.exe (进程 2008)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .![]()
结构体数组认知升维:
(1)使用结构体定义数组,即数组中的元素为结构体类型的元素,这样的数组叫作结构体数组;
结构体数组与基本的数组不一样的地方是,结构体数组中的元素是根据要求定义的结构体类型,而不是基本的数据类型;
(2)结构体数组定义有三种方式:
2.1: 先定义结构体类型,在定义结构体数组
struct 结构体名{
成员列表;
}; // 注意默认的分号不能漏掉
// 定义结构体类型的数组
struct 结构体名 数组名[数组长度]; // 定义结构体数组
2.2: 定义结构体类型的同时定义结构体数组
struct 结构体名 {
成员列表;
}数组名[数组长度];
2.3: 匿名结构体数组,也就是不给出结构体类型名;
struct {
成员列表;
}数组名[数组长度];
- #include
- #include
-
- /*
- * 结构体数组认知升维:
- (1)使用结构体定义数组,即数组中的元素为结构体类型的元素,这样的数组叫作结构体数组;
- 结构体数组与基本的数组不一样的地方是,结构体数组中的元素是根据要求定义的结构体类型,而不是基本的数据类型;
- (2)结构体数组定义有三种方式:
- 2.1: 先定义结构体类型,在定义结构体数组
- struct 结构体名{
- 成员列表;
- }; // 注意默认的分号不能漏掉
- // 定义结构体类型的数组
- struct 结构体名 数组名[数组长度]; // 定义结构体数组
- 2.2: 定义结构体类型的同时定义结构体数组
- struct 结构体名 {
- 成员列表;
- }数组名[数组长度];
- 2.3: 匿名结构体数组,也就是不给出结构体类型名;
- struct {
- 成员列表;
- }数组名[数组长度];
- */
- // 定义学生信息结构体,并初始化
- struct StudentStruct {
- int studentId; // id
- char name[20]; // 姓名
- int sex; // 性别: 0-男,1-女;
- char address[100]; // 居住地址
- char college[20]; // 毕业学校
- }students[3] = {
- {200010,"小米",0,"北京市海淀区中关村软件园创新中心","北京大学"},
- {200011,"小明",0,"北京市海淀区中关村软件园创新中心","清华大学"},
- {200012,"小王",0,"北京市海淀区中关村软件园创新中心","中央财经大学"}
- }; // 定义了三个元素的数组students;元素的类型为结构体
-
- // 定义教师信息结构体
- struct TeacherStruct {
- int teacherId; //id
- const char* teacherName="";// 教师名称,默认初始值为空串
- int teacherSex; // 性别: 0-男,1-女;
- const char* teacherAddress; // 居住地
- const char *teacherClass; // 教学班级
- };
-
- // 定义结构体数组,并初始化
- struct TeacherStruct teacherArray[2] = {
- {10010,"张老师",0,"北京市海淀区马连洼街道20院10020路!","初一三班"},
- {10011,"杨老师",0,"北京市朝阳区马连洼街道20院10020路!","初三二班"}
- };
-
- // 定义
- int main() {
-
- for (int i = 0; i < 3; i++) {
- printf("学生ID: %d \n", students[i].studentId);
- printf("学生姓名: %s \n", students[i].name);
- printf("学生性别: %d \n", students[i].sex);
- printf("学生居住地址: %s \n", students[i].address);
- printf("学生毕业学校: %s \n", students[i].college);
- printf("\n");
- }
-
- return 0;
- }
运行效果:
学生ID: 200010
学生姓名: 小米
学生性别: 0
学生居住地址: 北京市海淀区中关村软件园创新中心
学生毕业学校: 北京大学学生ID: 200011
学生姓名: 小明
学生性别: 0
学生居住地址: 北京市海淀区中关村软件园创新中心
学生毕业学校: 清华大学学生ID: 200012
学生姓名: 小王
学生性别: 0
学生居住地址: 北京市海淀区中关村软件园创新中心
学生毕业学校: 中央财经大学
D:\program_file\C++_workspace\ProjectToStructArray\x64\Debug\ProjectToStructArray.exe (进程 6656)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
C语言结构体指针认知升维:
(1)一个指向变量的指针表示的是变量所占用内存中的起始地址,如果一个指针指向结构体变量;
那么该指针指向的是结构体变量的起始地址,同样指针变量也可以执行结构体数组中的元素;
(2)指向结构体的指针,由于指针指向结构体变量的地址,因此可以使用指针类访问结构体变量中的成员,定义结构体指针一般形式如下:
struct 结构体类型名 *指针名 ; // 例如: struct telephone *pStruct; ,telephone为预先定义的结构体
(3)使用指向结构体的指针变量访问结构体成员有两种方式
3.1 使用点运算符(或者称为成员访问符)引用成员
(*pStruct).成员; // 结构体变量可以使用点运算符对其中的成员进行引用。*pStruct 整体表示指向结构体变量,
// 因此可以使用点运算符可以应用结构体变量中的成员
注意: *pStruct 一定要使用括号,因此点运算符的优先级是最高的,如果不使用括号,就会先执行点运算符然后从才执行
"*"运算; 如: (*Pstruct).price = 3099;
3.2 使用指针专用的成员访问符"->"
pStruct ->成员名; // pStruct->price = 3299;
3.3 三种等效的结构体成员访问效果等价
假如telephone1为结构体变量,pStruct为执行结构体变量的指针,则下面3种形式等价
telephone1.成员名;
(*pStruct).成员名;
pStruct ->成员名;
3.4 使用指针专用成员访问符"->"引用成员时,要注意分析以下情况;
3.4.1 pStruct->price表示指向的结构体变量中成员price的值;
3.4.2 pStruct->price++ 表示指向的结构体变量中成员price的值,使用后该值加1;
3.4.3 ++pStruct->price 表示指向的结构体变量中成员price的值加1,计算后再进行使用;
(4)结构体数组的指针
当指针变量指向结构体数组时,该变量称为指向结构体数组的指针;此时该指针变量的值为结构体数组首元素的地址;
(5)结构体变量,结构体体指针,结构体变量的成员都可以作为函数的参数,结构体变量与结构体成员作函数参数传递时,都是值
传递,此时的形参都是同类型的结构体或结构体成员,此时是指传递;而指针作实参传递时,由于指针表示的是某类变量的地址,
故其相对于值传递,占用内存少时间短,故执行效率高且快;
提示:传值时,实参与形参的类型要保持一致;
(6)C语言中没有类的概念,但可用把结构体这种类型类别于Java,Python,C++,Scala中类作关联类比区分;
而面向对象编程中三大特性: 封装,继承,多态
C语言中的结构体可类比于其他高级语言中的类
C语言中的结构体嵌套可类比于其他高级语言中的继承
- #include
-
- /*
- C语言结构体指针认知升维:
- (1)一个指向变量的指针表示的是变量所占用内存中的起始地址,如果一个指针指向结构体变量;
- 那么该指针指向的是结构体变量的起始地址,同样指针变量也可以执行结构体数组中的元素;
- (2)指向结构体的指针,由于指针指向结构体变量的地址,因此可以使用指针类访问结构体变量中的成员,定义结构体指针一般形式如下:
- struct 结构体类型名 *指针名 ; // 例如: struct telephone *pStruct; ,telephone为预先定义的结构体
- (3)使用指向结构体的指针变量访问结构体成员有两种方式
- 3.1 使用点运算符(或者称为成员访问符)引用成员
- (*pStruct).成员; // 结构体变量可以使用点运算符对其中的成员进行引用。*pStruct 整体表示指向结构体变量,
- // 因此可以使用点运算符可以应用结构体变量中的成员
- 注意: *pStruct 一定要使用括号,因此点运算符的优先级是最高的,如果不使用括号,就会先执行点运算符然后从才执行
- "*"运算; 如: (*Pstruct).price = 3099;
- 3.2 使用指针专用的成员访问符"->"
- pStruct ->成员名; // pStruct->price = 3299;
- 3.3 三种等效的结构体成员访问效果等价
- 假如telephone1为结构体变量,pStruct为执行结构体变量的指针,则下面3种形式等价
- telephone1.成员名;
- (*pStruct).成员名;
- pStruct ->成员名;
- 3.4 使用指针专用成员访问符"->"引用成员时,要注意分析以下情况;
- 3.4.1 pStruct->price表示指向的结构体变量中成员price的值;
- 3.4.2 pStruct->price++ 表示指向的结构体变量中成员price的值,使用后该值加1;
- 3.4.3 ++pStruct->price 表示指向的结构体变量中成员price的值加1,计算后再进行使用;
- (4)结构体数组的指针
- 当指针变量指向结构体数组时,该变量称为指向结构体数组的指针;此时该指针变量的值为结构体数组首元素的地址;
- (5)结构体变量,结构体体指针,结构体变量的成员都可以作为函数的参数,结构体变量与结构体成员作函数参数传递时,都是值
- 传递,此时的形参都是同类型的结构体或结构体成员,此时是指传递;而指针作实参传递时,由于指针表示的是某类变量的地址,
- 故其相对于值传递,占用内存少时间短,故执行效率高且快;
- 提示:传值时,实参与形参的类型要保持一致;
- (6)C语言中没有类的概念,但可用把结构体这种类型类别于Java,Python,C++,Scala中类作关联类比区分;
- 而面向对象编程中三大特性: 封装,继承,多态
- C语言中的结构体可类比于其他高级语言中的类
- C语言中的结构体嵌套可类比于其他高级语言中的继承
- */
- // 生日信息结构体
- struct Birthday {
- int year; // 年
- int month; // 月
- int day; // 日
- };
- // 表示学生信息的结构体
- struct Student {
- char name[30]; // 姓名
- int num; // 学号
- char sex; // 性别:
- struct Birthday birthday; // 出生日期
- }student = { "老高",200000200,'M',{1990,2,30} };
-
- int main() {
- printf("------------------学生入学信息---------------------\n");
- printf("Name: %s\n", student.name);
- printf("Number: %d\n", student.num);
- printf("Sex: %c\n", student.sex);
- printf("Birthday: %d,%d,%d\n", student.birthday.year, student.birthday.month, student.birthday.day);
- return 0;
- }
运行效果:
------------------学生入学信息---------------------
Name: 老高
Number: 200000200
Sex: M
Birthday: 1990,2,30D:\program_file\C++_workspace\ProjectToStructPoint\x64\Debug\ProjectToStructPoint.exe (进程 18820)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
链表的认知升维:
(1)数据是信息的载体,是描述客观事物属性的数,字符已经所有能输入到计算机中并被计算机程序识别和处理的集合。
数据结构是指数据对象以及其中的相互关系和构造方法。在数据结构中有一个线性存储结构称为"线性表"。我们知道数组是存放同类
数据的容器,在使用数组时,需要指定数组的长度,即数组能容纳元素个数是确定的,如果往数组中添加元素超过数组的长度,便不能将内容全部保存;
如我们定义一个数值来容纳学生信息,小班有30个同学,大班有50个同学,那么在定义数组时,我们只能定义该数组的长度为50,而不是30,因为定义30个长度的数组,
便不能容纳50个同学,如果用这数组去装30个同学信息,那么白白浪费了20个元素容量,有没有一种容量不固定,容量会随着元素的增加而增长的容器呢,答案是有,这种
数据结构就叫作"链表";
(2)"链表"是一种数据结构体,其存储的元素个数是不受限制的,当添加元素时存储的个数就会随之改变;
(3)在链表的数据结构中,必须利用指针才能实现,因此链表中的节点应该包含一个指针变量来保存下一个节点的地址;
4.2 链表的节点视图
- #define _CRT_SECURE_NO_WARNINGS
- #include
-
- /*
- * 链表的认知升维:
- (1)数据是信息的载体,是描述客观事物属性的数,字符已经所有能输入到计算机中并被计算机程序识别和处理的集合。
- 数据结构是指数据对象以及其中的相互关系和构造方法。在数据结构中有一个线性存储结构称为"线性表"。我们知道数组是存放同类
- 数据的容器,在使用数组时,需要指定数组的长度,即数组能容纳元素个数是确定的,如果往数组中添加元素超过数组的长度,便不能将内容全部保存;
- 如我们定义一个数值来容纳学生信息,小班有30个同学,大班有50个同学,那么在定义数组时,我们只能定义该数组的长度为50,而不是30,因为定义30个长度的数组,
- 便不能容纳50个同学,如果用这数组去装30个同学信息,那么白白浪费了20个元素容量,有没有一种容量不固定,容量会随着元素的增加而增长的容器呢,答案是有,这种
- 数据结构就叫作"链表";
- (2)"链表"是一种数据结构体,其存储的元素个数是不受限制的,当添加元素时存储的个数就会随之改变;
- (3)在链表的数据结构中,必须利用指针才能实现,因此链表中的节点应该包含一个指针变量来保存下一个节点的地址;
-
- */
-
- // 定义一个链表来表示班级,其中的链表的节点表示学生;
-
- struct Student {
- char cName[20]; // 姓名;
- int iNumberNo; // 学号;
- struct Student* pNext; // 指向下一个节点的指针;
- }; // 末位的分号不能少;
- int iCount; // 全局表示链表节点数的变量;
- // 定义一个创建链表的函数,放函数将会返回链表的头指针
- struct Student* createLinkTable() {
- struct Student* pHead = NULL; // 初始化链表头指针为空;
- struct Student* pEnd, *pNew; //
- // 初始化链表的长度
- iCount = 0;
- // 给指针变量pEnd与pNew分配内存空间,
- pEnd = pNew = (struct Student*)malloc(sizeof(struct Student)); // 给结构体Student分配内存空,并把指针pEnd与pNew指向这内存块;
- printf("please first Name,then Number\n");
- scanf("%s", &pNew->cName);// 把输入的值赋值给cName
- scanf("%d", &pNew->iNumberNo); // 把输入的学号赋值被iNumberNo变量成员
- while (pNew->iNumberNo != 0) { // 学号不等于零作为循环终止条件
- iCount++;
- if (iCount == 1) {
- pNew->pNext = pHead; // 将头指针赋值给新时节点的指针成员 头节点的指针成员为空;
- pEnd = pNew; // 把新时节点赋值个pEnd节点
- pHead = pNew; // 把新时节点赋值给头节点,把头节点指向新节点
- }else { // 最后一个节点的指针成员一定为空
- pNew->pNext = NULL; // 新节点的指针为空
- // 原链表的尾节点的指针指向该新节点
- pEnd->pNext = pNew;
- pEnd=pNew; // 再把原未节点指向新节点;
- }
- // 没循环一次需分配一次内存
- pNew = (struct Student*)malloc(sizeof(struct Student));// 每次循环都分配节点的内存空间
- scanf("%s", &pNew->cName);// 把输入的值赋值给cName
- scanf("%d", &pNew->iNumberNo); // 把输入的学号赋值被iNumberNo变量成员
- }
- free(pNew);// 释放没有用到的内存空间
- return pHead;
- }
-
- // 输出链表节点数据
- void print(struct Student* pHead) {
- struct Student* pTemp; // 循环所用的临时指针
- int iIndex = 1;// 表示链表中节点的序号
- printf("------------------the List has %d members:-----------\n", iCount);
- printf("\n");
- // 临时指针指向首节点
- pTemp = pHead;
- while (pTemp != NULL) {
- printf("序号: %d \n", iIndex);
- printf("名称: %s\n", pTemp->cName);
- printf("学号: %d\n", pTemp->iNumberNo);
- printf("\n");
- // 取出数据成员后,在把临时指针指向下一个节点
- pTemp = pTemp->pNext;
- iIndex++;
- }
- }
- int main() {
- struct Student* pStudent;
- pStudent= createLinkTable();
- print(pStudent);
- return 0;
- }
运行效果:
please first Name,then Number
老杨 1
老李 2
老高 3
老表 4
老板 5
exit 0
------------------the List has 5 members:-----------序号: 1
名称: 老杨
学号: 1序号: 2
名称: 老李
学号: 2序号: 3
名称: 老高
学号: 3序号: 4
名称: 老表
学号: 4序号: 5
名称: 老板
学号: 5
D:\program_file\C++_workspace\ProjectCToClassLinkTable\x64\Debug\ProjectCToClassLinkTable.exe (进程 14816)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
忙着去耍帅,后期补充完整...........