CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

奇怪哉,一个链表的问题

楼主kaneboy(.Net)2002-05-05 22:19:25 在 C/C++ / C语言 提问

我写了一个链表的C程序,原意是可以把新的项目插入到链表的后面,但是我发现如果插入一个新值,那么程序会更改链表中前面元素的值,大家可以在TC2里面运行一下,就可以发现这个问题。  
   
  #include   <stdio.h>  
  #include   <stdlib.h>  
   
  struct   LinkItem{  
          char   *   sName;  
          struct   LinkItem   *   pLinkItem;  
  };  
   
  void   printLink(struct   LinkItem   *   pStart);  
  void   insertItem(struct   LinkItem   *   pStart,   const   char   *   sNewName);  
   
  int   main()  
  {  
  int   choice   =   0;  
          char   *   sNewName;  
  struct   LinkItem   *   pStart;  
   
  system("CLS");  
  pStart->sName   =   "kaneboy";  
  pStart->pLinkItem   =   NULL;  
   
  while(choice!=4){  
  printf("Please   select:\n");  
  printf("1:Insert   an   item.\n");  
  printf("2:Delete   an   item.\n");  
  printf("3:Print   the   link.\n");  
  printf("4:Exit.\n");  
  scanf("%d",&choice);  
  switch(choice){  
  case   1:  
  printf("Enter   the   name   of   new   item:");  
  scanf("%s",sNewName);  
  insertItem(pStart,sNewName);  
  break;  
  case   3:  
  printLink(pStart);  
  break;  
  }  
  }  
          return   0;  
  }  
   
  void   printLink(struct   LinkItem   *   pStart){  
          struct   LinkItem   *   pTemp;  
          int   iItemCount   =   0;  
  pTemp   =   pStart;  
  printf("----------------------------------\n");  
          while(pTemp   !=   NULL){  
  printf("%d:%s\n",++iItemCount,(*pTemp).sName);  
                  pTemp   =   pTemp->pLinkItem;  
  }  
  printf("----------------------------------\n");  
  }  
   
  void   insertItem(struct   LinkItem   *   pStart,   const   char   *   sNewName){  
  struct   LinkItem   *   newItem;  
  struct   LinkItem   *   pTemp;  
  struct   LinkItem   *   pTemp2;  
  newItem   =   malloc(sizeof(struct   LinkItem));  
  newItem->sName   =   sNewName;  
  newItem->pLinkItem   =   NULL;  
  pTemp   =   NULL;  
  pTemp2   =   pStart;  
  while(pTemp2   !=   NULL){  
  pTemp   =   pTemp2;  
  pTemp2   =   pTemp->pLinkItem;  
  printf("After   %s\n",pTemp->sName);  
          }  
  pTemp->pLinkItem   =   newItem;  
          return   0;  
  } 问题点数:50、回复次数:15Top

1 楼steedhorse(晨星)回复于 2002-05-05 22:46:55 得分 0

你怎么还没给pStart分配空间就给它的成员赋值,不出内存错误已经很侥幸了。Top

2 楼zhwangquan(聪明的大傻瓜)回复于 2002-05-05 22:49:06 得分 0

有些错误在TC下发现不了Top

3 楼kaneboy(.Net)回复于 2002-05-05 23:21:45 得分 0

