數組和指針經常出現於編程語言中、也許上課的時候老師也說過數組和指針有區別、參考書上也應該講過,你是不是也不曾透徹的理清過?
這篇博文主要從內存和編譯的角度指出了數組和指針在訪問方式上的區別、至於他們在函數調用的區別、以及它們的聯系將在下一篇中詳細討論。
好了、這篇博文就講一下我對數組和指針的認識。希望能給你一些幫助。
為了說的清楚些、會先說一些基礎的部分、如果你已經掌握大可跳過
What's a Declaration? What's a Definition? 聲明和定義
c語言的對象必須有且只有一個定義,但可以有多個聲明(extern)這裡說的對象和面向對象中的對象沒有關系。
A definition is the special kind of declaration that creates an object; a declaration indicates a name
that allows you to refer to an object created here or elsewhere。
定義是一種特殊的聲明、它創建了一個對象;聲明簡單的說明了在其他地方創建的對象的名字,它允許你使用這個名字。
可以簡單的這樣理解:
聲明Declaration:描述在其他地方創建的對象,並不分配內存。(可以出現在多個地方)
定義Definition:產生一個新的對象,並分配內存。(只能出現一次)
How Arrays and Pointers Are Accessed -數組和指針是如何訪問的
數組和指針在內存中的訪問方式是不一樣的。這裡先要注意一下“地址y”和“地址y的內容”的區別。“地址y”表示變量y在內存中的地址,而“地址y的內容”指的是
位於這個地址中的內容,也就是變量y的值。大多數編程語言中用同一個符號來表示這兩個東西,而由編譯器根據上下文環境判斷它的含義。
以一個簡答的賦值為例:
上文中的x指的是x所代表的地址,而y的含義是y的內容。
出現在賦值符號左邊的值稱為左值、賦值符號右邊的稱為右值。編譯器為每個變量分配地址(左值)。這個地址在編譯時可知且一直存在,而它的右值在運行時
才能知道。通俗的說:每個變量都有一個地址,這個地址在編譯時可以知道,而地址裡存儲的內容(也就是變量的值)只有在運行時才能知道。如果需要用到變量
的值,(也就是已知地址存儲的值)那麼編譯器發出指令從指定地址讀入變量值並放入相應寄存器中。
這裡的關鍵是地址在編譯時可知、如果要對進行一些操作(比如說加上偏移量之類的)可以直接操作。相反、對於指針,必須在運行時取得它的地址,然後才能
對它進行接觸引用操作。下圖展示了對數組下標的引用:
這樣我們就可以解釋為什麼extern char a[]和extern char a[100]相同的原因了。這兩個什麼都是表名a是一個數組,也就是一個內存地址,
數組內的字符可以由這個地址找到。
和上面不同的是,如果聲明的是一個指針,如 extern char *p,它表示p指向一個字符,為了取得這個字符,必須知道地址p的內容,把它作為字符的地址
並從這個地址中取得這個字符。
如果是數組a[],那麼可以直接用數組名來訪問數組中的元素,因為它的內容就是第一個元素, 他的下一個地址也就對應了下一個數組元素的地址。
如果是指針*a,先要取出地址a的內容,再把它作為變量的地址並從這個地址中取得變量的內容。
數組和指針的其他區別:
定義指針時,編譯器並不為它所指向的對象分配空間,只為指針本身分配空間。除非在定義同時付給一個指針一字符竄常量進行初始化。
如:char *p = "breadfruit";
一般情況下初始化指針時創建的字符串變量被定義為只讀。如果試圖修改就會出現未定義的行為。
這篇文章主要是從訪問形式上對數組和指針的區別做了些小的總結,而對於數組和指針在函數調用中、已經更本質的區別、什麼時候數組
和指針又是等同的、將在下一篇博文中給出。如果完全弄清楚了、對今後的編程也會有不小的幫助。
參考資料:《expert c programming》
下載:Expert C Programming.pdf
歡迎任何形式的轉載,請注明出處:http://www.cnblogs.com/yanlingyin/
一條魚~ @博客園