可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I tried something like :
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);
}
But this example code can't compile. How to send array by value (not ref throw pointer) to function?
回答1:
In your example, you will need to specify the exact size of the array in the definition of struct vec
, for example int v[10]. Also your initialization can be written better. Try this:
#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:
You can't send an array by value in C. Every time you try to pass an array to a function, you'll pass the pointer to the first value.
To pass an array by value, you can cheat a little and encapsulate it in a struct, and send it by value (so it will be copied)... It's a dirty hack, as explained here, but well, if you really want that, it works.
Another way is to copy the array inside the function, with the pointer given.
回答3:
While it's true that an array in C has a size, that size can only be accessed through the sizeof
operator, and then only on the original array. You can't cast an array to a structure in the hopes that the compiler will fill in all fields.
In fact, it's actually impossible to pass an array to a function "by value". All arrays decays to pointers, so when you pass an array to a function that function receives a pointer. This decay to pointers is also why you can only use the sizeof
operator on the original array, once it decays to a pointer the compiler have no idea that it's actually pointing to an array, so using the sizeof
operator (even on something that points to an array) will return the size of the pointer and not what it points to.
In your case, it would be simpler to change your function to take two arguments, the pointer to the array and the number of entries in the array:
/* `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]));
}
回答4:
Arrays are always passed by reference in C, you can't change that.
What you can do is make a copy of array and pass the new array in the function
回答5:
As the others noted, the only way in C to pass an array by value is to use a struct
with a fixed size array. But this is not a good idea, because the array size will be hardcoded into the struct
definition.
However, you really should not try to pass arrays by value. Instead, what you should do is simply to declare your pointer parameter as const
, like this:
int sum(size_t count, const int* array) {
While this does not pass the array by value, it clarifies the intent not to change the array, i. e. you can now treat sum()
as if you were passing the array by value.
If your function does indeed not change the array (like your sum()
function), using a const
pointer comes for free, copying the array to pass it by value would just waste time.
If your function really wants to change a private copy, do so explicitely within the function. If the array won't get too large, you can simply allocate it on the stack, like so:
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.
}