C語(yǔ)言基礎(chǔ)知識(shí):最核心的—指針!知識(shí)總結(jié)(第一部分)
指針是C語(yǔ)言最重要也是最難理解的部分,它在我們平時(shí)的工作中無(wú)處不在。
有人說(shuō)學(xué)會(huì)了指針,C語(yǔ)言也就學(xué)會(huì)一半。為什么說(shuō)指針難。因?yàn)橹羔樑c數(shù)組相結(jié)合就涉及數(shù)組指針與指針數(shù)組。指針與結(jié)構(gòu)體結(jié)合就涉及結(jié)構(gòu)體指針。指針與字符結(jié)合涉及字符指針。指針與const結(jié)合涉及常量指針與指針常量。指針與函數(shù)結(jié)合涉及函數(shù)指針與指針函數(shù),同時(shí)也會(huì)涉及回調(diào)函數(shù)。指針和指針結(jié)合涉及到二維指針。

作者曾經(jīng)因?yàn)樯厦娴倪@些問(wèn)題,困擾了許久。因而在網(wǎng)上找了許多的博客來(lái)解答疑惑。這篇文章,我試圖將上面的知識(shí)點(diǎn)以例子的方式呈現(xiàn)給大家,我相信通過(guò)閱讀本文,大家會(huì)對(duì)指針有更深一步的了解。文中涉及的例子均來(lái)源于網(wǎng)上。
1 指針的定義
我們知道,普通的變量存儲(chǔ)的是一個(gè)值。而指針變量,它存儲(chǔ)的也是一個(gè)值,只是這是一個(gè)特殊的值:它的值是另一個(gè)變量的地址。
指針的定義形式如下:
其意思就是name是一個(gè)指針,它指向的是一個(gè)類(lèi)型為dataype的地址。
指針存儲(chǔ)的是一個(gè)地址,如果需要獲取這個(gè)地址對(duì)應(yīng)的內(nèi)容,可以通過(guò)解引用符*獲取:
這里需要注意的一點(diǎn),也是我以前經(jīng)常迷惑的一點(diǎn):定義指針時(shí),編譯器并不為指針?biāo)赶虻膶?duì)象分配空間,它只是分配指針本身的空間,除非在定義時(shí)同時(shí)賦給一個(gè)字符串常量進(jìn)行初始化。比如:
上面這個(gè)代碼段說(shuō)明了一個(gè)極為常見(jiàn)的錯(cuò)誤:我們聲明了這個(gè)變量,但從未對(duì)它進(jìn)行初始化,所以沒(méi)法預(yù)測(cè)12這個(gè)值將存儲(chǔ)于什么地方。如果變量是靜態(tài)的,它會(huì)被初始化為0,;如果變量是自動(dòng)地,它根本不會(huì)被初始化。無(wú)論哪種情況,聲明一個(gè)指向整型的指針都不會(huì)"創(chuàng)建"用于存儲(chǔ)整型值的內(nèi)存空間。
但是, 下面的定義創(chuàng)建了一個(gè)字符串常量(為其分配了內(nèi)存):
始化指針時(shí)所創(chuàng)建的字符串常量被定義為只讀。如果試圖通過(guò)指針修改這個(gè)字符串的值,程序就會(huì)出現(xiàn)未定義的行為。
除了上述的定義是對(duì)的外,其他的定義都是錯(cuò)誤的:
2 指針的運(yùn)算
指針 +(-) 整數(shù)指針存儲(chǔ)的是一個(gè)地址,這個(gè)地址本質(zhì)上是一個(gè)整數(shù),所以可以加上或減去一個(gè)整數(shù)。但是它不是普通的加法或減法,指針加上或減去一個(gè)整數(shù)結(jié)果是另一個(gè)指針。但是,運(yùn)算后的指針指向哪里呢?當(dāng)一個(gè)指針和一個(gè)整數(shù)執(zhí)行算術(shù)運(yùn)算時(shí),整數(shù)在執(zhí)行加法(減法)運(yùn)算前會(huì)根據(jù)合適的大小進(jìn)行調(diào)整。這個(gè)"合適的大小"就是指針?biāo)赶蝾?lèi)型的大小,"調(diào)整"就是把整數(shù)值和"合適的大小"相乘。
運(yùn)算結(jié)果:
由上面的結(jié)果可以看到,當(dāng)對(duì)指針pa,pb,pc進(jìn)行加1時(shí),實(shí)際地址增加的是對(duì)應(yīng)類(lèi)型的大小。減法也一樣。
指針 - 指針
只有當(dāng)兩個(gè)指針都指向同一個(gè)數(shù)組中的元素時(shí),才允許從一個(gè)指針減去另一個(gè)指針。兩個(gè)指針相減的結(jié)果是兩個(gè)指針之間的元素個(gè)數(shù)。比如,如果p1指向array[i]而p2指向array[j],那么p2-p1的值就是j-i的值。如果兩個(gè)指針?biāo)赶虻牟皇峭粋€(gè)數(shù)組中的元素,那么它們之間相減的結(jié)果是未定義的,也是毫無(wú)意義的。
3 指針與數(shù)組
3.1 數(shù)組指針(指向數(shù)組的指針)
數(shù)組指針,它是一個(gè)指針,指向的是一個(gè)數(shù)組。即它存的是一個(gè)數(shù)組變量的地址。所以這個(gè)指針每加一步的步長(zhǎng)就是數(shù)組的長(zhǎng)度。由于它每跨一步都是整個(gè)數(shù)組,所以又稱(chēng)行數(shù)組。
運(yùn)行結(jié)果:
首先,pa是一個(gè)數(shù)組指針,它首先存的是數(shù)組a的首元素的地址,由于數(shù)組名也是數(shù)組的首地址,所以a, &a, &a[0][0]的地址相同。pa中存的也是這個(gè)地址。然后對(duì)pa進(jìn)行解引用,*pa之后得到這個(gè)數(shù)組,然后(*pa)[i]就是獲得這個(gè)數(shù)組下標(biāo)為i的元素。
3.2 指針數(shù)組
指針數(shù)組,它本質(zhì)上是一個(gè)數(shù)組,只不過(guò)整個(gè)數(shù)組存的類(lèi)型是一個(gè)指針而已。
運(yùn)行結(jié)果:
4 指針與字符
在C語(yǔ)言中,表示字符串一般有兩種形式,一種是數(shù)組的形式,一種是字符指針的形式。
數(shù)組形式:
字符指針形式:
雖然上面兩種形式都能表示字符串,但是它們還是有些區(qū)別的:
存儲(chǔ)方式字符數(shù)組由若干元素組成,每個(gè)元素存放一個(gè)字符,而字符指針變量只存放字符串的首地址,不是整個(gè)字符串。
存儲(chǔ)位置。數(shù)組是在內(nèi)存中開(kāi)辟了一段空間存放字符串, 是存在棧區(qū)。而字符指針是在字面值常量區(qū)開(kāi)辟了一段空間存放字符串,將字符串的首地址付給指針變量str。
賦值方式。對(duì)于數(shù)組,下面的賦值方式是錯(cuò)誤的:
而對(duì)字符指針變量,可以采用下面方法賦值:
可否被修改。指針變量指向的字符串內(nèi)容不能被修改,但指針變量的值(即存放的地址或者指向)是可以被修改的。
來(lái)源:稀土掘金,作者:Elec

對(duì)啦對(duì)啦!另外的話為了幫助大家,輕松,高效學(xué)習(xí)C語(yǔ)言/C++,我給大家分享我收集的資源,從最零基礎(chǔ)開(kāi)始的教程到C語(yǔ)言項(xiàng)目案例,幫助大家在學(xué)習(xí)C語(yǔ)言的道路上披荊斬棘!可以來(lái)我粉絲群領(lǐng)取哦~
微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地
C語(yǔ)言零基礎(chǔ)入門(mén)教程(83集全)
整理分享(多年學(xué)習(xí)的源碼、項(xiàng)目實(shí)戰(zhàn)視頻、項(xiàng)目筆記,基礎(chǔ)入門(mén)教程)最重要的是你可以在群里面交流提問(wèn)編程問(wèn)題哦!
編程學(xué)習(xí)粉絲群:
