【零基礎(chǔ)學(xué)C語言】知識(shí)總結(jié)十:二級(jí)指針、指針數(shù)組和指向函數(shù)的指針
二級(jí)指針 (多級(jí)指針)
指針變量作為一個(gè)變量也有自己的存儲(chǔ)地址,而指向指針變量的存儲(chǔ)地址就被稱為指針的指針,即二級(jí)指針。依次疊加,就形成了多級(jí)指針。指針可以指向一份普通類型的數(shù)據(jù),例如 int、double、char 等,也可以指向一份指針類型的數(shù)據(jù),例如 int *、double *、char * 等。如果一個(gè)指針指向的是另外一個(gè)指針,我們就稱它為二級(jí)指針,或者指向指針的指針。,我們先看看二級(jí)指針,它們關(guān)系如下:
指針變量也是一種變量,也會(huì)占用存儲(chǔ)空間,也可以使用&獲取它的地址。C語言不限制指針的級(jí)數(shù),每增加一級(jí)指針,在定義指針變量時(shí)就得增加一個(gè)星號(hào)*。p1 是一級(jí)指針,指向普通類型的數(shù)據(jù),定義時(shí)有一個(gè)*;p2 是二級(jí)指針,指向一級(jí)指針 p1,定義時(shí)有兩個(gè)*。
多級(jí)指針的話就是:
想要獲取指針指向的數(shù)據(jù)時(shí),一級(jí)指針加一個(gè)*,二級(jí)指針加兩個(gè)*,三級(jí)指針加三個(gè)*關(guān)系如下:
指針數(shù)組、指向函數(shù)的指針、指向二維數(shù)組的指針
指針數(shù)組:
指針變量和普通變量一樣,也能組成數(shù)組,如果一個(gè)數(shù)組中的所有元素保存的都是指針,那么我們就稱它為指針數(shù)組。指針數(shù)組的定義形式一般為:
除了每個(gè)元素的數(shù)據(jù)類型不同,指針數(shù)組和普通數(shù)組在其他方面都是一樣的,下面是一個(gè)簡(jiǎn)單的例子:
指針數(shù)組還可以和字符串?dāng)?shù)組結(jié)合使用:
指向函數(shù)的指針:
一個(gè)函數(shù)總是占用一段連續(xù)的內(nèi)存區(qū)域,函數(shù)名在表達(dá)式中有時(shí)也會(huì)被轉(zhuǎn)換為該函數(shù)所在內(nèi)存區(qū)域的首地址,這和數(shù)組名非常類似。我們可以把函數(shù)的這個(gè)首地址(或稱入口地址)賦予一個(gè)指針變量,使指針變量指向函數(shù)所在的內(nèi)存區(qū)域,然后通過指針變量就可以找到并調(diào)用該函數(shù)。這種指針就是函數(shù)指針。
注意( )的優(yōu)先級(jí)高于*,第一個(gè)括號(hào)不能省略,如果寫作returnType *pointerName(param list);就成了函數(shù)原型,它表明函數(shù)的返回值類型為returnType *
用指針來實(shí)現(xiàn)對(duì)函數(shù)的調(diào)用:
指向二維數(shù)組的指針:
(復(fù)盤一下二維數(shù)組的知識(shí))二維數(shù)組在概念上是二維的,有行和列,但在內(nèi)存中所有的數(shù)組元素都是連續(xù)排列的,它們之間沒有“縫隙”。以下面的二維數(shù)組 a 為例:
? ? ? C語言中的二維數(shù)組是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;每行中的 4 個(gè)元素也是依次存放。數(shù)組 a 為 int 類型,每個(gè)元素占用 4 個(gè)字節(jié),整個(gè)數(shù)組共占用 4×(3×4) = 48 個(gè)字節(jié)。
C語言把一個(gè)二維數(shù)組分解成多個(gè)一維數(shù)組來處理。對(duì)于數(shù)組 a,它可以分解成三個(gè)一維數(shù)組,即 a[0]、a[1]、a[2]。每一個(gè)一維數(shù)組又包含了 4 個(gè)元素,例如 a[0] 包含`a[0][0] 、a[0][1]、a[0][2]、a[0][3]。
為了更好的理解指針和二維數(shù)組的關(guān)系,我們先來定義一個(gè)指向 a 的指針變量 p:
[ ]的優(yōu)先級(jí)高于*,( )是必須要加的,如果赤裸裸地寫作int *p[4],那么應(yīng)該理解為int *(p[4]),p 就成了一個(gè)指針數(shù)組,而不是二維數(shù)組指針。
對(duì)指針進(jìn)行加法(減法)運(yùn)算時(shí),它前進(jìn)(后退)的步長與它指向的數(shù)據(jù)類型有關(guān),p 指向的數(shù)據(jù)類型是int [4],那么p+1就前進(jìn) 4×4 = 16 個(gè)字節(jié),p-1就后退 16 個(gè)字節(jié),那么這正好是數(shù)組 a 所包含的每個(gè)一維數(shù)組的長度。也就是說,p+1會(huì)使得指針指向二維數(shù)組的下一行,p-1會(huì)使得指針指向數(shù)組的上一行。
按照上面的定義,我們來看看代碼:
? ?*(p+1)+1表示第 1 行第 1 個(gè)元素的地址:*(p+1)單獨(dú)使用時(shí)表示的是第 1 行數(shù)據(jù),放在表達(dá)式中會(huì)被轉(zhuǎn)換為第 1 行數(shù)據(jù)的首地址,也就是第 1 行第 0 個(gè)元素的地址,因?yàn)槭褂谜袛?shù)據(jù)沒有實(shí)際的含義,編譯器遇到這種情況都會(huì)轉(zhuǎn)換為指向該行第 0 個(gè)元素的指針;就像一維數(shù)組的名字,在定義時(shí)或者和 sizeof、& 一起使用時(shí)才表示整個(gè)數(shù)組,出現(xiàn)在表達(dá)式中就會(huì)被轉(zhuǎn)換為指向數(shù)組第 0 個(gè)元素的指針。
*(*(p+1)+1)表示第 1 行第 1 個(gè)元素的值。很明顯,增加一個(gè) * 表示取地址上的數(shù)據(jù):**
指針數(shù)組和二維數(shù)組指針在定義時(shí)非常相似,但是括號(hào)的位置不同所表示的意思也就天壤之別:
指針數(shù)組和二維數(shù)組指針有著本質(zhì)上的區(qū)別:
指針數(shù)組是一個(gè)數(shù)組,只是每個(gè)元素保存的都是指針,以上面的 p1 為例,在32位環(huán)境下它占用 4×5 = 20 個(gè)字節(jié)的內(nèi)存。二維數(shù)組指針是一個(gè)指針,它指向一個(gè)二維數(shù)組,以上面的 p2 為例,它占用 4 個(gè)字節(jié)的內(nèi)存。
至于多維數(shù)組和二維數(shù)組沒有本質(zhì)的區(qū)別,但是復(fù)雜度倒是高了許多。一般不常用。
結(jié)束語:
程序在運(yùn)行過程中需要的是數(shù)據(jù)和指令的地址,變量名、函數(shù)名、字符串名和數(shù)組名在本質(zhì)上是一樣的,它們都是地址的助記符:在編寫代碼的過程中,我們認(rèn)為變量名表示的是數(shù)據(jù)本身,而函數(shù)名、字符串名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址;程序被編譯和鏈接后,這些名字都會(huì)消失,取而代之的是它們對(duì)應(yīng)的地址。指針就是存放地址的一種變量。
常見的的指針:

1、 指針變量可以進(jìn)行四則運(yùn)算。指針變量的加減運(yùn)算并不是簡(jiǎn)單的加上或減去一個(gè)整數(shù),而是跟指針指向的數(shù)據(jù)類型與地址有關(guān)。
2、給指針變量賦值時(shí),要將一份數(shù)據(jù)的地址賦給它,不能直接賦給一個(gè)整數(shù),例如int *p = 1000;是沒有意義的,使用過程中一般會(huì)導(dǎo)致程序崩潰。
3、使用指針變量之前一定要初始化,否則就不能確定指針指向哪里,如果它指向的內(nèi)存沒有使用權(quán)限,程序就崩潰了。對(duì)于暫時(shí)沒有指向的指針,直接賦值NULL讓它變?yōu)榭罩羔槨?/p>
4、數(shù)組也是有類型的,數(shù)組名的本意是表示一組類型相同的數(shù)據(jù)。在定義數(shù)組時(shí),或者和 sizeof、& 運(yùn)算符一起使用時(shí)數(shù)組名才表示整個(gè)數(shù)組,表達(dá)式中的數(shù)組名會(huì)被轉(zhuǎn)換為一個(gè)指向數(shù)組的指針。
指針的用法暫時(shí)就這些,C指針大法這些才是入門!繼續(xù)加油咯~
作者:Mr_Li_
對(duì)啦對(duì)啦!另外的話為了幫助大家,輕松,高效學(xué)習(xí)C語言/C++,我給大家分享我收集的資源,從最零基礎(chǔ)開始的教程到C語言項(xiàng)目案例,幫助大家在學(xué)習(xí)C語言的道路上披荊斬棘!可以來我粉絲群領(lǐng)取哦~

微信公眾號(hào):C語言編程學(xué)習(xí)基地
整理分享(多年學(xué)習(xí)的源碼、項(xiàng)目實(shí)戰(zhàn)視頻、項(xiàng)目筆記,基礎(chǔ)入門教程)最重要的是你可以在群里面交流提問編程問題哦!
其他編程學(xué)習(xí)書籍分享:
