资源描述
C++学习笔记
SkySeraph 2010-7-31 阅读整理
摘自:
:
#include <iostream>
using namespace std;
struct Book//定义一个结构体。 名字为book 由于结构体他默认都是共有的 所以不用写公开了
{
int num;
float price;
struct Book *next;//这里的BOOK就是 struck 类型的结构 。后面是一个指向book 的指针。而这个指针就可以访问到 book类或者book类的成员
};
void main()
{
Book x,y,z,*head,*p;
x.num=10000;
x.price=30.5f;//如果不说明为浮点型 那么他会默认为为双精度型。
y.num=20000;
y.price=24.2f;
z.num=30000;
z.price=16.7f;
head=&x;//让HEAD指针指向 book的第一个成员地址。也就是头节点
x.next=&y;//让x.next 指向下一个节点。
y.next=&z;
z.next=NULL;//由于z是最后一个节点 他下面已经没有了 所以要给他定义为空 说明下
p=head;
while (p!=NULL)//当P不等于 为结点 也就是 空的时候
{
cout<<p->num<<endl<<p->price<<endl;//输出数据
p=p->next;//调到下一节点 这样 x就会变成y。
}
}//这就是结构体链表
2:
#include <iostream>
using namespace std;
class Book//上一节是在结构体中的链接,而要改成类的 只需要把 struct 改成class就可以了
{
public://这里要申明公开
int num;
float price;
Book *next;//吧前面的strcut 去除就可以了
};
void main()
{
Book x,y,z,*head,*p;
x.num=10000;
x.price=30.5f;
y.num=20000;
y.price=24.2f;
z.num=30000;
z.price=16.7f;
head=&x;
x.next=&y;
y.next=&z;
z.next=NULL;
p=head;
while (p!=NULL)
{
cout<<p->num<<endl<<p->price<<endl;
p=p->next;
}
}
3:
#include <iostream>
using namespace std;
struct Book//动态分配:我们可以在需要下一结点的时候才来调用就是动态分配
{
int num;
float price;
struct Book *next;
};
void main()
{
int *p=malloc(sizeof(Book));//malloc 是创建一个需要多少空间的函数 sizeof 是获取book 的空间大小 这样就可以创建一个可以容纳book结构的空间
free(p);//free 相当于 delete.以上两行代码是C语言中的 标准函数库的调用格式
int *p=new Book;
delete p;//这里是C++的操作符 。他们是不同的 当然 C++中的 类的创建是不能用在C语言中去的。
}
4:
#include <iostream>
using namespace std;
class Book
{
public:
int num;
float price;
Book *next;
};
Book* head=NULL;//创建一个指向book的指针head 并且让它为空。避免误操作
Book* creat()
{
Book *p1,*p2;
p1=new Book;//开辟空间。必须留下不开辟空间就对他进行判断会出问题
/* 。教程上面的全部源代码包含以下操作,但是我发现很多都是重复的。所以直接把这里注释起来都可以了。这样可以以更好的方式运算。
head=p1;
p2=p1;//让他们指向的地址都是第一节点
cout<<"请输入图书的编号,以0结束。";
cin>>p1->num;//把输入的编号保存到这个指针里面
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>p1->price;
}
else
{
delete p1;//如果输入为0 就要删除和把其他指针都赋值为空。
p2=NULL;
p2->next=NULL;
head=NULL;
return head;//返回空。结束
}
while (p1->num!=0)//由于if的循环限制条件,我们必须要要创建一个没有限制的循环语句 所以用while
{
p2=p1;//吧p1赋值给 p2
p1=new Book;
cout<<"请输入图书的编号,以0结束。";
cin>>p1->num;
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>p1->price;
}
p2->next=p1;
}
*/
while (p1->num!=0)//由于if的循环限制条件,我们必须要要创建一个没有限制的循环语句 所以用while
{
p2=p1;//吧p1赋值给 p2
cout<<"请输入图书的编号,以0结束。";//这下面的没法动了。你如果还有更好的算法请发给我参考下。
cin>>p1->num;
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>p1->price;
}
p2->next=p1;//把p1的值赋给P2的下一结点
}
delete p1;
p2->next=NULL;
return head;
}
void main()
{
creat();
}/*这个例子只是演示。 如果不是链表。他就相当于是下面这个了
int a,b;
cin>>a
while (a!=0)
{
cout<<"请输如1:";
cin>>a;
cout<<"青输入2:";
cin>>b;
}*/
5:
#include <iostream>
#include <string>
using namespace std;
class Book
{
public:
int num;
float price;
Book *next;
};
Book* head=NULL;
bool check(string str)//该函数接受一个C++类型字符串。或者说是 string 的字符串。
{
for (int i=0;i<str.length();i++)//for循环的 str.length() 是取字符串的长度。 他有多长就 循环多少次。
if ((str[i]>'9'||str[i]<'0')&&(str[i]!='.'))//判断的依据是 大于9 小于0 都成立 或者不等于.的话 返回假否则返回真
{
return false;//有字符返回假
}
return true;//没有字符返回真
}
Book* creat()
{
Book *p1,*p2;
p1=new Book;
head=p1;
p2=p1;
cout<<"请输入图书的编号,以0结束。";
string str;//定义 一个str字符串用以接受用户的输入
cin>>str;
while (!check(str))//while中判断 因为 while默认为真 也就是1 所以我们要加个 ! 逻辑非 那么当他等于0 也就是为假的时候输出下面的信息
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;//再次接受输入。避免无法退出!
}
p1->num=atoi(str.c_str());//stoi 是c语言中的转换,用以把 字符串转换为整数。因为我们的图书价格和编号都是整数 所以要带入下面的语句中 ,必须进行转换,但是由于 stoi是C语言中的 而 string 是c++中的 所以我们还需要把 string 转换为c语言中的格式。str已经提供了一个 转换函数。就是 c_str()函数 但是我们知道 string 是一个对象 所以我们要以 对象名加.运算符来调用此函数 。而且 atoi函数会把字符串转换为整数 并且返回他的值 所以最终的格式就是这个了。
//cin>>p1->num;由于我们已经对这个p1->num 进行赋值 所以这里 不需要了!
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->price=atof(str.c_str());//由于atoi 是转换为整数 但是 这里是浮点型 所以我们 需要把atoi改成 atof
//cin>>p1->price;
}
else
{
delete p1;
p2=NULL;
p2->next=NULL;
head=NULL;
return head;
}
while (p1->num!=0)
{
p2=p1;
p1=new Book;
cout<<"请输入图书的编号,以0结束。";
cin>>str;
while (!check(str))//这里同样需要进行判断,不如他只会在第一个循环中判断后 以后就不进行判断了
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->num=atoi(str.c_str());
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->price=atof(str.c_str());
}
p2->next=p1;
}
delete p1;
p2->next=NULL;
return head;
}
void main()
{
creat();
}//在上面的例子中,如果输入字符 就会出现死循环,那是因为 while 无法对字符进行判断 所以才会导致死循环。为了解决这个问题,就要用这个例子来实现
6:
#include <iostream>
#include <string>
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 *p1,*p2;
p1=new Book;
head=p1;
p2=p1;
cout<<"请输入图书的编号,以0结束。";
string str;
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->num=atoi(str.c_str());
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->price=atof(str.c_str());
}
else
{
delete p1;
p2=NULL;
p2->next=NULL;
head=NULL;
return head;
}
while (p1->num!=0)
{
p2=p1;
p1=new Book;
cout<<"请输入图书的编号,以0结束。";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->num=atoi(str.c_str());
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
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<<"\t";
cout<<"图书价格:"<<head->price<<endl;
head=head->next;
}
}
void DeleteBook(Book *head,int num)
{
Book *l;
if (head->num==num)
{
l=head;
head=head->next;
::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;
}
head=head->next;
}
cout<<"搜索完毕,未找到要删除的编号。"<<endl;
}
void EndInsert(Book *head,int num,float price)//尾插法
{
Book *listinsert=new Book;
Book *l;
while (head)//遍历到节点的最后
{
l=head;
head=head->next;//到最后的时候 指针为0 他会一直从头节点HEAD一直循环到 0 为假的时候 这个时候就是最后一个节点了
}
l->next=listinsert;//让新空间赋值给 l.next 也就是创建的新空间让 l->next指向他。
listinsert->num=num;//开始传递编号和价格
listinsert->price=price;
listinsert->next=NULL;//由于listinsert 为最后一个节点,所以他下面已经没有节点。我们把他下一节点赋值为空。
}
void HeadInsert(Book *head,int num,float price)//头插法。
{
Book *listinsert=new Book;
listinsert->num=num;
listinsert->price=price;
listinsert->next=head;//让他的下一结点指向头节点
::head=listinsert;//让listinsert 变成头节点。
}
void Insert(Book *head,int num,float price)//中间插法。
{
Book *listinsert=new Book;
listinsert->num=num;
listinsert->price=price;
if (num<=head->num)//判断输入进来的编号是不是小于或者等于头节点的编号。
{
listinsert->next=head;
::head=listinsert;
return;//如果这个if语句成立。要退出,不然程序会继续向下运行会造成多插入。
}
Book *Temp=NULL;//定义一个指针,指针在没使用的时候要赋值为空
while ((num>head->num)&&(head->next!=NULL))//如果上面不成立,判断输入的节点是否大于头节点,并且他的下一结点不为空。
{
Temp=head;//表达式成立就让 头节点赋值给TEMP指针。
head=head->next;//并且让指针的下一结点赋值给头节点。
}
if (num>head->num)//判断插入的的节点是否大于下一个节点。 也就是上面 head赋值过来的节点。
{
head->next=listinsert;//满足就把 原来的head尾节点来next指针指向新节点 listinsert.这样listinsert就变成了尾节点。
}
else//其他情况就是插入的节点小于或等于下一个节点。
{
Temp->next=listinsert;//我们已知,temp保存的是上一节点的位置,而 head保存的是下一结点的位置。因此我们可以用temp的next指针指向新节点listinsert.
listinsert->next=head;
}
}
void main()
{
//Book *head=NULL;这一句需要注释掉,因为上面已经有了一个全局变量了 所以这里这个就是多余的 ,如果存在,删除第一条会使程序崩溃。
head=creat();
ShowBook(head);
int BookNum;
float BookPrice;
/* cout<<"请输入你想删除的图书编号:";这里为了演示中间插入所以注释起来了,只需要把注释删除就可以正常使用了。
cin>>BookNum;
DeleteBook(head,BookNum);
ShowBook(head);
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
HeadInsert(head,BookNum,BookPrice);
ShowBook(head);
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
EndInsert(head,BookNum,BookPrice);
ShowBook(head);*/
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
Insert(head,BookNum,BookPrice);
ShowBook(head);
}//这个就是头插法和尾插法以及中间插法。也就是在链表的尾部或者头部以及中间插法插入数据。
以上代码如果是用 VC2008的话 会出现警告 解决方法如下:
第一点:for(int i=0;i<str.length();i++)这个警告是由符号和无符号不匹配。int是有符号长整型,str.length()是size_t型,在32位的系统上就是DWORD。
改法:for(size_t i=0;i<str.length();i++)
第二点:p1->price=atof(str.c_str());
float和double是两种类型,float占4个字节,double占8个.atof返回的是double,你的price定义的是float。
改法:1.可以把price的类型改成double,
2.还可以强制转换p1->price=(float)atof(str.c_str());
7:
#include <iostream>
#include <string>
using namespace std;
class Book
{
public:
int num;
float price;
Book *next;
};
Book* head=NULL;
bool check(string str)
{
for(size_t i=0;i<str.length();i++)//这个警告是由符号和无符号不匹配。int是有符号长整型,str.length()是size_t型,在32位的系统上就是DWORD。
if ((str[i]>'9'||str[i]<'0')&&(str[i]!='.'))
{
return false;
}
return true;
}
Book* creat()
{
Book *p1,*p2;
p1=new Book;
head=p1;
p2=p1;
cout<<"请输入图书的编号,以0结束。";
string str;
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->num=atoi(str.c_str());
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->price=(float)atof(str.c_str());//atof 返回值是 double 不是float 所以要强制转换!
}
else
{
delete p1;
p2=NULL;
//p2->next=NULL;这里要去掉。因为 p1已经被删除了 p2也被赋值空也不存在。所以p2调用next是非法的。会出现内存错误。应为p2指向了一个不存在的指针。具体你只需要测试下 在输入1调用重建,在把编号输入0 确定。 这就是第二个模块 中对空链表的处理
head=NULL;
return head;
}
while (p1->num!=0)
{
p2=p1;
p1=new Book;
cout<<"请输入图书的编号,以0结束。";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
p1->num=atoi(str.c_str());
if (p1->num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出:"<<endl;
cin>>str;
}
p1->price=(float)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<<"\t";
cout<<"图书价格:"<<head->price<<endl;
head=head->next;
}
}
void DeleteBook(Book *head,int num)
{
Book *l;
if (head->num==num)
{
l=head;
head=head->next;
::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;
}
head=head->next;
}
cout<<"搜索完毕,未找到要删除的编号。"<<endl;
}
void EndInsert(Book *head,int num,float price)
{
Book *listinsert=new Book;
Book *l;
while (head)
{
l=head;
head=head->next;
}
l->next=listinsert;
listinsert->num=num;
listinsert->price=price;
listinsert->next=NULL;
}
void HeadInsert(Book *head,int num,float price)
{
Book *listinsert=new Book;
listinsert->num=num;
listinsert->price=price;
listinsert->next=head;
::head=listinsert;
}
void Insert(Book *head,int num,float price)
{
Book *listinsert=new Book;
listinsert->num=num;
listinsert->price=price;
if (num<=head->num)
{
listinsert->next=head;
::head=listinsert;
return;
}
Book *Temp=NULL;
while ((num>head->num)&&(head->next!=NULL))
{
Temp=head;
head=head->next;
}
if (num>head->num)
{
head->next=listinsert;//注意这里
listinsert->next=NULL;//当插入的图书为尾节点时。那么尾节点的下一节就并没有指向空,所以当遍历到这里的时候 会引起程序崩溃。所以要把尾节点指向为空。
}
else
{
Temp->next=listinsert;
listinsert->next=head;
}
}
int GetBookNum(Book *head)//统计链表的个数。
{
int num=0;
while (head)//循环,他会一直循环 直到head的为0 或者空的时候 才退出这个循环
{
num++;//每执行一次 num都加 1
head=head->next;//跳入下一个节点。
}
return num;
}
int main(void)//使用标准的C++ MAIN函数头。
{
/* head=creat();
ShowBook(head);
int BookNum;
float BookPrice;
cout<<"请输入你想删除的图书编号:";
cin>>BookNum;
DeleteBook(head,BookNum);
ShowBook(head);
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
HeadInsert(head,BookNum,BookPrice);
ShowBook(head);
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
EndInsert(head,BookNum,BookPrice);
ShowBook(head);
cout<<"请输入你想插入的编号:";
cin>>BookNum;
cout<<"请输入图书的价格:";
cin>>BookPrice;
Insert(head,BookNum,BookPrice);
ShowBook(head);
cout<<"一共有图书:"<<GetBookNum(head)<<endl;*/
string str;
begin://标号。以前说过 一般配合 goto使用 他会无条件跳转到 标号处。
cout<<"1->重建图书,2->显示图书,3->插入图书,4->删除图书,5->图书数目,q->退出:";
cin>>str;
if (str[0]=='1')//用数组来判断 如果是输入的1 因为是字符 所以要引号
{
::head=creat();//调用 creat 函数 并且他有一个返回值 返回给 全局变量head。如果不返回 那么你将无法使用这个函数。
system("cls");//system 是系统,就是调用系统的命令 cls cls是清屏的意思。
goto begin;//执行完毕后 跳转到 begin.
}
else if (str[0]=='2')
{
if (head==NULL)//判断是否为空 为空就没法显示了。
{
cout<<"你的图书现在为空,请输入后在调用此命令。"<<endl<<"按回车键返回。"<<endl;
cin.get();//这里是接受用户输入,但是我们这里用他的作用是暂停的意思。
cin.get();//因为如果我们不适用的话 那么清屏命令会直接执行 而导致我们看不到上面的提示。
system("cls");
goto begin;
}
ShowBook(head);
}
else if (str[0]=='3')
{
int num;
float price;
if (head==NULL)//和上面一样
{
cout<<"你的图书现在为空,请输入后在调用此命令。"<<endl<<"按回车键返回。"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}
else
{
cout<<"请输入要插入的图书编号,以0结束。";//复制到 creat 函数中的代码 只需要修改一下 num和price 为变量即可。用于判断用户输入的值
string str;
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
num=atoi(str.c_str());
if (num!=0)
{
cout<<"请输入图书的价格:";
cin>>str;
while (!check(str))
{
cout<<"你输入的不是数值。按0退出。"<<endl;
cin>>str;
}
price=(float)atof(str.c_str());
}
else
{
system("cls");
goto begin;
}
Insert(head,num,price);
cout<<"操作成功,按回车键返回主程序。"<<endl;
}
}
else if (str[0]=='4')//赋值节点3
{
int num;
if (head==NULL)
{
cout<<"你的图书现在为空,请输入后在调用此命令。"<<endl<<"按回车键返回。"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}
else
{
cout<<"请输入要删除的图书编号,以0结束。";//该成删除
string str;
cin>>str;
w
展开阅读全文