主题:[讨论]用C写的串的链式存储表示,请帮我看一下错以哪里
kernxn [专家分:40] 发布于 2009-04-21 09:03:00
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<stdlib.h>
#define NULL 0
#define CHUNKSIZE 10
#define LEN sizeof(struct chun)
typedef struct chun
{
char *ch;
struct chun *next;
}chunk;
struct list
{
chunk *head,*tail;
int curlen;
}lstring;
int strlength(char *s)
{ //返回串s的长度
int i=0;
while(s[i++])
;
return i-1;
}
chunk *strcreat(char *s)
{ //对串s进行链式存储,每个结点默认为CHUNKSIZE,每个结点最后一个字符位存放'\0'
chunk *p1,*p2;
int cur=0,i;
lstring.curlen=0;
p1=p2=(chunk*)malloc(sizeof(LEN)); //开辟结点
p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);//开辟结点中存放串的空间
lstring.head=NULL;
for(i=0;i<strlength(s);i++,cur++)
{
if(cur==CHUNKSIZE-1)
{
if(lstring.head==NULL)
lstring.head=p1;
p1->ch[cur]='\0';
// printf("%s",p1->ch);
cur=0;
p2->next=p1;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN));
p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
}
p1->ch[cur]=s[i];
lstring.curlen++;
}
p1->ch[cur]='\0'; //最后一个结点的最后一个字符位存放'\0';
// printf("%s\n",p1->ch);
p1->next=NULL;
return lstring.head;
}
void print(chunk *head)
{ //打印链表
chunk *p;
p=head;
for(p=head;p!=NULL;p=p->next)
printf("%s,",p->ch);
printf("\n");
}
void main()
{
chunk *head;
char *s="abcdefghijklmnopqrstuvwxykwlqjfeioqpiurioewqjfklnwqioputz";
// printf("%s\n",s);
head=strcreat(s); //引用函数,对串s进行链式存储。
print(head);
}
运行输出时,老是提示出错,请帮我检验一下
最后更新于:2009-04-21 09:07:00
回复列表 (共9个回复)
沙发
sjl599 [专家分:70] 发布于 2009-04-21 13:30:00
改为:
if(cur==CHUNKSIZE-1)
{
if(lstring.head==NULL)
lstring.head=p1;
p1->ch[cur]='\0';
cur=0;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN));
p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
p2->next=p1;
}
板凳
kernxn [专家分:40] 发布于 2009-04-21 13:46:00
不错啊,
能不能解释一下这是为什么
以前学链表的时候老师好像是用那样写的。
可现在怎么不行了,
3 楼
sjl599 [专家分:70] 发布于 2009-04-21 15:14:00
p1要先把自己的地址赋给p2,,然后在给p1分配新的存储空间,并让p2->next指向这个新的p1;
4 楼
kernxn [专家分:40] 发布于 2009-04-21 15:41:00
p1=p2=(chunk*)malloc(sizeof(LEN)); //开辟结点
......
......
p2->next=p1;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN));
.......
把p2的尾针指向p1,并将p2指向新结点p1,接着再开辟新结点p1,
这样好像也可解释得通,
5 楼
kernxn [专家分:40] 发布于 2009-04-21 15:43:00
相比之下,你的写法不仅正确,而且更清晰
只是我不明白,以前正常的链表初始化方法现在用在串操作就不正常了
6 楼
kernxn [专家分:40] 发布于 2009-04-21 15:55:00
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define LEN sizeof(struct list)
struct list
{
int num;
struct list *next;
};
struct list *creat(void)
{
struct list *p1,*p2,*head=NULL;
p1=p2=(struct list*)malloc(LEN);
scanf("%d",&p1->num);
while(p1->num) //输入0表示结束
{
if(head==NULL)
head=p1;
p2->next=p1; //跟一楼一样的写法,但运行起来一点问题都没有
p2=p1; //有点想不通。
p1=(struct list*)malloc(LEN);
scanf("%d",&p1->num);
}
p2->next=NULL;
return head;
}
void print(struct list *head)
{
struct list *p;
for(p=head;p!=NULL;p=p->next)
printf("%d,",p->num);
}
main()
{
struct list *head;
head=creat();
print(head);
}
7 楼
sjl599 [专家分:70] 发布于 2009-04-21 19:58:00
p2->next=p1;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN));
当你如此操作的以后,你也许会以为p2->next的地址和p1的一样了,其实不然,p2->next和p2还是指向同一个值,即:p2==p2->next,而p1指向另一个新空间,可以说此时p1和p2没有联系.当循环再次执行的时候,因为有p2->next=p1,此时他们才会连接上.执行p2=p1后,p2->next变为野指针;依次类推:
当你执行最后一个数组的时候p1和链表并没有任何联系,而此时的p2->next是一个野指针;所以你的最后一个结构体并没有连上.
当你输出最后一个的时候,就会报内存不能为读的错误.
而楼上和你的程序的区别就是他并没有用最后一个.所以不会报错.
8 楼
kernxn [专家分:40] 发布于 2009-04-22 08:25:00
哈,,谢谢了,
茅塞顿开
9 楼
itkpz [专家分:90] 发布于 2009-05-08 13:53:00
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CHUNKSIZE 10
#define LEN sizeof(struct chun)
typedef struct chun
{
char *ch;
struct chun *next;
}chunk;
typedef struct list
{
chunk *head;
int curlen;
}lstring;
int strlength(char *s)
{ //返回串s的长度
int i=0;
while(s[i++]) ;
return i-1;
}
chunk *strcreat(char *s)
{ //对串s进行链式存储,每个结点默认为CHUNKSIZE,每个结点最后一个字符位存放'\0'
lstring *p; chunk *p1,*p2; int cur=0,i;
p=(struct list *)malloc(sizeof(struct list));
p->head=(chunk *)malloc(LEN); //头结点
p->curlen=0;
p2=p->head; //p2总指向表尾结点
p1=(chunk *)malloc(LEN); //p1总指向新生的结点
p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
for(i=0;i<strlength(s);i++,cur++)
{
if(cur==CHUNKSIZE-1) //如果到了串尾,赋予'\0'且生成新的结点
{
p1->ch[cur]='\0';
cur=0;
p2->next=p1; //p1链接到表尾
p2=p1; //p2移动下一个结点
p1=(chunk *)malloc(LEN);
p1->ch=(char *)malloc(sizeof(char)*CHUNKSIZE);
}
p1->ch[cur]=s[i];
p->curlen++;
}
p1->ch[cur]='\0'; //最后一个结点的最后一个字符位存放'\0';
p2->next=p1; //------注意:最后一个结点要链入表尾----------
p2=p1;
p2->next=NULL;
p1=NULL;
return p->head;
}
void print(chunk *head)
{ //打印链表
chunk *p;
for(p=head->next;p!=NULL;p=p->next)
printf("%s\n",p->ch);
printf("\n");
}
main()
{
chunk *head;
char *s="abcdefghijklmnopqrstuvwxykwlqjfeioqpiurioewqjfklnwqioputz";
printf("%d\n",strlength(s));
head=strcreat(s); //引用函数,对串s进行链式存储。
print(head);
system("pause");
}
我来回复