(C++)函数参数传递中的一级指针和二级指针
主要內(nèi)容:
1、一級指針和二級指針
2、函數(shù)指針傳遞的例子
3、什么時候需要傳遞二級指針?
4、二級指針在鏈表中的使用
1、一級指針和二級指針
一級指針:即我們一般說的指針,就是內(nèi)存地址;
二級指針:指向指針的指針,就是地址的地址;
如:
int a=1;
int *p=&a; //p 為a變量的地址,通過*p可以得到a的值
int **q = &p;? //q為p指針的地址,通過**q可以得到a的值
2、函數(shù)指針傳遞的例子
程序1:
#include <stdio.h>void fun(int *p) {int b=100;p=&b; }int main() {int a=10;int *q;q=&a;printf("%d\n", *q);fun(q);printf("%d\n", *q);return 0; }運行結果:
10
10
程序2:
#include <stdio.h>void fun(int **p) {int b=100;*p = &b; }int main() {int a=10;int *q;q = &a;printf("%d\n", *q);fun(&q);printf("%d\n", *q);return 0; }運行結果:
10
100
程序3:
#include <stdio.h> #include <stdlib.h>void myMalloc(char *s) {s = (char *)malloc(100); }int main() {char *p=NULL;myMalloc(p);if (p == NULL) printf("P is not changed!\n");else {printf("P has been changed!\n");free(p);}return 0; }運行結果:
P is not changed!
程序4:
#include <stdio.h> #include <stdlib.h>void myMalloc(char **s) {*s = (char *)malloc(100); }int main() {char *p = NULL;myMalloc(&p);if (p == NULL) printf("P is not changed!\n");else {printf("P has been changed!\n");free(p);}return 0; }運行結果:
P has been changed!
?
3、什么時候需要傳遞二級指針?
通過上述例子,我們可以看到,在有些情況下,函數(shù)參數(shù)傳遞一級指針時,在函數(shù)體內(nèi)對指針做變動,也不會對原始指針產(chǎn)生變化,而傳遞二級指針時,則可以,這是為什么呢?
在傳遞一級指針時,只有對指針所指向的內(nèi)存變量做參數(shù)才是有效的;
在傳遞二級指針時,只有對指針的指向做改變才是有效的;
下面做簡單的分析:
在函數(shù)傳遞參數(shù)時,編譯器總會為每個函數(shù)參數(shù)制作一個副本,即拷貝;
例如:
void fun(int *p),指針參數(shù)p的副本為_p,編譯器使_p=p,_p和p指向相同的內(nèi)存空間,如果在函數(shù)內(nèi)修改了_p所指向的內(nèi)容,就會導致p的內(nèi)容也做相應的改變;
但如果在函數(shù)內(nèi)_p申請了新的內(nèi)存空間或者指向其他內(nèi)存空間,則_p指向了新的內(nèi)存空間,而p依舊指向原來的內(nèi)存空間,因此函數(shù)返回后p還是原來的p。
這樣的話,不但沒有實現(xiàn)功能,反而每次都申請新的內(nèi)存空間,而又得不到釋放,因為沒有將該內(nèi)存空間的地址傳遞出來,容易造成內(nèi)存泄露。
void fun(int **p),如果函數(shù)參數(shù)是指針的地址,則可以通過該參數(shù)p將新分配或新指向的內(nèi)存地址傳遞出來,這樣就實現(xiàn)了有效的指針操作。
如果覺得二級指針比較難理解,也可以通過函數(shù)返回值的形式來傳遞動態(tài)內(nèi)存(切記不能返回棧內(nèi)存),如:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include<stdio.h> #include<stdlib.h> ? char* myMalloc(){ ?????char?*s=(char*)malloc(100); ?????return?s; } ? int?main() { ?????char??*p=NULL; ?????p=myMalloc(); ?????if(p==NULL) ????????printf("P is not changed!\n"); ?????else{ ????????printf("P has been changed\n"); ????????free(p); ?????} ?????return?0; } |
知道了上述這些,就不難理解上面四個小程序的執(zhí)行結果了。
4、二級指針在鏈表中的使用
在鏈表或者樹的操作中,也需要用到二級指針,
比如創(chuàng)建鏈表的頭指針:
在初始化鏈表函數(shù)中,傳入頭指針,并在函數(shù)中為該指針分配空間,此時就應該使用二級指針,如void initLinklist(Node **head);
而在添加刪除結點的過程中,我們并沒有改變函數(shù)參數(shù)指針的指向,而是通過傳入的指針如Node *head,找到要刪除結點的位置,并未對該指針做改變,因此退出函數(shù)后,該指針無影響。
?
總結
以上是生活随笔為你收集整理的(C++)函数参数传递中的一级指针和二级指针的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git clone 所有远程分支
- 下一篇: redis 使用-hiredis库使用(