C語言指針及陷阱

寫這一篇博客的主要目的是記錄在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.如何傳遞數組到函數中

 

未完待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章