指標詳解
指標實際就是儲存記憶體地址的一個變數,指標是有型別的,當對指標進行解引時,會根據指標的型別對所指的記憶體進行相應的解析,同變數一樣也佔用一定的記憶體(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語言指標
- C語言指標詳解(二)C語言指標
- c++ 智慧指標用法詳解C++指標
- 陣列,函式與指標 詳解陣列函式指標
- C指標和陣列的關係詳解指標陣列
- C++指標的概念解讀 超詳細C++指標
- Go高階特性 12 | 指標詳解:在什麼情況下應該使用指標?Go指標
- 【原創】淺談指標(七)字串相關(詳細版本)與指標運算指標字串
- C語言函式傳遞指標引數的問題詳解C語言函式指標
- C++ 智慧指標詳解: std::unique_ptr 和 std::shared_ptrC++指標
- Go 的記憶體對齊和指標運算詳解和實踐Go記憶體指標
- 雙指標妙解三數之和指標
- 指向指標的常量引用瞭解指標
- C語言指標(三):陣列指標和字串指標C語言指標陣列字串
- 陣列指標,指標陣列陣列指標
- 指標指標
- 【評價指標】詳解F1-score與多分類MacroF1&MicroF1指標Mac
- 指標陣列與陣列指標指標陣列
- 指標函式 和 函式指標指標函式
- c語言之解釋複雜指標C語言指標
- 圖解兩數之和:雙指標法圖解指標
- 一文詳盡系列之模型評估指標模型指標
- 第 10 節:複合型別-5. 指標 -- 指標與指標變數 -8. 多級指標型別指標變數
- HTML常見標籤詳解HTML
- Git tag標籤用法詳解Git
- OpenGL 座標系統詳解
- 標準庫~JSON物件詳解JSON物件
- POM.xml 標籤詳解XML
- 選購交換機的引數依據和主要的引數指標詳解指標
- 一文詳解機器學習的判別指標(精準率,召回率)機器學習指標
- C指標原理(14)-C指標基礎指標
- C指標原理(15)-C指標基礎指標
- 指標常量和常量指標的區別指標
- isa指標指標
- 姜指標指標
- MACD指標Mac指標