在线等,c++简单问题。。。。急!

#include<iostream>usingnamespacestd;classbook{public:intnum;floatprice;book*next;};bo... #include <iostream>
using namespace std;
class book
{
public:
int num;
float price;
book *next;
};

book*head=NULL; //为什么要声明这个全局变量?

bool check(string str) //检查用户输出是否为字符
{
for(int i=0;i<str.length();i++)
{
if((str[i]>'9' || str[i]<'0') && (str[i]!='.'))
return false;
}
return true;
}

book *creat() //返回book类的指针
{
book *p1,*p2;
p1=new book;
head=p1;
p2=p1;
cout<<"请输出图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str()); //str调用类成员函数c_str把输入的string字符串转化成字

符数组型,再由atoi转化成整数型。
//c_str()成员函数返

回的是*char类型的临时指针,要把返回值赋给某变量名应该用strcpy函数
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str()); //atof会把字符串转化成浮点型数值
}
else
{
delete p1;
p1=NULL;
head=NULL;
return head;
}
while(p1->num!=0)
{
p2=p1;
p1=new book;
cout<<"请输出图书的编号,以0结束"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str());
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str());
}
p2->next=p1;
}
delete p1;
p2->next=NULL;
return head;
}

void showbook(book *head)
{
cout<<endl;
cout<<"图书信息如下:"<<endl;
while(head)
{
cout<<"图书编号:"<<head->num<<"价格:"<<head->price<<endl;
head=head->next;
}

}

void Delete(book *head,int num)
{
book *l;
if(head->num==num)
{
l=head;
head=head->next;
::head=head; //赋给全局的head;
delete l;
cout<<"操作成功"<<endl;
return;
}
while(head)
{
if(head->next==NULL)
{
cout<<"找不到要删除的编号."<<endl;
return;
}
if(head->next->num==num)
{
l=head->next;
head->next=l->next;
delete l;
cout<<"操作成功"<<endl;
return;
}
head=head->next;
}
cout<<"找不到要删除的编号."<<endl;
}

int main()
{
book *head;
head=creat();
showbook(head);
showbook(head);
cout<<"请输入你要删除的图书编号"<<endl;
int booknum;
cin>>booknum;
Delete(head,booknum);
showbook(head);
return 0;
}
--------------------------------------------分割线------------------------------------
删除编号为1的结点后,再调用showbook函数程序输入一个错误编号和价格,程序崩溃。
问题二,main函数里定义的*head作为参数传入creat和showbook函数里是按地址传送的吧?在creat里用new申请的结点空间是需要用delete来回书的吧,不会是子函数调用结束用new申请的空间也会自动回收?

问题三,showbook子函数里的head=head->next为什么不会出错?作为链表的头结点,指向一个节点,前一个结点不是丢了吗?c++与c语言在某些特性上差别很大吗?
展开
 我来答
nbda1121440
2010-08-19 · TA获得超过409个赞
知道小有建树答主
回答量:274
采纳率:0%
帮助的人:150万
展开全部
首先要指出一点,你的程序并没有用到头结点,所以在Delete函数中删除了第一个结点导致主函数中链表没有没有了头,因此程序崩溃,最好的办法是引入头结点

不好意思,貌似程序还有问题,我再修改一下

这回应该对了
最主要的还是Delete函数的问题,当然不用头结点也是可以做的,但有头结点更简单一些,下面是我修改的程序

#include <iostream>
#include <string>
using namespace std;
class book
{
public:
int num;
float price;
book *next;
};

/*定义这个全局变量只是为了在creat()这个函数中使用head时不用再声明类型罢了*/
//book*head=NULL; //为什么要声明这个全局变量?
/*所以我删了这个全局变量*/

bool check(string str) //检查用户输出是否为字符
{
for(int i=0;i<str.length();i++)
{
if((str[i]>'9' || str[i]<'0') && (str[i]!='.'))
return false;
}
return true;
}

