zoukankan      html  css  js  c++  java
  • C语言博客作业--结构体

    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);  
        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("
    成绩最高的学生是:
    ");  
        printf("学号:%ld
    姓名:%s
    三门课成绩:%d %d %d
    平均成绩:%5.2f
    
    ",  
                              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("
    ");
     }
    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
    ",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];
    }
    

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

  • 相关阅读:
    WCF客户端获取服务端异常[自定义异常]
    关于VS2013 Browser Link 新功能
    MVC 单元测试xUnit初探
    ASP.NET MVC4中加入Log4Net日志记录功能
    简洁的MVC思想框架——Nancy(Session的使用)
    iOS开发之快速排序算法
    iOS开发之内购的完整流程
    ios面试数据结构与算法
    iOS开发之读取info.plist配置信息
    iOS开发之ARC与非ARC的设置
  • 原文地址:https://www.cnblogs.com/doimpossible/p/8064945.html
Copyright © 2011-2022 走看看