IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 10讲学会C语言之第九讲:结构体 -> 正文阅读

[C++知识库]10讲学会C语言之第九讲:结构体


前言

大家好,我是卷卷,本节课的主题是结构体。本节课主要有以下三个部分:结构体的定义与使用,学生成绩管理,作业。(文末附课程资源和讨论q群号)


一、结构体的定义与使用

所谓结构体,是自定义的数据类型。所以它也有一般数据类型的性质,比如定义数组,定义指针等等。在结构体中,可存放多个不同类型的数据,这是与一般数据类型的最大区别。结构体的语法如下:

struct 结构名{
	数据类型1 变量名1;
	数据类型2 变量名2;
	......;
};

注意花括号后要加分号!结构体定义变量和普通数据类型定义变量的格式差不多,假设结构名为stu,则有struct stu a;这就定义了一个名为a的,数据类型为stu的变量。a中也包含了一个stu的所有成员。一般结构体定义变量需要加struct,为使定义变得更简单,可用typedef关键字定义结构体,语法如下:

typedef struct 名称1{
	数据类型1 变量名1;
	数据类型2 变量名2;
	......;
}名称2;

这样,如果使用名称2定义变量,就无需加struct。其中typedef针对的是struct这个整体,也就是从s开始到花括号结束的部分,是typedef的对象。以上描述可简化为:typedef 结构体 结构体别名;使用结构体别名即可像普通数据类型那样定义变量。另外,名称1和名称2可以是相同的。如果使用C++语法,还可以进一步简化,语法如下:

struct 名称1{
	数据类型1 变量名1;
	数据类型2 变量名2;
	......;
};

这样就可以直接使用名称1,像普通数据类型那样定义变量了。在cpp文件中,这样定义结构体后,用不用struct效果都一样。但在c文件中,必须加上struct。C++还支持在花括号后再加一个名称来作为别名。别名定义变量时也无需加struct。访问结构体成员很简单,只需在结构体变量后面加“点”。举例如下:

#include<stdio.h>
struct student{
	int no;
	double grade;
	char name[20];
};
student stu;
int main(){
	stu.grade=80;
	return 0;
}

以上代码定义了一个叫作student的结构体,有int,double等变量。还定义了一个student类型的变量stu。由于全局变量只能在花括号内被修改,所以在主函数内访问stu的成员。如果stu是一个student类型的指针,则点号就要变成箭头,即:->。当然,既然是非空指针,肯定要指向一块空间。可以用C或C++语法动态分配一块空间,这里不再赘述。

二、学生成绩管理

例1:输入n(n<50)个学生的成绩信息,自定义函数stu_sort(),对每个学生的平均成绩排序。自定义函数stu_update(),修改学生信息。在主函数中调用这两个函数。分析:显然需要定义一个表示学生的结构体,存放课程成绩,平均分等。题目包含多个学生,所以需要定义结构体数组。因为要对数组元素操作,所以自定义函数的参数类型是结构体指针。因为只有修改功能,所以返回类型为void。函数体内,可以用指针++的方式访问结构体成员,但需要用箭头符号。也可以用方括号,需要用点号访问。排序函数内,可以选择不同的排序算法排序。注意这里的交换元素操作,也是对整个结构体变量操作。代码:

#include<stdio.h>
struct student{
	int no;//学号 
	char name[10];
	int comp,en,math;//计算机,英语,数学成绩
	double avg;//平均分 
};
void stu_sort(student* stu,int n);
void stu_update(student* stu,int n);
int find_no(student* stu,int n,int num);
void input_data(student* stu,int index);
int main(){
	int n;
	student students[50];
	printf("输入学生数:");
	scanf("%d",&n);
	printf("输入学生信息:\n");
	for(int i=0;i<n;i++){
		printf("输入第%d个学生的信息:\n",i+1);
		input_data(students,i);
		//统计平均分
		students[i].avg=(students[i].comp+
		students[i].en+students[i].math)/3.0;
	}
	printf("\n平均分排序前:\n");
	for(int i=0;i<n;i++)
		printf("%s:%.2f ",students[i].name,
		students[i].avg);
	stu_sort(students,n);
	printf("\n平均分排序后:\n");
	for(int i=0;i<n;i++)
		printf("%s:%.2f ",students[i].name,
		students[i].avg);
	printf("\n");
	stu_update(students,n);
	return 0;
}
void stu_sort(student* stu,int n){
	//选择排序 
	for(int i=0;i<n-1;i++){
		int k=i;//最小值下标 
		for(int j=k+1;j<n;j++)//往后比较 
		if(stu[j].avg<stu[k].avg)//若比k位置的元素更小 
			k=j;//更新最小下标 
		if(k!=i){
	//若最小下标有更新,则将最小元素换到一开始的位置 
			student temp=stu[k];
			stu[k]=stu[i];
			stu[i]=temp;
		}
	}
}
void input_data(student* stu,int index){
	//输入学生信息 
	printf("输入学号:");
	scanf("%d",&stu[index].no);
	printf("输入姓名:");
	scanf("%s",stu[index].name);
	printf("输入计算机成绩:");
	scanf("%d",&stu[index].comp);
	printf("输入英语成绩:");
	scanf("%d",&stu[index].en);
	printf("输入数学成绩:");
	scanf("%d",&stu[index].math);
}
int find_no(student* stu,int n,int num){
	//查找学号
	for(int i=0;i<n;i++) 
	if(stu[i].no==num)
		return i;
	return -1;
}
void stu_update(student* stu,int n){
	int num;
	printf("输入要修改的学生学号:");
	scanf("%d",&num);
	int index=find_no(stu,n,num);
	if(index==-1){
		printf("学号不存在,修改失败!\n");
		return;
	}
	printf("输入要修改的信息:\n");
	input_data(stu,index);
	//统计平均分
	stu[index].avg=(stu[index].comp+
	stu[index].en+stu[index].math)/3.0;
	printf("修改成功!\n");
}

这就是本题的全部代码了。定义结构体,我想大家应该没有什么问题。选择排序函数,如果大家之前的作业有认真做的话,选择排序应该不是问题。需要注意这里传入的是一个结构体指针,由于这里定义了一个结构体数组,所以传入的是数组名,结构体的元素用点号访问。查找学号函数,其中num是要查找的学号,如果要查找的学号和已有的相同,就返回当前下标,如果循环结束,说明学号未找到,就返回-1。修改函数,首先输入要修改的学生学号,然后再利用查找函数去查找,这里用了嵌套调用,一个函数体内调用另一个函数。这是一个比较方便的做法,这种形式能够提高编程效率,可减少很多重复的代码。如果找不到,则给出提示,然后直接返回。如果找到学号,就输入要修改的信息。这就是自定义函数的基本介绍了。主函数里也要用到输入函数input_data,所以如果一段代码用的非常频繁的话,建议把它封装成一个函数,方便调用,也能够提高编程效率。我们验证一下,为了更直观地表示运行结果,我们来进行一次调试。在调试之前,我们需要先准备好一些数据,以方便调试和运行。数据如下:

/*测试数据
3
001 张三 80 50 80
002 李四 100 80 90
003 王五 40 80 60
*/

好,现在开始调试。首先在这个地方打断点:在这里插入图片描述
然后粘贴数据,按下回车:在这里插入图片描述
这样,结构体数组就接收了全部的数据。我们来观察下,双击students,点击“添加查看”:在这里插入图片描述
左边就是结构体数组的信息了:在这里插入图片描述
可以看到,输入正常。然后我们不断点“下一步”,直到第30行,然后查看结果:在这里插入图片描述
结果显示了排序前的数据。由于已经调用了排序函数,我们可以提前在查看窗口查看排序结果:在这里插入图片描述
排序功能正常。然后我们不断点“下一步”,直到第35行,然后查看结果:在这里插入图片描述
正常输出。接下来是修改函数,为了节约时间,我们直接点下一步,修改结构体成员,然后查看变化:在这里插入图片描述
可以看到,修改功能正常。点击上方的红叉,结束调试。好了,这就是本题的讲解了,下一讲大家要做一个学生管理系统,代码量会比这个大的多,中间肯定要经过一些调试,调试就按我之前的方法操作即可。

三、作业

最后是作业,1道练习题加两道练习题,总共3道题。练习1:在这里插入图片描述
这道题很简单,找最大值和最小值的算法,我想大家之前都已经练习过,只不过这里的数据类型不是int,也不是字符串,而是结构体。练习2:在这里插入图片描述
题目只包括生日,没有直接包括年龄,所以不能定义这个属性。既然给出一个生日,它要比较大小,我想大家应该已经知道了,用string compare函数。特别注意,年龄和出生日期的大小比较是相反的,也就是出生日期越大,年龄越小,出生日期越小,年龄越大。然后还要注意一下string compare函数的比较方式,第一个和第二个比较,如果第一个小于第二个,那么就输出一个负数,如果第一个大于第二个,那么就输出一个正数。好了,这就是本讲的全部内容了,我们下讲见!
课后作业和参考答案 提取码:l2du
讨论群号:1028887052

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 18:44:48  更:2022-05-21 18:47:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:33:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码