c語言之指針

一、指針是什麼?

指針的實質就是個變量,指針完整的名字應該叫指針變量,簡稱爲指針。指針變量是用來存放內存地址的。

二、如何使用指針?

1.定義指針變量

int *p;//p是個變量名字, int * 表示該p變量只能存儲int類型變量的地址

2.關聯指針變量

int i = 10;
p = &i;//關聯指針變量

將整形變量i的地址賦值給指針變量p,我們稱作p指向i

3.解引用

int j = *p;

p指向i,所以*p就等價於i(在任何時候,i和*p都可以互換)。

三、野指針

1、定義

當我們只定義一個變量而爲對該指針變量進行初始化時,指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的),我們稱之爲野指針。野指針因爲指向地址是不可預知的,所以有3種情況:

  • 第一種是指向不可訪問(操作系統不允許訪問的敏感地址,譬如內核空間)的地址,結果是觸發段錯誤,這種算是最好的情況了;
  • 第二種是指向一個可用的、而且沒什麼特別意義的空間(譬如我們曾經使用過但是已經不用的棧空間或堆空間),這時候程序運行不會出錯,也不會對當前程序造成損害,這種情況下會掩蓋你的程序錯誤,讓你以爲程序沒問題,其實是有問題的;
  • 第三種情況就是指向了一個可用的空間,而且這個空間其實在程序中正在被使用(譬如說是程序的一個變量x),那麼野指針的解引用就會剛好修改這個變量x的值,導致這個變量莫名其妙的被改變,程序出現離奇的錯誤。一般最終都會導致程序崩潰,或者數據被損害。這種危害是最大的

2、如何避免野指針

  • 定義指針時,同時初始化爲NULL
  • 在指針解引用之前,先去判斷這個指針是不是NULL
  • 指針使用完之後,將其賦值爲NULL
  • 在指針使用之前,將其賦值綁定給一個可用地址空間

四、指針與一維數組

1.如何理解數組?

(1) 數組中各個元素的地址是依次相連的,數組中各個元素的類型相同。

(2) 數組中其實就是地址相連接、佔地大小相同的一塊連續的內存空間。

(3) 幾個關鍵符號(a  &a   &a[0])的理解(前提是 int a[10])

  • a就是數組名。a只能做右值,表示數組首元素(數組的第0個元素,也就是a[0])的首地址(首地址就是起始地址,就是4個字節中最開始第一個字節的地址)。a做右值等同於&a[0];
  • &a只能做右值,表示整個數組的首地址。
  • &a[0]字面意思就是數組第0個元素的首地址(搞清楚[]和&的優先級,[]的優先級要高於&,所以a先和[]結合再取地址)。做左值時表示數組首元素對應的內存空間,做右值時表示數組首元素的值(也就是數組首元素對應的內存空間中存儲的那個數值)。做右值時&a[0]等同於a。

note:

&a、a、&a[0]從數值上來看是完全相等的,但是意義來看就不同了。從意義上來看,a和&a[0]是數組首元素首地址,而&a是整個

數組的首地址;從類型來看,a和&a[0]是元素的指針,也就是int *類型;而&a是數組指針,是int (*)[5];類型。

所以:

int *p; int a[5];	p = a;		// 類型匹配
int *p; int a[5];	p = &a;		// 類型不匹配。p是int *,&a是整個數組的指針,也就是一個數組指針類型,不是int指針類型,所以不匹配

2.如何訪問數組

(1) 以下標方式訪問:

數組名[下標]; (注意下標從0開始)

(2) 以指針方式訪問:

p[i]永遠等價於 *(p+i)

note:

指針變量+1時實際不是加1而是加1×sizeof(指針類型),主要原因是希望指針+1後剛好指向下一個元素(而不希望錯位)。

小結:

數組下標方式和指針方式均可以訪問數組元素,兩者的實質其實是一樣的。在編譯器內部都是用指針方式來訪問數組元素的,數組下標方式只是編譯器提供給編程者一種殼(語法糖)而已。所以用指針方式來訪問數組纔是本質的做法。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章