函数内对形参的操作并不能影响实参,函数内修改的是实参的副本。要想在函数内部修改输入参数,要么传入的是实参的引用,要么传入的是实参的地址。
#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 *************************************************/