指針,初學(xué)者的夢(mèng)魘
對(duì)于初學(xué)者,在學(xué)習(xí)C語(yǔ)言的過(guò)程中每每提到指針都會(huì)讓無(wú)數(shù)人聞風(fēng)散膽吧。 因?yàn)樵谖覀儗W(xué)C語(yǔ)言的時(shí)候很多人(包括學(xué)長(zhǎng)或老師)可能都會(huì)告訴我們指針是C語(yǔ)言中最難的一部分,所以導(dǎo)致還沒(méi)開(kāi)始接觸就勸退了一批人。 確實(shí),C語(yǔ)言的精華也在于此,這也是它之所以長(zhǎng)盛不衰的原因。 很多時(shí)候初學(xué)者之所以害怕使用指針是因?yàn)楹ε氯L試,其實(shí)如果在初學(xué)階段愿意去嘗試,敢于去修改bug,這時(shí)你就會(huì)發(fā)現(xiàn)指針學(xué)起來(lái)也簡(jiǎn)單多了。 你是不是因?yàn)楹ε赂慊?code>*(p+1)與*p+1
,const int *p
與int *const p
,**p
,&p
等看起來(lái)就讓人蒙圈的變量、符號(hào),并且怎么記都似乎記不住? 那就應(yīng)該多去練習(xí)! 在之前的內(nèi)容中我也一直沒(méi)有寫(xiě)這部分知識(shí)點(diǎn),因?yàn)槲易约河X(jué)得指針只要去使用它確實(shí)是沒(méi)難度的,另外一個(gè)原因是,這種沒(méi)難度似乎又只可意會(huì)不可言傳,自己總結(jié)出來(lái)的話(huà)總是沒(méi)有書(shū)籍中寫(xiě)的清晰,每個(gè)人基礎(chǔ)不一樣同樣的話(huà)對(duì)不同人理解的程度又不同,所以這里還是希望初學(xué)者自己主動(dòng)把這塊硬骨頭啃下去,我就提點(diǎn)我自己認(rèn)證之內(nèi)的技巧供大家參考。
從定義出發(fā)去理解指針
這里對(duì)于指針的官方定義我就不做搬運(yùn)了,所有講解C語(yǔ)言的書(shū)本都少不了對(duì)指針的定義。 如果需要權(quán)威的說(shuō)明可以查看《C Primer Plus》
這本經(jīng)典書(shū)籍,其中還包含很多細(xì)節(jié)說(shuō)明和舉例應(yīng)用,把它作為參考書(shū)再好不過(guò)了,我想我能描述出來(lái)的文字絕對(duì)比不上他書(shū)中寫(xiě)的專(zhuān)業(yè)詳細(xì)。 指針最簡(jiǎn)單的概念就是:它是程序運(yùn)行過(guò)程中的一個(gè)內(nèi)存地址
。 至于一些針對(duì)指針變量衍生出來(lái)的奇奇怪怪的的表達(dá)式實(shí)質(zhì)上就是運(yùn)算符優(yōu)先級(jí)與結(jié)合規(guī)律的基礎(chǔ)內(nèi)容。 如果區(qū)分不出來(lái)可以先復(fù)習(xí)運(yùn)算符部分知識(shí)。 我們都知道所有程序要跑起來(lái)都需要先加載到內(nèi)存中,程序運(yùn)行所需的數(shù)據(jù)都會(huì)根據(jù)程序指令進(jìn)行動(dòng)態(tài)分配。 很多朋友平時(shí)可能會(huì)說(shuō),哎呀,我的電腦(手機(jī))又卡死啦,這時(shí)候很大可能性就是你的電腦或手機(jī)內(nèi)存被占滿(mǎn)了,而不是硬盤(pán)(存儲(chǔ)器)沒(méi)有足夠空間。 當(dāng)然如果你的磁盤(pán)空間不夠,然后運(yùn)行內(nèi)存也消耗過(guò)多那活該你的機(jī)器被卡。
學(xué)習(xí)時(shí)該怎么樣避免踩坑
還是哪句話(huà),多練習(xí)把坑踩平自然而就不會(huì)再踩坑了,這肯定是一句廢話(huà),學(xué)啥技術(shù)都可以這么說(shuō)。 我的建議就是善用編譯器的調(diào)試功能
和printf()
函數(shù),現(xiàn)在的編譯器功能都是越來(lái)越完善的,在初學(xué)階段使用程序調(diào)試功能可以讓你少走很多彎路,結(jié)合打斷點(diǎn)調(diào)試程序,單步執(zhí)行,觀察變量信息,哪里對(duì)點(diǎn)哪里,調(diào)多了你編程都會(huì)越來(lái)越有手感。 當(dāng)然,等你有一定經(jīng)驗(yàn)之后,在項(xiàng)目開(kāi)發(fā)過(guò)程中還是希望你不要過(guò)多的依賴(lài)調(diào)試功能。 希望你對(duì)程序能夠熟練到通過(guò)看代碼就能發(fā)現(xiàn)邏輯是否正確。 至于初學(xué)者嘛,此時(shí)不用你還想啥時(shí)候用呢! 另外一個(gè)很關(guān)鍵的的技巧就是多打印信息,當(dāng)然也是要你到處都打印,一個(gè)變量都不落下的打印,如果你不想時(shí)不時(shí)的調(diào)試代碼,那就選擇這種方式,選擇在關(guān)鍵的地方對(duì)關(guān)鍵的數(shù)據(jù)進(jìn)行輸出,這樣你直接在控制或者串口助手中就能及時(shí)發(fā)現(xiàn)問(wèn)題。 當(dāng)然采用這種方式在開(kāi)發(fā)階段還是比較實(shí)用的,如果在巧妙的結(jié)合一些宏定義語(yǔ)句進(jìn)入功能調(diào)試的差不多之后就整體關(guān)閉輸出就好了,即使日后出現(xiàn)bug需要再調(diào)試處理起來(lái)也是非常方便。 所以以上兩種方法用于練習(xí)指針操作對(duì)初學(xué)者來(lái)說(shuō)也是再好不過(guò)了,總之我曾經(jīng)就是這么練習(xí)的。
Keil中怎么了解指針
Keil和常用的C語(yǔ)言編譯器VS一樣具備調(diào)試功能,所以在你不會(huì)的時(shí)候也是可以采用調(diào)試的辦法仿真程序運(yùn)行結(jié)果來(lái)達(dá)到學(xué)習(xí)指針的目的。 下面舉一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明。
隨便寫(xiě)一個(gè)邏輯上跑得通的例子程序,編譯沒(méi)問(wèn)題之后點(diǎn)擊debug即可。
#include
#include
unsigned int var1 = 0;
unsigned int idata var2[] = {1,2,3,4};
unsigned int data var3[] = {5,6,7};
unsigned int var4[] = {8,9};
unsigned int code var5[] = {10,11,12};
unsigned int data *var6;
unsigned int *var7;
unsigned int *var8;
unsigned int *var9;
unsigned int *var10;
//unsigned int *var11;
void main(void)
{
var1 = 100;
var2[0] = 101;
var3[0] = 102;
var4[0] = 103;
// va5[0] = 104;//這是一條錯(cuò)誤語(yǔ)句,存放于flash中的數(shù)據(jù)為只讀
var6 = &var1;
var7 = &var2;
var8 = &var3;
var9 = &var4;
var10 = &var5;
}
在接下來(lái)彈出的窗口中就可以查看,哪些是指針的地址,以及其對(duì)應(yīng)的值,都可以看的一目了然。
匯編中內(nèi)存信息
這個(gè)辦法學(xué)起來(lái)難度不比單純的敲代碼更有意義嗎,即可以從底層了解單片機(jī)執(zhí)行原理又可以了解代碼的執(zhí)行過(guò)程,我感覺(jué)這應(yīng)該不會(huì)那么無(wú)聊吧。 單片機(jī)只是一種微型的計(jì)算機(jī)放大到開(kāi)發(fā)計(jì)算機(jī)程序也是一樣的道理吧。
如果底層代碼理解起來(lái)有一定的難度也可以添加變量到觀察窗口進(jìn)行單步測(cè)試,這樣也一樣直觀明了。
變量觀察窗口
當(dāng)然還有很多方法進(jìn)行查看指針變量的變化過(guò)程,這里只是舉了一個(gè)非常簡(jiǎn)單的例子,初學(xué)者完全可以充分發(fā)揮自己的動(dòng)手能力探索自己的方法。 如果有自己想法歡迎留言或私信交流。
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
3037瀏覽量
74147 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7608瀏覽量
137134 -
程序
+關(guān)注
關(guān)注
117文章
3792瀏覽量
81165 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4338瀏覽量
62751 -
指針
+關(guān)注
關(guān)注
1文章
480瀏覽量
70582
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論