| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1313 人关注过本帖
标题:前辈帮忙指导,里面的程序有些问题想请教
只看楼主 加入收藏
kin3z
Rank: 5Rank: 5
等 级:职业侠客
威 望:4
帖 子:157
专家分:390
注 册:2011-4-24
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:9 
前辈帮忙指导,里面的程序有些问题想请教
程序代码:

#include <stdio.h>
#include <stdlib.h>

struct sdu_info{
    int number;    //学号
    int sex;    //0为男,1为女
    int age;    //年龄
    int class;    //班级代码
    int counter;    //成绩分数
    struct sdu_info * next;    //节点指针
};

typedef struct sdu_info Sdu;    //Sdu链表
typedef Sdu * SduPtr;    //Sdu链表指针

int input(int i);
void set(int i,SduPtr *head,SduPtr *last);
void add(SduPtr *head,SduPtr *last);
void List(SduPtr head);
//以下的函数可否用函数指针来处理,请前辈指教
SduPtr chake(int data,int i,SduPtr head,SduPtr last);
SduPtr ck01(int data,SduPtr head,SduPtr last);
SduPtr ck02(int data,SduPtr head,SduPtr last);
SduPtr ck03(int data,SduPtr head,SduPtr last);
SduPtr ck04(int data,SduPtr head,SduPtr last);
SduPtr ck05(int data,SduPtr head,SduPtr last);

//以下函数有问题。
void del(SduPtr *head,SduPtr *last);

int main(int argc, char **argv)
{
    SduPtr head = NULL;    //头元素地址
    SduPtr last = NULL;    //最后元素地址
    int i = 0;    //流程控制码
    
    do {
//        printf("in main head = %p , last = %p\n",head,last);
        set(input(i),&head,&last);
        List(head);
    }while(1);
    
    return 0;
}

//输入增加、删除操作码
int input(int i){
    printf("1 is add , 2 is del , input your select : ");
    do {
        scanf("%d",&i);
    }while(i!=1 && i!=2);
    return i;
}

//接收操作码后的操作
void set(int i,SduPtr *head,SduPtr *last){
    switch (i){
        case 1:
            add(head,last);
            break;
        case 2:
            del(head,last);
            break;
        default:
            printf("select error !\n");
            break;
    }
}

//实现添加链表
void add(SduPtr *head,SduPtr *last){
    SduPtr p = (SduPtr)malloc(sizeof(Sdu));
    
    //申请失败则提示并返回
    if ( p == NULL){
        printf("malloc cache is NULL , error!\n");
        return;
    }
    
    //申请成功,录入新数据
    printf("input your mouber :");
    scanf("%d",&p->number);
    printf("input sex (0 man , 1 wuman):");
    scanf("%d",&p->sex);
    printf("input your age :");
    scanf("%d",&p->age);
    printf("input your class :");
    scanf("%d",&p->class);
    printf("input counter :");
    scanf("%d",&p->counter);
    
    //每次都从head重新计算last的地址
    *last = *head;
    
    //插入新数据p
    if (*head == NULL){    //表空的操作
        *head = p;
        *last = p;
        (*head)->next = NULL;
    }else{                    //表不为空的操作
        if ((*head)->next == NULL){    //表不空,但只有表头1个数据的操作
            (*head)->next = p;
            *last = p;
            (*last)->next = NULL;
        }else{
            do {                        //很多数据,则重新计算生成last的地址并链接新数据
                *last = (*last)->next;
            }while((*last)->next != NULL);
            (*last)->next = p;
            *last = p;
        }
    }
//    printf("in add head = %p , last = %p , p = %p\n",*head,*last,p);
}

//按选择的类型与其值来搜索删除数据
void del(SduPtr *head,SduPtr *last){
    SduPtr p , now1 , now2 ;
    int i , data;
    
    //数据为null返回
    if (*head == NULL){
        printf("link node is NULL, no data .\n");
        return ;
    }
    
    //否则操作录入要删除的资料
    printf("1 del number , 2 del sex , 3 del age , 4 del class ,5 del counter .\n");
    printf("input your del type num : ");
    scanf("%d",&i);
    printf("input your del data value : ");
    scanf("%d",&data);

    //检查是否存在要删除的数组,有则接收其指针p,无则NULL
    p = chake(data,i,*head,*last);
    
    //操作查询返回的结果p
    now1 = *head;
    now2 = *head;
    
    if (p == NULL){
        printf("no your find DATA , error !\n");
    }else{
        if(now1->next == NULL){
            *head = NULL;
        }else{
            do {
                now2 = now2->next;
                if (now2 == p){
                    now1->next = now2->next;
                    free(now2);
                    break;
                }
                now1 = now2;
            }while(now2->next != NULL);
        }
    }
}

SduPtr chake(int data,int i,SduPtr head,SduPtr last){
    SduPtr p;
    switch (i){
        case 1:
            p = ck01(data,head,last);
            break;
        case 2:
            p = ck02(data,head,last);
            break;
        case 3:
            p = ck03(data,head,last);
            break;
        case 4:
            p = ck04(data,head,last);
            break;
        case 5:
            p = ck05(data,head,last);
            break;
    }
    return p;
}

SduPtr ck01(int data,SduPtr head,SduPtr last){
    SduPtr i = head;
    do {
        if (i->number == data){
            break;
        }
        i = i->next;
    }while(i->next != NULL);
    if (i == last){
        i = NULL;
    }
    return i;
}

SduPtr ck02(int data,SduPtr head,SduPtr last){
    SduPtr i = head;
    do {
        if (i->sex == data){
            break;
        }
        i = i->next;
    }while(i->next != NULL);
    if (i == last){
        i = NULL;
    }
    return i;
}
SduPtr ck03(int data,SduPtr head,SduPtr last){
    SduPtr i = head;
    do {
        if (i->age == data){
            break;
        }
        i = i->next;
    }while(i->next != NULL);
    if (i == last){
        i = NULL;
    }
    return i;
}

SduPtr ck04(int data,SduPtr head,SduPtr last){
    SduPtr i = head;
    do {
        if (i->class == data){
            break;
        }
        i = i->next;
    }while(i->next != NULL);
    if (i == last){
        i = NULL;
    }
    return i;
}

SduPtr ck05(int data,SduPtr head,SduPtr last){
    SduPtr i = head;
    do {
        if (i->counter == data){
            break;
        }
        i = i->next;
    }while(i->next != NULL);
    if (i == last){
        i = NULL;
    }
    return i;
}

void List(SduPtr head){
    SduPtr i = head;
    if (i == NULL){
        printf("now is NULL\n");
    }else{
        do{
            printf("data ptr = %p , ",i);
            printf(
            "number %d,sex %d,age %d,class %d,counter %d.\n",
            i->number,i->sex,i->age,i->class,i->counter);
            i = i->next;
            printf("\n");
        }while(i != NULL);
    }
}

搜索更多相关主题的帖子: color 
2017-01-17 00:42
kin3z
Rank: 5Rank: 5
等 级:职业侠客
威 望:4
帖 子:157
专家分:390
注 册:2011-4-24
收藏
得分:0 
本人新手,今晚看了学生系统的贴,想试试制作,结果弄到了深夜。
del函数是有问题的,不过太晚不修了,望有兴趣的请连同建议或优化方案一并回复。

还有发代码的目的就是因为在以下部分及其以下的代码感觉很重复,可否用函数指针来优化代替?
p = chake(data,i,*head,*last);  //检查是否存在要删除的数组,有则接收其指针p,无则NULL

望高手指点,并提出意见。谢谢!
2017-01-17 01:01
ICU
Rank: 4
等 级:业余侠客
威 望:2
帖 子:92
专家分:268
注 册:2017-1-14
收藏
得分:0 
楼主的编程注释习惯很赞!此贴持续关注。
贴程序前,最好把题目要求和自己的编程思路说一下

//定义函数指针数组
SduPtr (*proa[])()={check,ck01,ck02,ck03,ck04,ck05};//第一个数组元素也许是NULL,根据楼主需要自行确定
//。。。
//调用
proa[i](...);
2017-01-17 07:16
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
感觉知道指针地址删除单向链表元素有点麻烦,因为要重头到尾遍历一遍链表~
试试改用双向链表~可以直接知道指针地址进行删除~

那个函数指针如果想丰富内容的话可以试试二维函数指针~这个可以实现简单的多级菜单功能~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-01-17 11:06
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
SduPtr ck01(int data,SduPtr head,SduPtr last);
SduPtr ck02(int data,SduPtr head,SduPtr last);
SduPtr ck03(int data,SduPtr head,SduPtr last);
SduPtr ck04(int data,SduPtr head,SduPtr last);
SduPtr ck05(int data,SduPtr head,SduPtr last);

这里可以改用typedef进行批量处理~声明就不会显得啰嗦或者出错了~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-01-17 11:09
kin3z
Rank: 5Rank: 5
等 级:职业侠客
威 望:4
帖 子:157
专家分:390
注 册:2011-4-24
收藏
得分:0 
统一回复:
3楼:
下午我尝试使用2楼建议的方法去试试。

4楼:
学习内容要求先学单向链表,所以就先耗着了。。。
至于函数类型的二维指针,有否更详细的例子代码或直接更新本代码给本人作为学习与参考 ,先谢!

5楼:
方法可行,我还没想到有这个方法,学习了,谢谢。
不过感觉还是治标不治本,对于编译器来说其实编码其实一样,目前函数类型的二维指针是最合适的,可惜本人没多用过,现在学。

最后:
纠结在使用函数类型的二维指针上,是因为这程序就是学习使用之一,但本人又对函数类型的二维指针应该到本程序的结构体里要如何实现毫无经验,因此求助,求得前辈们的宝贵经验成果而学之。最后再次谢谢大家的建议。
2017-01-17 11:27
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:10 
回复 6楼 kin3z
https://bbs.bccn.net/thread-473336-1-1.html

函数二维指针的参考代码~我自己写的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-01-17 11:35
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:10 
刚好闲下来,帮你看了下,做部分优化和修改:
1、class是c++的关键字,我现在用的是vc6,因此将class修改为class1后你的代码可在vc6上运行
2、你的输入没有退出选择,替你加了菜单选项,选择错误或0可退出
3、你结构体中元素类型相同,紧挨着定义,因此可用类似数组的方式操作,极大地简化代码,改正了del函数,其他无关函数通通删除
4、如果是我写这类链表,感觉应该更简明。
修改后代码如下,在vc6上简单测试通过,未做全面测试:
程序代码:
#include <stdio.h>
#include <stdlib.h>

struct sdu_info{
    int number;    //学号
    int sex;    //0为男,1为女
    int age;    //年龄
    int class1;    //班级代码
    int counter;    //成绩分数
    struct sdu_info * next;    //节点指针
};

typedef struct sdu_info Sdu;    //Sdu链表
typedef Sdu * SduPtr;    //Sdu链表指针

int input(int i);
void set(int i,SduPtr *head,SduPtr *last);
void add(SduPtr *head,SduPtr *last);
void List(SduPtr head);

//以下函数有问题。
void del(SduPtr *head,SduPtr *last);

int main(int argc, char **argv)
{
    int i;
    SduPtr head = NULL;    //头元素地址
    SduPtr last = NULL;    //最后元素地址
    while(i=input(i))
    {
        set(i,&head,&last);
        List(head);
    }
    
    return 0;
}

//输入增加、删除操作码
int input(int i){
    printf("1 is add , 2 is del , 0 exit\ninput your select  : ");
    i=0;
    scanf("%d",&i);
    return i;
}

//接收操作码后的操作
void set(int i,SduPtr *head,SduPtr *last){
    switch (i){
    case 1:
        add(head,last);
        break;
    case 2:
        del(head,last);
        break;
    default:
        printf("select error !\n");
        break;
    }
}

