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