首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按值传递数组

按值传递数组
EN

Stack Overflow用户
提问于 2017-02-05 03:33:25
回答 3查看 2.7K关注 0票数 12

通常,当我们以数组的名称传递数组时,它是按地址调用。这意味着,如果我们在main()之外更改数组的任何值,它将反映在main()中。

所以,如果我想将数组作为函数的参数传递并在main()中调用它,那么我应该做什么,这样就不会在main()中反映对该函数的任何更改。

例如:

代码语言:javascript
复制
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.
}

现在,我想按值将abc数组传递给Foo

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-05 04:28:28

可以通过在struct中包装数组来实现这一点。您可以为数组的大小包括一个字段,这样就不需要显式地传递这个参数。这种方法的优点是避免了以后必须释放的额外内存分配。

C已经通过值将参数传递给函数,但是数组标识符在大多数表达式中都会衰减到指针,特别是在函数调用中。然而,structs不会衰减到指针,而是通过值传递给函数,这意味着原始结构及其所有内容的副本在函数的范围内是可见的。如果struct包含一个数组,这也会被复制。注意,如果struct包含一个指向动态数组的int指针,那么当struct传递给函数时,指针就会被复制,但是副本和原始指针都引用相同的内存。这种方法依赖于包含实际数组的struct

还请注意,struct不能包含不完整类型的成员,因此不能包含VLA。这里,我将全局常量MAX_ARR定义为100,以便为处理具有相同struct类型的不同大小的数组提供一些空间。

您还可以从函数返回一个struct。我已经包含了一个示例,它修改传递给函数的Array struct,并返回要分配给调用函数中的不同Array struct的修改后的struct。这将导致调用方同时访问原始数组和转换数组。

代码语言:javascript
复制
#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;
}

程序输出:

代码语言:javascript
复制
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
票数 15
EN

Stack Overflow用户

发布于 2017-02-05 04:08:07

一般来说,你不能。

打电话的人可以这样做;

代码语言:javascript
复制
int main()
{
    int abc[]={5,1,2,9};

    {
         int temp[sizeof (abc)/sizeof (*abc)];
         memcpy(temp, abc, sizeof(abc));
         Foo(temp);
    }
}

请记住,Foo()没有收到任何有关传递的数组中元素数量的信息。

如果您希望Foo()做类似的事情,所以调用者不需要这样做,那么有必要将元素的数量作为一个单独的参数传递。

代码语言:javascript
复制
void Foo(int arr[], size_t size)    /*  C99 or later */
{
       int temp[size];   //   VLA
       memcpy(temp, arr, size*sizeof(int));
         /* whatever */
}

或者(在C99之前)。

代码语言:javascript
复制
void Foo(int arr[], size_t size)    /*  Before C99 */
{
       int *temp = malloc(size * sizeof (int));
       memcpy(temp, arr, size*sizeof(int));
         /* whatever */
       free(temp);
}

为了避免内存泄漏,在第二种情况下,必须确保函数在调用free(temp)之前不会返回。

在上述两个版本的Foo()中,可能需要额外的错误检查(例如,检测空指针或传递零大小、malloc()成功等)。

票数 5
EN

Stack Overflow用户

发布于 2017-02-05 03:45:47

(我不知道为什么Ryan不自愿提供自己的答案,但我同意以下几点应该有效:)

代码语言:javascript
复制
#include <stdlib.h> // In header
#include <string.h>

int Foo(size_t size, int arr[])
{
   // guard against bad arguments
   if (arr == NULL || size <= 0)
   {
       return -1;
   }

   // create local array, since size is variable, allocate dynamically
   int* arr_2 = NULL;
   if ((arr_2 = malloc(n * sizeof(*arr_2)) == NULL)
   {
       return -1; // malloc allocation error
   }
   // otherwise if the size is constant:
   // int arr_2[SOME_CONSTANT_SIZE];

   // copy from arr to arr_2
   memcpy(arr_2, arr, n * sizeof(*arr_2));

   // some computation

   free(arr_2);

   return 0;
}

记住,一旦我们离开了arr_2的作用域,Foo就不再存在了。另外,对于非原始数组元素,您需要做更多的复制工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42048268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档