book *creat() //返回book类的指针,
{
book *p1,*p2;
p1=new book;
book *head=p1;
/**************头结点后面那个结点才开始存储数据*************/
p1->next = new book;
p1 = p1->next;
/**************头结点后面那个结点才开始存储数据*************/
p2=p1;
cout<<"请输出图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str());
//str调用类成员函数c_str把输入的string字符串转化成字符数组型,再由atoi转化成整数型。
//c_str()成员函数返回的是*char类型的临时指针,要把返回值赋给某变量名应该用strcpy函数
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str()); //atof会把字符串转化成浮点型数值
}
else
{
delete p1;
p1=NULL;
head=NULL;
return head;
}
while(p1->num!=0)
{
p2=p1;
p1=new book;
cout<<"请输出图书的编号,以0结束"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str());
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str());
}
p2->next=p1;
}
delete p1;
p2->next=NULL;
return head;
}

void showbook(book *head)
{
cout<<endl;
cout<<"图书信息如下:"<<endl;
/**************head是头结点,head后面一个结点才有数据***********************/
head = head->next;
/**************head是头结点,head后面一个结点才有数据***********************/
while(head)
{
cout<<"图书编号:"<<head->num<<"价格:"<<head->price<<endl;
head=head->next;
}
}

/*********使用头结点后,Delete函数修改*************************/
void Delete(book *head,int num)
{
book *l;
if(head->next->num==num)
{
l=head->next;
head->next=head->next->next;
// ::head=head; //赋给全局的head;
delete l;
cout<<"操作成功"<<endl;
return;
}
while(head)
{
if(head->next==NULL)
{
cout<<"找不到要删除的编号."<<endl;
return;
}
if(head->next->num==num)
{
l=head->next;
head->next=l->next;
delete l;
cout<<"操作成功"<<endl;
return;
}
head=head->next;
}
cout<<"找不到要删除的编号."<<endl;
}

int main()
{
book *head;
head=creat();
showbook(head);
// showbook(head);
cout<<"请输入你要删除的图书编号"<<endl;
int booknum;
cin>>booknum;
Delete(head,booknum);
showbook(head);
return 0;
}
yulinlin12345
2010-08-19
知道答主
回答量:4
采纳率:0%
帮助的人:0
展开全部
c/c++是按值传递的...
问题1:delete删除首结点后,showbook还是从head首结点开始打印.
问题2/3:传值...

附:修改后的程序
#include <cstdlib>
#include <iostream>
using namespace std;
class book
{
public:
int num;
float price;
book *next;
};

book*head=NULL; //为什么要声明这个全局变量?

bool check(string str) //检查用户输出是否为字符
{
for(int i=0;i<str.length();i++)
{
if((str[i]>'9' || str[i]<'0') && (str[i]!='.'))
return false;
}
return true;
}

book *creat() //返回book类的指针
{
book *p1,*p2;
p1=new book;
head=p1;
p2=p1;
cout<<"请输出图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str()); //str调用类成员函数c_str把输入的string字符串转化成字
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str()); //atof会把字符串转化成浮点型数值
}
else
{
delete p1;
p1=NULL;
head=NULL;
return head;
}
while(p1->num!=0)
{
p2=p1;
p1=new book;
cout<<"请输出图书的编号,以0结束"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str());
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str());
}
p2->next=p1;
}
// delete p1;
p2->next=NULL;
return head;
}

void showbook(book *head)
{
cout<<endl;
cout<<"图书信息如下:"<<endl;
while(head)
{
cout<<"图书编号:"<<head->num<<"价格:"<<head->price<<endl;
head=head->next;
}

}

void Delete(book **head,int num)
{
book *l;
if((*head)->num==num)
{
l=*head;
*head=(*head)->next;
::head=*head; //赋给全局的head;
delete l;
cout<<"操作成功"<<endl;
return;
}
while(*head)
{
if((*head)->next==NULL)
{
cout<<"找不到要删除的编号."<<endl;
return;
}
if((*head)->next->num==num)
{
l=(*head)->next;
(*head)->next=l->next;
delete l;
cout<<"操作成功"<<endl;
return;
}
*head=(*head)->next;
}
cout<<"找不到要删除的编号."<<endl;
}

