C语言博客作业--结构体
2017-12-24 17:09
405 查看
一、PTA实验作业
题目1:
1. 本题PTA提交列表
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171222234644834-550590991.png)
2. 设计思路
void calc(struct student *p,int n){ for i=0 to i=n-1 累加三门成绩存于sum end for; } void sort(struct student *p,int n){ 定义结构体变量tmp; /*选择法*/ for i=0 to i=n-2 定义变量index=i; for j=i+1 to j=n-1 判断数组最大数,并将下标存于index; end for 交换p[i]与p[index]的位置 end for }
3.代码截图
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171222234627975-390270573.png)
4.本题调试过程碰到问题及PTA提交列表情况说明
碰到的问题:最开始用冒泡法,排序反了解决方法:改变冒泡法内层循环的判断条件,改为 小于时调换位置 if(p[j].sum < p[j+1].sum);或者用选择法做
题目2:有理数比较
1. 本题PTA提交列表
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223085934225-1595293938.png)
2. 设计思路
定义结构体 fraction{ 包含分子,分母 }; //该结构体表示分数 int main() { 定义结构体数组 s[2]; 定义整形数组 real[2]; for i=0 to i=2 输入每个分数 计算分数的大小存于real[i]中; end for 判断real[0]与real[1]的大小,输出相应的情况 }
3.代码截图
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223085528662-1100317712.png)
4.本题调试过程碰到问题及PTA提交列表情况说明
本题没有碰到问题题目3:通讯录的录入与显示
1. 本题PTA提交列表
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223084038365-1542624121.png)
2. 设计思路
定义结构体 info{ 包含姓名,出生年月日,性别,固定电话和手机 };//该结构体存放朋友的信息 int main() { 定义变量 输入要录入的人数n; 定义结构体数组 s ; for i=0 to i=n-1 输入每个人的信息; end for 输入查询次数k 定义数组num[11],存放查询的序号; for i=0 to i=k-1 输入num[i]; end for for i=0 to i=k-1 判断输入的序号num[k]是否在有效,若有效输出对应信息,否则输出Not found end for }
3.代码截图
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223084213568-1674336397.png)
4.本题调试过程碰到问题及PTA提交列表情况说明
碰到的问题:数组越界,刚开始定义电话num长度为16,没有考虑到结束符;![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223085438146-1164680299.png)
解决办法:将数组长度定义为20
二、截图本周题目集的PTA最后排名。
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223085154787-669012354.png)
三、阅读代码
1.刽子手游戏
游戏规则:1、答案单字写在纸上(每个字元一张纸),并且被盖起来,玩家每次猜一个英文字元(letter)。
2、如果这个英文字元猜中(在答案的英文单字中有出现),被猜中的字元就被翻开。例如:答案是book,如果你猜o,book中的两个o就会被视为已猜中。
3、如果这个英文字元未出现在答案的单字中,就会在hangman的图中多加一划。要完成hangman图共需7划,如下图。注意:同一个猜错的字元只能再图上画一划,例如:答案是book,第一次你猜a(未猜中)会在图上画一划,但第二次以后再猜a并不会再多画。
4、如果在hangman图完成之前,玩家已猜中所有答案中的字元,则玩家赢(win)。
5、如果玩家尚未猜中所有答案中的字元而hangman图完成了,,则玩家输(lose)。
6、如果玩家在还没输赢的情况之下就不玩了,那我们说玩家胆小放弃了(chicken out)
代码:
#include<stdio.h> #include<string.h> #define maxn 100 int left ,chance; //还需猜left个位置,错chance次后输 char s[maxn],s2[maxn]; //答案字符串s,玩家猜的字母序列s2 int win,lose; //win=1 表示赢了,lose=1 表示输了 void guess (char ch); int main(){ int rnd; while(scanf("%d%s%s",&rnd,s,s2)==3&&rnd!=-1){ printf("Round %d\n",rnd); win=lose=0; //求解一组新数据是初始化 left=strlen(s); chance=7; for(int i=0;i<strlen(s2);i++){ guess(s2[i]); //猜一个字母 if(win||lose) break; //检查状态 } //根据结构进行输出 if(win) printf("You win.\n"); else if(lose) printf("You lose.\n"); else printf("You chickened out.\n"); } return 0; } void guess(char ch){ int bad=1; for(int i=0;i<strlen(s);i++) if(s[i]==ch) { left--; s[i]=' '; //将以猜过的字母改为空格 bad=0; } if(bad) --chance; if(!chance) lose=1; if(!left) win=1; }
对于本题来说,需要维护的的内容比较多,例如:是否赢了或输了,以及剩余的机会数等,代码中用了全局变量来解决,如果不用全局变量,则它们都要传给函数guess,其中有些参数会被guess修改。
题目中说的猜过的字母再猜一次算错,代码中并没有保存已经猜过的字母,若要保存需要在程序中增加一个字符数组,让guessed[ch]标识字母ch是否已经猜过。但程序中有一个更好的方法,就是将已经猜过的字母改成空格
2.设计函数char *insert(s1,s2,n),用指针实现在字符串s1中的指定位置n处插入 字符串s2
代码:#include<stdio.h> char* insert(char *s1,char *s2,int n) { int j=0; char *ss=new char[100]; char *tsptr=ss; for(int i=0;i<n;i++) *ss++=*s1++; //s1前n-1个存于新数组 ss while(*s2!=0) *ss++=*s2++; //将s2存入新 ss while(s1!=0) *ss++=*s1++ //将 s1 剩余的字符存入 ss *ss==0; //添加结束符 return tsptr; } void main() { char s1[]="123456789"; char s2[]="1234"; char *ss=intsert(s1,s2,4); //调用函数 printf("%s",ss); }
本题函数中用指针,代码里大大减少
四、本周学习总结
1.总结本周学习内容。
1.结构体
struct 结构名{ 类型名 结构成员名1; 类型名 结构成员名2; …… 类型名 结构成员名n; }结构变量1,结构变量2,……;
2.共用体
union 结构名{ 类型名 结构成员名1; 类型名 结构成员名2; …… };
特点:
同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种
共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用
共用体变量的地址和它的各成员的地址都是同一地址
不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量时对它初始化
不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针
共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员
3.枚举
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };
特点:
枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
可以人为设定枚举成员的值,从而自定义某个范围内的整数。
枚举型是预处理指令#define的替代。
类型定义以分号;结束。
注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量.
既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明.
方法一:枚举类型的定义和变量的声明分开:
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };
enum DAY yesterday;
enum DAY today;
enum DAY tomorrow; //变量tomorrow的类型为枚举型enum DAY
enum DAY good_day, bad_day; //变量good_day和bad_day的类型均为枚举型enum DAY
方法二:类型定义与变量声明同时进行:
enum //跟第一个定义不同的是,此处的标号DAY省略,这是允许的。 { saturday, sunday = 0, monday, tuesday, wednesday, thursday, friday } workday; //变量workday的类型为枚举型enum DAY enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days; enum BOOLEAN { false, true } end_flag, match_flag; //定义枚举类型并声明了两个枚举型变量
方法三:用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明:
typedef enum workday { saturday, sunday = 0, monday, tuesday, wednesday, thursday, friday } workday; //此处的workday为枚举型enum workday的别名 workday today, tomorrow;
2.罗列本周一些错题。
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223222500506-1193734100.png)
本题没注意到D选项中数组越界
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223222817928-85439167.png)
![](https://images2017.cnblogs.com/blog/1232091/201712/1232091-20171223222846271-1626927121.png)
本题填空题应该定义结构体数组