寫這一篇博客的主要目的是記錄在C語言編程的過程中,碰到的一些奇怪的關於指針的問題,通過對指針這一C語言特色變量的研究,爲以後編寫更爲穩定的程序打下良好的基礎,主要介紹了指針在函數值傳遞、地址轉換等方面的相關陷阱!
一、指針變量&函數形參
1.首先如下所示爲基本的函數形參指針傳遞值過程:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int point(int *val){ 5 printf("Address Of ParamA=%x\n",val); // Print the param val's address. 6 *val = 10; // Change the value of val var. 7 } 8 int main(void) 9 { 10 int A = 1; 11 printf("A=%d Address=%x\n",A,&A); // Print the val and the Address of A. 12 point(&A); 13 printf("A'=%d Address'=%x\n",A,&A); // Print the val and the Address of A. 14 }
如下所示爲運行的結果:
val的地址應該是&val,而函數中打印的是val地址中的內容,也就是A的地址了。
這裏我們可以看到,形參指向的地址0x65fe1c和main函數中A指向的地址是相同的,這裏值得注意的是,對於A地址變量和val地址變量而言,其自身的存儲地址是不同的,而地址中保存的指向a變量的地址是相同的,都是0x65fe1c,其自身的地址如下所示:
#include <stdio.h> #include <stdlib.h> int point(int *val){ printf("Address Of ParamA=%x\n",&val); // Print the param val's address. *val = 10; // Change the value of val var. } int main(void) { int *A; int a = 1; A = &a; printf("A=%d Address=%x\n",*A,&A); // Print the val and the Address of A. point(A); printf("A'=%d Address'=%x\n",*A,&A); // Print the val and the Address of A. }
Notice:運行的結果如下,這裏可以看到形參的地址和main中A的地址是不同的,當然他們指向了同一個地址空間,這就是爲什麼指針傳遞能夠改變數值,因爲傳到函數中的地址是待改變的var變量的地址,因此完成了數值的改變,這也就是所謂的形參實際上是地址參數的一個副本,他不是完全相同的,而是地址不同,指向地址相同的兩個不同的變量,當函數完成以後,這個形參地址變量副本將會被回收。
形參地址和傳入地址變量的地址不同。
同時可以看到,通過在函數中改變val 的值確實達到了傳遞參數的效果。
2.在函數中改變形參指向地址的陷阱
1 #include <stdio.h> 2 3 int point(int *val){ 4 int *P = (int *)malloc(sizeof(int)*3); // Alloc a new mem in func-point 5 printf("Address Of ParamA=%x\n",val); // Print the param val's address. 6 *P = 10; 7 val = P; 8 printf("Address Of ParamA=%x\n",val); // Print the param val's address. 9 } 10 int main(void) 11 { 12 int *A; 13 int a = 1; 14 A = &a; 15 printf("A=%d Address=%x\n",*A,&A); // Print the val and the Address of A. 16 point(A); 17 printf("A'=%d Address'=%x\n",*A,&A); // Print the val and the Address of A. 18 }
程序運行結果如下所示:
可以看到在主函數中顯示的A的地址0x65fe18居然不等於函數形參未改變之前的地址0x65fe14,經過Debug對程序進行調試,發現地址起始是一樣的,都是0x65fe14,至於爲什麼會出現打印結果和Debug結果的不同還有待分析。
重要的是,在值傳遞之前,對形參中指向的地址進行了重新的賦值,此時形參副本將不會指向外部數據的地址,從此無法改變外部數據值,從而無法完成值傳遞,因此,一定要注意對形參進行指針賦值的情況,否則將造成數據無法傳遞的情況。(此時新的地址0x7713f0指向的地址的內容爲10.)
二、數組地址值傳遞及分析
1.二維數組&多維數組的構造方式
2.如何傳遞數組到函數中
未完待續!