0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

周立功手把手教你學(xué)C語言編程:用數(shù)組,構(gòu)造一個雙重指針

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:電子大兵 ? 2017-09-04 14:15 ? 次閱讀

第一章為程序設(shè)計基礎(chǔ),本文為1.8.3 指針數(shù)組中的第二要點(diǎn):字符串與指針的指針、第三要點(diǎn):字符串與二維數(shù)組。

>>>>1.字符串與指針的指針

除了作為sizeof或&的操作數(shù)外,指針數(shù)組的數(shù)組名在表達(dá)式中等價一個雙重指針常量,其右值為數(shù)組變量的首地址。比如:

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

其完全等價于

int main(int argc, char **argv)

顯然,如果要訪問一個指針數(shù)組,使用指向指針的指針最為方便,但稍不注意偶爾也會寫出錯誤的程序,詳見程序清單 1.45。

程序清單1.45一個錯誤的范例程序

1 #include

2 int main(void)

3 {

4 char **pKeyWord;

5 static char * keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};

6

7 pKeyWord = keyWord;

8 while(**pKeyWord != NULL)

9 printf("%s\n", *(pKeyWord++));

10 return 0;

11 }

由于字符串末尾的空字符或'\0'與空指針或NULL的值0恰好相等,因此上述代碼的編譯和執(zhí)行結(jié)果都是正確的,但確實(shí)是一個錯誤的示例。因?yàn)榇蠖鄶?shù)編譯器在編譯程序清單 1.45(9)時進(jìn)行了類型轉(zhuǎn)換,將**pKeyWord由char類型轉(zhuǎn)換成了void *,或?qū)ULL由void *轉(zhuǎn)換成了char類型,但在編譯時一般會給出一條警告信息,因?yàn)榭兆址钦麛?shù)類型,而空指針是指針類型。

之所以寫出這樣的代碼,說明程序員完全沒有理解“""”和NULL的區(qū)別。如果編譯器完全禁止char與指針之間的相互轉(zhuǎn)換,則上述代碼可能編譯失敗。由此可見,需要認(rèn)真對待編譯器給出的每一條警告信息,并分析出現(xiàn)警告信息的原因,而不是僅僅編譯通過、程序執(zhí)行結(jié)果正確就萬事大吉了。

程序清單 1.46針對程序清單 1.45的一種解決方案。其首先判斷*keyWord是否為空指針,如果為空指針,則退出循環(huán);如果不是,則輸出顯示該字符串,然后將pKeyWord加1指向下一個字符串。

程序清單 1.46 用指針數(shù)組變量與雙重指針變量處理多個字符串

1 #include

2 int main(void)

3 {

4 char **pKeyWord;

5 static char * keyWord[6] = {"eagle", "cat", "and", "dog", "ball", "NULL"};

6

7 pKeyWord = keyWord;

8 while(*pKeyWord != NULL)

9 printf("%s\n", *(pKeyWord++));

10 return 0;

11 }

由于指針類型的數(shù)組也是一維數(shù)組,因此雙重指針的算術(shù)運(yùn)算與普通指針的算術(shù)運(yùn)算十分相似。當(dāng)pKeyWord指向keyWord時,keyWord[i]、pKeyWord[i]、*(keyWord+i)與*(pKeyWord+i)是等效的訪問指針數(shù)組變量元素的4種表現(xiàn)形式。keyWord[i]指向了第i個字符串的首地址,即第i個字符串第1個字符的地址。若訪問指針keyWord[0]所指向的目標(biāo)變量,則*keyWord[0]的值是字符串"Monday"的第1個字符M。當(dāng)然,*keyWord[0]也可以寫成*pKeyWord[0]、**keyWord、**pKeyWord等表現(xiàn)形式。

程序清單 1.47是針對程序清單 1.45的另一種解決方案。其首先判斷*pKeyWord所指向的是否為空字符串(即只包含'\0'的字符串,也就是字符串第0個元素為'\0'的字符串),如果為空字符串,則退出循環(huán);如果不是,則輸出顯示該字符串,然后將pKeyWord加1指向下一個字符串。

程序清單1.47用指針數(shù)組變量與雙重指針變量處理多個字符串(2)

1 #include

2 int main(void)

3 {

4 char **pKeyWord;

5 static char * keyWord[6] = {"eagle", "cat", "and", "dog", "ball", "NULL"};

6

7 pKeyWord = keyWord;

8 while(**pKeyWord != ""[0]) // ""[0]等價于'\0'

9 printf("%s\n", *(pKeyWord++));

10 return 0;

11 }

在實(shí)際的應(yīng)用中,程序清單 1.47(9)中的“""[0]”是一種非常少見的用法。如果用'\0'代替它則功能一樣,執(zhí)行效率還稍微高一點(diǎn)。由于字符串常量是只讀字符數(shù)組,因此字符串常量“""”就是只有字符串結(jié)束字符'\0'的字符串常量,即數(shù)組變量的第0個元素的值為'\0'。由于“""”是一個數(shù)組變量,因此可以使用下標(biāo)運(yùn)算符對“""”進(jìn)行求值運(yùn)算,獲得指定的數(shù)組元素,從而得到“""[0]”的值'\0'。一般來說,在大多數(shù)程序中都直接使用'\0'不使用""[0],而程序清單 1.47(8)之所以使用“""[0]”有兩重意義:

與程序清單 1.47(5)對應(yīng),使程序的含義更清晰。當(dāng)*pKeyWord指向最后一個字符串的第0個元素時,則結(jié)束循環(huán);注意:這個字符串的第0個元素與其他任何一個字符串的第0個元素都不相同。

可移植性更好。如果將來C語言的字符修改了結(jié)束字符的定義,則程序也不必修改。比如,為了支持中文,將一個中文字作為一個字符,則字符類型必須修正,因?yàn)樗辉偈?位,所以其結(jié)束字符也可能修改。

如果要存儲靜態(tài)的表格式數(shù)據(jù),當(dāng)然應(yīng)該用數(shù)組。搜索程序必須知道數(shù)組中有多少個元素,對這個問題的處理方法是傳遞一個數(shù)組長度參數(shù)。這里采用的另一種方法是選擇指針數(shù)組方式。即:

const char * keyWord[6] = {"eagle", "cat", "and", "dog", "ball", NULL};

即在表尾增加了一個NULL指針,這個NULL指針使函數(shù)在搜索這個表時能夠檢測到表的結(jié)束,而無需預(yù)先知道表的長度,其相應(yīng)的搜索范例程序詳見程序清單 1.48。

程序清單1.48搜索范例程序

1 int lookup(char *word, char *keyword[])

2 {

3

4 for(int i = 0; keyiWord[i] != NULL; i++)

5 if(strcmp(word, keyWord[i] == 0))

6 return i;

7 return -1;

8 }

在C語言中,字符串?dāng)?shù)組參數(shù)可以是char *keyiWord[]或char **keyWord,雖然它們都是等價的,但前一種形式能將參數(shù)的使用方式表達(dá)得更清楚。

這里采用的搜索算法稱為順序搜索,它逐個查看每個數(shù)據(jù)是不是要找的那一個。如果數(shù)據(jù)的個數(shù)不多,順序搜索也很快。標(biāo)準(zhǔn)庫中提供了一些函數(shù),它們可以處理某些特定類型的順序搜索問題,比如,strchr和strstr能搜索給定的字符串中的字符或子串,如果對某個數(shù)據(jù)類型有這種函數(shù)就應(yīng)該直接使用它。

雖然搜索看起來非常簡單,但它的工作量與被搜索數(shù)據(jù)的個數(shù)成正比。如果要找的的數(shù)據(jù)并不存在,而數(shù)據(jù)量加倍也會使搜索的工作量加倍。這是一種線性關(guān)系,其運(yùn)行時間是數(shù)據(jù)規(guī)模的線性函數(shù),因此這種搜索也被稱為線性搜索。

>>>>2.字符串與二維數(shù)組

有兩種風(fēng)格描述C風(fēng)格的字符串?dāng)?shù)組,即二維數(shù)組和指針數(shù)組,比如:

char keyWord[][6] = {"eagle", "cat", "and", "dog", "ball"};

char * keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};

其中,第1個聲明創(chuàng)建了一個二維數(shù)組,詳見圖 1.16(a)。第2個聲明創(chuàng)建了一個指針數(shù)組,每個指針元素都初始化為指向各個不同的字符串常量,相加圖 1.16(b)。

圖 1.16 矩形數(shù)組和不規(guī)則數(shù)組


如果改用二維數(shù)組代替指針數(shù)組修改程序清單 1.44,這兩種方法使用了相同的初始化列表,顯示字符串的for循環(huán)代碼也相同,因此只要修改形參和局部變量的聲明即可。由于數(shù)組變量名的值是指針,因此無論傳遞給函數(shù)的是指針還是數(shù)組名,函數(shù)都能運(yùn)行。盡管它們的聲明不同,但從某些方面看起來,它們非常相似,兩者都代表5個字符串。當(dāng)使用一個下標(biāo)時都分別表示一個字符串,但兩者的類型并不相同。當(dāng)使用2個下標(biāo)時都分別表示一個字符,比如,keyWord[1][2]表示keyWord數(shù)組中第2個指針指向的字符串的第3個字母't'。初看上去二維數(shù)組的效率似乎低一些,因?yàn)樗恳恍械拈L度都被固定為剛好能容納最長的關(guān)鍵字,但它不需要任何指針。另一方面,指針數(shù)組也要占用內(nèi)存,但是每個字符串常量占用的內(nèi)存空間只是它本身的長度。

