1. 程式人生 > >C/C++指標陣列的問題

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]沒有定義最內層的東西,只有最外層的指標。

一個是一維陣列,一個是二維陣列。雖然定義不一樣,但是本質上沒啥大區別,我們用它們實現的功能都差不多

所以我說可以看成是二維陣列的名字