我有一个函数 foo ,它处理大小是用户定义的数组元素。
这个函数需要两个参数(不一定是两个单独的参数,或者我认为是这样) - 一个指向数组和数组大小的指针。
以下使用的三种方法对函数的调用是否有效?
int size; // Obtained from user
int arr[size];
foo(int (*arr)[size]); // Will size be available as a vairable inside foo ?
foo(int (*arr)[],size);
foo(int (*arr)[size],size); // Is the 2nd parameter redundant here ?
答案 0 :(得分:0)
在C中,大小不是数组“对象”的一部分。因此,惯用的C代码传递数组的大小以及数组本身:
foo(arr, size);
for function
void foo(int arr[], int size);
(在整数数组的情况下)。
例如参见main
函数:
int main(int argc, char *argv[]);
(注意这里的论点是相反的。)
答案 1 :(得分:0)
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()
在访问d2
时理解arr[i][j]
,但不知道arr
外部维度为d1
,即使/* d1 */
已替换为d1
{1}}。
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
如果需要 fixed 数组,则可以省略数组大小,具体取决于数据的传递方式。
对于可变大小的数组,需要以某种方式传递维度。
数组也可以作为struct/union
的字段传递 - 未显示。