指針是C++中一類頗具特色的數據類型,允許直接操作內存地址,實現內存的動態分配。指針問題通常包括指針常量,常量指針,數組指針,指針數組,函數指針,指針傳值等。
指針和引用的區別
-
非空區別。在任何情況下都不能使用指向空值的引用。因此如果你使用一個變量並讓它指向一個對象,但是該變量在某些時候也可能不指向任何對象,這時你應該把變量聲明為指針,因為這樣你可以賦空值給該變量。相反,如果變量肯定指向一個對象,例如你的設計不允許變量為空,這時你就可以把變量聲明為引用。不存在指向空值的引用這個事實意味着使用引用的代碼效率比使用指針要高。
-
合法性區別。在使用引用之前不需要測試它的合法性。相反,指針則應該總是被測試,防止其為空。
-
可修改區別。指針與引用的另一個重要的區別是指針可以被重新賦值以指向另一個不同對象。但是引用則總是指向在初始化時被指定的對象,以后不能改變,但是指定的對象其內容可以改變。
下面幾個函數的區別
void swap1(int p,int q)
{
int temp;
temp=p;
p=q;
q=temp;
}
值傳遞,a,b兩個數交換不成功。
void swap2(int *p,int *q)
{
int *temp;
*temp=*p;
*p=*q;
*q=*temp;
}
注意上面的temp是一個指針但是卻沒有進行初始化,然而*temp = *p確實將p所指向的內容幅值給temp指向的地址,但是temp所指向的地址卻沒有給分配,這里在給temp指向的內存賦值時系統會臨時的給其分配一個存儲空間,但是這里分配的內存卻不會在函數執行結束時給釋放掉,造成內存泄露。
void swap3(int *p,int *q)
{
int *temp;
temp=p;
p=q;
q=temp;
}
仍然是temp是個指針但是其指向的內存卻沒有分配,故temp=p是temp也指向p所指向的內存(也就是變量a),所以這里交換只是形參p,q的值,而不是指針所指向的值。
void swap4(int *p,int *q)
{
int temp;
temp=*p;
*p=*q;
*q=temp;
}
void swap5(int &p,int &q)
{
int temp;
temp=p;
p=q;
q=temp;
}
上面兩個函數分別使用了指針傳遞和引用傳遞,是可以正確的交換兩個數的值的。
字符數組和字符串常量
有如下兩個定義
char str1[] = "hello world" ;
char *str2 = "hello world" ;
作為局部變量時,字符數組和字符串常量的主要區別就是其生命周期不同。字符數組保存在棧中,所以在函數調用結束時就被銷毀了,字符串常量是保存靜態存儲區域中,在函數調用結束時並不會被銷毀。
有下面兩個函數
char *strA()
{
char *str = "hello world";
return str;
}
char *strB()
{
char str[] = "hello world";
return str;
}
函數strB返回的是局部變量字符數組是不正確的,因為在函數調用結束后str及其所指向的存儲空間會被銷毀。但是strA卻是可以的,因為str指向的是一個字符串常量,存儲在靜態存儲區域,在函數調用結束時指針str會被銷毀,但是其指向的區域卻不會被銷毀,所以返回其指向的存儲區域是可以的。
對於要返回字符數組的也如下面這樣處理
char *strB()
{
static char str[] = "hello world";
return str;
}
將str聲明為static,str就存儲在靜態存儲區域,但是其作用域只是函數內部。