歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C指針解析及指針作為參數傳遞的應用

C指針解析及指針作為參數傳遞的應用

日期:2017/3/1 9:49:08   编辑:Linux編程

計算機內存中的每個位置都由一個地址標識,通常,鄰近的內存位置合成一組,這樣就允許存儲更大范圍的值,指針就是它的值表示內存地址的變量。

指針變量的值並非它所指向的內存位置所存儲的值。我們必須使用間接訪問來獲得它所指向位置存儲的值。當然直接訪問的話需要通過變量,而變量名字與內存位置之間的關聯並不是硬件所提供的,它是由編譯器為我們實現的。所有這些變量給了我們一種更方便的方法記住地址——硬件仍然通過地址訪問內存地址。

所有值都是以0和1存儲在內存中,當我們區訪問變量時,系統該怎樣區解釋這些變量呢?這就要通過變量的類型來區別了。假設這麼這個32位二進制:

01100111011011000110111101100010

我們可以像下面這樣來解釋

這一切我們不需要直接去處理,這是編譯器范疇內的任務,編譯器能夠保證值的聲明和值的使用之間的關系是適當的,從而幫助我們確定值的類型。

聲明一個指針變量並不會自動分配任何內存。在對指針執行間接訪問前,指針必須進行初始化:或者指向現有的內存,或者給它分配動態內存。對未初始化的指針變量執行間接訪問操作是非法的。例如:

int *ptr;

*ptr = 1024;

我們聲明了一個變量,但從未對它進行初始化,所以我們沒有辦法預測1024將存儲在什麼地方。如果執行這個程序,會出現什麼情況呢?如果運氣好的話,ptr的初始值會是個非法地址,這樣賦值語句將會出錯,從而終止程序,在linux系統下會出現dump core。如果你運氣不好,這個指針可能包含一個合法的地址,於是位於該位置的值將被修改,這可能不是你想要的結果。

對所有的指針變量進行顯示化初始化是一個好習慣。如果你已經知道指針將被初始化什麼地址,就把它初始化為該地址,否則就把它初始化為NULL。另一個非常號的習慣就是,當你需要解引用指針時,你應該在指針解應用之前對它進行檢查,if(ptr!=NULL),這會減少你大量的調試時間,也減少出錯的概率。

下面說一下指針作為參數的應用,舉一個網上典型的例子,申請一片內存區,並將申請到的內存首地址返回給調用函數:首先給出錯位的程序:

void getptr(int *p,int num) {
p=(int *)maccol(num*sizeof(int));
return;
}
int main()
{
int *ptr; int k;
getptr(ptr,10);
for(k=0;k<10;k++)
scanf("%d",&ptr[k]);
}

這段代碼的將不會給ptr分配內存,因為ptr是以傳值的方式傳給p,所以p是ptr的一份拷貝,p指向了動態分配的內存,但是函數調用結束後臨時變量將不復存在,動態分配的內存也沒有釋放,ptr也沒有指向這塊動態分配的內存。正確的代碼應該如下所示:

void getptr(int **p,int num) {
*p=(int *)maccol(num*sizeof(int));
return;
}
int main()
{
int *ptr; int k;
getptr(&ptr,10);
for(k=0;k<10;k++)
scanf("%d",&ptr[k]);
}

我們應該傳指針的指針來改變指針所指的地址,這與我們應該傳遞變量的指針來改變變量是一個道理,因為指針也是變量,傳值是 改變不了變量的,只有傳指針和引用才能將改變體現在變量上。

Copyright © Linux教程網 All Rights Reserved