相信學習過C語言的童鞋,一定被這2個東西折騰過吧?究竟它們都是何方神圣呢?帶著這個問題,筆者想通過本文給你一個清晰的答案。通過閱讀本文,你將了解到以下內(nèi)容:
- 什么是數(shù)組指針?
- 什么是指針數(shù)組?
- 數(shù)組指針和指針數(shù)組有什么區(qū)別?
- 使用指針數(shù)組的注意事項
什么是數(shù)組指針?
? 【數(shù)組指針】,從字面意思上理解,就是一個【指針】;“數(shù)組”只是起到了修飾“指針”的作用,所以連起來的意思就是【指向數(shù)組的指針】。這一點與上一篇文章介紹 【函數(shù)指針】有異曲同工的含義。
? 從C語言的語法上理解,數(shù)組指針的表示形式為:
//定義一個一維數(shù)組
int a[3];
//定義一個指針,指向一維數(shù)組的首地址
int *q = a;
//定義一個3行4列的二維數(shù)組
int b[3][4];
//定義一個數(shù)組指針,它指向二維數(shù)組的首地址
int (*p)[4] = b;
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-eQIadh0d-1661923181862)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
? 從數(shù)組指針的形式上看,因為()運算符擁有最高優(yōu)先級,所以整個語句優(yōu)先被解釋成一個指針;接著,這個指針再指向另一個數(shù)組的首地址,[x]接上該數(shù)組的列數(shù),即得到如上的數(shù)組指針的定義。
? 經(jīng)過這個例子,我們可以看到,數(shù)組指針一般用于表達多維數(shù)組,對比起多維數(shù)組的表示,采用數(shù)組指針的形式可以在一定程度上理解難度減小了。比如,有了如上的數(shù)組指針定義后,這里b是個二維數(shù)組的數(shù)組名,相當于一個二級指針常量;p是一個指針變量,它指向包含5個int元素的一維數(shù)組,此時p的增量以它所指向的**一維數(shù)組長度為單位;*(**p+i)是一維數(shù)組b[i][0]的地址;(p+2)+3表示b[2][3]地址(第一行為0行,第一列為0列),(*(p+2)+3)表示b[2][3]的值。
什么是指針數(shù)組?
? 【指針數(shù)組】,從字面意思上理解,它就是一個數(shù)組,只不過“指針”是用于修飾“數(shù)組”的,所以合起來理解就是:【一個數(shù)組元素存放的是指針的數(shù)組】。
? 從C語言的語法上理解,【指針數(shù)組】的定義形式如下所示:
//定義一個char *的指針數(shù)組
char *p[5];
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Qud5CpbF-1661923181865)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
? 這里,它表示的含義是,一個由5個元素組成的一維數(shù)組,每個數(shù)組元素都是一個指針(地址)。訪問數(shù)組的元素,我們都是采用 數(shù)組名[數(shù)組下標] 的形式訪問的,那么【指針數(shù)組】也不例外,訪問第一個元素,則是p[0];同理,p[2]表示的是第3個指針。
數(shù)組指針和指針數(shù)組有什么區(qū)別?
? 從字面上看,確實很容易混淆兩者的概念;我們理解的時候,需要注意名詞誰先誰后。一般來說,在前面的名詞是用于修飾后面的名詞,而后面的名詞決定了整個詞組的性質(zhì)。
? 【數(shù)組指針】:數(shù)組修飾指針,它的本質(zhì)是一個指針;一般這個指針指向一個二維數(shù)組,形式為: int (*p)[M]。
? 【指針數(shù)組】:指針修飾數(shù)組,它的本質(zhì)是一個數(shù)組;這個數(shù)組里面的元素,存放的都是指針,形式為: int *p[M]。
? 如上定義中,第一個M表示二維數(shù)組的列數(shù),第二個M表示的指針數(shù)組(一維數(shù)組)的元素個數(shù)。
? 數(shù)據(jù)訪問方面:
- (*p)[0] 表示的是二維數(shù)組中的第一行的首地址;
- p[0] 表示的指針數(shù)組的第一個元素,即第一個指針地址。
使用指針數(shù)組的注意事項
? 這兩個概念不但容易混淆,而且在使用過程中也是十分容易出錯,曾經(jīng)筆者在【指針數(shù)組】上摘過跟頭。現(xiàn)將出錯的教訓分享給大家:
- 求一個指針數(shù)組的中元素的個數(shù),不是簡單地使用sizeof
? 比如有一個指針數(shù)組的定義:
char *p[5];
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CRsvrkY7-1661923181868)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
? 假設在編程平臺上,一個指針所占用的地址空間是4個字節(jié),即sizeof(char ) = 4;那么如果使用sizeof§去求這個指針數(shù)組所占用的地址空間時,求得的大小是45=20;而每個元素都是char *類型,所以求得指針元素的個數(shù)為: 20 / 4 = 5。
? 于是,我們得出一個公式,求指針數(shù)組的元素個數(shù):
//直接求得指針數(shù)組p的元素個數(shù)
cnt = sizeof(p) / sizeof(p[0]);
//很多時候,我們會定義一個宏來表示,形式如下:
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif
//使用ARRAY_SIZE宏求指針數(shù)組p的元素個數(shù)
cnt = ARRAY_SIZE(p);
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qwfXvoOo-1661923181869)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
- 定義字符串類型的指針數(shù)組時,每個元素(字符串)注意用分號隔開,否則可能出現(xiàn)意想不到的事情
? 假設有以下2個指針數(shù)組的定義:
const char *p1[] =
{
"12345",
"23456",
"34567",
"45678",
"56789",
};
const char *p2[] =
{
"12345",
"23456"
"34567",
"45678"
"56789",
};
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Wt3RK9bs-1661923181874)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
? 如果你不仔細看,你可能覺得p1和p2的定義是一致;仔細一看,原來p2中少了2個分號;而這2個分號一少,直接就導致p2的最終被編譯器識別成的定義為:
//最終被識別的定義
const char *p2[] =
{
"12345",
"2345634567",
"4567856789",
};
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aNeQ6PqX-1661923181875)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
? 看到區(qū)別了嗎?由于分號的缺失導致前后相鄰的字符串被結(jié)合在一塊,被連接成一個更長的字符串,而這種【拼接】是編譯器自動識別完成的,它不會提示任何錯誤,因為在它看來根本就不是錯誤。對使用者而言,這樣定義一改變,原本本應該為5個元素的字符串數(shù)組,就變成了3個字符串的數(shù)組,這簡直就是災難?。。?!
? 以上就是筆者對【數(shù)組指針】和【指針數(shù)組】的實踐,得出的切實理解,希望能夠幫助大家更近一步地理解它們。以上提及觀點,均為筆者本人的觀點,如有紕漏之處,還望指正。感激不盡。
-
C語言
+關(guān)注
關(guān)注
180文章
7594瀏覽量
135858 -
數(shù)組指針
+關(guān)注
關(guān)注
0文章
5瀏覽量
5222 -
函數(shù)指針
+關(guān)注
關(guān)注
2文章
56瀏覽量
3770
發(fā)布評論請先 登錄
相關(guān)推薦
評論