改了一下,还是一样的问题:  
   
  #include   <stdio.h>  
  #include   <stdlib.h>  
   
  struct   LinkItem{  
          char   *   sName;  
          struct   LinkItem   *   pLinkItem;  
  };  
   
  typedef   struct   LinkItem   *   PLinkItem;  
   
  void   printLink(PLinkItem);  
  void   insertItem(PLinkItem   *,   char   *);  
   
  int   main()  
  {  
  int   choice   =   0;  
          char   *   sNewName;  
  PLinkItem   pStart   =   NULL;  
   
  system("CLS");  
   
  while(choice!=4){  
  printf("Please   select:\n");  
  printf("1:Insert   an   item.\n");  
  printf("2:Delete   an   item.\n");  
  printf("3:Print   the   link.\n");  
  printf("4:Exit.\n");  
  scanf("%d",&choice);  
  switch(choice){  
  case   1:  
  printf("Enter   the   name   of   new   item:");  
  scanf("%s",sNewName);  
  insertItem(&pStart,sNewName);  
  break;  
  case   3:  
  printLink(pStart);  
  break;  
  }  
  }  
          return   0;  
  }  
   
  void   printLink(PLinkItem   pS){  
  PLinkItem   pTemp;  
  pTemp   =   pS;  
  printf("----------------------------------\n");  
          while(pTemp   !=   NULL){  
  printf("%s   --   ",pTemp->sName);  
                  pTemp   =   pTemp->pLinkItem;  
  }  
  printf("\n----------------------------------\n");  
  }  
   
  void   insertItem(PLinkItem   *   ppS,   char   *   sNN){  
  PLinkItem   newItem,   pTemp,   pTemp2;  
  newItem   =   malloc(sizeof(PLinkItem));  
  newItem->sName   =   sNN;  
  newItem->pLinkItem   =   NULL;  
  pTemp   =   NULL;  
  pTemp2   =   *ppS;  
  printf("\n");  
  while(pTemp2   !=   NULL){  
  printf("%s   --   ",pTemp->sName);  
  pTemp   =   pTemp2;  
  pTemp2   =   pTemp->pLinkItem;  
  }  
  if(pTemp   ==   NULL){  
  newItem->pLinkItem   =   *ppS;  
  *ppS   =   newItem;  
  }else{  
  pTemp->pLinkItem   =   newItem;  
  newItem->pLinkItem   =   pTemp2;  
  }  
          return   0;  
  }Top

4 楼zhwangquan(聪明的大傻瓜)回复于 2002-05-05 23:55:02 得分 0

#include   <stdio.h>  
  #include   <stdlib.h>  
   
  struct   LinkItem{  
          char   *   sName;  
          struct   LinkItem   *   pLinkItem;  
  };  
   
  typedef   struct   LinkItem   *   PLinkItem;  
   
  void   printLink(PLinkItem);  
  void   insertItem(PLinkItem   *,   char   *);  
   
  int   main()  
  {  
  int   choice   =   0;  
  PLinkItem   pStart=NULL;  
  char   *   sNewName=(char*)   malloc(sizeof(char)*256);  
  char   sNN[256]="";  
   
   
  system("CLS");  
   
  while(choice!=4){  
  printf("Please   select:\n");  
  printf("1:Insert   an   item.\n");  
  printf("2:Delete   an   item.\n");  
  printf("3:Print   the   link.\n");  
  printf("4:Exit.\n");  
  scanf("%d",&choice);  
  switch(choice){  
  case   1:  
  printf("Enter   the   name   of   new   item:");  
  scanf("%s",sNN);  
  sNewName=(char*)malloc(sizeof(char)*256);  
  strcpy(sNewName,sNN);  
  insertItem(&pStart,sNewName);  
  break;  
  case   3:  
  printLink(pStart);  
  break;  
  }  
  }  
          return   0;  
  }  
   
  void   printLink(PLinkItem   pS){  
  PLinkItem   pTemp;  
  pTemp   =   pS;  
  printf("----------------------------------\n");  
          while(pTemp   !=   NULL){  
  printf("%s   --   ",pTemp->sName);  
                  pTemp   =   pTemp->pLinkItem;  
  }  
  printf("\n----------------------------------\n");  
  }  
   
  void   insertItem(PLinkItem   *   ppS,   char   *   sNN){  
  PLinkItem   newItem,   pTemp,   pTemp2;  
  newItem   =   (PLinkItem)malloc(sizeof(PLinkItem));  
  newItem->sName   =   sNN;  
  newItem->pLinkItem   =   NULL;  
  pTemp   =   NULL;  
  pTemp2   =   *ppS;  
  printf("\n");  
  while(pTemp2   !=   NULL){  
  pTemp   =   pTemp2;  
  pTemp2   =   pTemp->pLinkItem;  
  }  
  if(pTemp   ==   NULL){  
  newItem->pLinkItem   =   *ppS;  
  *ppS   =   newItem;  
  }else{  
  pTemp->pLinkItem   =   newItem;  
  newItem->pLinkItem   =   pTemp2;  
  }  
  }  
  //有意思每次输入的都会覆盖原来的,试试这个Top

