【问题标题】:Passing Array Size along with pointer in c在c中传递数组大小和指针
【发布时间】:2015-06-03 10:32:17
【问题描述】:

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

【问题讨论】:

  • 只需像这样将参数传递给方法:foo(arr,size); 您的函数需要以下声明:void foo(int *array, int size);
  • 它可以工作,但是当我在方法 1 中进行声明时,我是否可以访问 size 变量及其相应的原型声明?
  • 对不起,我对C很熟悉,但我从来没有见过这样的函数调用。

标签: c arrays pointers


【解决方案1】:

在 C 中,大小不是数组“对象”的一部分。因此,惯用的 C 代码将数组的大小与数组本身一起传递:

foo(arr, size);

函数

void foo(int arr[], int size);

(在整数数组的情况下)。

例如见main函数:

int main(int argc, char *argv[]);

(注意这里的论点是颠倒的。)

【讨论】:

  • 声明不应该是:void foo(int (*arr)[], int size);
  • 在你的问题中你有int arr[size];。在这种情况下,int arr[] 是正确的参数声明。您的声明是“指向 int 数组的指针”。 (main 示例中的 argv 是“指向 char 的指针数组”。)
  • 大小是数组对象的一部分。您可以使用sizeof 找到它。
【解决方案2】:

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()在访问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 的字段传递 - 未显示。

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多