如何通过值发送数组到c中的函数?

时间:2014-02-23 13:52:58

标签: c flexible-array-member

我尝试过类似的事情:

typedef struct vec{
     int sz;
     int v[];
} ff;

int sum(struct vec z){
    int o=0,i;
    for(i=0;i<z.sz;i++)
        o+=z.v[i];
    return o;
}

int main(){
    int test[]={10,1,2,3,4,5,6,7,8,9,10};
    return sum((struct vec)test);
}

但是这个示例代码无法编译。如何按值发送数组(不是ref throw指针)来运行?

5 个答案:

答案 0 :(得分:3)

您无法在C中按值发送数组。每次尝试将数组传递给函数时,都会将指针传递给第一个值。
要按值传递数组,你可以稍微欺骗并将其封装在结构中,并按值发送(因此它将被复制)......这是一个肮脏的黑客,as explained here,但是,如果你真的很想要,它有效。
另一种方法是使用给定的指针复制函数内的数组。

答案 1 :(得分:2)

在您的示例中,您需要在struct vec的定义中指定数组的确切大小,例如int v [10]。您的初始化也可以更好地编写。试试这个:

#define MAX_SIZE 50
struct vec {
   int sz;
   int v[MAX_SIZE];
};

int sum(struct vec z){
  int i, o;
  o = 0;
  for(i=0; i<z.sz; i++) o += z.v[i];
  return o;
}

int main(){
  struct vec test = {10, {1,2,3,4,5,6,7,8,9,10}};
  return sum(test);
}

答案 2 :(得分:1)

虽然C中的数组确实具有大小,但只能通过sizeof运算符访问该大小,然后才能访问原始数组。您不能将数组转换为结构,希望编译器将填充所有字段。

实际上,实际上不可能将数组传递给“按值”的函数。所有数组衰减到指针,因此当您将数组传递给函数时,该函数会接收指针。这种对指针的衰减也是为什么你只能在原始数组上使用sizeof运算符,一旦它衰减到指针,编译器就不知道它实际指向一个数组,所以使用sizeof运算符(即使是指向数组的东西)也会返回指针的大小而不是它指向的大小。

在您的情况下,更改函数以获取两个参数,指针到数组以及数组中的条目数更简单:

/* `array` is an array containing `elements` number of `int` elements. */
int sum(const int *array, const size_t elements)
{
    ...
}

int main(void)
{
    ...
    printf("Sum = %d\n", sum(test, sizeof(test) / sizeof(test[0]));
}

答案 3 :(得分:0)

数组总是在C中通过引用传递,你无法改变它。

你可以做的是复制数组并在函数

中传递新数组

答案 4 :(得分:0)

正如其他人所指出的,C中通过值传递数组的唯一方法是使用具有固定大小数组的struct。但这不是一个好主意,因为数组大小将被硬编码到struct定义中。

但是,你真的不应该尝试按值传递数组。相反,你应该做的只是将你的指针参数声明为const,如下所示:

int sum(size_t count, const int* array) {

虽然这不会按值传递数组,但它澄清了不更改数组的意图,i。即您现在可以将sum() 视为按值传递数组 如果你的函数确实没有改变数组(比如sum()函数),那么使用const指针是免费的,复制数组以按值传递它只会浪费时间。
如果您的函数确实想要更改私有副本,请在函数中明确地执行此操作。如果数组不会太大,你可以简单地在堆栈上分配它,如下所示:

int doSomethingWithPrivateCopy(size_t count, const int* array) {
    int mutableCopy[count];
    memcpy(mutableCopy, array, sizeof(mutableCopy));
    //Now do anything you like with the data in mutable copy.
}