(1)指標 p
pp 指向變數 a
aa 意思是 指標變數的內容值是 a
aa 的位址,也就是說p = &a
int b; <==> int *const b;
陣列名b
bb也是個指標(位址),只不過它是乙個con
stconst
cons
t 指標,也就是說b
bb的內容值不能被修改,b
bb指向某個地方的事實不能被更改,b = &b[0]
(2)說明:c++中*
的三個角色
(3)指標的大小
指標的大小也就是位址的大小是跟機器有關係的,有些是4,有些是8
指標p可以加上或減去乙個整數n,但指標的這種運算的意義和通常的數值的加減
運算的意義是不一樣的,它是以單元為單位,如p指向int型整數,則乙個單位是sizeof(int)
(1)示例1
char a[20]
="you are my friend"
;int
*ptr=
(int
*)a;
ptr = ptr +
3;
char陣列的每個單位是乙個位元組,而指標ptr指向的單元是4個位元組
所以沒加3前的 ptr 指向陣列a的第1 - 4個位元組(看作乙個整體),加3後,ptr已經指向了陣列a的第13 - 16個位元組,即指向a[12] - a[15]這部分
(2)示例2
#include
using
namespace std;
intmain()
;int
*ptr = array;
// 陣列名array是位址,把它賦給指標ptr
for(
int i =
0; i <
20; i++
) ptr = array;
for(
int i =
0; i <
16; i +=4
)return0;
}
(3)char **p; p++;分析執行後p的值
char m =
'c';
char
*t =
&m;// char *t = "hello"; // 字串是位址常量(第乙個字元的位址)
char
**p =
&t;
p是個二級指標
總結乙個指標(位址)ptrold加(減)乙個整數 n 後,結果是乙個新的指標(位址)ptrnew,
ptrnew的型別和ptrold的型別相同,ptrnew所指向的型別和ptrold所指向的型別也相同
ptrnew 的值將比 ptrold 的值增加(減少)了 n 乘sizeof(ptrold 所指向的型別)個位元組
也就是說:ptrnew 所指向的記憶體區將比 ptrold 所指向的記憶體區向高(低)位址方向移動了 n 乘sizeof(ptrold 所指向的型別)個位元組。
指標和指標進行加減:
陣列名array本質是乙個指標,所以
int array=
;int
*p = array;
記住一點
*(p + 4) 和 p[4]是等價的
*(array + 4) 和 array[4]是等價的
又array[0]
等價於p[0]
,因為p = array;
所以實際上,上面四個都是等價的
而對於二維陣列int a[3][4]
這裡的陣列名a相對於乙個二級指標,a是乙個指向一維陣列(指標)的指標
a + 1 = &a[1]
*(a + 1) = *&a[1] = a[1]
a[0]
是第乙個一維陣列的陣列名(位址),若令指標p = a[0],則*(p + 3) =*( a[0]+3) = a[0][3]
更清晰地解釋可以看下面這張圖
char a[10]
和char *a
是不一樣的
說明:char *p = "abcd";
"abcd"是個位址常量,它等於第乙個字元a的位址
struct node node;
node tu;
node *p =
&tu;
只要記住一點:(*p).data和p->data; 是等價的
(1)示例1
int a;
int*p =
&a;p +=1
;*p =
8;
上面的**存在嚴重的錯誤,因為第三行**p += 1
執行後,p指向了整型變數a相鄰的高位址方向的一塊儲存區域,而我們居然用第四行**往這塊區域裡寫入資料,這非常危險,因為我們不知道它裡面原來的內容是什麼,萬一是系統十分重要的資料呢
在陣列int a[10]時類似地操作可行,那是因為我們已經申請了乙個長度長度為10的連續空間,這部分空間是我們已知的且可隨意寫資料的
所以說,我們在使用指標時一定要非常清楚:這個指標究竟指向了**
(2)示例2
當我們使用指標的強制型別轉換p1=(type *)p2 時,如果 sizeof(p2 的型別) 大於 sizeof(ptr1 的型別),那麼在使用指標 p1 來訪問 p2 所指向的儲存區時是安全的。否則是會出現嚴重問題的
char t =
'a';
int*p;
p =(
int*
)&t;
*p =
520;
執行**,可能不會報錯,但這存在著安全隱患,因為p指向的是字元a
以及和它相鄰高位址方向的三個位元組,而後面三個位元組的內容我們並不知道是什麼,萬一很重要的呢
(3)下面的**是安全的,而且可以說明我的機器是小端模式
因為從t最後的值為48,可以看出p指向的是int4個位元組中的低位元組,而強制轉換的char指標p預設是指向int4個位元組中低位址的位元組的,所以可以說明我的機器是小端模式(低位元組在低位址)
int t =7;
char
*p;
p =(char*)
&t;*p =
'0';
// 對應48:00110000 char 乙個位元組:0-127
cout <<
*p << endl;
cout << t << endl;
// 輸出48
野指標野指標:指標變數指向非法的記憶體空間
示例:
#include
using
namespace std;
intmain()
空指標和野指標都不是我們自己申請的空間,所以不要隨意地去訪問它 C 深入淺出之指標
1 指標陣列 char str 10 指標陣列,顧名思義是乙個陣列,其元素是乙個指標。上述 是定義乙個指標陣列,其陣列元素為指向字元的指標。所謂指標陣列,重頭戲在於陣列,指標可以抽象為修飾符,那麼如何來理解指標陣列呢?很簡單,的優先順序高於 因此先被結合,加上陣列名,就構成了陣列。2 陣列指標 in...
深入淺出c 之 this指標
前言 c語言中的陣列指標和指標陣列 陣列指標,是指向陣列的指標的縮寫 指標陣列,是存放指標的陣列的縮寫。其實很多時候,往往因為簡寫和縮寫帶給我們很多困惑。我曾想過不用簡稱去學習,但在很多時候,我們查詢的書籍文件和文章中還是會頻頻出現這樣的簡稱,所以有必要扣一下字眼了。1 int p 3 優先順序大於...
C 深入淺出Dynamic
我們知道c 是乙個強型別語言,也就是說編譯器在編譯的時候會堅持資料型別是否正確。但是dynamic的出現讓c 具有了弱語言型別的特性。編譯器在編譯的時候不再對型別進行檢查,編譯器預設dynamic物件支援你想要的任何特性。dynamic dy 100 dy.name 89 dy.getname 上例...