2012-01-03 220 views
-4

可能重複:
C sizeof a passed array調用的功能

,而不是發送的sizeof:

void main() 

    int x[] = {1, 2, 3, 1, 3, 0, 6}; 
    dupes(x, sizeof x/sizeof x[0]); 
... 
} 

int dupes(int a[], int n) 
... 
... 

爲什麼不能我只用數組來調用它:

int main() 
{ 
    int x[] = {1, 2, 3, 1, 3, 0, 6}; 
    dupes(x); 
... 
} 
int dupes(int a[]) 
{ 
    int n = sizeof a/sizeof a[0]; 

當我這樣做的大小總是得到1 - 它不能是1 casue我發送7個元素的數組!

+1

投票關閉並否決由於Sveta26複製粘貼到所有的答案同樣的評論,似乎不關心什麼實際答案說。 – unwind 2012-01-03 13:27:08

回答

0

這是因爲當你將一個數組傳遞給一個函數時,它會被複制到一個指針中,並且關於它的大小的信息會丟失。在被調用的函數中,它只是一個普通的指針。

所以(a)的變大小4(因爲其指針)和sizeof(A [0])也是4(因爲它的一個整數),所以n等於1

+0

好吧,所以我怎麼能從函數內部定義它,並只使用數組指針進行調用? – Sveta26 2012-01-03 13:19:51

+1

沒有辦法從指針中獲取數組的大小,您必須通過 – 2012-01-03 13:22:31

0

sizeof a [0];重建數組的第一個元素

並且當您傳遞數組時,它將返回數組第一個元素的地址,因此您還必須指定長度。

在內部橫穿陣列如下:

int a[]={1,2,3}; 

when you pass a[] as a function argument it sends the address of the element a[0]也就是1的內部地址,並計算出[1]作爲

address of a[0] + size of int (type of an array)

當鍵入sizeof(a[]) it will return the sizeof(int pointer) as a[0] contains the internal address(integer pointer).

+0

好吧,那麼我怎麼能從函數內部定義它,並只使用數組指針進行調用? – Sveta26 2012-01-03 13:20:14

+0

如果你知道數組的長度,你可以使用指針來遍歷它,但是對於這個「小心,因爲你正在做內存操作」,請參考http://www.programmersheaven.com/mb/CandCPP/159211/159211/using-一個指針遍歷該數組索引/ – 2012-01-03 13:25:06

3

sizeof不是一個函數,它是一個編譯器操作符(所以你不要「調用」sizeof,你只需使用sizeof運營商)。編譯器無法知道函數dupes的正式參數a的大小(並且視爲int* a,即指針正式)。

sizeof總是在編譯時計算。

+0

好吧,那麼我怎麼能從函數內部定義它,並只使用數組指針進行調用? – Sveta26 2012-01-03 13:22:02

+0

您必須在某處放置數組的(運行時)維度。你如何給予你(作爲第二個參數,作爲常規常量,作爲結構成員,在全局變量中......)。處理器不知道什麼是陣列!我強烈建議花幾個小時**閱讀一本好的C編程書籍** – 2012-01-03 13:24:34

+2

「'sizeof'總是在編譯時計算出來的」。始終只有在sizeof表達式中沒有VLA。使用VLA,如果數組大小的值影響'sizeof'表達式的值,那麼將評估數組表達式。 – ouah 2012-01-03 13:32:18

1

當數組傳遞給函數時,數組衰減爲指向其第一個元素的指針。 sizeof只適用於傳遞實際原始數組。

在其他語言中,數組引用始終與它們一起攜帶長度,但C哲學反對這種隱藏的性能損失,因此您必須自己通過該長度。

+0

好吧,所以我怎麼能從函數內部定義它,並只使用數組指針進行調用? – Sveta26 2012-01-03 13:21:44

+0

@ Sveta26:你不能。你可以考慮做的不是通過一個單獨的長度屬性來標記輸入的結束,而是使用特殊的終止符值來標記最後一個元素。這是他們如何處理標準庫中的字符串。 – hugomg 2012-01-03 13:39:15

1

該原型在C:

int dupes(int a[]) 
{ 

} 

等效於此原型:

int dupes(int *a) 
{ 

} 

您數組參數a被轉換爲指針int

關於函數聲明,這出現在6.7.5.3p7在C99標準

一個參數作爲「」「類型的數組」的聲明,應調整至 「」合格指針爲類型「」 ,其中類型限定符(如果有的話)是 在數組類型派生[和]中指定的那些。

C中的數組是二等公民,您不能將數組傳遞給函數。您只需將指針傳遞給數組的第一個元素即可。

所以當你計算sizeof a時,結果是指針的大小而不是數組的大小。

在你的函數體sizeof a/sizeof a[0]實際計算的:sizeof (int *)/sizeof (int)它產生在你的系統1,因爲int *的大小是一樣的int的系統中的大小。

+0

ok的大小,那麼我如何從函數內部定義它並僅使用數組指針進行調用? – Sveta26 2012-01-03 13:21:53

+0

使用'int dupes(int a [],size_t n)'是要走的路。 – ouah 2012-01-03 13:28:54

0

這是因爲您無法直接將數組傳遞給函數。您只能將指針傳遞給此類數組中的元素。

在功能參數時,[]確實平均陣列,這意味着一個指針

int dupes(int a[]) 

是完全相同

int dupes(int *a) 

當使用的陣列爲一體的名稱一個值,它實際上意味着指向該數組中的1.元素的指針。指針就是這個指針。它不知道它指向給定大小的數組。

因此,例如, int *a = x;將分配一個指向x中的第一個元素的指針,以a - 同樣的事情,當您調用一個函數時,dupes(x)將傳遞一個指針指向x中的第一個元素作爲dupes函數的參數。這跟調用dupes(&x[0])

在dupes()函數裏面,它的參數只是一個指針。因此sizeof x/sizeof x[0]等於sizeof(int*)/sizeof(int),如果指針的大小與int相同,則爲1。 (但是,由於您向數組中的元素傳遞了指針,因此您可以增加該指針以訪問其他元素,例如,x + 2將使x指向3.元素(從1開始計數),因爲陣列。如果您取消引用該指針,則會得到它的值:*(x + 2)。並記住,作爲值,x[2]相同*(x + 2)

+0

好吧,那麼我怎麼能從函數內部定義它,並只使用數組指針進行調用? – Sveta26 2012-01-03 13:21:32

+0

@ Sveta26如果你必須只傳遞一個參數,「數組」,你必須弄清楚別的。例如您可以將該大小存儲在您在該函數中讀取的全局可變數據中。或者你可以存儲一個特殊值作爲數組中的最後一個元素,例如-1,並且函數計算它在找到-1之前遍歷了多少個元素。 – nos 2012-01-03 13:37:21

0

當型「T N元件陣列」的表達出現在大多數情況下,它是隱式轉換爲類型的表達式「指針T」和它的值是數組中第一個元素的地址。當數組表達式是sizeof和一元運算符&的操作數時,或者是用於在聲明中初始化數組的字符串文字時,纔會出現此規則的唯一例外情況。

當調用dupes,表達x從型「int 7個元素的數組」到「指針int」轉換,所以dupes函數接收指針值,而不是陣列。在函數參數聲明的上下文中,T a[N]T a[]相當於T *a

所以在dupes功能,sizeof a/sizeof a[0]相當於sizeof (int *)/sizeof (int),而你的情況是1