2013-02-01 51 views
2

我有一個小問題:我可以計算一個向量的長度,但只有當向量是在同一個函數中定義的時候。當我嘗試將矢量傳遞給另一個函數時,它會返回錯誤的輸出,我不明白爲什麼。一個向量的長度,初學者

#include <stdio.h> 

int len(int vec[]); 

main() 
{ 
    int a[6]; 

    printf("%d\n", sizeof(a)/sizeof(int)); 
    printf("%d\n", len(a)); 

    return 0; 
} 

len(int vec[]) 
{ 
    return sizeof(vec)/sizeof(int); 
}  

輸出爲:

6 
1 

爲什麼功能len()不起作用?它應該返回6而不是1.

+0

可能重複[C編程語言中數組的大小?](http://stackoverflow.com/questions/1975128/sizeof-an-array-in-the-c-programming-language) – Lundin

回答

7

這是因爲數組衰減當傳遞給函數時變成了它們的第一個元素的指針。

沒有與數組關聯的長度的運行時存儲,所以這不起作用。基本上對於函數參數,諸如int a[]的類型與int *a等價,即它只是一個指針。

當你需要將數組傳遞給函數時總是傳遞一個長度是最好的,而且你永遠不會有像你的len()這樣的函數。當然,如果您將自己的長度存儲在指向的數據中,例如字符串使用終止符字符,則當然是例外。

作爲一個文體的角度來看,這代碼main()

printf("%d\n", sizeof(a)/sizeof(int)); 

在我看來是更好的寫法如下:

printf("%zu\n", sizeof a/sizeof *a); 

通過以下值得關注的變化:

  • 結果的sizeofsize_t,這不是int。它由格式說明符%zu正確打印。
  • 請注意,sizeof不是一個函數,所以大多數情況下不需要括號。
  • 傾向於引用變量,而不是重複可能或可能不與變量關聯的類型名稱。 sizeof *a表示「a指向的值的大小」。
  • 還要注意的是根據C's operator precedence rulessizeof結合不同於/更緊,所以表達式實際上意味着(sizeof a)/(sizeof *a),這是期望的結果。
+0

寫一個函數計算一個長度通過它長度似乎有點無用:)但我明白。非常感謝。 – JoulinRouge

2

len函數採用作爲參數未指定大小的陣列,在這種情況下它被視爲只是指針類型(在您的情況下,int指針)。在您的特定平臺上,指針的大小與int的大小相同,因此sizeof(vec)/sizeof(int)爲1.

如果明確指定數組參數的長度,那麼您的大小計算將按預期行爲 - 但是你的函數只會接受這個長度的數組參數。

參見:C++ arrays as function arguments

1

因爲int len(int vec[])是在現實中int len(int *vec)。在len的內部,變量vec被視爲指針,因此sizeof vec返回保存地址所需的字節數。

請注意,sizeof是一個運算符,而不是一個函數。這意味着sizeof返回的值是在編譯時計算的。