指標詳解
指標實際就是儲存記憶體地址的一個變數,指標是有型別的,當對指標進行解引時,會根據指標的型別對所指的記憶體進行相應的解析,同變數一樣也佔用一定的記憶體(32位系統下佔4位位元組,64位佔8位位元組)
指標的定義
int a;
int* p = &a;
*代表 p為int型別的指標,&為取地址符
int* p, s1;
在這行程式碼中p為int型別的指標,s1為整形變數
指標的三種const用法
const int* p;// int const* p;
p = &a;
//這兩種定義方法的指標,所指向的資料不能通過該指標進行修改
int a;
int* const p = &a;
//這種方式定義的指標,必須進行初始化,且該指標值不會改變,可以通過指標對其指向的值進行修改
int a;
const int* const p = &a;//或者int const* const p = &a;
//這種方式定義的指標,必須進行初始化,且該指標值不會改變,不可以通過指標對其指向的資料進行修改
指標與陣列的糾纏
當函式引數中出現陣列時,實際上傳遞的陣列首個元素的地址,而不是把整個陣列copy到棧空間,大量的拷貝會使得程式效率下降.因此在函式中對形參傳來的陣列進行的操作會影響實參裡的值
指標陣列的定義
int* p[100];
指標陣列傳參
//方式一: 指標陣列傳參,宣告成指標陣列,不指定陣列大小
void method_4(int *arr[], int len) {
for(int i=0; i<len; i++){ printf(" arr[%d] = %d\n", i, *arr[i]);
}
}
//方式二: 指標陣列傳參,宣告成指標陣列,指定陣列大小
void method_5(int *arr[10])
{
for(int i=0; i<10; i++){ printf(" arr[%d] = %d\n", i, *arr[i]);
}
}
//方式三: 二維指標傳參
//傳過去是指標陣列的陣列名,代表首元素地址,而陣列的首元素又是一個指標,
//就表示二級指標,用二級指標接收
void method_6(int **arr, int len) {
for(int i=0; i<len; i++){ printf(" arr[%d] = %d\n", i, *(*(arr+i)));
}
}
空指標
- 什麼是空指標? 空指標,就是值為 0 的指標。(任何程式資料都不會儲存在地址為 0 的記憶體塊中,它是被操作系 統預留的記憶體塊。) int *p = 0; 或者int *p = NULL; //強烈推薦
- 空指標的使用
1)指標初始化為空指標 int *select = NULL; 目的就是,避免訪問非法資料。
2)指標不再使用時,可以設定為空指標 int *select = &xiao_long_lv; //和小龍女約會 select = NULL;
3)表示這個指標還沒有具體的指向,使用前進行合法性判斷897943840118979438401111 int *p = NULL; // 。。。。 if § { //p 等同於 p!=NULL //指標不為空,對指標進行操作 }
壞指標
int *select; //沒有初始化
情形一printf(“選擇的房間是: %d\n”, *select);
情形二select = 100; printf(“選擇的房間是: %d\n”, *select);
指標也分等級
二級指標只能存放一級指標的地址,三級指標只能存放二級指標的地址,以此類推.(不能越級)
空指標
void => 空型別 void* => 空型別指標,只儲存地址的值,丟失型別,無法訪問,要訪問其值,我們必須對這個指 針做出正確的型別轉換,然後再間接引用指標。 所有其它型別的指標都可以隱式自動轉換成 void 型別指標,反之需要強制轉換
指標運算
(1)指標與整數的運算,指標加減數字表示的意義是指標在陣列中位置的移動; 對於整數部分而言,它代表的是一個元素,對於不同的資料型別,其陣列的元素佔 用的位元組是不一樣的, 比如指標 + 1,並不是在指標地址的基礎之上加 1 個地址,而是在這個指標地址的 基礎上加 1 個元素佔用的位元組數:
如果指標的型別是 char*,那麼這個時候 1 代表 1 個位元組地址;
如果指標的型別是 int*,那麼這個時候 1 代表 4 個位元組地址;
如果指標的型別是 float*,那麼這個時候 1 代表 4 個位元組地址;
如果指標的型別是 double*,那麼這個時候 1 代表 8 個位元組地址。
(2)通用公式: 資料型別 *p;
p + n 實際指向的地址:
p 基地址 + n * sizeof(資料型別)
p - n 實際指向的地址:
p 基地址 - n * sizeof(資料型別)
比如
對於 int 型別,比如 p 指向 0x0061FF14,則: p+1 實際指向的是 0x0061FF18,與 p 指向的記憶體地址相差 4 個位元組; p+2 實際指向的是 0x0061FF1C,與 p 指向的記憶體地址相差 8 個位元組
對於 char 型別,比如 p 指向 0x0061FF28,則: p+1 實際指向的是 0x0061FF29,與 p 指向的記憶體地址相差 1 個位元組; p+1 實際指向的是 0x0061FF2A,與 p 指向的記憶體地址相差 2 個位元組
指標和指標可以做減法操作,但不適合做加法運算.
指標和指標做減法適用的場合:兩個指標都指向同一個陣列,相減結果為兩個指標之 間的元素數目,而不是兩個指標之間相差的位元組數。
如果兩個指標不是指向同一個陣列,它們相減就沒有意義。
不同型別的指標不允許相減(指標之間可以進行比較)
函式指標
//函式指標的定義 把函式宣告移過來,把函式名改成 (* 函式指標名)
int (*fp)(const void *, const void *);
/貝爾實驗室的C和UNIX的開發者採用第1種形式,而伯克利的UNIX推廣者卻採用第2 種形式ANSI C 相容了兩種方式/
fp = &compare_int;
(*fp)(&x, &y); //第1種,按普通指標解引的放式進行呼叫,(*fp) 等同於compare_int
fp(&x, &y); //第2種 直接呼叫
陣列指標
指向陣列的指標
陣列指標的定義假設指向一個int 型別的陣列,陣列成員為3個
int (* p)[3];
引用
可以理解為對一個變數起別名,實際上c++是用常指標實現的,所謂明修棧道暗度陳倉
int &a = 10;時是成立的,編譯器會在棧開闢int空間,並起一個名字
相關文章
- 詳解 常量指標和指標常量指標
- c語言指標詳解C語言指標
- C++ 智慧指標詳解C++指標
- JavaScript之this指標深入詳解JavaScript指標
- 詳解Javascript 中的this指標JavaScript指標
- 詳解c++指標的指標和指標的引用C++指標
- JavaScript獲取滑鼠指標座標詳解JavaScript指標
- C語言指標詳解(一)C語言指標
- C語言指標詳解(二)C語言指標
- c++ 智慧指標用法詳解C++指標
- C++函式指標詳解C++函式指標
- 陣列,函式與指標 詳解陣列函式指標
- 詳解C/C++函式指標宣告C++函式指標
- C指標和陣列的關係詳解指標陣列
- Go高階特性 12 | 指標詳解:在什麼情況下應該使用指標?Go指標
- C語言核心之陣列和指標詳解C語言陣列指標
- C++中的指標與引用詳細解讀C++指標
- Oracle Statspack報告中各項指標含義詳解!Oracle指標
- Oracle Statspack報告中各項指標含義詳解Oracle指標
- NULL 指標、零指標、野指標Null指標
- Oracle Statspack報告中各項指標含義詳解!(轉)Oracle指標
- (轉)Oracle Statspack報告中各項指標含義詳解!Oracle指標
- 野指標 空指標指標
- 乙太網交換機效能比較對照指標詳解(轉)指標
- 指標的詳細講解指標
- 【原創】淺談指標(七)字串相關(詳細版本)與指標運算指標字串
- 指標常量和常量指標指標
- 一文詳解機器學習的判別指標(精準率,召回率)機器學習指標
- C語言函式傳遞指標引數的問題詳解C語言函式指標
- C語言指標(三):陣列指標和字串指標C語言指標陣列字串
- 陣列指標,指標陣列陣列指標
- ARC中強指標與弱指標指標
- 控制指標與統計指標指標
- 陣列指標 指標陣列陣列指標
- 關於指標傳遞和指標的指標指標
- 雙指標妙解三數之和指標
- 指標指標
- input 標籤詳解