久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 兩道(dao)面試題所(suo)引發的(de)C指針的(de)思考

兩(liang)道面試(shi)題所引發的(de)C指針的(de)思考 時間:2018-08-15      來源:未知

 C語(yu)言(yan)(yan)(yan)是(shi)一門(men)使用(yong)比較廣(guang)泛的(de)高級編程語(yu)言(yan)(yan)(yan),而指針(zhen)則是(shi)C語(yu)言(yan)(yan)(yan)的(de)精髓所在,可(ke)以說學習C語(yu)言(yan)(yan)(yan)不會靈(ling)活使用(yong)指針(zhen)就(jiu)談(tan)不上(shang)精通C語(yu)言(yan)(yan)(yan)。但是(shi)由(you)于C語(yu)言(yan)(yan)(yan)指針(zhen)的(de)靈(ling)活性(xing)導致了我(wo)們在使用(yong)過程中出現莫名其(qi)妙的(de)各種(zhong)問題,甚(shen)至是(shi)段(duan)錯誤。

本文引用地址://fsbing.cn/emb/Column/7260.html

本文將以(yi)兩道典型的面試題(ti)為切入點,引發我(wo)們對于C語言指(zhi)針(zhen)的思考。并給予詳(xiang)細的解(jie)釋,從原理角度來解(jie)析C指(zhi)針(zhen)。全(quan)文也是源(yuan)碼分析加(jia)結果演示的形式說(shuo)明問(wen)題(ti)所在。

問題一:

一下的代碼(ma)段(duan)是否正(zheng)(zheng)確(que)(que),如(ru)果正(zheng)(zheng)確(que)(que)結(jie)果是什么?如(ru)果不正(zheng)(zheng)確(que)(que)如(ru)何改正(zheng)(zheng)?

void fun(char *p)

{

p=(char *)malloc(100);

}

int main(int argc, const char *argv[])

{

char *str=NULL;

fun(str);

strcpy(str,"hello");

printf("%s\n",str);

return 0;

}

如果(guo)大家不(bu)仔細看的(de)話,一定(ding)(ding)認(ren)為是正確的(de),因為沒有發(fa)(fa)(fa)(fa)現明顯的(de)語(yu)法錯(cuo)誤。不(bu)錯(cuo)你(ni)的(de)想法是對的(de),編(bian)譯的(de)時候(hou)一定(ding)(ding)可以(yi)通過,但是當(dang)你(ni)運行(xing)(xing)可執行(xing)(xing)程序(xu)的(de)時候(hou)發(fa)(fa)(fa)(fa)現:“哎呀,段(duan)錯(cuo)誤!”,也(ye)(ye)沒錯(cuo),確實也(ye)(ye)發(fa)(fa)(fa)(fa)生(sheng)了段(duan)錯(cuo)誤,也(ye)(ye)許(xu)這個段(duan)錯(cuo)誤比較(jiao)隱蔽(bi)不(bu)易發(fa)(fa)(fa)(fa)現并定(ding)(ding)位(wei)。下面我們使用gdb來定(ding)(ding)位(wei)到段(duan)錯(cuo)誤的(de)位(wei)置(zhi),并分(fen)析錯(cuo)誤原(yuan)因:

命(ming)令行輸(shu)入(ru):gcc -g -rdynamic test.c (test.c即是(shi)我們將源碼(ma)頭文件(jian)加上編寫的(de)C語言(yan)源文件(jian)),然后生成(cheng)了可(ke)以以用于gdb調試且可(ke)以定(ding)位(wei)段錯誤的(de)可(ke)執行程(cheng)(cheng)序(xu),接下(xia)來輸(shu)入(ru)gdb ./a.out 進(jin)入(ru)gdb調試模式,輸(shu)入(ru)r運行程(cheng)(cheng)序(xu),則立馬定(ding)位(wei)到(dao)strcpy(str,"hello"); 這(zhe)行程(cheng)(cheng)序(xu)段,于是(shi)我們回(hui)到(dao)程(cheng)(cheng)序(xu)中分析代碼(ma):發現(xian)是(shi)我們把一個(ge)指(zhi)針(zhen)常(chang)量NULL作為(wei)fun函數的(de)參(can)數傳遞(di)給了p,造成(cheng)了子函數中對一個(ge)指(zhi)針(zhen)常(chang)量進(jin)行賦(fu)值操作,于是(shi)就在程(cheng)(cheng)序(xu)運行中調用fun函數的(de)時候造成(cheng)了段錯誤。

