熟练掌握数组的定义、元素的访问、排序等重要知识点。
熟练使用数组编程解决实际应用问题。
1、定义一个数组a,用以存放学生的成绩
2、从键盘输入10个学生成绩
3、采用冒泡法,将学生成绩按照从高到低进行排序
4、再输入一个学生的成绩,将此成绩按照排序规律插入原学生成绩数组
5、将排好序的成绩单进行反序存放,即原来是从高到低,现在改为从低到高排列
1.初始化:定义一个大小为11的数组a,用于存放学生成绩。
2.输入成绩:从键盘输入10个学生成绩,并存储在数组a的前10个位置。
3.成绩排序:使用冒泡排序算法对输入的10个成绩进行从高到低的排序。
4.插入新成绩:从键盘输入一个新学生的成绩,将新成绩按照已排序的成绩顺序(从高到低)插入到数组a中。
5.反转数组:将排序并插入新成绩后的数组a进行反转,使成绩从低到高排列。
6.输出:输出排序后的成绩,插入新成绩后的成绩和反转后的成绩。
在本次实验中,我们编写了一个C语言程序,该程序实现了以下功能:定义数组以存储学生成绩、从键盘输入成绩、使用冒泡排序算法对成绩进行排序、插入新成绩、反转数组并输出结果。学会如何在C语言中实现基本的数组操作和排序算法,如何处理在编程过程中遇到的常见问题。
实验中应注意的问题
<1>冒泡排序实现问题:在实现冒泡排序时,应考虑到应该按照降序(从高到低)排序。
<2>插入新成绩逻辑错误:在插入新成绩时,应考虑到需要将大于新成绩的成绩向后移动,若将小于新成绩的成绩向后移动,会导致插入位置错误。
<3>数组越界风险:在插入新成绩时,如果没有检查数组是否已满(即是否还有空间插入新成绩),可能会导致数组越界。
<4>反转数组逻辑问题:在反转数组时,应避免使用了错误的索引计算方式,导致部分元素没有被正确交换。
解决办法
<1>冒泡排序修正:重新检查冒泡排序的实现,修改比较逻辑,使成绩按照从高到低排序。
<2>插入新成绩逻辑修正:重新审视插入新成绩的逻辑,修改循环条件,确保大于新成绩的成绩被正确地向后移动。
<3>添加数组越界检查:在插入新成绩之前,添加一个检查,确保数组a还有最后一个空位用于存放新成绩。
在本例中,由于数组大小固定为11,这个检查相对简单。但在更通用的场景中,可能需要动态分配数组或使用其他数据结构来避免越界问题。
<4>反转数组逻辑修正:重新计算索引,确保反转逻辑的正确性。使用对称的索引来交换元素,例如arri和arrn-i-1。
复习巩固函数的定义、函数的调用、函数参数传递等。
熟练使用函数编程解决实际应用问题。
1、在函数中进行 10 个学生成绩从高到低排名 sort(int a10)
2、改进第一步的函数为 sort(int a[],int n),进行 n 个学生成绩从高到低排名,
3、改进第二步的函数为 sort(int a[],int n, char style), 将 n 个学生成绩从高到低排名,排名方式为降序;
4、根据 sort(int a[],int n, char style)函数的 style 参数进行排序,如 style 为‘a’按升序排,style 为’d’按降序排(备注: a:ascending 升,d:descending 降)
注意:体会以上函数改进的地方及优点,并在主函数中分别调用 1 和调用 4 中的 sort 函数,对主函数中 10 个学生的成绩进行排序;调用 4 中 sort()时,排序方式根据主函数中键盘输入的排序方式的值决定。
1.初始化:定义一个能够存储学生成绩的数组(如int scores10或int* scores动态分配)。
2.输入成绩:从键盘输入学生成绩,并存储在数组中。
3.成绩排序:实现一个排序函数,用于对成绩进行排序。这个函数会根据需要进行改进,从只支持固定数量(如10个)的排序,到支持任意数量(n个)的排序,再到支持根据指定方式(升序或降序)进行排序。
4.输出:输出排序后的成绩。
在本次实验中,我们实现了对学生成绩进行排序的功能,并随着实验的深入,对排序函数进行了多次改进和扩展,使其从只能处理固定数量的成绩排序,到可以处理任意数量的成绩排序,并最终实现了根据用户指定的排序方式(升序或降序)进行排序。
实验中应注意的问题
<1>固定数组大小:最初实现的排序函数只能处理固定数量的成绩(如10个),这限制了其灵活性和可重用性。
<2>排序方式单一:早期的排序函数只支持降序排序,应考虑到用户可能需要升序排序的情况。
<3>代码复用性:随着功能的增加,有些代码段(如排序算法的核心部分)在多个函数中重复出现,这降低了代码的复用性和可维护性。
<4>用户交互:在实现根据用户指定的排序方式进行排序时,需要处理用户输入的有效性,确保用户输入的是有效的排序方式。
解决办法
<1>使用动态数组或变长参数:通过使用动态分配的数组(如int scores = malloc(n sizeof(int));)或变长参数(如void sort(int a[], int n)),我们可以处理任意数量的成绩排序,提高了函数的灵活性和可重用性。
<2>增加排序方式参数:在排序函数中增加一个参数(如char style),用于指定排序方式(升序或降序)。根据这个参数的值,我们可以在函数内部选择执行升序排序还是降序排序。
<3>提取公共代码段:将排序算法的核心部分提取到一个单独的函数中,并在需要排序的地方调用这个函数。这样可以减少代码重复,提高代码的复用性和可维护性。
<4>增加用户输入验证:在处理用户输入时,增加验证逻辑,确保用户输入的是有效的排序方式。如果输入无效,可以给出提示并重新要求用户输入。
复习巩固指针的含义、指针变量的含义
复习通过指针访问变量,通过指针访问数组
熟练使用指针编程解决实际应用问题
1、定义一个数组 stu10存放 10 个学生的成绩,从键盘输入数据,要求用指针实现
2、将数组 stu10的内容输出到屏幕上,要求用指针实现
3、将成绩数组按照从高到低进行排序,要求用指针实现
4、将第三步内容放在函数中实现,在主函数中调用实现排序,用指针实现,输出排序后的成绩单
5、采用指针方法,输入字符串“student score ”,复制该字符串并输出(复制字符串采用库函数或用户自定义函数)
1.数组元素的访问:使用指针指向数组的首地址,通过指针的算术运算(如递增或递减)来访问数组中的不同元素。
理解指针与数组下标的关系,即指针加1(或减1)等价于数组下标加1(或减1)。
2.数组元素的排序:编写一个排序函数,该函数接受一个指向数组首元素的指针和数组的长度作为参数。
在函数内部,使用指针来遍历数组,并根据排序算法(如冒泡排序、选择排序等)对数组元素进行排序。
排序完成后,数组中的元素将按照升序(或降序)排列。
3.字符串的复制:编写一个字符串复制函数,该函数接受两个参数:一个指向目标字符串的指针和一个指向源字符串的指针。使用指针逐个字符地从源字符串复制到目标字符串,直到遇到源字符串的结束符('\0')。
在本次实验中,我通过指针操作实现数组元素的输入、输出,实现数组元素的排序,将排序功能封装进函数,并在主函数中调用,并使用指针和库函数或自定义函数实现字符串的复制。加深了我对指针和数组的理解,掌握了使用指针操作数组元素的方法,并学会了将功能封装进函数进行调用。同时,我们也意识到了在编写程序时需要注意的问题,如错误处理、内存管理、代码的可读性和可维护性等。
遇到的问题及解决办法
<1>排序函数的编写:在编写排序函数时,注意排序逻辑错误或循环边界问题。
<2>动态内存分配和释放:在复制字符串时,如果使用动态内存分配(如malloc),可能会忘记释放分配的内存,导致内存泄漏。
<3>错误处理和边界检查:在编写程序时,可能会忽略对用户输入的检查,如输入的成绩是否有效,或者分配内存是否成功。
解决问题
<1>排序函数的编写:仔细检查排序算法的逻辑,确保每一轮循环都能正确地将最大(或最小)的元素放到正确的位置,并更新需要继续排序的数组范围。
<2>动态内存分配和释放:在分配内存后,确保在不再需要这块内存时(如字符串使用完后)使用free函数释放它。
<3>错误处理和边界检查:在接收用户输入或分配内存后,加入相应的错误检查和处理逻辑,如检查输入是否为数字,检查malloc的返回值是否为NULL。
复习结构体类型的定义、结构体变量定义
复习结构体数组的定义及赋值及访问
熟练使用结构体编程解决实际应用问题
1、定义一个结构体数组,存放 10 个学生的学号,姓名,三门课的成绩
2、从键盘输入 10 个学生的以上内容
3、输出单门课成绩最高的学生的学号、姓名、以及该门课程的成绩
4、输出三门课程的平均分数最高的学生的学号、姓名及其平均分
5、将 10 个学生按照平均分从高到低进行排序,输出结果,格式如下所示: number name math Chinese English average
103 tom 90 90 100 95
101 alice 90 80 70 80
……
1.数据输入:获取学生的基本信息(学号、姓名、数学、语文、英语成绩)。
2.数据处理:计算每个学生的平均分。找出数学、语文、英语三科各自的最高分学生。
3.数据排序:根据平均分从高到低对学生信息进行排序。
4.数据输出:输出每个学生的基本信息及平均分;数学、语文、英语三科各自的最高分学生信息;按平均分排序后的学生信息列表。
在本次实验中,成功实现了一个简单的学生信息管理系统,该系统能够处理学生信息的输入、计算平均分、找出各科最高分学生、按平均分排序以及显示相关信息。
实验中应注意的问题:
<1>输入验证:在输入学生信息时,没有进行有效的输入验证,可能导致用户输入无效数据(如非数字字符、超出范围的分数等)。
<2>浮点数精度:在计算平均分时,由于使用了float类型,可能导致精度损失,尤其是在涉及多个小数位相加后取平均的情况。
<3>错误处理:在程序运行过程中,如果发生错误(如除数为0),程序可能会崩溃或给出不正确的结果,但没有相应的错误提示。
<4>排序算法效率:对于大量学生数据,使用冒泡排序可能会导致效率较低,需要更高效的排序算法。
解决办法:
<1>输入验证:在输入学生信息时,增加了输入验证的逻辑,确保用户输入的数据是有效的。例如,使用scanf的返回值来判断是否成功读取了整数或浮点数,或者使用fgets和sscanf结合来读取字符串并进行格式验证。
<2>浮点数精度:为了避免浮点数精度问题,可以考虑使用double类型代替float,或者使用定点数表示法。在本实验中,由于分数范围较小,直接使用float并保留两位小数对结果影响不大。
<3>错误处理:在程序中增加了错误处理的逻辑,当发生错误时(如除数为0),程序会给出相应的错误提示并退出或进行其他处理。
<4>排序算法效率:对于大规模数据,可以使用更高效的排序算法,如快速排序、归并排序等。但在本实验中,由于数据量较小(仅10个学生),冒泡排序已经足够快速且易于实现。
综合应用并掌握本学期程序设计基础 C 语言的重要知识及面向过程程序设计方法,提高编程能力和分析问题的能力。
建立学生成绩管理系统,主要完成以下功能:
1、输入:函数 input 把 10 个学生的学号、姓名、3 科成绩以及平均成绩和总成绩放在一个结构体数组中,学生的学号、姓名、3 科成绩可由键盘输入也可由文件读取,然后计算出平均成绩和总成绩放在结构体对应的域中。
2、插入:insert 函数输入一个学生的记录,按学号的先后顺序插入该学生的全部内容到原有的学生信息中。
3、排序:sort 函数对所有学生按要求排序(1.学号 2.总成绩 )并输出排序后的学生信息。
4、查找:find 函数输入一个学生的学号或姓名,输出相应的结果。要求能查询多次。
5、删除:delete 函数输入一个学生的学号或姓名,输出删除学生的具体信息。
6、输出:函数 output 输出全部学生的信息。
7、在 main 函数中调用其他函数,实现系统全部功能
(注:除了定义结构体外,不允许使用全局变量,函数之间的数据全部使用参数进行传递)
备注:进入系统时首先看到的是一个主要功能选项窗口。
1.定义一个Student结构体,包含学生的学号、姓名和成绩信息。
2.实现计算总分和平均分的函数calculate_scores;按学号排序的函数sort;查找学生信息的函数find;删除学生信息的函数delete_student,并更新有效学生数量;输出学生信息的函数output。
3.在main函数中,管理这些函数的调用,并与用户进行交互。
4.使用结构体数组来存储学生信息,定义一个变量来跟踪当前有效的学生数量。
在本次实验中,创建了一个学生信息管理系统,旨在实现学生信息的录入、总分和平均分的计算、按学号排序、查找特定学生信息、删除特定学生信息等功能。
实验中应注意的问题
<1>数据结构设计:使用固定大小的数组来存储学生信息,但这限制了系统的可扩展性。当需要添加更多学生时,系统无法处理。
<2>动态内存分配:使用动态内存分配(如malloc和realloc)时,容易遇到内存泄漏和数组越界的问题。
<3>排序算法实现:在实现排序功能时,冒泡排序算法在大数据集上性能不佳。
解决办法
<1>使用动态数组:为了解决数据结构设计的问题,改用动态分配的数组(即动态数组),可以根据需要调整大小。这样,系统就能够在需要时添加或删除学生信息。
<2>内存管理:为了防止内存泄漏和数组越界,每次使用malloc或realloc分配内存后,确保在适当的时候使用free释放内存。
<3>优化排序算法:为了提高排序性能,使用快速排序或归并排序。
在本次实训中,构建了一个功能完备的学生信息管理系统,涉及了数据结构设计、动态内存分配、排序算法实现、错误处理以及用户交互等多个方面。
一、数据结构设计
在第一个实验中,面临数据结构设计的问题,使用固定大小的数组来存储学生信息,限制了系统的可扩展性。为了解决这个问题,使用动态分配的数组(即动态数组),使得系统可以根据需要动态地添加或删除学生信息。这大大提高了系统的灵活性和可扩展性。
二、动态内存分配
在第二个实验中,深入学习了动态内存分配的概念,并实践了malloc和realloc等函数的使用。然而,在这个过程中,容易遇到内存泄漏和数组越界的问题。通过不断调试和修改代码,学会了如何正确地分配和释放内存,以及如何避免数组越界。
三、排序算法实现
在第三个实验中,实现了按学号排序的功能。冒泡排序算法在大数据集上性能不佳。为了提高性能,考虑了更高效的排序算法,如快速排序或归并排序。然而,为了保持实验的简单性,最终选择了优化冒泡排序算法的性能。通过添加标志来检测数组是否已排序,我们显著提高了排序的效率。
四、错误处理
在第四个实验中,专注于提高系统的错误处理能力。在删除和查找操作时,如果输入了不存在的学号,程序可能会崩溃或给出不正确的反馈。为了解决这个问题,在代码中添加了更多的条件判断,以检测用户输入的有效性和学生信息的存在性。如果输入了不存在的学号,程序会给出清晰的错误提示,而不是崩溃或给出不正确的反馈。这大大提高了系统的稳定性和用户体验。
五、用户交互
在最后一个实验中,改善了系统的用户交互界面。通过增加清晰的提示和反馈,使系统更加易于使用和理解。例如,在输入学号时,给出了明确的格式要求;在删除或查找学生时,给出了操作成功或失败的提示。这些改进使得用户能够更轻松地与系统交互,并提高了系统的整体可用性。
通过这五个实验,不仅掌握了C语言编程的基本技能,还学会了如何设计和实现一个完整的系统。在解决问题的过程中,提高了自己的编程能力、分析问题的能力以及解决问题的能力。同时,也对数据结构、动态内存分配、排序算法、错误处理以及用户交互等方面有了更深入的了解。这些经验和知识将对未来的学习和工作产生积极的影响。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。