在c中传递数组大小和指针

时间:2015-06-03 10:32:17

标签: pointers

我有一个函数 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 ?

2 个答案:

答案 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将转换为其第一个元素的类型和地址 - 这将变为asizeof 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的字段传递 - 未显示。