如果它們的長度差不多,那么二維數(shù)組形式更緊湊一些。如果各個字符串的長度差別很大,絕大多是字符串都很短,只有少數(shù)幾個很長,那么使用指針數(shù)組形式會更緊湊一些,取決于指針?biāo)加玫目臻g是否小于每個字符串都存儲于固定長度的行所浪費(fèi)的空間。實(shí)際上,除了非常巨大的表,它們之間的差別是非常小的,所以根本不重要。除非要改變其中的任何一個字符串,二維數(shù)組是更好的選擇。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    476

    瀏覽量

    70483
  • C語言編程
    +關(guān)注

    關(guān)注

    6

    文章

    90

    瀏覽量

    21076
  • 周立功
    +關(guān)注

    關(guān)注

    38

    文章

    130

    瀏覽量

    37536
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    412

    瀏覽量

    25869

原文標(biāo)題:周立功:用數(shù)組,構(gòu)造一個雙重指針

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠(yuǎn)電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    手把手教你學(xué)單片機(jī)之AVR入門視頻教程

    第02講 AVR硬件電路設(shè)計教程_手把手教你學(xué)單片機(jī)之AVR入門篇第03講 AVR開發(fā)基礎(chǔ)知識_手把手教你
    發(fā)表于 03-02 11:04

    手把手教你學(xué)單片機(jī)c語言》視頻教程

    `《手把手教你學(xué)單片機(jī)C語言》視頻教程電驢、優(yōu)酷、迅雷等下載地址《手把手
    發(fā)表于 10-26 14:14

    力天手把手教你學(xué)單片機(jī)視頻全集下載

    基礎(chǔ)知識下--力天手把手教你學(xué)單片機(jī)之入門篇.rarhttp://115.com/file/an9yqmx3#07.第四講.C語言基礎(chǔ)知識-
    發(fā)表于 02-14 17:06

    期待宋老師的《手把手教你學(xué)51單片機(jī)-C語言版》

    看過宋老師的《手把手教你學(xué)51單片機(jī)-C語言版》,感覺挺好的,如果有書的教材那就更完美了!
    發(fā)表于 07-17 15:43

    手把手教你學(xué)CPLD/FPGA與單片機(jī)聯(lián)合設(shè)計》-興華

    。此外,為了幫助讀者掌握單片機(jī)與CPLD/FPGA的聯(lián)合設(shè)計,還介紹了51單片機(jī)的基本知識及單片機(jī)c語言編程的基礎(chǔ)知識,并通過實(shí)例設(shè)計進(jìn)行詳解?!?b class='flag-5'>手把手
    發(fā)表于 12-29 17:10

    手把手教你學(xué)CPLD/FPGA與單片機(jī)聯(lián)合設(shè)計》-興華

    。此外,為了幫助讀者掌握單片機(jī)與CPLD/FPGA的聯(lián)合設(shè)計,還介紹了51單片機(jī)的基本知識及單片機(jī)c語言編程的基礎(chǔ)知識,并通過實(shí)例設(shè)計進(jìn)行詳解?!?b class='flag-5'>手把手
    發(fā)表于 01-06 17:21

    手把手教你學(xué)FPGA 編程規(guī)范篇

    手把手教你學(xué)FPGA 編程規(guī)范篇
    發(fā)表于 02-02 11:32

    手把手教你學(xué)PIC單片機(jī)C語言

    手把手教你學(xué)PIC單片機(jī)C語言教程第1課- PICHL-K18- PICHL-K18慧凈電子--做人人都買得起的PPIICC單片機(jī)開發(fā)板真誠
    發(fā)表于 07-15 09:23

    手把手教你構(gòu)建完整的工程

    手把手教你構(gòu)建完整的工程
    發(fā)表于 08-03 09:54 ?33次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>構(gòu)建<b class='flag-5'>一</b><b class='flag-5'>個</b>完整的工程

    手把手教你學(xué)DSP28335_張卿杰

    手把手教你學(xué)DSP28335張卿杰百度云分享手把手教你學(xué)DSP28335張卿杰百度云分享
    發(fā)表于 01-11 11:45 ?176次下載

    指針數(shù)組

    手把手教你C語言難點(diǎn)編程,很好的C語言
    發(fā)表于 03-25 15:30 ?1次下載

    手把手教你學(xué)電子書制作

    手把手教你學(xué)電子書制作,可以自己DIY電子書
    發(fā)表于 09-13 11:26 ?0次下載

    手把手教你如何開始DSP編程

    手把手教你如何開始DSP編程。
    發(fā)表于 04-09 11:54 ?12次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>如何開始DSP<b class='flag-5'>編程</b>

    手把手教你學(xué)LabVIEW視覺設(shè)計

    手把手教你學(xué)LabVIEW視覺設(shè)計手把手教你學(xué)LabVIEW視覺設(shè)計
    發(fā)表于 03-06 01:41 ?3067次閱讀

    手把手教你學(xué)FPGA仿真

    電子發(fā)燒友網(wǎng)站提供《手把手教你學(xué)FPGA仿真.pdf》資料免費(fèi)下載
    發(fā)表于 10-19 09:17 ?2次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b><b class='flag-5'>學(xué)</b>FPGA仿真