陣列長度

陣列具有固定長度,這些長度在其宣告範圍內是已知的。然而,計算陣列長度是可能的並且有時是方便的。特別是,當從初始化程式自動確定陣列長度時,這可以使程式碼更靈活:

int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

/* size of `array` in bytes */
size_t size = sizeof(array);

/* number of elements in `array` */
size_t length = sizeof(array) / sizeof(array[0]); 

但是,在表示式中出現陣列的大多數上下文中,它會自動轉換為(衰減到)指向其第一個元素的指標。陣列是 sizeof 運算子的運算元的情況是少數例外之一。結果指標本身不是一個陣列,它不攜帶有關從中派生它的陣列長度的任何資訊。因此,如果需要與指標一起使用該長度,例如當指標傳遞給函式時,則必須單獨傳送它。

例如,假設我們要編寫一個函式來返回 int 陣列的最後一個元素。從上面繼續,我們可以這樣稱呼它:

/* array will decay to a pointer, so the length must be passed separately */
int last = get_last(array, length);

該功能可以像這樣實現:

int get_last(int input[], size_t length) {
    return input[length - 1];
}

特別要注意的是,雖然引數 input 的宣告類似於陣列的宣告但它實際上將 input 宣告為指標 (對於 int)。它完全相當於將 input 宣告為 int *input。即使給出了維度,情況也是如此。這是可能的,因為陣列不能成為函式的實際引數(它們在函式呼叫表示式中出現時會衰減為指標),並且它可以被視為助記符。

嘗試從指標確定陣列大小是一個非常常見的錯誤,這不起作用。不要這樣做:

int BAD_get_last(int input[]) {
    /* INCORRECTLY COMPUTES THE LENGTH OF THE ARRAY INTO WHICH input POINTS: */
    size_t length = sizeof(input) / sizeof(input[0]));

    return input[length - 1];  /* Oops -- not the droid we are looking for */
}

事實上,這個特定的錯誤是如此常見,以至於一些編譯器認識到它並對此發出警告。例如,clang 會發出以下警告:

warning: sizeof on array function parameter will return size of 'int *' instead of 'int []' [-Wsizeof-array-argument]
        int length = sizeof(input) / sizeof(input[0]);
                           ^
note: declared here
int BAD_get_last(int input[])
                     ^