C语言博客作业--结构体

一、PTA实验作业

题目1:结构体数组按总分排序

1. 本题PTA提交列表

2. 设计思路(伪代码或流程图)

calc函数
传入结构体的地址和长度
定义结构体指针,指向传入的结构体
for p=stu to stu+n
    for i=0 to 2
        初始化sum为0
    end
end
指针返回初始位置
for p=stu to stu+n
    for i=0 to 2
        累加sum
    end
end
sort函数
定义结构体指针stu,和p2作为内循环指针,max指针存放最大sum的变量地址
定义结构体变量作为交换两变量
for p=stu to stu+n-1
    max存p
    for p2=p+1 to stu+n-1
        如果p2指的变量里的sum大于max指的变量里的sum
            交换两变量的数据
    end
end

3.代码截图

4.本题调试过程碰到问题及PTA提交列表情况说明。

前几次提交时少复制了后面的几个花括号,导致了几次编译错误
calc函数sum没有初始化,导致devc++上答案错误
解决方法:遍历结构体的sum,初始化为0

题目2:计算职工工资

1. 本题PTA提交列表

2. 设计思路(伪代码或流程图)

struct staff{
	char name[100];
	double base,flow,put,actual; 
};//name为名字,base为基本工资,flow为浮动工资,put为支出,actual为实际工资
定义n为人数,i为循环变量
输入n
定义结构数组,长度为n
for i=0 to n-1
    输入单个结构的内容
end
for i=0 to n-1
    计算实际工资
end
for i=0 to n-1
    输出
end

3.代码截图

4.本题调试过程碰到问题及PTA提交列表情况说明。

定义结构体时基本工资,浮动工资,支出定义成了int,计算的结果却放到了浮点型的变量里,输出结果用的是%f,用函数写是编译错误,去掉函数就变成答案错误。

解决方法:改变定义的类型

题目3:通讯录的录入与显示

1. 本题PTA提交列表

2. 设计思路(伪代码或流程图)

struct list{
	char name[100];
	char birthday[100];
	char sex;
	char tel[100];
	char mobil[100];
};//name表示名字,birthday生日,sex性别,tel电话,mobil手机
定义为存入信息数,i为循环变量,num为查找信息编号,n2查找个数
输入n
定义结构体数组lis【n】
for i=0 to n-1
    输入信息
end
输入查找信息个数
for i=0 to n2-1
    输入查找信息的编号
    如果编号在可用范围内,输出信息
    否则输出没找到
end

3.代码截图

4.本题调试过程碰到问题及PTA提交列表情况说明。

答案错误:输出时信息的位置放错了
解决方法:调整了信息的位置输出
部分正确:定义电话的时后给的长度不够
解决方法:加大了电话的数组长度

二、截图本周题目集的PTA最后排名

三、阅读代码

  • 编一程序,用指针数组在主函数中输入十个等长的字符串。用另一函数对它们排序,然后在主函数中输出10个已排好序的字符串
#include<stdio.h> 
#include<string.h> 
void sort(char *[]); 
int main()
{   
     int i;   
    char str[10][6], *p[10];   
    printf("please input 10 string:/n");   
    for(i=0;i<10;i++)//首先将10个str的首地址赋值给10个p[i];   
        p[i]=str[i];//将第i个字符串的首地址赋予指针数组p的第i个元素;  
    for(i=0;i<10;i++)    
        scanf("%s",p[i]);//scanf输入到&p[i]  
    sort(p);   
    printf("the output 10 string:/n");  
    for(i=0;i<10;i++)    
        printf("%s/n",p[i]);//输出到p[i]; 
}
void sort(char *s[]) 
{   
    char *temp;  int i,j;   
    for(i=0;i<9;i++)   
        for(j=0;j<9-i;j++)     
            if(strcmp(*(s+j),*(s+j+1))>0)    {      
                temp=*(s+j);//*(s+j)指向数组指针,我想应该是字符串的首地址;所以可以直接赋值给temp指针;     
                *(s+j)=*(s+j+1);     
                *(s+j+1)=temp;    
            } 
}

这道题指针的做法很有借鉴价值,将第i个字符串的首地址赋予指针数组p的第i个元素,后续就不用再拿二维数组的地址来用,简化程序,提高可读性。

  • 有n个结构体变量,内含学生学号、姓名和3门课程的成绩。要求输出平均成绩最高的学生的信息(包括学号、姓名、3门课程成绩和平均成绩)。
#include<stdio.h>  
#define N 3 //学生数为3  
struct student  
{  
    long num;  
    char name[20];  
    int score[3];  
    float aver;  
}stu[N];  
int main()  
{  
    void input(struct student stu[]);  
    struct student max(struct student stu[]);  
    void print(struct student stu);  
    struct student *p=stu;  
    input(p);  
    print(max(p));  
    return 0;  
}  
void input(struct student stu[])  
{  
    int i;  
    printf("请输入%d个学生的信息(学号、姓名、三门课成绩):\n",N);  
    for(i=0;i<N;i++)  
    {  
        scanf("%ld %s %d %d %d",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);  
        stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;  
    }  
}  
struct student max(struct student stu[])  
{  
    int i,m=0;  
    for(i=1;i<N;i++)  
        if(stu[i].aver>stu[m].aver) m=i;  
    return stu[m];  
}  
void print(struct student stu)  
{  
    printf("\n成绩最高的学生是:\n");  
    printf("学号:%ld\n姓名:%s\n三门课成绩:%d %d %d\n平均成绩:%5.2f\n\n",  
                          stu.num,stu.name,stu.score[0],stu.score[1],stu.score[2],stu.aver);  
}  

这道题使用了结构体,但是我觉得更好的地方是用函数来分装代码,整个结构很好,值得借鉴。

四、本周学习总结

1.总结本周学习内容。

结构体、共用体、枚举这种构造数据类型特点。

结构体
struct 结构体名
{
成员表列
} 变量表列;
例:
struct data{
    int a;
    char b;
    double c;
} s1;

结构体变量就像数组一样,但是不同于数组的是,他内部的元素可以不同,而且结构体内部还可以嵌套,这对于数据的分类管理就起到很大作用。

共用体
union 共用体名
{
成员表列
} 变量表列;
列:
union data
{
    int i;
    char ch;
    float f;
} a, b, c;

1.同一个内存段可以用来存放几种不同类型的成员,但是在每一瞬间只能存放其中的一种,而不是同时存放几种。
2.共用体变量中起作用的成员是最后一次存放的成员,在存入一个新成员后,原有成员就失去作用。
3.共用体变量的地址和它的各成员的地址都是同一地址。
4.不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。
5.共用体类型可以出现在结构体类型的定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型的定义中,数组也可以作为共用体的成员。
6.共用体变量的初始化。
(1)union data a=b; //把共用体变量初始化为另一个共用体
(2)union data a={123}; //初始化共用体为第一个成员
(3)union data a={.ch='a'}; //指定初始化项目,按照C99标准
7.共用体变量也可以作为函数的参数和返回值。

共用体的使用大大降低编程时内存的占用,但是使用时也要格外小心,不同于结构体数据所占内存不同,共同体占的内存相同,取值只取最后存放的数,所以使用时要注意。
此外结构体与共用体的定义方式差不多,可以结合起来记忆。

枚举

enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
例:
enum weekday{sun,mon,tue,wed,thu,fri,sat};

如果枚举没有初始化,即省掉"=整型常数"时, 则从第一个标识符开始,顺次赋给标识符0, 1, 2, ...。但当枚举中的某个成员赋值后,其后的成员按依次加1的规则确定其值。
例如下列枚举说明后,x1, x2, x3, x4的值分别为0, 1, 2, 3。enum Num{x1, x2, x3, x4}x;
当定义改变成

