函数内对形参的操作并不能影响实参,函数内修改的是实参的副本。要想在函数内部修改输入参数,要么传入的是实参的引用,要么传入的是实参的地址。
#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_gnawinit_node_by_referenceToPointer
单链表逆置后
wang_shi_huiafter destory tmp= 0
no data to display---------------------
单链表逆置前
987654321init_node_by_pointerToPointer
单链表逆置后
123456789after destory tmp= 0
no data to display
*************************************************/