3 种方法
传递数组和大小。(以任意顺序。)b 将转换为其第一个元素的类型和地址 - 这将变为 a。 sizeof b/sizeof b[0] 将采用 42 的值 - 对于不到处重复 42 很有用。 foo1 接收指向数组第一个元素的指针并知道数组元素计数。
void foo1(int *a, size_t n);
size_t sz = 42;
int b[sz];
foo1(b, sizeof b/sizeof b[0]);
传递一个指向固定大小数组的指针。 固定大小数组的地址被传递给foo2()。 foo2() 可以使用 (*d)[0] 访问第一个数组元素,(*d)[41] 访问最后一个元素。 foo2() 不必接收数组元素计数,因为数组元素是已知的并且固定为 42。
void foo2(int (*d)[42]);
int e[42];
foo2(&e);
int f[13];
foo2(&f); // invalid
传递维度然后是可变长度数组。 VLA 在 C99 中可用,在 C11 中也可用。注意foo3()在访问arr[i][j]时理解d2,但不知道arr外维度是d1,即使/* d1 */被替换为d1。
void foo3(size_t d1, size_t d2, char arr[/* d1 */][d2]) {
char x = 0;
for (size_t i=0; i<d1; i++) {
for (size_t j=0; j<d2; j++) {
arr[i][j] = ++x;
}
}
}
void foop(size_t d1, size_t d2, char arr[/* d1 */][d2]) {
printf("ptr size:%zu, sub-array size:%zu, element size:%zu |",
sizeof arr, sizeof arr[0], sizeof arr[0][0]);
for (size_t i=0; i<d1; i++) {
for (size_t j=0; j<d2; j++) {
printf(" %d", arr[i][j]);
}
}
printf("\n");
}
int foo2(int (*arr)[42]) {
printf("%zu\n", sizeof *arr);
return 0;
}
#define SZ(a) (sizeof(a)/sizeof((a)[0]))
int main() {
char a[2][3];
char b[4][5];
foo3(SZ(a),SZ(a[0]), a);
foop(SZ(a),SZ(a[0]), a);
foo3(SZ(b),SZ(b[0]), b);
foop(SZ(b),SZ(b[0]), b);
}
样本输出
ptr size:4, sub-array size:3, element size:1 | 1 2 3 4 5 6
ptr size:4, sub-array size:5, element size:1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
如果需要固定数组,则可以省略数组大小,具体取决于数据的传递方式。
对于可变大小的数组,需要以某种方式传递维度。
数组也可以作为 struct/union 的字段传递 - 未显示。