C/C++指標陣列的問題
本人小白,本文專門給初學者準備,大神自動跳過。
不喜勿噴,謝謝。
如有錯誤,請指正,謝謝。
正文:
進來有人問我一些有關於指標的問題。在此我貼出問題
問題如下:
char *msg[5] = {"Thank you","You are"};
mian()
{
printf("%s",msg[0]);
}
問題一:為什麼msg[0]可以輸出Thank you?
問題二:如果把msg看成是二維陣列的名字,那msg[0]不應該是Thank you 的首地址麼?
問題三:用%s這個可是可以輸出地址裡的內容麼?
問題四:如果用msg可以輸出Thank you 麼?*msg呢?
解答:
首先我們來看看我們定義的是什麼吧
我們定義的是char *msg[5];這是代表我們定義了一個數組,陣列名叫msg,陣列包含了5個元素,這些元素的型別是char *型別,很明顯這些元素是指標
也就是說我們定義了一個指標陣列,我們這個陣列就是儲存了一些地址而已
而且我們在定義的時候,是對這些元素(指標)進行了初始化了的。
msg[0]這個指標存放了“Thank you”這個字串的首地址,msg[1]這個指標存放了“You are”這個字串的首地址。
另外我們知道%s是隻要我給了一個地址,它就能完整的輸出字串
所以我們在輸出的時候傳入了一個msg[0],也就是傳入了一個地址,這是“Thank you”的首地址。自然而然計算機就能輸出完整的Thank you
至於我們能不能將msg看成二維陣列的名字呢?我們之後討論,我們先說最後一個問題
用msg能不能輸出Thank you呢?答案是不能
用*msg能不能輸出Thank you呢?答案是能
我們來看一下這兩者的區別
1.一個數組的名字在C/C++中,如果沒有特別說明,那麼它就代表的是一個指標,這個指標指向這串陣列的首個元素的地址
那麼我們在呼叫msg的時候,電腦預設我們給了一個msg[0]的地址,也就相當於msg = &msg[0]
所以我們在用%s輸出msg的時候,實際上我們就是傳入了一個msg[0]的地址,那msg[0]是什麼?是指標啊!!!不是字串啊!!!
所以用msg的時候就不能正確輸出
2.那麼第二個呢?*msg又如何呢?
前面一種情況我們已經介紹了msg表示msg[0]的地址。那麼當我們使用*msg的時候,它就指向了msg[0]中的內容。因而*msg = msg[0]
那msg[0]存放了什麼?存放了“Thank you”的首地址!!!
所以我們在用%s輸出*msg的時候是可以正確輸出的
最後我們再來看看我們能不能將msg看成是二維陣列的名字呢?
我的理解是可以的,雖然不嚴謹,但是在大部分使用上我認為我可以替換的
這裡我們先不講枯燥的理論知識,我們先來介紹一下如何用動態記憶體分配去搞出個二維陣列
int i;
char **p;//定義一個指向指標的指標(好繞口……)
p = (char **)calloc(5,sizeof(char*));//先分配最外層的記憶體,這裡我們可以看到我們是分配了5個char*型別的記憶體,也就是我們打算在這裡放5個指標
for(i = 0; i < 5; i++)
(*p) = (char *)calloc(10,sizeof(char));//在分配最內層的記憶體,也就是我們用來存放“Thank you”的記憶體
這很經典,仔細觀察我們可以發現這和我們上面提到的char *msg[5]很像,不同的是char *msg[5]沒有定義最內層的東西,只有最外層的指標。
一個是一維陣列,一個是二維陣列。雖然定義不一樣,但是本質上沒啥大區別,我們用它們實現的功能都差不多
所以我說可以看成是二維陣列的名字