int main(void)
{
book *head;
head=creat();
showbook(head);
showbook(head);
cout<<"请输入你要删除的图书编号"<<endl;
int booknum;
cin>>booknum;
Delete(&head,booknum);
showbook(head);
return 0;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
lk8823
推荐于2016-07-29
知道答主
回答量:28
采纳率:0%
帮助的人:0
展开全部
问题出在Delete时的head传递上,修改如下:

class book
{
public:
int num;
float price;
book *next;
};

book*head=NULL; //为什么要声明这个全局变量?

bool check(string str) //检查用户输出是否为字符
{
for(int i=0;i<str.length();i++)
{
if((str[i]>'9' || str[i]<'0') && (str[i]!='.'))
return false;
}
return true;
}

book *creat() //返回book类的指针
{
book *p1,*p2;
p1=new book;
head=p1;
p2=p1;
cout<<"请输出图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str()); //str调用类成员函数c_str把输入的string字符串转化成字

//符数组型,再由atoi转化成整数型。
// //c_str()成员函数返

// 回的是*char类型的临时指针,要把返回值赋给某变量名应该用strcpy函数
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str()); //atof会把字符串转化成浮点型数值
}
else
{
delete p1;
p1=NULL;
head=NULL;
return head;
}
while(p1->num!=0)
{
p2=p1;
p1=new book;
cout<<"请输出图书的编号,以0结束"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->num=atoi(str.c_str());
if(p1->num!=0)
{
cout<<"请输入图书的价格"<<endl;
cin>>str;
while(!check(str))
{
cout<<"输入的不是数字,请重新输入,按0返回!!";
cin>>str;
}
p1->price=atof(str.c_str());
}
p2->next=p1;
}
delete p1;
p2->next=NULL;
return head;
}

void showbook(book *head)
{
cout<<endl;
cout<<"图书信息如下:"<<endl;
while(head)
{
cout<<"图书编号:"<<head->num<<"价格:"<<head->price<<endl;
head=head->next;
}

}

book *Delete(book *head,int num)
{
book *l;
if(head->num==num)
{
l=head;
head=head->next;
//::head=head; //赋给全局的head;
delete l;
cout<<"操作成功"<<endl;
return head;
}
while(head)
{
if(head->next==NULL)
{
cout<<"找不到要删除的编号."<<endl;
return head;
}
if(head->next->num==num)
{
l=head->next;
head->next=l->next;
delete l;
cout<<"操作成功"<<endl;
return head;
}
head=head->next;
}
cout<<"找不到要删除的编号."<<endl;
return head;
}

int main()
{
book *head;
head=creat();
showbook(head);
showbook(head);
cout<<"请输入你要删除的图书编号"<<endl;
int booknum;
cin>>booknum;
head=Delete(head,booknum);
showbook(head);
return 0;
}

函数内部会形成一个head的副本,就是说你给进来参数*head,但实际上函数内部的所有操作实际是对head的副本"head"(它不是真正的head,只是二者指向同一个位置)进行操作的。如果改变"head"的指向,原始的head并不会被改变,只是副本的head被指向另外的位置。
另外new的内存,一定要delete,子函数结束不会自己释放的
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
huangkehan
2010-08-19 · TA获得超过111个赞
知道答主
回答量:52
采纳率:0%
帮助的人:72.6万
展开全部
我最喜欢在线等的问题了
现在解答问题三:
void showbook(book *head)
该函数是传值,传指针的值,

所以在函数里会生成一个局部指针变量head,它的值等于传入的head指针,在函数里对head的操作不会影响传入的head

比如你在函数内加上
cout<<&head;
在main函数里加上
cout<<&head;

看看这两个变量是不是同一个地址
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式