当按值提供给函数时,结构的数组字段是否会完全克隆?

时间:2018-09-13 11:59:08

标签: c arrays pointers struct pass-by-value

在C中:

  • 结构通过值(通过参数)发送到函数中时,将创建一个新的 struct ,因此更改了函数内部的结构不会改变原始结构。

  • 当通过值将数组(通过参数)发送到函数中时,会创建一个新的指针,因此请在函数内部更改数组不会更改原始数组,但是更改函数内部的数组值(因为我们有指向原始数组的指针)将更改原始数组中的值。

  • 当具有 array 字段的结构通过值通过值(通过参数)发送到函数时, ????? < / strong>已创建,因此更改函数内部的数组(指针)不会更改原始数组,更改数组值也不会更改原始数组中的值。

第三点是否意味着在将结构数组字段发送给函数时,它将被完全克隆?为什么不只使用指针呢?规范对此有何说明?

我玩过的一段代码:

typedef struct {
    int value;
    int array[3]; /* initialized to 0 by default */
} Struct_t;

void foo(Struct_t structure)
{
    printf("-- %p\n", structure.array); /* Pointer to local array */

    structure.value = 1;
    *structure.array = 1;       /* Won't change the original array */
    *(structure.array + 1) = 1; /* Won't change the original array */
    structure.array[2] = 1;     /* Won't change the original array */
}

int main()
{
    Struct_t s = { .value = 0 };

    foo(s);

    printf("-- %p\n", s.array); /* Pointer to original array */

    printf("%d\n", s.value);
    printf("%d\n", s.array[0]);
    printf("%d\n", s.array[1]);
    printf("%d\n", s.array[2]);
}

输出:

-- 0x7ffe8f17d194
-- 0x7ffe8f17d1b4
0
0
0
0

4 个答案:

答案 0 :(得分:5)

OP的“何时发送数组...”需要澄清。

  

当数组通过值(通过参数)发送到函数中时,会创建一个新的指针,因此更改函数内部的数组不会更改原始数组,而是更改函数内部的数组值(因为我们有指向原始数组的指针)将更改原始数组中的值。 (OP)

将下面的s[]之类的数组传递给strcpy(char *s1, const char *s2)时,会先进行转换。对象s将转换为数组第一个元素的地址。 strcpy()不会收到s[]作为s1参数,而是会收到&s[0]值的副本。

char s[6] = "Hello";
strcpy(s, "World");

strcpy()中,s1不是数组s1是指向char的指针。 strcpy()没有“在函数内部更改数组”的概念,因为函数不知道s1指向数组内存,分配的内存或其他任何内容。 strcpy()理解s1指向char


  

第三点是否意味着将结构的数组字段发送给函数时将其完全克隆?

是的。当将对象传递给C语言中的函数时,它可能会被转换,然后按值传递。这很像任何作业。转换后,对象的内容将复制到目标。转换后,对象是struct, union, int, double, void*, int(*)()等还是包含数组的struct ,都没有区别。

int a;
double b;
a = 5;  // 5 is copied to a
b = a;  // a is converted to double and copied to b


char s[6] = "Hello";
char *e;
void *v;
e = s; // s is converted to the address on the first array element and then copied to e
v = e; // e is converted to a `void*` and then copied to v

Struct_t f = {0};
Struct_t g;
g = f; // f is copied to g

答案 1 :(得分:2)

  

第三点是否意味着将结构的数组字段发送给函数时将其完全克隆?

是的

  

为什么不只使用指针呢?

因为没有指针。数组不是指针。 (More on this here.

答案 2 :(得分:0)

C中,所有都是按值传递。

  1. 传递值时,我们会将变量的副本传递给函数。

  2. 当我们通过引用传递时,我们会将变量的别名传递给函数。

    它将指针的值(地址)复制到函数中。

  

如果将struct按值传递给函数,则bytes   struct被复制为功能参数。所做的一切   函数中的struct更改副本,而不是原始副本   struct

答案 3 :(得分:0)

结构是内存的预定义结构,具有一定的内存布局。通过将数组添加到struct中,数组的实际内存位于struct中而不是指针中。这就是为什么必须将其与其余结构一起复制的原因。

数组不是指针,数组具有特定的不可更改的内存位置,而指针可以指向您想要的任何地方。