第七章 指標和引用、遞迴
1. 指標和引用的而區別
首先1,指標是非空性,而引用總是指向某些物件(
必須宣告時初始化
),不存在指向空值的引用。
其次2,合法性,指標總是在使用前測試是否為空指標,引用不用測試。
再次3,可修改,指標可以重新賦予新的位址指向不同物件,而引用則始終指向初始化時指定的物件,但是指定物件的內容可以改。
如果有情況1或3,則建議用指標,否則建議用引用。
2.傳遞動態記憶體
當指標作為函式形參時,同樣是輸入乙個指標的副本,作用域在函式內部,和變數一樣,函式結束後會被銷毀,而作為輸入的指標並沒有改變。
不能返回函式體內的
區域性變數的位址(陣列隱轉化的指標),因為在函式呼叫時,在棧上分配給指標的位址,當函式結束後,空間被**,所以指標指向的位址不錯在,報錯(和返回乙個變數的
原理是不同的)。如下:
char* mina()
當然,如果這麼做就是可以的:
char* aa()
char *str和char str的區別:前者是全域性陣列,儲存在全域性區域,字串常量儲存在唯讀的資料段
後者是區域性陣列,而不像全域性變數那樣儲存在普通的資料段(靜態區域)
後者是區域性變數,對應的是記憶體中的棧,所以可以修改,但是函式結束後會被**,所以不能返回。如下:
char *c = "asdfg";
*c = 't';//會出錯,唯讀;
char c = "asdfg";
c[0] = 't';//可改;
3.記住:
指標就是位址。編譯後,乙個類或者結構體中的資料成員都是記住其相對首位址的偏移量,根據首位址+偏移量進行查詢。第乙個成員變數相對首位址偏移量為0(這句
話不太確定)。
能能人為寫乙個32/64位的二進位制位址給乙個指標賦予位址,位址管理是由系統管理分配(詳細的見下面的控制代碼分析),這樣會報錯,如下是錯誤的:
int* p;
p = (int*)0x8000;//錯誤的(作業系統+控制代碼)
*p = 5;
引申:繼承類,基類建構函式的呼叫順序:先基類建構函式,然後再呼叫繼承類的建構函式,如果變數覆蓋,呼叫基類的方法時涉及的成員變數同樣是基類的成員變數的值
4.函式指標
如下就明白了(盡量少用):
int max(int a, int b)
int main()
就像陣列名是陣列首元素的位址一樣,函式名字也是函式的位址入口;
5.指標陣列和陣列指標
這兩個名字不同當然所代表的意思也就不同。我剛開始看到這就嚇到了,主要是中文太博大精深了,整這樣的簡稱太專業了,把人都繞暈了。從英文解釋或中文全稱看就比較容易理解。
指標陣列:array of pointers,即用於儲存指標的陣列,也就是陣列元素都是指標
陣列指標:a pointer to an array,即指向陣列的指標
還要注意的是他們用法的區別,下面舉例說明。
int* a[4] 指標陣列
表示:陣列a中的元素都為int型指標
元素表示:*a[i] *(a[i])是一樣的,因為優先順序高於*
int (*a)[4] 陣列指標
表示:指向陣列a的指標
元素表示:(*a)[i]
注意:在實際應用中,對於指標陣列,我們經常這樣使用:
typedef int* pint;
pint a[4];
這跟上面指標陣列定義所表達的意思是一樣的,只不過採取了型別變換。例子如下:
int main()
; int *a[4]; //指標陣列
int(*b)[4]; //陣列指標
b = &c;
//將陣列c中元素賦給陣列a
for (int i = 0; i < 4; i++)
//輸出看下結果
cout << *a[1] << endl; //輸出2就對
cout << (*b)[2] << endl; //輸出3就對
return 0;
}
指標的加減操作:
int a = ;
int*p = (int*)(&a + 1);
printf("%d%d", *(a + 1), *(p - 1));//結果2,5
牢記:陣列本身就是指標,再加乙個&,就是
雙指標,也就是二維陣列,加1,就是陣列整體加一行,所以p指向陣列第六個元素位址(雖然沒有值)。
6.迷途指標
一句話:指標釋放後,沒有將指標賦值為null,此時編譯器很可能將指向的位址分配給其他資料了,進而再次操作會出現錯誤(再次刪除也會出錯)。
解決:釋放後,將指標賦值為null,讓他成為空指標(再次刪除空指標完全合法)。
7.智慧型指標
附加類+計數器+與指標繫結;
auto_ptr智慧型指標,用法如下(不能放在vector中):
std::auto_ptrp(new type);
//或者
std::auto_ptrp()
//或者
type *a;
std::auto_ptrp(a);
8.this指標
只能在成員函式中使用,成員函式第乙個形參其實預設都是calssname* const this。全域性函式,靜態函式都不能使用this指標。
this不占用物件的空間,他在成員函式執行前被構造,在成員函式執行結束後清除。
this指標是指向「物件」的常指標,所以為唯讀,並且只能在成員函式中才能&this進行讀取。
9指標和控制代碼
window是乙個以虛擬記憶體為基礎的作業系統,我了滿足需要,記憶體管理器經常在記憶體中來回的移動物件,以滿足記憶體適應各種應用程式,物件移動,則位址變了。那麼怎麼解決這個問題呢,window額外騰出一定的空間,存放一些位址,專門登記物件的位址變化,這個就叫控制代碼,用控制代碼就可以找到物件的位址(類似中介作用)。控制代碼是系統資源的
唯一標識
,是32 位uint型別,指標則是具體的某個位址。
10.遞迴函式的特點
一定要有遞迴的
終止條件,否則無限遞迴會導致堆疊溢位,遞迴演算法天生
效率低,遞迴函式要素如下:
1)確定終止條件
2)確定返回值是什麼?
3)確定那些是全域性變數、那些是區域性變數。
C C 自學旅程 5 指標和引用
學c語言的時候,指標一直是乙個讓人頭大的東西,懂,但是不會用,還好現在慢慢會了,還好c 的指標還是跟c基本相同,還好如此我就只用記一些不同的東西了 一 無名變數 動態變數 可以用new來建立乙個無名變數,這種變數沒有識別符號,如 int p newint 可以在動態建立的同時指定初始化列表,如 do...
7 4 指標和引用
7.4.1指標的好處 1.可以動態分配記憶體。2.對多個相似變數進行一般訪問。3.為動態資料結構,尤其是樹和鍊錶提供支援 4.遍歷陣列,解析字串。5.高效的按引用複製陣列和結構。7.4.2 引用還是指標 1.指標本質是儲存位址的變數,指標則是 從一而終 的別名,且不能為空 2.作為引數傳遞,二者不同...
溫習C C 筆記 2 指標和引用的區別
首先看一段 以及執行結果,我將結合該段 講解指標和引用的兩點區別 main.cpp testc 02 created by fei dou on 12 7 29.include include using namespace std int main int argc,const char argv...