当看完题目时感觉很简单,没想到折腾一天才搞好........让我泪奔........怎么老是WA,终于在第五次AC了![]()
![]()
![]()
总结原因就是C语言结构,链表,指针,当这些东西混合在一起很容易出错,往往一个段溢出错误要找半天,找到最后原来是自己的逻辑错误,分配了无效的指针,这就是折腾一天的教训,看来C语言指针真的很重要,功底不扎实就是容易出错!!!!
这是第一种情况的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define COUNT 25
char s1[4]="move";
char s2[4]="pile";
char s3[4]="quit";
char s4[4]="onto";
char s5[4]="over";
char s6[20];
typedef struct Block_Problem
{
char n;
struct Block_Problem *next, *prev;
}BLOCK;
BLOCK *Point[COUNT], *p;
void BlockNum(BLOCK **a,BLOCK **b)
{
int i=0;
while(s6[i]!='\0')
{
if(s6[i]>='0' && s6[i]<='9')
{
if(*a == NULL)
*a=p+(s6[i]-48);
else *b=p+(s6[i]-48);
}
i++;
}
}
void moveTo()
{
BLOCK *a=NULL, *b=NULL, *p1=NULL;
BlockNum(&a,&b);
p1=a;
if(a->prev != NULL)
(a->prev)->next=NULL;
a->prev=NULL;
while(p1->next !=NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
p1=b;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void moveOver()
{
BLOCK *a=NULL, *b=NULL, *p1=NULL;
BlockNum(&a,&b);
p1=a;
if(a->prev != NULL)
(a->prev)->next=NULL;
a->prev=NULL;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
while(b->next != NULL)
{
b=b->next;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void pileTo()
{
BLOCK *a=NULL, *b=NULL, *p1=NULL;
BlockNum(&a,&b);
if(a->prev != NULL)
(a->prev)->next=NULL;
p1=b;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void pileOver()
{
BLOCK *a=NULL, *b=NULL, *p1=NULL;
BlockNum(&a,&b);
if(a->prev != NULL)
(a->prev)->next=NULL;
while(b->next != NULL)
b=b->next;
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void Print(int n)
{
int i=0;
BLOCK *p=NULL;
for(i=0;i<n;i++)
{
printf("%d:",i);
if(Point[i]!=NULL)
{
printf(" %d",Point[i]->n);
p=Point[i]->next;
while(p!=NULL)
{
printf(" %d",p->n);
p=p->next;
}
}
printf("\n");
}
}
int Legal()
{
BLOCK *a=NULL, *b=NULL, *p1=NULL;
BlockNum(&a,&b);
if(a->n == b->n)
return 0;
else
{
p1=a;
while(p1->next != NULL)
{
p1=p1->next;
if(p1->n == b->n)
return 0;
}
while(a->prev != NULL)
{
a=a->prev;
if(a->n == b->n)
return 0;
}
}
return 1;
}
int main()
{
int n=0,i=0;
while(scanf("%d",&n)!=EOF)
{
memset((void*)Point,0,sizeof(Point));
p=(BLOCK*)malloc(n*sizeof(BLOCK));
for(i=0; i<n; i++)
{
Point[i]=p+i;
Point[i]->n=i;
Point[i]->next=NULL;
Point[i]->prev=NULL;
}
i=0;
while(gets(s6))
{
if(i ==0)
{
i++;
continue;
}
if(strncmp(s6,s3,4)==0)
break;
if(Legal()==0)
continue;
if(strncmp(s6,s1,4)==0)
{
if(strncmp(s6+7,s4,4)==0)
moveTo();
else if(strncmp(s6+7,s5,4)==0)
moveOver();
}
else if(strncmp(s6,s2,4)==0)
{
if(strncmp(s6+7,s4,4)==0)
pileTo();
else if(strncmp(s6+7,s5,4)==0)
pileOver();
}
}
Print(n);
free(p);
}
return 0;
}第二种AC的代码(跟上一个代码比较,就是我在输入过程中只用了一种输入方式,两种不同的读入数据方式有可能导致的错误)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define COUNT 26
typedef struct Block_Problem
{
char n;
struct Block_Problem *next, *prev;
}BLOCK;
int n;
BLOCK *Point[COUNT], *p;
void moveTo(int a1, int b1)
{
BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
p1=a;
if(a->prev != NULL)
(a->prev)->next=NULL;
a->prev=NULL;
while(p1->next !=NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
p1=b;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void moveOver(int a1, int b1)
{
BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
p1=a;
if(a->prev != NULL)
(a->prev)->next=NULL;
a->prev=NULL;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
while(b->next != NULL)
{
b=b->next;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void pileTo(int a1, int b1)
{
BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
if(a->prev != NULL)
(a->prev)->next=NULL;
p1=b;
while(p1->next != NULL)
{
p1=p1->next;
Point[p1->n]=p1;
(p1->prev)->next=NULL;
p1->prev=NULL;
}
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void pileOver(int a1, int b1)
{
BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
if(a->prev != NULL)
(a->prev)->next=NULL;
while(b->next != NULL)
b=b->next;
b->next=a;
Point[a->n]=NULL;
a->prev=b;
}
void Print()
{
int i=0;
BLOCK *p=NULL;
for(i=0;i<n;i++)
{
printf("%d:",i);
while(Point[i]!=NULL)
{
printf(" %d",Point[i]->n);
Point[i]=Point[i]->next;
}
printf("\n");
}
}
int Legal(int a1, int b1)
{
BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
if(a->n == b->n)
return 0;
else
{
p1=a;
while(p1->next != NULL)
{
p1=p1->next;
if(p1->n == b->n)
return 0;
}
while(a->prev != NULL)
{
a=a->prev;
if(a->n == b->n)
return 0;
}
}
return 1;
}
void init()
{
int i;
memset((void*)Point,0,sizeof(Point));
for(i=0; i<n; i++)
{
Point[i]=p+i;
Point[i]->n=i;
Point[i]->next=NULL;
Point[i]->prev=NULL;
}
}
int main()
{
char s1[5], s2[5];
int a,b;
int i=0;
scanf("%d",&n);
p=(BLOCK*)malloc(n*sizeof(BLOCK));
init();
while(scanf("%s",s1) && s1[0] != 'q')
{
scanf("%d%s%d",&a,s2,&b);
if(Legal(a,b)==0)
continue;
if(s1[0]=='m' && s2[1]=='n')moveTo(a,b);
if(s1[0]=='m' && s2[1]=='v')moveOver(a,b);
if(s1[0]=='p' && s2[1]=='n')pileTo(a,b);
if(s1[0]=='p' && s2[1]=='v')pileOver(a,b);
}
Print();
free(p);
return 0;
}
本文分享了一位程序员在使用C语言进行编程时遇到的问题,特别是涉及结构、链表和指针时的挑战。通过一系列代码实例,作者详细解释了如何避免常见的错误,如段溢出、无效指针分配等,并强调了C语言中指针使用的重要性。此外,还对比了两次尝试解决问题的不同方法,揭示了输入数据方式对程序正确性的影响。
524

被折叠的 条评论
为什么被折叠?