enum Num
{
    x1,
    x2=0,
    x3=50,
    x4
}x;
则x1=0, x2=0, x3=50, x4=51
  1. 枚举中每个成员(标识符)结束符是"," 不是";", 最后一个成员可省略","。

  2. 初始化时可以赋负数, 以后的标识符仍依次加1。

  3. 枚举变量只能取枚举说明结构中的某个标识符常量。

  4. 枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。例如对枚举weekday的元素再作以下赋值: sun=5;mon=2;sun=mon; 都是错误的。

  5. 枚举元素本身由系统定义了一个表示序号的数值,从0 开始顺序定义为0,1,2…。如在weekday中,sun值为0,mon值为1, …,sat值为6。

  6. 只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。如: a=sun;b=mon; 是正确的。而: a=0;b=1; 是错误的。如一定要把数值赋予枚举变量,则必须用强制类型转换,如: a=(enum weekday)2;其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于: a=tue; 还应该说明的是枚举元素不是字符常量也不是字符串常量, 使用时不要加单、双引号。

相比于结构体或共同体,枚举的定义方法有点类似,但有很大区别,如2所提到,以及系统定义数值要非常注意;枚举的使用方便了常量的使用,使代码可读性大大提高。

递归函数原理:

递归(recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。

递归通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有>直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接
解决。因此,递归有两个基本要素:
(1)边界条件:确定递归到何时终止,也称为递归出口。
(2)递归模式:大问题是如何分解为小问题的,也称为递归体。递归函数只有具备了这两个要素,才能在有限次计算后得出结果

在递归函数中,调用函数和被调用函数是同一个函数,需要注意的是递归函数的调用层次,如果把调用递归函数的主函数称为第0层,进入函数后,首次递归调用自身称为第1层调用;从第i层递归调用自身称>为第i+1层。反之,退出第i+1层调用应该返回第i层。

递归函数的内部执行过程:

一个递归函数的调用过程类似于多个函数的嵌套的调用,只不过调用函数和被调用函数是同一个函数。为了保证递归函数的正确执行,系统需设立一个工作栈。具体地说,递归调用的内部执行过程如下:
(1)运动开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。

总之,递归函数就是将一个复杂的问题分解成几个相似的小问题,调用函数来解决问题。只需考虑问题的分解,及分解到边界时如何解决即可,其他部分交给计算机来解决。

2.罗列本周一些错题。

对于以下结构定义,(*p)->str++中的++加在()。 (2分)
struct { int len; char\ *str; } *p;
A、
指针str上
B、
指针p上
C、
str指向的内容上
D、
语法错误
答案:d 错选:c
分析:*p已经是内容,不能->,如果是p->str++,则++加在指针str上
线性表用顺序实现。请填空写一个求线性表L 中所有奇数之和的算法。
例如:
L=(1,2,3,4,5) 其和为 9(本题结构体定义很不错。)

#include <stdio.h>
#define N 10
typedef struct sqlist
 {
   int data[N];
   int last;
   }LIST;

 int Total(List list)
 {

     return sum;  
 }
 void Show(LIST list)
 {
   int i;
   for(i=0;i<=list.last;i++)
      printf("%3d", list.data[i]);
   printf("\n");
 }
int main()
 {
    LIST list;
    int i,sum;
    for(i=0;i<=5;i++)
     list.data[i]=i;
    list.last=5;
    Show(list);
    sum=Total(list);
    printf("sum=%3d\n",sum);
    return 0;
}
参考答案
int sum=0;
for(int i=0;i<=list.last;i++)
   if(list.data[i]%2)
      sum+=list.data[i];
我的作答


int sum=0,i;
for(i=0;i<list.last;i+=2){
    sum+=list.data[i];
}

分析,没看清楚题目,题目要的是奇数的和,不是下标

posted on 2017-12-23 20:59  斯慕  阅读(595)  评论(7编辑  收藏  举报