C语言阵列长度

示例

数组具有固定长度,这在其声明范围内是已知的。但是,计算数组长度是可能的,有时也很方便。特别是,当从初始化程序自动确定数组长度时,这可以使代码更灵活:

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[])
                     ^