函数内对形参的操作并不能影响实参,函数内修改的是实参的副本。要想在函数内部修改输入参数,要么传入的是实参的引用,要么传入的是实参的地址。
#include <iostream>
#include <cstdlib>
#include <cstring>//strlen
using namespace std;
//template <class T>
class node
{
public:
node * next;
char data;
};
node *node_reverse(node *head)
{
//如果一个函数的输入参数有指针,一定要记住判断指针时候为空
//1>:在使用一个指针之前一定要判断它是否为空;
//2>:使用完后要释放由指针指向的存储单元
//3>:释放完存储单元后要将指针赋值为NULL;
if(head->next==NULL || head==NULL)
return head;
node* pPre=head; //先前指针
node* pCurrent=pPre->next; //当前指针
node* pNext=NULL; //后继指针
//要注意这里面的顺序,先将pNext保存在pCurrent中,
//然后再将pNext移动到下一个元素,然后才能改动pCurrent
//
while(pCurrent!=NULL)
{
pNext=pCurrent->next;
pCurrent->next=pPre;
pPre=pCurrent;
pCurrent=pNext;
}
head->next=NULL;
head=pPre;
return head;
}
/**************
void init_node(node *tail,char *init_array)
这样声明函数是不正确的,函数的原意是通过数组初始化链表
若链表结点传入的是指针,则并不能创建链表,除非是二维指针
即指向指针的指针
****************/
void init_node_by_referenceToPointer(node *&tail,const char *init_array)
{
node * tmp = NULL;
int j=strlen(init_array);
for(int i=0; i<j; i++)
{
tmp = new node;
tmp->data = *(init_array+i);
tmp->next = tail;
tail = tmp;
}
}
/***************************************
void init_node_by_referenceToPointer(node &*tail,char *init_array)
error: cannot declare pointer to 'class node&'
****************************************/
void init_node_by_pointerToPointer(node **tail,const char *init_array)
{
node * tmp = NULL;
int j=strlen(init_array);
for(int i=0; i<j; i++)
{
tmp = new node;
tmp->data = *(init_array+i);
tmp->next = *tail;
*tail = tmp;
}
}
void display(node *nn,char *print=NULL)
{
if(nn==NULL)
{
cout << "no data to display\n";
return ;
}
cout<<print;
node *dis = nn;
while(dis!=NULL)
{
cout << dis->data;
dis = dis->next;
}
}
//释放动态申请的空间
void distroy(node *nn)
{
if (nn==NULL)
{
return ;
}
while (nn!=NULL)
{
node *tmp = nn;
nn = nn->next;
delete tmp;
}
}
void test_by_referenceToPointer()
{
node *test = NULL;
char *test_array="wang_shi_hui";
init_node_by_referenceToPointer(test,test_array);
//如果输入参数是指向指针的引用
display(test,"单链表逆置前\n");
cout << "\n init_node_by_referenceToPointer" << endl;
node *tmp = node_reverse(test);
if(test==NULL)
exit(0);
display(tmp,"单链表逆置后\n");
//tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
//并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
distroy(tmp);//释放动态申请的内存
tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
test = NULL;
cout << "\n after destory tmp= " << tmp << endl;
//如果上面没有tmp = NULL;test = NULL;,display将会出错,
//因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,
//那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,
//这样就会出现异常.
display(test);
}
void test_by_pointerToPointer()
{
node *test = NULL;
char *test_array="123456789";
init_node_by_pointerToPointer(&test,test_array);
//如果输入参数是指向指针的指针
display(test,"单链表逆置前\n");
cout << "\n init_node_by_pointerToPointer" << endl;
node *tmp = node_reverse(test);
if(test==NULL)
exit(0);
display(tmp,"单链表逆置后\n");
//tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
//并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
distroy(tmp);//释放动态申请的内存
tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
test = NULL;
cout << "\n after destory tmp= " << tmp << endl;
//如果上面没有tmp = NULL;test = NULL;,display将会出错,
//因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,
//那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,
//这样就会出现异常.
display(test);
}
int main()
{
test_by_referenceToPointer();
cout<<"\n---------------------\n";
test_by_pointerToPointer();
}
/************************************************
单链表逆置前
iuh_ihs_gnaw
init_node_by_referenceToPointer
单链表逆置后
wang_shi_hui
after destory tmp= 0
no data to display
---------------------
单链表逆置前
987654321
init_node_by_pointerToPointer
单链表逆置后
123456789
after destory tmp= 0
no data to display
*************************************************/