Fah*_*hik 11 c arrays function pass-by-value
通常当我们按名称传递数组时,它是按地址调用的.这意味着如果我们改变外部数组的任何值,main()它将被反映出来main().
那么,如果我想将数组作为函数的参数传递并在其中调用,main()以便该函数中的任何更改都不会反映在内部,我应该怎么做main()?
例如:
void Foo(int arr[]) //takes an integer array `arr` as argument
{
// do something with `arr
}
int main()
{
int abc[]={5,1,2,9};
//do something to pass `abc` inside `Foo` so that changes inside `Foo` doesn't change the value of `abc` array.
}
Run Code Online (Sandbox Code Playgroud)
现在我想通过值传递abc数组Foo.
ex *_*ilo 13
可以通过将数组包装在一个中来实现struct.您可以包含数组大小的字段,以便您不需要显式传递此参数.这种方法的优点是避免了以后必须释放的额外内存分配.
C已经通过值将参数传递给函数,但是数组标识符在大多数表达式中衰减为指针,特别是在函数调用中.然而,structs不会衰减到指针,而是通过值传递给函数,这意味着原始结构的副本及其所有内容在函数范围内都是可见的.如果struct包含一个数组,也会复制它.请注意,如果struct包含,例如,指向int动态数组的指针,则在struct传递给函数时复制指针,但复制和原始指针都引用相同的内存.这种方法依赖于struct包含实际数组.
另请注意,a struct不能包含具有不完整类型的成员,因此不能包含VLA.在这里,我将全局常量定义MAX_ARR为100,以便为处理具有相同struct类型的不同大小的数组提供一些空间.
您也可以struct从函数返回a .我已经包含了一个示例,它修改了Array struct传递给函数的函数,并返回修改后的函数,该函数struct被赋值给不同Array struct的函数.这导致调用者可以访问原始数组和转换后的数组.
#include <stdio.h>
#define MAX_ARR 100
struct Array {
size_t size;
int array[MAX_ARR];
};
void print_array(struct Array local_arr);
void func(struct Array local_arr);
struct Array triple(struct Array local_arr);
int main(void)
{
struct Array data = {
.size = 10,
.array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
};
struct Array transformed_data;
func(data);
transformed_data = triple(data);
printf("Original\n");
print_array(data);
printf("Transformed\n");
print_array(transformed_data);
return 0;
}
void print_array(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
printf("%5d", local_arr.array[i]);
}
putchar('\n');
}
void func(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
local_arr.array[i] *= 2;
}
printf("Modified\n");
print_array(local_arr);
}
struct Array triple(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
local_arr.array[i] *= 3;
}
return local_arr;
}
Run Code Online (Sandbox Code Playgroud)
节目输出:
Modified
2 4 6 8 10 12 14 16 18 20
Original
1 2 3 4 5 6 7 8 9 10
Transformed
3 6 9 12 15 18 21 24 27 30
Run Code Online (Sandbox Code Playgroud)
一般来说,你不能.
来电者可以这样做;
int main()
{
int abc[]={5,1,2,9};
{
int temp[sizeof (abc)/sizeof (*abc)];
memcpy(temp, abc, sizeof(abc));
Foo(temp);
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,Foo()没有收到有关传递的数组中元素数量的任何信息.
如果你想做Foo()类似的事情,那么调用者不需要,有必要将元素的数量作为单独的参数传递.
void Foo(int arr[], size_t size) /* C99 or later */
{
int temp[size]; // VLA
memcpy(temp, arr, size*sizeof(int));
/* whatever */
}
Run Code Online (Sandbox Code Playgroud)
或(在C99之前).
void Foo(int arr[], size_t size) /* Before C99 */
{
int *temp = malloc(size * sizeof (int));
memcpy(temp, arr, size*sizeof(int));
/* whatever */
free(temp);
}
Run Code Online (Sandbox Code Playgroud)
为避免内存泄漏,在第二种情况下,必须确保函数在调用之前不返回free(temp).
在Foo()上面的两个版本中,可能需要额外的错误检查(例如,检测空指针或传递的零大小,malloc()成功等).