以(yi)上(shang)就(jiu)是這段(duan)(duan)代碼(ma)的錯(cuo)誤(wu)分析,既(ji)然我們通過(guo)gdb定位到了(le)(le)(le)段(duan)(duan)錯(cuo)誤(wu)的位置,也分析出了(le)(le)(le)段(duan)(duan)錯(cuo)誤(wu)產(chan)生的原因(yin),那么如何修改(gai)(gai)代碼(ma)才能(neng)實現相應的功(gong)能(neng)還不至于造成段(duan)(duan)錯(cuo)誤(wu)呢(ni)?考慮到要盡量保證代碼(ma)段(duan)(duan)的完整性,于是想到從傳遞(di)的參數上(shang)尋突破口。既(ji)然不能(neng)傳遞(di)指(zhi)針(zhen)常量,那么我們想到傳遞(di)一個(ge)值(zhi)能(neng)夠裝(zhuang)得下指(zhi)針(zhen)不就(jiu)行了(le)(le)(le)于是對代碼(ma)段(duan)(duan)做如下改(gai)(gai)變(修改(gai)(gai)部(bu)分已做好了(le)(le)(le)紅色標記):

void fun(char **p)

{

*p=(char *)malloc(100);

}

int main(int argc, const char *argv[])

{

char *str=NULL;

fun(&str);

strcpy(str,"hello");

printf("%s\n",str);

return 0;

}

對比發現,這次我們傳遞了一個二級指針&str,實際上就是傳遞了裝載指針的容器,這樣以來我們就可以把在子函數中動態分配的內存空間的首地址放到了這個“容器”中了(即是str被賦值上了新分配內存的首地址)。在一次編譯執行,無段錯誤,結果輸出“hello”字符串。也就完美地解決了這道錯誤非常隱蔽的面試題。同樣有的同學會想,把NULL掉咋樣?編譯運行發現還是出現段錯誤,還是同樣的問題:指針str屬于局部變量,系統會隨機分配一個地址給str,同樣是指針常量賦值。 而當我們解決了這道題,我們能夠感受到指針的靈活性和操作的隱蔽性,我們也就知道了常量是不能被賦值的(因為他被系統認為是只讀),還知道了將一個二級指針作為參數傳遞可以保存一個地址的值,這也是編程的一個技巧。

接下(xia)來(lai)我(wo)們在看一(yi)看第二道題:

問題二:

以下代碼段的執(zhi)行結果?

int main(int argc, const char *argv[])

{

int i,n=0;

for(i=1;i

{

n=10*n+*argv[i]-'0';

}

printf("%d\n",n);

return 0;

}

./a.out 12 345 678

雖(sui)然代碼很簡(jian)練,但是(shi)(shi)(shi)(shi)(shi)(shi)如(ru)果不細心分(fen)析還是(shi)(shi)(shi)(shi)(shi)(shi)很難把這(zhe)(zhe)(zhe)道題(ti)答(da)案寫出來的(de)(de)(de)(de),甚至是(shi)(shi)(shi)(shi)(shi)(shi)沒有任何思(si)路。實(shi)際上(shang)這(zhe)(zhe)(zhe)道題(ti)考(kao)察(cha)的(de)(de)(de)(de)是(shi)(shi)(shi)(shi)(shi)(shi)大(da)家對于指(zhi)針(zhen)的(de)(de)(de)(de)掌握和(he)ascii的(de)(de)(de)(de)一(yi)些知(zhi)識(shi):大(da)家一(yi)定要理(li)解*argv[i]意思(si),如(ru)果不注(zhu)意可能會認為(wei)是(shi)(shi)(shi)(shi)(shi)(shi)取命令(ling)行參數的(de)(de)(de)(de)第(di)二(er)個字(zi)符(fu)(fu)(fu)串(chuan)(chuan)的(de)(de)(de)(de)值,其實(shi)不然,這(zhe)(zhe)(zhe)樣理(li)解的(de)(de)(de)(de)話大(da)家對于指(zhi)向一(yi)個字(zi)符(fu)(fu)(fu)串(chuan)(chuan)的(de)(de)(de)(de)字(zi)符(fu)(fu)(fu)指(zhi)針(zhen)的(de)(de)(de)(de)的(de)(de)(de)(de)不理(li)解,指(zhi)向一(yi)個字(zi)符(fu)(fu)(fu)串(chuan)(chuan)的(de)(de)(de)(de)字(zi)符(fu)(fu)(fu)指(zhi)針(zhen)實(shi)際上(shang)是(shi)(shi)(shi)(shi)(shi)(shi)指(zhi)向一(yi)個字(zi)符(fu)(fu)(fu)串(chuan)(chuan)首字(zi)符(fu)(fu)(fu)的(de)(de)(de)(de)地址,命令(ling)行參數輸入的(de)(de)(de)(de)12 345 678看(kan)似數字(zi),實(shi)際上(shang)是(shi)(shi)(shi)(shi)(shi)(shi)一(yi)個個字(zi)符(fu)(fu)(fu)串(chuan)(chuan),*argv[i]的(de)(de)(de)(de)意思(si)也(ye)(ye)就是(shi)(shi)(shi)(shi)(shi)(shi)取各自字(zi)符(fu)(fu)(fu)串(chuan)(chuan)的(de)(de)(de)(de)首字(zi)符(fu)(fu)(fu)也(ye)(ye)就是(shi)(shi)(shi)(shi)(shi)(shi)取1、3、6,說到這(zhe)(zhe)(zhe)里這(zhe)(zhe)(zhe)道面試題(ti)也(ye)(ye)就引刃而解了。那么(me)*argv[i]-'0'是(shi)(shi)(shi)(shi)(shi)(shi)啥(sha)意思(si)呢?很顯然嗎,就是(shi)(shi)(shi)(shi)(shi)(shi)將ascii表示的(de)(de)(de)(de)字(zi)符(fu)(fu)(fu)轉(zhuan)化為(wei)對應的(de)(de)(de)(de)數字(zi)也(ye)(ye)就是(shi)(shi)(shi)(shi)(shi)(shi)數字(zi)1、3、6。到這(zhe)(zhe)(zhe)里我們在通過推(tui)理(li)就得到了終(zhong)的(de)(de)(de)(de)結果:136。

通過了這一番地分析是不是也挺簡單的,那必須的啊,通過這道面試題我們也就知道了:指向一個字符串的指針實際上就是把字符串的首地址賦給了指針變量,還有就是一個字符減去’0’就能得到字符所對應的數字。

當然這只是(shi)兩道比較易錯的(de)(de)(de)(de)使(shi)用(yong)指針(zhen)(zhen)(zhen)的(de)(de)(de)(de)面試(shi)(shi)題,很(hen)多(duo)面試(shi)(shi)題都(dou)是(shi)從(cong)大家對(dui)指針(zhen)(zhen)(zhen)本(ben)質(zhi)的(de)(de)(de)(de)認識上(shang)(shang)著手來考察大家,只要掌握(wo)指針(zhen)(zhen)(zhen)的(de)(de)(de)(de)本(ben)質(zhi),了解常見段錯誤的(de)(de)(de)(de)產生的(de)(de)(de)(de)原因和處(chu)理方案,了解C語(yu)言內存的(de)(de)(de)(de)分配情況(kuang)就(jiu)(jiu)能煉(lian)就(jiu)(jiu)一(yi)雙(shuang)”火眼(yan)金(jin)睛“,從(cong)本(ben)質(zhi)上(shang)(shang)真正精通C語(yu)言。以(yi)上(shang)(shang)也是(shi)本(ben)人通過(guo)實踐和深入的(de)(de)(de)(de)分析得出(chu)的(de)(de)(de)(de)一(yi)些經(jing)驗,如若有(you)更加(jia)簡單易懂的(de)(de)(de)(de)方案望給(gei)出(chu)寶貴意見,待以(yi)后修正完善。

上一篇:wireshark抓包工具如何使用

下一篇:Linux C中對json格式數組數據的生成與解析

熱點文章推薦
華清學員就業(ye)榜(bang)單
高(gao)薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企(qi)業(ye)培(pei)訓洽談專線:010-82525379 院校合作洽(qia)談(tan)專線(xian):010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部