溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

【C深度剖析】sizeof操作符與數(shù)組

發(fā)布時(shí)間:2020-06-27 00:23:54 來源:網(wǎng)絡(luò) 閱讀:2302 作者:沃特water 欄目:系統(tǒng)運(yùn)維

sizeof操作符與數(shù)組

一、  sizeof是何方神圣

說到sizeof,首先必須知道的一點(diǎn):sizeof不是函數(shù),sizeof是操作符。sizeof的作用就是,計(jì)算一個(gè)對象或類型所占的內(nèi)存字節(jié)數(shù)。


  1.1 sizeof的語法

        sizeof()

這也正是為什么sizeof會有那么多人誤解其為函數(shù)。括號里面可以是一個(gè)數(shù)據(jù)對象,也可以是一個(gè)數(shù)據(jù)類型。對于有括號的這種語法來說,你大可以不用理會括號里面是一個(gè)數(shù)據(jù)類型還是一個(gè)數(shù)據(jù)對象。

sizeof object:

初次見面,以為是語法錯(cuò)誤,其實(shí)這也是sizeof的一種用法,計(jì)算數(shù)據(jù)對象所占的內(nèi)存字節(jié)數(shù)。如果計(jì)算的是一個(gè)數(shù)據(jù)類型,那么請用上面的括號形式。如此看來,那么多程序員使用()的語法形式是有道理的,因?yàn)榉胖暮=詼?zhǔn)。


1.2 sizeof如何計(jì)算大小

如果你學(xué)習(xí)過JAVA,那么你會發(fā)現(xiàn),JAVA中根本不存在sizeof操作符。難道是因?yàn)?/span>JAVA不夠完善嗎?其實(shí)不然。JAVA之所以沒有sizeof操作符,也正如JAVA設(shè)計(jì)者所言:JAVA不需要sizeofJAVA的運(yùn)行時(shí)需要JVM的,不同的操作系統(tǒng)都有對應(yīng)的JVM,在JVM中保證了所有類型的大小一致,不管你運(yùn)行在32位還是64位的機(jī)器上,數(shù)據(jù)類型的大小都是已知的,這也正是JAVA可移植性能夠?qū)崿F(xiàn)的最根本的原因?;氐皆掝}來,為什么C/C++需要sizeof?顯然,對于一個(gè)合格的C程序員,我們應(yīng)該知道,我們所寫的程序運(yùn)行在不同結(jié)構(gòu)的機(jī)器上的時(shí)候,類型的大小有所區(qū)別。當(dāng)我們需要知道一個(gè)類型的大小才能繼續(xù)寫程序的時(shí)候,我們就需要sizeof。這就是為什么我們需要sizeof。


、  數(shù)組并沒有那么簡單

  數(shù)組和指針是C語言中的重頭戲,那么數(shù)組是什么數(shù)據(jù)類型呢?按照其他書籍的介紹,數(shù)組是復(fù)合類型(與基本數(shù)據(jù)類型結(jié)合構(gòu)成的類型)。數(shù)組是同一類型的數(shù)據(jù)的集合,在內(nèi)存中的表現(xiàn)為一串連續(xù)的內(nèi)存,內(nèi)存的大小為單個(gè)數(shù)據(jù)類型的大小與數(shù)據(jù)量的乘積。在我個(gè)人看來,數(shù)組更應(yīng)該稱為數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)結(jié)構(gòu)中的順序表,其實(shí)現(xiàn)的核心就是數(shù)組。由此可見,數(shù)組更像是一種C語言預(yù)先定義的數(shù)據(jù)結(jié)構(gòu)。


  2.1 數(shù)組的語法



數(shù)據(jù)類型 數(shù)組名[數(shù)據(jù)個(gè)數(shù)]

倘若我們在定義的時(shí)候就初始化,那么數(shù)組中第一個(gè)維度的數(shù)據(jù)大小可以不寫。


 2.2 數(shù)組名到底是什么

數(shù)組名是一段內(nèi)存空間的名字,其指向了這段內(nèi)存空間。我們講到了sizeof,那么sizeof(數(shù)組名)計(jì)算出來的,理所應(yīng)當(dāng)計(jì)算的就是數(shù)組名指向的這段內(nèi)存空間的字節(jié)數(shù),事實(shí)也正是如此。但是,當(dāng)我們對數(shù)組名繼續(xù)深究下去,我們就會開始對sizeof(數(shù)組名)疑惑了。看下面的例子:

int arr[3] = {0,1,2};
printf(“%p”,arr);