5 楼collin_tj(collin)回复于 2002-05-06 00:19:07 得分 0

1。   应该   #include<string.h>  
    2.     输入到第4个ITEM时,出现死循环!!Top

6 楼kaneboy(.Net)回复于 2002-05-06 00:20:12 得分 0

这个程序肯定有一个很大的bug,但是我就是找不出来!Top

7 楼esc8888(esc8888)回复于 2002-05-06 00:50:21 得分 0

是不是函数用指向指针的指针传递出现的问题?  
  Top

8 楼esc8888(esc8888)回复于 2002-05-06 00:54:33 得分 0

而且在最尾端插入的那段我也不能理解Top

9 楼kaneboy(.Net)回复于 2002-05-06 00:58:17 得分 0

if(pTemp   ==   NULL){  
  newItem->pLinkItem   =   *ppS;  
  *ppS   =   newItem;  
  }else{  
  pTemp->pLinkItem   =   newItem;  
  newItem->pLinkItem   =   pTemp2;  
  }  
  的意思是如果这个链表是空的,那么新值就放在链表的第一位,如果链表不是空的,就放在最尾端。  
   
  Top

10 楼skyfine(柳荣宏)回复于 2002-05-06 01:06:30 得分 5

我是一个初学者,我有一个问题:  
       
      char   s[]="str",*p;  
      p=s;  
      这显然是可以的。  
      当s[]的值发生改生时,p的值的指向也当然发生的改变.  
      newItem->sName   =   sNN  
      应该说语法上没有什么错误。  
      但strcpy()的实质又是什么呢?为什么不用strcpy()呢?这两个语句是否等同.(我想不是这样的吧!)Top

11 楼fang_jb(寂寞如雪)回复于 2002-05-06 01:26:56 得分 45

void   insertItem(PLinkItem   *   ppS,   char   *   sNN){  
  PLinkItem   newItem,   pTemp,   pTemp2;  
  newItem   =   (PLinkItem)malloc(sizeof(PLinkItem));  
  /*这里的问题是PLinkItem被你typedef成struct   LinkItem   *了,怎么可以这样分配?*/  
  newItem->sName   =   sNN;  
  /*结构里的数据用指针指的话,如果sNN地址的值变了你怎么办?为什么不是拷贝过来呢?*/  
  newItem->pLinkItem   =   NULL;  
  pTemp   =   NULL;  
  pTemp2   =   *ppS;  
  printf("\n");  
  while(pTemp2   !=   NULL){  
  pTemp   =   pTemp2;/*???你想干什么?这里如果是要记住上一个节点的内容的话,那下面的pTemp==NULL怎么会成立?*/  
  pTemp2   =   pTemp->pLinkItem;  
  }  
  /*这个循环应该始终保证了pTemp的非空,pTemp应该记住了最后一个非空指针的地址*/  
  if(pTemp   ==   NULL){  
  newItem->pLinkItem   =   *ppS;  
  *ppS   =   newItem;  
  }else{  
  pTemp->pLinkItem   =   newItem;  
  /*这里也不能使用=号,newItem的生存期只在这个函数里,应该把它拷贝给ppS,然后free掉*/  
  newItem->pLinkItem   =   pTemp2;  
  /*你又想干什么?*/  
  }  
  }  
   
  不客气的说,我觉得你这里很混乱,  
  至少一般的链表程序通常会有一个static指针来记录头指针的位置,  
  从而在操作的时候总是有一个遍历的起点,malloc的时候应该小心一点,  
  更不可以不malloc,就拿着指针到处指,我觉得你应该先看看写链表程序  
  通常的做法,不然头想破了也不知道bug在哪的。  
   
  另外,问一下,这个程序真的不会core掉吗?Top

12 楼kaneboy(.Net)回复于 2002-05-06 08:21:04 得分 0

对于上面各位疑问,请大家看一下deitel写的《C   How   to   program》里面的例程:  
   
  /*   Operating   and   maintaining   a   list   */  
  #include   <stdio.h>  
  #include   <stdlib.h>  
   
  struct   listNode   {     /*   self-referential   structure   */  
        char   data;  
        struct   listNode   *nextPtr;  
  };  
   
  typedef   struct   listNode   LISTNODE;  
  typedef   LISTNODE   *LISTNODEPTR;  
   
  void   insert(LISTNODEPTR   *,   char);  
  char   delete(LISTNODEPTR   *,   char);  
  int   isEmpty(LISTNODEPTR);  
  void   printList(LISTNODEPTR);  
  void   instructions(void);  
   
  main()  
  {  
        LISTNODEPTR   startPtr   =   NULL;  
        int   choice;  
        char   item;  
   
        instructions();     /*   display   the   menu   */  
        printf("?   ");  
        scanf("%d",   &choice);  
   
        while   (choice   !=   3)   {  
   
              switch   (choice)   {  
                    case   1:  
                          printf("Enter   a   character:   ");  
                          scanf("\n%c",   &item);  
                          insert(&startPtr,   item);  
                          printList(startPtr);  
                          break;  
                    case   2:  
                          if   (!isEmpty(startPtr))   {  
                                printf("Enter   character   to   be   deleted:   ");  
                                scanf("\n%c",   &item);  
   
                                if   (delete(&startPtr,   item))   {  
                                      printf("%c   deleted.\n",   item);  
                                      printList(startPtr);  
                                }  
                                else  
                                      printf("%c   not   found.\n\n",   item);  
                          }  
                          else  
                                printf("List   is   empty.\n\n");  
   
                          break;  
                    default:  
                          printf("Invalid   choice.\n\n");  
                          instructions();  
                          break;  
              }  
   
              printf("?   ");  
              scanf("%d",   &choice);  
        }  
   
        printf("End   of   run.\n");  
        return   0;  
  }  
   
  /*   Print   the   instructions   */  
  void   instructions(void)  
  {  
        printf("Enter   your   choice:\n"  
                      "       1   to   insert   an   element   into   the   list.\n"  
                      "       2   to   delete   an   element   from   the   list.\n"  
                      "       3   to   end.\n");  
  }  
   
  /*   Insert   a   new   value   into   the   list   in   sorted   order   */  
  void   insert(LISTNODEPTR   *sPtr,   char   value)  
  {  
        LISTNODEPTR   newPtr,   previousPtr,   currentPtr;  
   
        newPtr   =   malloc(sizeof(LISTNODE));  
   
        if   (newPtr   !=   NULL)   {         /*   is   space   available   */  
              newPtr->data   =   value;  
              newPtr->nextPtr   =   NULL;  
   
              previousPtr   =   NULL;  
              currentPtr   =   *sPtr;  
   
              while   (currentPtr   !=   NULL   &&   value   >   currentPtr->data)   {  
                    previousPtr   =   currentPtr;                     /*   walk   to   ...       */  
                    currentPtr   =   currentPtr->nextPtr;     /*   ...   next   node   */  
              }  
   
              if   (previousPtr   ==   NULL)   {  
                    newPtr->nextPtr   =   *sPtr;  
                    *sPtr   =   newPtr;  
              }  
              else   {  
                    previousPtr->nextPtr   =   newPtr;  
                    newPtr->nextPtr   =   currentPtr;  
              }  
        }  
        else  
              printf("%c   not   inserted.   No   memory   available.\n",   value);  
  }  
   
  /*   Delete   a   list   element   */  
  char   delete(LISTNODEPTR   *sPtr,   char   value)  
  {  
        LISTNODEPTR   previousPtr,   currentPtr,   tempPtr;  
   
        if   (value   ==   (*sPtr)->data)   {  
              tempPtr   =   *sPtr;  
              *sPtr   =   (*sPtr)->nextPtr;     /*   de-thread   the   node   */  
              free(tempPtr);                           /*   free   the   de-threaded   node   */  
              return   value;  
        }  
        else   {  
              previousPtr   =   *sPtr;  
              currentPtr   =   (*sPtr)->nextPtr;  
   
              while   (currentPtr   !=   NULL   &&   currentPtr->data   !=   value)   {  
                    previousPtr   =   currentPtr;                     /*   walk   to   ...       */  
                    currentPtr   =   currentPtr->nextPtr;     /*   ...   next   node   */  
              }  
   
              if   (currentPtr   !=   NULL)   {  
                    tempPtr   =   currentPtr;  
                    previousPtr->nextPtr   =   currentPtr->nextPtr;  
                    free(tempPtr);  
                    return   value;  
              }                                                                                                                  
        }  
   
        return   '\0';  
  }  
   
  /*   Return   1   if   the   list   is   empty,   0   otherwise   */  
  int   isEmpty(LISTNODEPTR   sPtr)  
  {  
        return   sPtr   ==   NULL;  
  }  
   
  /*   Print   the   list   */  
  void   printList(LISTNODEPTR   currentPtr)  
  {  
        if   (currentPtr   ==   NULL)  
              printf("List   is   empty.\n\n");  
        else   {  
              printf("The   list   is:\n");  
   
              while   (currentPtr   !=   NULL)   {  
                    printf("%c   -->   ",   currentPtr->data);  
                    currentPtr   =   currentPtr->nextPtr;  
              }  
   
              printf("NULL\n\n");  
        }  
  }Top

13 楼kaneboy(.Net)回复于 2002-05-06 08:27:31 得分 0

我发现了问题所在:  
   
  问题诚如上面的朋友说的,字符串的赋值应该用strcpy,  
  我把“newItem->sName   =   sNN;”改用“strcpy()”实现就OK了!  
   
  但是对于fang_jb(小方)朋友说这个程序其他的问题,我不觉得,大家可以看  
  一下上面deitel在他们写的很有名的C   how   to   program里面的例程,我的程序  
  的基本思路是沿用他们的程序的。Top

14 楼huwei_008(写程序就跟开极品飞车一样,得不停的追,不停的开,不停的写啦!)回复于 2002-05-06 09:17:23 得分 0

同意建议看"c   how   to   program"(机械工业出版社出版)   这本,不过动手最重要!Top

15 楼diaopeng(放飞自己)回复于 2002-05-06 09:22:12 得分 0

应该用地址或strcpy()Top

相关问题

  • 历遍链表的问题~~~~奇怪了~~~~
  • 奇怪的链接出错.
  • 奇怪的报表问题?
  • 奇怪的数组列表?
  • VB报表的奇怪问题
  • 一个奇怪的注册表问题。。。
  • 新建表的问题,很奇怪?
  • 有关水晶报表:好奇怪呀!!~~~~~~~~
  • 一个奇怪的表达式
  • 创建表出现奇怪问题

关键词

  • 指针
  • plinkitem
  • ptemp
  • pstart
  • snewname
  • newitem
  • snn
  • printlink
  • startptr
  • choice

得分解答快速导航

  • 帖主:kaneboy
  • skyfine
  • fang_jb

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo