解讀 C 語言中的指標

2021-07-15 09:44:40 字數 3092 閱讀 1258

我想對很多學習c語言的新手來說,指標無疑是乙個難點。但是,我覺得指標也是c語言特別重要的乙個特性。也許,你在除了c和c++以外的程式語言中,很少看到指標。而c++中,也多用引用,而非指標。指標,作為一種高效的工具,可謂是一把雙刃劍——用得好,可以大大提高程式效率,但用的不好,就是很多bug的滋生地。

一,基本概念

關於指標的基本概念,我就不詳細介紹了,因為有許多書都介紹的很詳細。這裡我只介紹一部分。指標指向乙個位址,而指標本身在大多數系統上都是乙個無符號整數(在32bit機上是4byte,在64bit機上是8byte)。下面用乙個例子來說明其機制:

在上面的例子中,先定義了乙個指標p,它的型別是int,也就是說它只能指向乙個int型的變數,而不能指向其他型別的變數。最後我們將a變數的位址賦給p。在這個過程中,涉及到兩個記憶體塊,乙個是存放指標p的記憶體(用&p可得到記憶體位址),乙個是存放a的值的記憶體塊(用&a可以得到記憶體位址)。而第乙個記憶體存的p的值經過賦值語句後也就是&a的值了。另外乙個注意點是, *(星號)和變數型別以及變數名之間可以有任意個空格,也可以沒有。比如下面三種方式都是一樣的:

在上面的例子中,先定義了乙個指標p,它的型別是int,也就是說它只能指向乙個int型的變數,而不能指向其他型別的變數。最後我們將a變數的位址賦給p。在這個過程中,涉及到兩個記憶體塊,乙個是存放指標p的記憶體(用&p可得到記憶體位址),乙個是存放a的值的記憶體塊(用&a可以得到記憶體位址)。而第乙個記憶體存的p的值經過賦值語句後也就是&a的值了。另外乙個注意點是, *(星號)和變數型別以及變數名之間可以有任意個空格,也可以沒有。比如下面三種方式都是一樣的:

解讀方法:

看下面乙個例子:

二,陣列首位址a,&a,&a[0]

注:a,&a,&a[0]的含義雖然不同,但是他們三個的值是相等的!

以int a[3]為例說明:

a作為右值時,代表陣列首元素的首位址,而非陣列位址。 也就是a[0]的位址。int i = (a+1),這裡a是右值,所以代表首元素的首位址,a+1代表下乙個元素的首位址,即&a[1]。

a是整個陣列的名字。所以sizeof(a)的值為sizeof(int) * 3 = 40,代表整個陣列的大小。

&a[0]代表首元素的首位址。 所以sizeof(&a[0]) = 4。

&a[3],很顯然陣列越界了,但它的sizeof是多少呢? 也是4,因為關鍵字sizeof求值是在編譯的時候,雖然並不存在a[3]這個元素,但是這裡並沒有真正訪問a[3],而是根據陣列元素型別來確定其值的。所以sizeof(a[3])不會出錯。

a[-1]代表什麼意思?首先要明白下標的形式被編譯器解析成指標的形式,即a[1]被解析成(a+1)。那麼,a[-1]被解析成*(a-1)。

關於陣列首元素的首位址和陣列的首位址的區別:其實,陣列首元素的首位址和陣列首位址的值是相同的,即&a[0]和a(以及&a)是相等的,但是而這含義不一樣。首元素的首位址加1後,是第二個元素的首位址(之所以一直說首位址,是因為有的型別儲存時會佔多個位址),但陣列的首位址加1後是「下乙個陣列的位址」,這裡的下乙個陣列只是為了說明加1時加了整個陣列的大小,而不是乙個元素的大小。

輸出結果:

說明(下面的行數隻計算main函式內有**的行):

程式第1行定義了乙個具有3個元素的整型陣列。

第2行列印了long型的大小。因為我是64bit的,所以乙個long是8byte。

第3行列印了*(a+1)的值,結果和a[1]的值相等。說明a雖然代表整個陣列,但作為右值時,的確代表首元素的首位址。

第4行輸出值為12,是整個陣列的大小。

第5行列印了乙個出界元素的大小,沒有報錯,驗證了上面第5條。

第6行列印了a[-1]和*(a-1),輸出值相等。驗證了上面第6條。

第7行列印了a和&a[0],值相等。說明陣列的首位址和首元素的首位址是相等的。

第8行列印了a,(a+1),(&a+1),由結果就可以看出首元素的首位址加1是加了乙個陣列元素的大小,而陣列首位址加1是加了乙個陣列的大小。

三,指標陣列和陣列指標

指標陣列: 首先它是乙個陣列,陣列的元素是指標,也成為「儲存指標的陣列」。

陣列指標: 首先它是乙個指標,它指向乙個陣列,也可以理解為「陣列的指標」。 也可以利用前面的「解讀方法」去分析。

四,函式指標和指標函式

函式指標: 指向函式的指標變數。

指標函式: 帶指標的函式,也就是返回指標的函式。

五,指標常量和常量指標

怎麼記?

可以先把型別名去掉,然後看const離誰近,就修飾誰。

也可以const在*左邊的為常量指標,const在*右邊的為指標常量。

三~五的****

其實,關於「指標陣列與陣列指標、函式指標與指標函式、指標常量與常量指標」的判斷,有乙個****。那就是根據我們強大的中文語法:前邊是修飾詞,後邊才是主語。比如「指標陣列」,前面的指標只是修飾詞,後面的陣列才是主語,所以它是乙個陣列。

六,野指標

野指標指沒有確定指向的指標。造成野指標的情況有:

1. 指標變數建立但沒有初始化。

2. 指標p被free或者delete之後,沒有置為null。

C語言指標解讀

乙個變數在記憶體中所占用儲存單元的位址被稱為該變數的指標。即 指標 僅表示物件在記憶體中的位址。計算機中,記憶體是乙個連續編號或編址的空間。每個儲存單元都有乙個固定的編號,編號稱之為位址。不同的資料型別占用不同位元組的儲存空間,而每個位元組都有乙個位址,一般把每個資料的首位元組位址稱為該資料的位址。...

C 語言中的指標

指標是 c 語言中的精華,正確靈活的運用指標,可以表示複雜的資料結構,動態分配記憶體,方便使用字串和陣列,呼叫函式返回多結果,直接處理記憶體單元等等。位址就是記憶體的編號,如果拿旅店作為記憶體,那麼每個房間號其實就相當於位址了。當程式編譯時,就會對變數分配記憶體單元,分配時按變數型別分配大小。經過編...

C語言中的指標

隨著程式語言的越來越多,但c語言在程式語言中的地位似乎始終沒有改變,其中得益於c語言中的指標,可以直接去操作記憶體位址與暫存器,執行效率也高,在嵌入式領域運用得尤其廣泛。對於初學者來說指標是c語言中很難翻越的一座大山,指標的掌握程度直接關係到c語言的掌握程度,其實指標並不是那麼高不可攀,只是紙老虎而...