//实现添加链表
void add(SduPtr *head,SduPtr *last){
    SduPtr p = (SduPtr)malloc(sizeof(Sdu));
    
    //申请失败则提示并返回
    if ( p == NULL){
        printf("malloc cache is NULL , error!\n");
        return;
    }
    
    //申请成功,录入新数据
    printf("input your mouber :");
    scanf("%d",&p->number);
    printf("input sex (0 man , 1 wuman):");
    scanf("%d",&p->sex);
    printf("input your age :");
    scanf("%d",&p->age);
    printf("input your class1 :");
    scanf("%d",&p->class1);
    printf("input counter :");
    scanf("%d",&p->counter);
    p->next =NULL;
    //每次都从head重新计算last的地址
    *last = *head;
    
    //插入新数据p
    if (*head == NULL){    //表空的操作
        *head = p;
        *last = p;
        (*head)->next = NULL;
    }else{                    //表不为空的操作
        if ((*head)->next == NULL){    //表不空,但只有表头1个数据的操作
            (*head)->next = p;
            *last = p;
            (*last)->next = NULL;
        }else{
            do {                        //很多数据,则重新计算生成last的地址并链接新数据
                *last = (*last)->next;
            }while((*last)->next != NULL);
            (*last)->next = p;
            *last = p;
        }
    }
    //    printf("in add head = %p , last = %p , p = %p\n",*head,*last,p);
}

//按选择的类型与其值来搜索删除数据
void del(SduPtr *head,SduPtr *last){
    SduPtr p , now1 , now2 ;
    int i=0 , j,data,*n;
    
    //数据为null返回
    if (*head == NULL){
        printf("link node is NULL, no data .\n");
        return ;
    }
    
    //否则操作录入要删除的资料
    printf("1 del number , 2 del sex , 3 del age , 4 del class1 ,5 del counter ,0 exit.\n");
    printf("input your del type num : ");
    scanf("%d",&i);
    printf("input your del data value : ");
    scanf("%d",&data);
    if(i<1||i>5)return;     //同样增加退出的
    //检查是否存在要删除的数组,有则接收其指针p,无则NULL
    now1=*head;
    now2=NULL;
    while(now1!=NULL)
    {
        n=&now1->number ;  //由于接下来的结构体元素都是int变量,在内存中的顺序一致,等同数组操作
        if(n[i-1]==data)
        {//找到要删除的记录,做删除操作
            if(now2==NULL)*head=now1->next;
            else now2->next=now1->next;
            free(now1);
            break;
        }
        now2=now1;
        now1=now1->next;
    }
}

void List(SduPtr head){
    SduPtr i = head;
    if (i == NULL){
        printf("now is NULL\n");
    }else{
        do{
            printf("data ptr = %p , ",i);
            printf(
                "number %d,sex %d,age %d,class1 %d,counter %d.\n",
                i->number,i->sex,i->age,i->class1,i->counter);
            i = i->next;
            printf("\n");
        }while(i != NULL);
    }
}
2017-01-17 12:00
kin3z
Rank: 5Rank: 5
等 级:职业侠客
威 望:4
帖 子:157
专家分:390
注 册:2011-4-24
收藏
得分:0 
回复 8楼 xzlxzlxzl
对啊 ,我写得太长了,也很不简洁,最后结构体里的元素后期才发现单独应用很麻烦(选择类型删除哪里就开始抓狂了)。

所以我想看看 成熟的做法是如何实现的,以及代码风格是怎么样的,用以学习。
重申本人新手,敢于发代码并不因为认为了得,而是想勾起前辈们的兴趣,从而发出更好更漂亮的代码,好让本小白学习。谢谢!
2017-01-18 10:30
kin3z
Rank: 5Rank: 5
等 级:职业侠客
威 望:4
帖 子:157
专家分:390
注 册:2011-4-24
收藏
得分:0 
回复 7楼 九转星河
谢谢,学习&消化ing
2017-01-18 10:35
快速回复:前辈帮忙指导,里面的程序有些问题想请教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.039192 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved