注册 登录
编程论坛 C++教室

关于链表的一个问题

CooperOne 发布于 2012-02-05 19:17, 465 次点击
程序代码:
#include <iostream>
using namespace std;

class A
{
public:
    void get()
    {
        cout<<"a:";
        cin>>a;
        cout<<endl;
    }
    A *next;
    int a;
};
A *head=0;
void creat()
{   
    A *p1=new A;
    p1->next=0;
    A *p2;
    ::head=p1;
    int num;
    cout<<"以零结束"<<endl;
    cin>>num;
    while(num)
    {
        p1->get();
        p2=p1;
        A *p1=new A;
        p2->next=p1;
        cout<<"以零结束"<<endl;
        cin>>num;
    }
    p1->next=0;
}
void show(A *head)
{
    while(head)
    {
        cout<<head->a<<endl;
        if(head->next)
        {
            head=head->next;
        }
        system("pause");
    }
    return;
}
   
   
   
   
void main()
{
    creat();
    show(head);

}
那个....编译时是没问题的,但是运行时
1.最后只会显示最后一个结点的a值,然后一直显示一个随机数,但是所有指针都有指向了,要不就指向空地址,怎么会有随机指针呢?
2.其实和1差不多,即使一开始就输入0,一样会显示随机指针,怎么回事呢?
5 回复
#2
lz10919149992012-02-05 19:32
while(num)
    {
        p1->get();
        p2=p1;
        p1=new A;
        p2->next=p1;
        cout<<"以零结束"<<endl;
        cin>>num;
    }
#3
BianChengNan2012-02-06 09:25
特别喜欢楼上的头像,顶楼上
#4
CooperOne2012-02-06 09:43
回复 2楼 lz1091914999
这个和我原来的有什么区别么,不都是开辟新空间,用p1来指向新空间么
#5
CooperOne2012-02-06 09:50
回复 2楼 lz1091914999
还有一个问题-_-...就是我把最后一个结点的next指针指向空地址了,但为什么最后还是跳不出循环呢?一直在显示随机数....
#6
lz10919149992012-02-06 13:30
回复 5楼 CooperOne
你的程序在逻辑上面有些问题:
1、你在while之前定义了一个p1,然后在while里面定义了一个p1,导致外面的p1被隐藏:
程序代码:
void creat()
{  
    A *p1=new A; // (0)
    p1->next=0;
    A *p2; // (1)
    ::head=p1;
    int num;
    cout<<"以零结束"<<endl;
    cin>>num;
    while(num)
    {
        p1->get(); // (2)
        p2=p1; // (3)
        A *p1=new A; // (4)
        p2->next=p1; // (5)
        cout<<"以零结束"<<endl;
        cin>>num;
    }
    p1->next=0;
}
在while循环里,(2)这句代码都是给while外面定义的那个p1(0)调用get(),(3)然后再把while外面p1(0)的值赋给while外面的p2(1),(4)这句话在while里定义了一个与(0)一样名字的变量,导致(0)被隐藏,(5)又把(4)赋值给了p2的next字段,这样每次循环下去,都只是为p1调用get(),然后创建一个新的A再把它赋值给p1的next字段,所以p1并没有像楼主期望的那样指向末尾,原因可能就在(4),因为它不应该把外面的(0)隐藏了,它应该被赋值一个新的结点,这样每次p1都会指向末尾结点,所以要把(4)改为p1 = new A,前面不要有A *,这样就变成了定义,而不是重赋值。
2、show()因为那个if所以造成了逻辑错误:
程序代码:
void show(A *head)
{
    while(head)
    {
        cout<<head->a<<endl;
        if(head->next)
        {
            head=head->next;
        }
        system("pause");
    }
    return;
}
因为在while循环面里由于外面的p1被隐藏所以p1始终指向第一个结点,而最后你又把p1的next字段赋值为0,所以head->next为0,那么if (head->next) 测试失败,所以head=head->next;这句话不会被执行,这样就变成了无限循环,一直输出第一个结点,正确的代码是:
程序代码:
void show(A *head)
{
    while(head)
    {
        cout<<head->a<<endl;
        head=head->next;
        system("pause");
    }
    return;
}
根本不需要判断,为什么需要判断呢?其实这种逻辑错误也是我经常遇到的,主要原因就是你并没有设计你的程序,然后就开始写程序,也就是说你并没有在头脑中或在纸上把你需要解决的问题描述清楚,然后你就开始写代码了,这样就导致一系列的逻辑错误发生(我以前也是这样),除非这个问题足够简单(比如计算1 + 2 + 3 + ... + 99 + 100,一个循环就可以搞定),你可以很容易的把这个问题的解决方案在头脑中描述清楚,否则你必须设计之后才能写代码。你对C++语法了解也有所欠缺,建议你可以去学习C++ Primer或Thinking in C++,这2本书的作者都把C++语法的细节非常清楚的描述了一遍,我推荐这两本书。


1