2019年春季第九周 编程总结

一、作业头内容

这个作业属于那个课程 C语言程序设计II
这个作业要求在哪里 C语言作业评价标准
我在这个课程的目标是 掌握结构指针的操作,并应用于函数传递。
这个作业在那个具体方面帮助我实现目标 在对结构定义与逻辑设计中,能够使用结构变量与结构数组进行编程。
参考文献 C语言中的->定义与声明 ; PTA平台做题中出现的问题;Warning相关问题

二、基础作业:

PTA:

1 、函数题:按等级统计学生成绩
2 、编程题:一帮一、考试座位号

第一题:

(1、题目:6-1 按等级统计学生成绩

本题要求实现一个根据学生成绩设置其等级,并统计不及格人数的简单函数。

函数接口定义:

int set_grade( struct student *p, int n );

其中p是指向学生信息的结构体数组的指针,该结构体的定义为:

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

n是数组元素个数。学号num、姓名name和成绩score均是已经存储好的。set_grade函数需要根据学生的成绩score设置其等级grade。等级设置:85-100为A,70-84为B,60-69为C,0-59为D。同时,set_grade还需要返回不及格的人数。

裁判测试程序样例:

#include <stdio.h>
#define MAXN 10

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

int set_grade( struct student *p, int n );

int main()
{   struct student stu[MAXN], *ptr;
    int n, i, count;

    ptr = stu;
    scanf("%d\n", &n);
    for(i = 0; i < n; i++){
       scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
    } 
   count = set_grade(ptr, n);
   printf("The count for failed (<60): %d\n", count);
   printf("The grades:\n"); 
   for(i = 0; i < n; i++)
       printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade);
    return 0;
}
/* 你的代码将被嵌在这里 */

输入样例:

10
31001 annie 85
31002 bonny 75
31003 carol 70
31004 dan 84
31005 susan 90
31006 paul 69
31007 pam 60
31008 apple 50
31009 nancy 100
31010 bob 78

输出样例:

The count for failed (<60): 1
The grades:
31001 annie A
31002 bonny B
31003 carol B
31004 dan B
31005 susan A
31006 paul C
31007 pam C
31008 apple D
31009 nancy A
31010 bob B
(2、程序代码:
int set_grade( struct student *p, int n )
{
	int num = 0;             //不及格人数。 
	for(int i = 0;i<n;i++,p++)
	{
		if( ( (*p).score<=100)&&( (*p).score>=85) )
		    (*p).grade = 'A';
		
		else if( ( (*p).score<85)&&( (*p).score>=70) )
			(*p).grade = 'B';
			
		else if( ( (*p).score<70)&&( (*p).score>=60) )
			(*p).grade = 'C';
	
		else if( (*p).score<60)
		{
			(*p).grade = 'D';
			num++;
    	}

	}
	return num;
}
(3、设计思路,流程图:
设计思路:

一:该题目要求为补写自定义函数,先定义一个整形常量,用于存储学生中不及格总个数;
二:再利用for循环去判断好“‘A’、‘B’、‘C’、‘D’”,并记录好在结构体中的“grade”中;
三:将得到的学生不及格总个数num返回主函数;
四:程序代码完成。

流程图

(4、本题调试过程碰到的问题及解决办法。

错误截图:

问题:

编写的代码在改题目中逻辑思路正确,但在关于对A的评判处条件判断不严谨,考虑不到位,语句“if( ( (p).score<100)&&( (p).score>=85) )”不合题意。即有忽略存在学生分数为100的未评判为A。

解决办法:

调试判断语句对100分的处理不到位;将语句“if( ( (p).score<100)&&( (p).score>=85) )”修改为“if( ( (p).score<=100)&&( (p).score>=85) )”,即缺少一个“=”。

(5、程序运行结果的截图或者效果录像。

正确截图:

第二题:

(2、题目:7-1 一帮一

“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组

输入格式:

输入第一行给出正偶数N(≤50),即全班学生的人数。此后N行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。

输出格式:

每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。

输入样例:

8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda

输出样例:

Amy Jack
Tom Linda
Bill Maya
Cindy John
(2、实验代码:
#include<stdio.h>
int main (void)
{
    int n,i,j,a[50]; 
	char b[50][300]; 
	scanf("%d",&n); 
	for(i=0; i<n; i++) 
	{
	    scanf("%d %s",&a[i],&b[i]);
	} 
	for(i=0; i<n; i++) 
	{
	    for(j=n-1; j>=0; j--) 
		{ 
		    if(a[i]!=a[j]&&a[i]<=1&&a[j]<=1) 
			{ 
			    a[i]=a[j]=10;
				printf("%s %s\n",b[i],b[j]); 
				break; 
			}
		}
	}
    return 0;
}

(3、设计思路,流程图:
设计思路:

一 :建立头文件;
二 :定义三个整形变量,其中一个存放学生个数,两个为循环结构的序数;一个整形数组为按顺序存放“性别”;一个字符型二维数组用于存放学生姓名;
三 :输入按从高到低的顺序给出的每个学生的性别和姓名;
四 :应用两个for循环并且为嵌套模示,在里面用一个if条件语句处理学生信息,核心为条件通过,输出一组两个学生的姓名;
五 :返回值为0;程序结束。

流程图

(4、本题调试过程碰到的问题及解决办法。

错误截图:

问题:

错误原因为逻辑错误,首先实验代码的数据处理只对第一次正确,而后的情况是名次在后的学生名字会重复出现。

解决办法:

在双for循环内,即嵌套for循环的if条件语句中,在条件设计中应将以处理好的学生名字排除在外;一种思路是将要处理的学生名字与其附带的性别指示重新赋值并大于1,且在if条件中并列判断大于1的否定。

(5、程序运行结果的截图或者效果录像。

正确截图:

第三题:

(3:题目:7-2 考试座位号

每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。

输入格式:

输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。
考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。

输出格式:

对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。

输入样例:

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4

输出样例:

3310120150912002 2
3310120150912119 1
(2、程序代码:
#include<stdio.h>
struct T
{
    double a;
	int b;
    int c;
};


int main (void) 
{ 
    int n,m; 
	scanf("%d",&n);
	struct T s[n]; 
	int i,j,d[n];

	for(i=0;i<n;i++) 
	scanf("%lf %d %d",&s[i].a,&s[i].b,&s[i].c); 

	scanf("%d",&m); 
	
	for(i=0;i<m;i++)  
	scanf("%d",&d[i]); 
	
	for(i=0;i<m;i++) 
	{ 
		for(j=0;j<n;j++)
		{ 
		    if(d[i]==s[j].b) 
		    printf("%.lf %d\n",s[j].a,s[j].c); 
		} 
	} 
	return 0; 
}

(3、设计思路,流程图:
设计思路:

一 :建立好头文件;
二 :学生信息结构定义;
三 :先输入考生的个数,再通过for循环输入好考生的信息:“准考证号 、试机座位号 、考试座位号”,再根据题目要求输入需要查询试机座位号码的考的个数和待查询的试机座位号码;
四 :应用两个for循环并且为嵌套模示,在里面用一个if条件语句处理学生信息,条件通过,将学号和“试机座位号码”对应的考试座位号输出;
五 :返回值为0;程序结束。

流程图

(4、本题调试过程碰到的问题及解决办法

错误截图:

问题:

实验代码逻辑正确,思路可行,但PTA不支持,每一段都提示“Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result”。

解决办法:

原因在于结构体中的数组与定义的结构的数组在PTA上不同,前者直接引用其中的数组会提示错误;解决办法,将结构体中数组修改为变量,定义结构变量修改为结构数组;其他细微处也要修改成正确表达形式。

(5、程序运行结果的截图或者效果录像。

正确截图:


三、挑战作业:

(1:题目:关于字符串的挑战题:
根据九宫格键盘对应英语单词的对应关系设计一个程序,如对于号码5869872,可以依次输出其代表的所有字母组合。如:JTMWTPA、JTMWTPB……

输入样例:

586

输出样例:

JTM
JTN
……
(2、程序代码:
#include<iostream>
using namespace std;
 
const int MaxLength = 9;
char c[10][10] = {"", "", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
int total[10] = {0,0,3,3,3,3,3,4,3,4};
 
int main(void)
{
	int number[MaxLength] = {5,8,6};            //本例输入数字5,8,6
	int answer[MaxLength] = {0};
	int len=3;                                                 //长度为3.
	
	while(true)
	{
		for(int i = 0; i < len; i++)
			printf("%c", c[ number[i] ][ answer[i] ]);     //依次输出号码代表的所有字母组合
		printf("\n");
		
		int k = len - 1;                                  //控制列的变化的数次。
		while(k >= 0)    
		{
			if(answer[k] < total[number[k]] - 1)
			{
				answer[k]++;
				break;
			}                                   //改变列。
			else
			{
				answer[k] = 0;
				k--; 
			}                                  //列归为,重新开始 
		}
		if(k < 0)
			break;                        //循环结束,程序完成要输出号码代表的所有字母组合,跳出循环。
	}
	return 0;
}
(3、设计思路:
根据九宫格键盘来研究,我们可以发现,除了0,1之外,其他数字上最少都有3个字符,其中7和9上有4个字符,我们可以假设0,1都是空字符。
首先讲问题简单化,若电话号码只有一位数,比如说5,那么其代表的单词为J,K,L;
接着若电话号码升级到两位数,比如58,又将如何呢?分两步走,从左到右,在选择一个第一位数字所代表的字符的基础上,遍历第二位数字所代表的字符,直到遍历完第一位数字代表的所有字符。
就拿58来说,5所能代表的字符为JKL,8所能代表的字符为TUV,首先让5代表J,接着遍历8所能代表的所有字符,即可得到JT,JU,JV,然后再让5代表K,再次遍历8所能代表的所有字符,即可得到KT,KU,KV,最后让5代表L,那么同理可得到LT,LU,LV.
(4、本题调试过程碰到的问题及解决办法
问题:递归解法逻辑设计复杂!
解决办法:参考论坛中相关博客,参考博客     [电话号码与英文单词对应](https://blog.csdn.net/hellotomhaha/article/details/51089829)    对程序进行调试解读原理。
(5、程序运行结果的截图或者效果录像。

正确截图:


四、预习作业:


a)、.预习的主要内容
C语言程序一般都由许多小的函数组成,而不是由少量较大的函数组成;外部变量:当两个函数共享数据,但是又不相互调用,就把该数据定义为外部变;程序可以看做是变量定义和函数定义的集合,函数之间的通信可以使用参数、函数返回值、和外部变量。
b)、.预习中存在的疑惑
如何设计与使用函数嵌套求解复杂的问题!

五、学习进度统计和学习感悟 :

1)、进度统计条:

2)、学习进度表:

| 第N周 | 日期 | 这周花的时间 | 代码行数 | 学到的知识点简介 | 目前比较迷惑的问题 |
| ------------ | ------------ | ------------ | ------------ | ------------ |
| 第九周 | 4/22-/26 | 计13小时 | 360 | 结构指针的概念、结构指针作为函数参数 | 结构体内的二维数组用结构名调用出错 |
| 第八周 | 4/15-/19 | 计13小时 | 450 | 动态内存分配,字符指针 | -- |
| 第七周 | 4/8-/11 | 计11小时 | 520 | 复习冒泡排序法;详解指针、数组与地址间的关系;指针之间的运算 | -- |
| 第六周 | 3/29-4/5 | 计 9小时 | 390 | 指针变量的初始化、指针作为函数参数、指针变量的赋值与运算 | -- |
| 第五周 | 3/25-/28 | 计 8小时 | 200 | 字符串的基本概念、操作方法 | -- |
| 第四周 | 3/18-/22 | 计 8小时 | 400 | 冒泡排序法、选择排序法、二维数组 | -- |
| 第三周 | 3/11-/16 | 计 4小时 | 150 | 指针、二维数组 | -- |

3)、学习感悟:
(1)本周你学习哪些内容(不限于课上)?你有哪些收获?
C语言中结构体是一种构造类型,和数组、基本数据类型一样,可以定义指向该种类型的指针。
使用结构指针,由指向数组的指针比数组本身更容易操作一样,指向结构的指针通常比结构本身更容易操作。
(2)本周所学内容中你觉得哪些地方是难点?对此你做了哪些措施去克服这些困难?
在对嵌套结构体的初始化时还有困难,一些小细节还不太清楚,虽然本质上可以参照基本结构体的初始化方式,对结构体的元素分别进行初始化,但嵌套本就比较复杂。

六、结对编程感受:

1)、过程:
  首先是组织一起练习与解决PTA上的基础题题,第一题的函数题,通过合作、分工对主函数解读和自定义函数设计与猜想与讨论再根据思路画出大概流程;
再是两人一起设计和完善编写程序,代码通过PTA和相关软件运行检查;之后转至基础题中的编程题,过于复杂的先在网上查找与完善、修改代码,一起粗略画出流程图,再讨论简化完善。
最后,总结,相互提问与一起解决问题。
2)、看法:
 结对编程很大程度上提高了编程的效率及质量,是一种较好的实践模式。这是一种很好的合作学习,起到了互助的作用。

posted @ 2019-04-26 13:27  青尘忆梦  阅读(394)  评论(1编辑  收藏  举报