您好,登錄后才能下訂單哦!
sizeof操作符與數組
一、 sizeof是何方神圣
說到sizeof,首先必須知道的一點:sizeof不是函數,sizeof是操作符。sizeof的作用就是,計算一個對象或類型所占的內存字節數。
1.1 sizeof的語法
sizeof():
這也正是為什么sizeof會有那么多人誤解其為函數。括號里面可以是一個數據對象,也可以是一個數據類型。對于有括號的這種語法來說,你大可以不用理會括號里面是一個數據類型還是一個數據對象。
sizeof object:
初次見面,以為是語法錯誤,其實這也是sizeof的一種用法,計算數據對象所占的內存字節數。如果計算的是一個數據類型,那么請用上面的括號形式。如此看來,那么多程序員使用()的語法形式是有道理的,因為放之四海皆準。
1.2 sizeof如何計算大小
如果你學習過JAVA,那么你會發現,JAVA中根本不存在sizeof操作符。難道是因為JAVA不夠完善嗎?其實不然。JAVA之所以沒有sizeof操作符,也正如JAVA設計者所言:JAVA不需要sizeof。JAVA的運行時需要JVM的,不同的操作系統都有對應的JVM,在JVM中保證了所有類型的大小一致,不管你運行在32位還是64位的機器上,數據類型的大小都是已知的,這也正是JAVA可移植性能夠實現的最根本的原因。回到話題來,為什么C/C++需要sizeof?顯然,對于一個合格的C程序員,我們應該知道,我們所寫的程序運行在不同結構的機器上的時候,類型的大小有所區別。當我們需要知道一個類型的大小才能繼續寫程序的時候,我們就需要sizeof。這就是為什么我們需要sizeof。
二、 數組并沒有那么簡單
數組和指針是C語言中的重頭戲,那么數組是什么數據類型呢?按照其他書籍的介紹,數組是復合類型(與基本數據類型結合構成的類型)。數組是同一類型的數據的集合,在內存中的表現為一串連續的內存,內存的大小為單個數據類型的大小與數據量的乘積。在我個人看來,數組更應該稱為數據結構。數據結構中的順序表,其實現的核心就是數組。由此可見,數組更像是一種C語言預先定義的數據結構。
2.1 數組的語法
數據類型 數組名[數據個數]
倘若我們在定義的時候就初始化,那么數組中第一個維度的數據大小可以不寫。
2.2 數組名到底是什么
數組名是一段內存空間的名字,其指向了這段內存空間。我們講到了sizeof,那么sizeof(數組名)計算出來的,理所應當計算的就是數組名指向的這段內存空間的字節數,事實也正是如此。但是,當我們對數組名繼續深究下去,我們就會開始對sizeof(數組名)疑惑了。看下面的例子:
int arr[3] = {0,1,2}; printf(“%p”,arr);
上面的例子,打印的將會是數組首元素的地址。由此我們可以推測:arr是一個指針。我們這么推測是有理由的,因為指針才能存儲一個地址。但是倘若我們想現在下定論,就需要考慮sizeof(arr)。這時候你再來回答,sizeof(arr)的大小是多少。兩種答案:4或者12。答案是4的顯示,我們把arr當做一個指針,指針的內存在所占的字節數為4;12則是把數組名看做一種數據結構,這個數據結構的大小為12字節。正確答案大家知道是12。到這里我們的疑惑就更深了,既然編譯器認為arr不是指針,但是arr在打印地址的時候,又保存了一個地址。這就是我們需要說的:數組名是一個類似于指針的數據結構變量名。在普通情況下,我們可以把數組名當做指針來使用。繼續看下面的一個例子:
int arr[3] = {0,1,2}; int arr2[3] = {3,4,5}; arr= arr2;
上面的代碼我們想完成的事情是將arr2數組賦值給arr數組,但是編譯的時候是錯誤的,因為arr在表現為指針屬性的時候,實際上是一個常量指針。我們不會對一個已經初始化了的變量再次賦值。
2.3 數組作為函數參數
當數組作為函數形參的時候,數組名則淪為指針,既然是一個指針,我們就可以對其自增、自減和修改。在函數體內,數組名僅僅作為一個數組的指針。我們知道了他是指針,只要我們搞清楚這個指針實際指向的數據類型,那么對于指針的使用就顯得簡單了。
三、 sizeof與數組
看下面的一段代碼:
int arr[2][2] = { {0,1}, {2,3} }; printf(“%d,”,sizeof(arr)); printf(“%d,”,sizeof(arr[0])); printf(“%d\n”,sizeof(arr[0][0]));
三個printf將會打印什么?答案:16,8,4
3.1 sizeof(arr)
弄清楚答案的緣由我們先了解一下多維數組。
C/C++中,多維數組實際上是一位數組。多維數組在分配內存的時候,是分配一段完整的連續的內存空間。這么說可能理解不深刻。我們先來了解一下JAVA中的多維數組,就以二維數組來看。JAVA中的二維數組在分配空間的時候,首先會分配一個大小為2的數組,其保存的是2個一維數組的起始地址。這兩個一維數組在內存上并不一定是連續的。再看看C中的數組,就能理解其完整的連續的意思。
正是因為如此,所以sizeof(arr)才會打印16。因為sizeof計算的是數組名對應的內存空間的大小,不管維度大小。
3.2 sizeof(arr[0])
接下來我們看一下sizeof(arr[0])。如果外面沒有sizeof操作符,arr[0]在此處如果換成指針來看待,其運算如下:(arr + 0 ),其指向的依然是數組的首行首元素的地址。但是在sizeof操作符下,arr[0]顯然不能夠當做指針來看待,這時應該理解為二維數組的一維數組(邏輯上是如此,實際上多維數組還是一位數組)。arr[0]指向的是第一行的一位數組,我們可以理解為arr[0]就是一個數組名,其內存空間為arr數組的前2個元素對應的內存空間,我們sizeof,得到的結果就應該為8。
3.2 sizeof(arr[0][0])
最后來看sizeof(arr[0][0]),arr[0][0]表示訪問的是二維數組的首行一維數組的首元素,其變量就是一個int類型,所以結果為4。
由此看來,數組名與sizeof操作符搭配的時候,其表現也并不簡單,其依然還是保留了數組名作為一種數據結構的特性。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。