上面的例子,打印的將會是數(shù)組首元素的地址。由此我們可以推測:arr是一個(gè)指針。我們這么推測是有理由的,因?yàn)橹羔槻拍艽鎯σ粋€(gè)地址。但是倘若我們想現(xiàn)在下定論,就需要考慮sizeof(arr)。這時(shí)候你再來回答,sizeof(arr)的大小是多少。兩種答案:4或者12。答案是4的顯示,我們把arr當(dāng)做一個(gè)指針,指針的內(nèi)存在所占的字節(jié)數(shù)為4;12則是把數(shù)組名看做一種數(shù)據(jù)結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)的大小為12字節(jié)。正確答案大家知道是12。到這里我們的疑惑就更深了,既然編譯器認(rèn)為arr不是指針,但是arr在打印地址的時(shí)候,又保存了一個(gè)地址。這就是我們需要說的:數(shù)組名是一個(gè)類似于指針的數(shù)據(jù)結(jié)構(gòu)變量名。在普通情況下,我們可以把數(shù)組名當(dāng)做指針來使用。繼續(xù)看下面的一個(gè)例子:

int arr[3] = {0,1,2};
int arr2[3] = {3,4,5};
arr= arr2;

上面的代碼我們想完成的事情是將arr2數(shù)組賦值給arr數(shù)組,但是編譯的時(shí)候是錯(cuò)誤的,因?yàn)?/span>arr在表現(xiàn)為指針屬性的時(shí)候,實(shí)際上是一個(gè)常量指針。我們不會對一個(gè)已經(jīng)初始化了的變量再次賦值。

 2.3 數(shù)組作為函數(shù)參數(shù)

  當(dāng)數(shù)組作為函數(shù)形參的時(shí)候,數(shù)組名則淪為指針,既然是一個(gè)指針,我們就可以對其自增、自減和修改。在函數(shù)體內(nèi),數(shù)組名僅僅作為一個(gè)數(shù)組的指針。我們知道了他是指針,只要我們搞清楚這個(gè)指針實(shí)際指向的數(shù)據(jù)類型,那么對于指針的使用就顯得簡單了。



、  sizeof與數(shù)組

看下面的一段代碼:

int arr[2][2] = {
{0,1},
{2,3}
};
printf(“%d,”,sizeof(arr));
printf(“%d,”,sizeof(arr[0]));
printf(“%d\n”,sizeof(arr[0][0]));

三個(gè)printf將會打印什么?答案:16,8,4


 3.1 sizeof(arr)


弄清楚答案的緣由我們先了解一下多維數(shù)組。

C/C++中,多維數(shù)組實(shí)際上是一位數(shù)組。多維數(shù)組在分配內(nèi)存的時(shí)候,是分配一段完整的連續(xù)的內(nèi)存空間。這么說可能理解不深刻。我們先來了解一下JAVA中的多維數(shù)組,就以二維數(shù)組來看。JAVA中的二維數(shù)組在分配空間的時(shí)候,首先會分配一個(gè)大小為2的數(shù)組,其保存的是2個(gè)一維數(shù)組的起始地址。這兩個(gè)一維數(shù)組在內(nèi)存上并不一定是連續(xù)的。再看看C中的數(shù)組,就能理解其完整的連續(xù)的意思。

正是因?yàn)槿绱?,所?/span>sizeof(arr)才會打印16。因?yàn)?/span>sizeof計(jì)算的是數(shù)組名對應(yīng)的內(nèi)存空間的大小,不管維度大小。


 3.2 sizeof(arr[0])


   接下來我們看一下sizeof(arr[0])。如果外面沒有sizeof操作符,arr[0]在此處如果換成指針來看待,其運(yùn)算如下:(arr + 0 ),其指向的依然是數(shù)組的首行首元素的地址。但是在sizeof操作符下,arr[0]顯然不能夠當(dāng)做指針來看待,這時(shí)應(yīng)該理解為二維數(shù)組的一維數(shù)組(邏輯上是如此,實(shí)際上多維數(shù)組還是一位數(shù)組)。arr[0]指向的是第一行的一位數(shù)組,我們可以理解為arr[0]就是一個(gè)數(shù)組名,其內(nèi)存空間為arr數(shù)組的前2個(gè)元素對應(yīng)的內(nèi)存空間,我們sizeof,得到的結(jié)果就應(yīng)該為8


 3.2 sizeof(arr[0][0])


最后來看sizeof(arr[0][0]),arr[0][0]表示訪問的是二維數(shù)組的首行一維數(shù)組的首元素,其變量就是一個(gè)int類型,所以結(jié)果為4。

由此看來,數(shù)組名與sizeof操作符搭配的時(shí)候,其表現(xiàn)也并不簡單,其依然還是保留了數(shù)組名作為一種數(shù)據(jù)結(jié)構(gòu)的特性。



向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI