一:C语言结构体认知
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 <stdio.h>
/*
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。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
二:C语言结构体数组认知升维
结构体数组认知升维:
(1)使用结构体定义数组,即数组中的元素为结构体类型的元素,这样的数组叫作结构体数组;
结构体数组与基本的数组不一样的地方是,结构体数组中的元素是根据要求定义的结构体类型,而不是基本的数据类型;
(2)结构体数组定义有三种方式:
2.1: 先定义结构体类型,在定义结构体数组
struct 结构体名{
成员列表;
}; // 注意默认的分号不能漏掉
// 定义结构体类型的数组
struct 结构体名 数组名[数组长度]; // 定义结构体数组
2.2: 定义结构体类型的同时定义结构体数组
struct 结构体名 {
成员列表;
}数组名[数组长度];
2.3: 匿名结构体数组,也就是不给出结构体类型名;
struct {
成员列表;
}数组名[数组长度];
#include <stdio.h>
#include <string>
/*
* 结构体数组认知升维:
(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语言结构体指针
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 <stdio.h>
/*
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。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
四:C语言中链表动态创建方法论
链表的认知升维:
(1)数据是信息的载体,是描述客观事物属性的数,字符已经所有能输入到计算机中并被计算机程序识别和处理的集合。
数据结构是指数据对象以及其中的相互关系和构造方法。在数据结构中有一个线性存储结构称为"线性表"。我们知道数组是存放同类
数据的容器,在使用数组时,需要指定数组的长度,即数组能容纳元素个数是确定的,如果往数组中添加元素超过数组的长度,便不能将内容全部保存;
如我们定义一个数值来容纳学生信息,小班有30个同学,大班有50个同学,那么在定义数组时,我们只能定义该数组的长度为50,而不是30,因为定义30个长度的数组,
便不能容纳50个同学,如果用这数组去装30个同学信息,那么白白浪费了20个元素容量,有没有一种容量不固定,容量会随着元素的增加而增长的容器呢,答案是有,这种
数据结构就叫作"链表";
(2)"链表"是一种数据结构体,其存储的元素个数是不受限制的,当添加元素时存储的个数就会随之改变;
(3)在链表的数据结构中,必须利用指针才能实现,因此链表中的节点应该包含一个指针变量来保存下一个节点的地址;
4.1 链表是概念
首先我们来了解一下线性存储结构。线性存储结构是一种最常见的存储结构。其特点是数据元素之间存在一一对应的关系。线性存储结构又分为两种,即顺序存储结构和链式存储结构。
1.首先,我们来了解一下顺序存储结构。顺序存储的线性表称为顺序表(数组)。其原理是逻辑上相邻的元素在物理位置上也相邻。
我们可以理解为一堆按照一定顺序摆放的书。我们在知道它的排列规律之后就可以通过它的排列规律来找到我们想找到的那本书。我们也可以通过一本一本的去找,来找到我们想要找到的那本书。
我们可以很方便的理解,要在这一堆有顺序的书中放进去一本或者拿出来一本,我们必然要先找到要它的位置在进行操作,而且我们需要一个连续的地方来放这一堆书。
2.其次,我们来了解一下链式存储结构(链表)。它的特点是逻辑上不相邻的两个元素在物理位置上也相邻。我们可以理解为有一本书,这本书在你打开它之后会看到它本身的内容,也会得到第二本书所在的地址。你可以通过这个地址来寻找第二本书。
不难理解,如果我们要在这组书中加入一本书,只需要在某一本书后边加上这本书所在的地址,在在这本书后边加上原本那本书后边的地址即可。而且我们并不需要一块很大的连续的空间来存放这堆书。
链表是一种类似于数组又不同于数组的一种线性表。
4.2 链表的节点视图
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
/*
* 链表的认知升维:
(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。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
忙着去耍帅,后期补充完整...........