QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1099|回复: 10

单链表的返回值问题。

[复制链接]
发表于 2004-5-28 13:58:48 | 显示全部楼层 |阅读模式
在find_lklist()子程序中,如何返回要查找的结点。且在主程序能正确显示其值。能不能出了子程序return p;主程序p= find_lklist()外其他方法,如我这种方法。在参数中直接返回。

[code:1]
/*带头结点的单链表*/
#include <stdio.h>

typedef struct node
{
  int data;
  struct node *next;
} lklist;

int main (void)
{
  lklist *head, *p;
  int input;
  int output;
  int count;
  printf("请输入一些数字(0为结束):");
  initiate_lklist(&head);
  create_lklist(&head);
  print_lklist(&head);
  printf("请输入要查找的序号:");
  scanf("%d", &input);
  find_lklist(&head, input, &p);
  printf("第%d号的值为%d\n", input, *p);
  printf("请输入要查找的值:");
  scanf("%d", &input);
  locate_lklist(&head, input, &output);
  printf("该值%d的位置是%d\n", input, output);
}

int initiate_lklist (lklist **head)
{
  (*head) = (lklist *) malloc (sizeof(lklist));
  (*head) -> next = NULL;
}

int create_lklist (lklist **head)
{
  lklist *new, *end;
  int x;
  end = *head;
  scanf("%d", &x);
  while (x != 0)
    {
      new = (lklist *) malloc (sizeof(lklist));
      new -> data = x;
      end -> next = new;
      end = new;
      scanf("%d", &x);
    }
  end -> next = NULL;
}

int print_lklist (lklist **head)
{
  lklist *p;
  int j = 1;
  p = *head;
  printf("最新的排列:");
  if ((*head) != NULL)
    {
      p = p -> next;
      while (p != NULL)
        {
          printf("(%d):", j);
          j++;
          printf("%d ", p -> data);
          p = p -> next;
        }
    }
  printf("\n");
}

int find_lklist (lklist **head, int i, lklist *p)
{
  int j = 0;
  p = *head;
  while ((p -> next != NULL) && (j < i))
    {
      p = p -> next;
      j++;
    }
  if (i == j)
    return 1;   
  else
    {
      printf("该位置不存在!\n");
      return 0;
    }
}

int locate_lklist (lklist **head, int x, int *output)
{
  lklist *p;
  int j = 0;
  p = *head;
  while ((p -> next != NULL) && (p -> data != x))
    {
      p = p -> next;
      j++;
    }
  if (p -> data == x)
    {
     *output = j;
     return 1;
    }
  else
    {
      printf("\n该值不存在!\n");
      return 0;
    }
}


[/code:1]
发表于 2004-5-28 15:14:48 | 显示全部楼层
lklist *head, *p;
....
printf("第%d号的值为%d\n", input, *p);


?
回复

使用道具 举报

发表于 2004-5-28 21:02:49 | 显示全部楼层
[quote:0a98a49b64="Ivn"]
lklist *head, *p;
....
printf("第%d号的值为%d\n", input, *p);

?[/quote]同样疑问
回复

使用道具 举报

 楼主| 发表于 2004-5-28 21:19:11 | 显示全部楼层
倒~就是这里有问题才问的啊.求解决方法.
回复

使用道具 举报

发表于 2004-5-29 14:38:44 | 显示全部楼层
lluct,我注意你很久了!

很少看到像你这样认认真真学习、踏踏实实实践的人。PFPF。
回复

使用道具 举报

发表于 2004-5-31 23:18:38 | 显示全部楼层
在你的代码中指针用法有误,该用"指针的指针"时你却使用了"指针",而该用"指针"的地方你却用了"指针的指针"!

在函数initiate_lklist()、create_lklist()、print_lklist()和locate_lklist()中,第一个参数应该使用指针,声明为lklist *head(而不应使用指针的指针lklist **head!),在调用函数时直接以指针调用如initiate_lklist(head),而不用&head。注意,尽管按你的用法最终的运行结果也是一样的,但这种隐含的错误还是应该改掉。

而接下来的错误则是导致程序运行结果有误的主要原因,即在find_lklist()函数中没有正确地使用(指针的)指针,所以在本函数内部打印p->data正常而出了函数外则p->data即变成了1474660693这样的数值! 试想如果你要在函数内要改动外部整数变量的值,那么就应该传递该变量的指针来完成,而在此你要做的是改动外部指针变量的值,所以应该传递给函数的是指针的指针!此函数应该改成:
[code:1]
int find_lklist(lklist *head,int i,lklist **p)
{
    int j = 0;
    *p = head;
    while( ( (*p)->next != NULL ) && ( j<i) ) {
        (*p) = (*p)->next;
        j++;
    }
    if( i == j)retrun 1;
    else {
        printf("该位置不存在!\n");
        return 0;
    }
}
[/code:1]

调用时应该写成find_lklist(head,input,&p);printf("第%号的值为%d\n",input,p->data);  这样就可以得到正确的结果了。按常规来讲,最好还是返回符合项的指针,而不要传递指针到函数内部修改来得到结果,那样的话代码晦涩难懂又易出错。
回复

使用道具 举报

发表于 2004-5-31 23:45:28 | 显示全部楼层
另外,代码不太规范,要多阅读好的代码并常练习之,以形成好的编程风格。比如print_lklist()函数可以优化如下:
[code:1]
int print_lklist(lklist *head)
{
    lklist *p;
    int i = 1;
    p = head->next;
    printf("最新的排列:");
    while (p) {
        printf("(%d)%d ",i,p->data);
        p = p->next;
        i++;
    }
    printf("\n");
}
[/code:1]

调用为print_lklist(head); (注意前面已经改过的代码,这里不要再用&head了。)
这里开始时就让p=head->next,因为你的代码中在构造链表时第一个元素的data并无赋值,本语句将使p指向首个含data有效数值的元素。在链表头多出这样一个data空数值项的元素是否有意为之并不清楚(因为在链首或链尾多做一个元素可能有作其它控制的用意),所以我没有去更改构造链表的算法。
回复

使用道具 举报

 楼主| 发表于 2004-5-31 23:50:14 | 显示全部楼层
谢谢了.
回复

使用道具 举报

发表于 2004-5-31 23:52:45 | 显示全部楼层
程序的第一行注释就已经提到这是带头结点的链表,头结点确实是有意加上的,呵呵,我只顾回复了,竟然没注意到这个细节,真不好意思了!

我也在南宁。有空可以联系我,E-mail:[email protected]
回复

使用道具 举报

 楼主| 发表于 2004-5-31 23:55:50 | 显示全部楼层
[quote:879450f1d5="lanche"]程序的第一行注释就已经提到这是带头结点的链表,头结点确实是有意加上的,呵呵,我只顾回复了,竟然没注意到这个细节,真不好意思了!

我也在南宁。有空可以联系我,E-mail:[email protected]。[/quote]
没事.您能抽空看.我已经感激不尽了.以后有问题希望还能问您啊.嘻嘻~
回复

使用道具 举报

发表于 2004-6-1 00:06:50 | 显示全部楼层
我开始时没仔细看代码,调试了好久才找到BUG的,所以说养成好的编程习惯很重要,别人容易阅读,自己维护也简单,尽量采用已经形成惯例代码写法,比如可以用while(p)的时候不要写成while(p!=NULL),对于链表查找应该要返回符合项的指针等,当然作其它尝试也是有益的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 06:06 , Processed in 0.043857 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表