【无标题】现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点输入是一组学生的姓名、学号和绩点,以链表形式存储。删除绩点小于平均绩点的学生结点,成为一个新链表。后按照输入的顺

题目描述:

现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点

输入是一组学生的姓名、学号和绩点,以链表形式存储。

删除绩点小于平均绩点的学生结点,成为一个新链表。

后按照输入的顺序,依序输出新链表的学生信息。

平均绩点是输入的所有学生绩点取算术平均值。

输入描述:
        输入包括若干行。 每行是一个学生的姓名、学号和绩点,以空格隔开。

最后一行是*.
输出描述:
        输出包括学生姓名。 每个学生姓名一行。

样例输入:

sddv 005 3.6
jjjbjb 1465 1.5
jdsf 0156  2.8
scc 003 1.5
wzwa 008 4.2
*

样例输出:

sddv
jdsf
wzwa

提示:本题需要创建自定义链表创建函数creat(),链表删除函数delete()。我认为在链表的使用过程中遇到最多的问题应该是“

信号: SIGSEGV (Segmentation fault)

”这个信号,代表程序包括非法内存访问,数组越界,指针漂移,调用系统禁用的系统函数等。可想而知当遍历链表时需要用到循环,当循环走到链表倒数第二个节点时,p=p->next会直接使p=NULL形成空指针,此时你再想用p->score这样的语句去取出某些成员的值,势必出现上述信号,写代码过程中要注意这点。

代码实现:(编译环境:CLion 2022.2.4)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n;
struct student
{
    char name[100];
    char num[100];
    double score;
    struct student *next;
};
struct student *creat()
{
    struct student *head=NULL,*p1,*p2;
    char end[10];
    strcpy(end,"*");
    int i=0;
    do
    {
        p1=(struct student *)malloc(sizeof(struct student));
        scanf("%s",p1->name);
        if(*(p1->name)!=*end)
        {
            scanf("%s", p1->num);
            scanf("%lf", &p1->score);
        }
        else
        {
            break;
        }
        if(i==0)
        {
            p2=head=p1;
        }
        else
        {
            p2->next=p1;
            p1->next=NULL;
            p2=p1;
        }
        i++;
        n=i;
    }while(p1);
    return(head);
}
void delete(struct student *head,int i)
{
    struct student *p=head,*q;
    int j=0;
    while(p&&j<i-1)
    {
        p=p->next;
        j++;
    }
    q=p->next;
    p->next=q->next;
    free(q);
}
int main()
{
    struct student *head,*p;
    head=creat();
    p=head;
    double sum=0,average;
    int i=0;
    do                                                
    {
        sum=sum+p->score;
        p=p->next;
        i++;                                          
    }while(i<n);
    p=head;
    average=sum/n;
    int k=0;
    for(i=0;i<n;i++)
    {
        if(p==NULL)
        {
            break;
        }
        if(p->score<average)
        {
            delete(head,k);
            i=0;
            p=head;
            k=0;
        }
        p=p->next;
        k++;
    }
    p=head;
    for(i=0;i<n;i++)
    {
        if(p!=NULL) {
            printf("%s\n", p->name);
            p=p->next;
        }
    }
    return 0;
}

注意:至少对于CLion来说,如果你直接输入数据运行的话,系统是不会给出

“信号: SIGSEGV (Segmentation fault)”这个信号的,只是很有可能代码正常退出然而什么也不会输出,此时调试是至关重要的了,调试过程中可以看到每一步的数据动态变化,并且会清楚指明上述信号发生在哪一句,帮你更快而精确的找到bug。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值