指针作为函数形参
?
普通函數參數
下面程序試圖改變main函數中a和b的值
#include<stdio.h>
void fun(int x,int y)
{
???int c;
???c=a;
???a=b;
???b=c;
}
int main()
{
???int a=1,b=2;
???fun(a,b);
???printf("a=%d b=%d\n",a,b);
???return 0;
}
函數參數傳遞分析:
實參:
| &a 28ff18 | a? 1 |
| &b 28ff14 | b? 2 |
?
?
?
在將實參傳遞給形參的時候,編譯器將實參拷貝一份給形參。
拷貝份的特點為:
1) 值與實參相同
2) 地址與實參不同
拷貝份(形參)
| &x 28ff04 | x? 1 |
| &y 28ff00 | y? 2 |
?
?
?
則在函數內部更改拷貝份的時候,只是對函數內部的局部變量改變,而局部變量是存儲在棧空間里的,當fun函數執行結束后,這兩個變量會自動銷毀,不會改變實參的數值。
?
一級指針作為函數參數
下面程序試圖改變main函數中a和b的值
#include<stdio.h>
void fun(int *a,int *b)
{
???int c;
???c=*a;
???*a=*b;
???*b=c;
}
int main()
{
???int *a,*b;
???int x=1,y=2;
???a=&x;
b=&y;
fun(a,b);
???printf("a=%d b=%d\n",x,y);
???return 0;
}
函數參數傳遞分析
?
main中變量的存儲情況如下
?
| 變量地址 | 變量值 |
| &x: 28ff18 | x:1 |
| &y: 28ff14 | y:2 |
| 指針變量地址 | 指針變量內容 | 指針表示地址里的內容 |
| &a:28ff28 | a: &x | *a:? x |
| &b:28ff24 | b: &y | *b:? y |
?
?
?
?
?
可見在main函數中,指針a和b的地址為28ff28,28ff24。而指針a和b存儲的內容為x和y的地址28ff18、28ff14。*a,*b則是代表x和y變量的值。
當調用fun函數時。main中的指針a和b則要拷貝一份給fun函數的形參。則形參的存儲情況如下:
| 形參指針變量地址 | 形參指針變量內容 | 形參指針變量存儲的地址表示的內容 |
| &a:28f740 | a: 28ff18 | *a:? x |
| &b:28f736 | b: 28ff14 | *b:? y |
?
?
?
?
?
?
?
可見:把實參指針變量傳遞給形參后。
實參指針和形參指針的地址是不相同的。但是存儲的內容確實相同的。均是指向main函數中的x,y變量,當再fun函數中執行c=*a;*a=*b;*b=c;交換語句時。*a和*b為main函數中的x、y變量。這時候將會交換這兩個變量的值。
?
二級指針作為函數參數
如果想在函數中改變父函數中的指針變量呢。
#include<stdio.h>
void fun(int **c)
{
???int *b;
b=(int *)malloc(sizeof(int));
*b=2;
?*c=b;
}
int main()
{
???int *a,x=1;
???a=&x;
???printf("%x\n",a);
???fun(&a);
???printf("%x\n",a);
???return 0;
}
函數的實參存儲如下:
| 指針變量地址 | 指針變量值 | 指針變量值表示的內容 |
| &a:28f73b | a:28f740 | *a: x 1 |
?
| 變量地址 | 變量值 |
| &x:28f740 | x: 1 |
?
?
?
?
?
函數的形參存儲如下
| &c | c:(&a) | *c:(a) | **c:(*a=x) |
| 28ff1c | 28f73b | 28f740 | 1 |
?
?
?
?
局部變量b的存儲如下
| &b | b(堆空間地址) | *b |
| 28ffeec | 391798 | 2 |
?
?
?
函數運行完后,指針變量a的指向則為在fun函數中申請的堆空間的地址,存儲如下
?
| 指針變量地址 | 指針變量值 | 指針變量值表示的內容 |
| &a:28f73b | a:381798 | *a: 2 |
?
?
?
?
?
?
?
將一級指針的地址賦值給形參的話,將會將一級指針的地址,變量值都賦值給二級指針的形參。此時在函數內部,二級指針(c)則能后獲得外部一級指針變量(a)的地址、變量值、和普通變量(i)的值。只要知道實參變量的地址,則在函數內部就可以改變實參變量的值。所以這里的二級指針就可以改變一級指針所指向的內容(一級指針變量的值),一級指針所指向地址的內容。函數運行完后,一級指針a則指向申請的堆空間的地址,指向地址的內容則為堆空間存儲的內容,不再指向變量i。
?
指針數組作為函數參數
下面程序是利用指針數組改變數組的值
#include<stdio.h>
void fun(int *c[],int n)
{
???int i;
???for(i=0;i<n;i++){
???????*c[i]=0;
??? }
}
?
int main()
{
???int b[3]={1,2,3};
???int *a[3]={b,b+1,b+2};
???fun(a,3);
???return 0;
}
在main函數中變量的存儲情況如下
| 地址 | 內容 |
| &b[0]:28ff04 | b[0]:1 |
| &b[1]:28ff08 | b[1]:2 |
| &b[2]:28ff0c | b[2]:3 |
| 地址 | 內容 | 指向內容 | ? | ? |
| a:28fef8 | a[0]:28ff04 | *a[0] | ? | ? |
| a+1:28fefc | a[1]:28ff08 | ? | ? | ? |
| a+2:28ff00 | a[2]:28ff0c | ? | ? | ? |
?點擊打開鏈接
?
?
總結
- 上一篇: C++中重载与重写函数区别及虚函数(转载
- 下一篇: x264 的 cache详解