回到「13. 額外語法 (Extra syntax)」
上一頁
當您讀到「陣列」這個單元時,大可將「宣告一個大小為n的陣列」理解成「讓電腦幫你一次宣告n個變數」
但是,事實真的是如此嗎?
當您宣告一個變數的時候,電腦會挪出一塊記憶體給你用,啊然後咧?
這就像您想要網購某個東西,在購物網站上點了「購買」按鈕、付了錢,然後就以為沒事了(?)
不對啊,你總要知道要去哪裡取貨吧!
因此,程式向電腦「訂購」了記憶體之後,電腦就要告訴程式「取貨地址」--也就是「記憶體編號」,或稱「指標」
當程式執行到「int a;」這一行,程式會向電腦訂購32位元記憶體,然後電腦會告訴程式這32位元記憶體的「指標」。程式會小心翼翼地把這個「指標」記好,這樣才能隨時去使用它訂購的32位元記憶體
然而,有一件殘酷的事實是:
「記住指標」這個動作會讓程式需要額外的static記憶體 (之後會學到甚麼是static記憶體)
那這樣的話,把「宣告一個大小為$n$的陣列」理解成「讓電腦幫你一次宣告$n$個變數」會有甚麼問題嗎?
注意到,與其「訂購$32$位元記憶體$n$次,並記住$n$個指標」,還有另一種更有效率的方式:
直接一次性地訂購$32n$位元記憶體 (恩對一條街被買下來了(?)),然後依照「門牌號碼」分配給每個變數各$32$位元記憶體
差別在哪?這時程式只需要記住1個指標 (而非$n$個),也就是那「$32n$位元記憶體」的指標
當程式要取得第$i$ ($1\leq i\leq n$) 個變數的指標時,只要將第1個變數的指標加上$32(i-1)$位元就好了
怎麼證明電腦真的在做這件事?
信不信,陣列的名稱可以直接當指標來用XD (?!)
當然,小莫還要示範給你看!
#include<cstdio> int main() { int a[10]; a[0]=2; printf("%d\n",*a); a[0]=4; printf("%d\n",*a); return 0; }
|
改變「a[0]」,「a指標」指到的記憶體所儲存的數值也跟著改變 |
陣列真的是指標耶!而且真的是陣列第一個元素的指標!
那麼,「陣列」等不等於「指標」呢?
為了確認這點,除了要確認「陣列就是指標」,我們還需要確認是不是「指標就是陣列」
要怎麼確認指標是不是陣列呢?
我們可以取「a陣列」的第一個元素的指標,看看這個指標能不能當作「a陣列」來用就好啦
#include<cstdio> int main() { int a[10]; int *b=&a[0]; b[0]=1; printf("%d\n",a[0]); b[9]=2; printf("%d\n",a[9]); b[0]=3; printf("%d\n",a[0]); b[9]=4; printf("%d\n",a[9]); return 0; }
把b當作陣列來用,改變b的第i項,a的第i項也跟著改變 |
可以發現,當我們硬把「b」當作陣列來用的時候,不僅沒有出事,「b」的行為也完全和「a」一模一樣!
所以,「陣列」=「指標」,是嗎?
當然~
很意外吧XD
例外狀況:
- 我們不能從指標來得知陣列的長度,但是從陣列的名字就可以 (可以用sizeof(a)/sizeof(a[0]))
- 二維或更多維的陣列無法用指標表示
下一頁
感謝:匿名網友
(版權所有 All copyright reserved)
雖然一般情況下pointer和array可以通用 但也有不能的時候 比如說2D array就不能用pointer表示
回覆刪除另外 可以從陣列名稱知道長度吧? 用sizeof應該可以?
感謝您~已修正!
刪除作者已經移除這則留言。
回覆刪除