当按值提供给函数时,结构的数组字段是否会被完全克隆?
Does the array field of a struct get entirely cloned when fed by value to a function?
在 C 中:
当 struct 按值发送(通过参数)到函数时,一个新的 struct已创建,因此更改函数内部的结构不会更改原始结构。
当 array 按值发送(通过参数)到函数时,一个新的 pointer已创建,因此更改函数内的数组不会更改原始数组,但更改函数内的数组值(因为我们有指向原始数组的指针)将更改原始数组中的值。
当带有 array 字段的 struct 按值发送(通过参数)到函数中时, ?????? 被创建,这样改变函数内部的数组(指针)不会改变原来的数组,改变数组的值也不会改变原来的值数组.
第三点是否意味着 struct 的 array 字段在发送到函数时将被完全克隆?为什么不只使用指针呢?规范对此有何规定?
我玩过的一段代码:
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
在 C
中,一切都是按值传递。
当我们按值传递时,我们将变量的副本传递给函数。
当我们通过引用传递时,我们将变量的别名传递给函数。
就是把指针的值,也就是地址,复制到函数中。
If a struct
is passed by value to a function the bytes
of the
struct
are copied as the function parameter. Anything done to that
struct
within the function changes the copy, not the original
struct
结构体是内存的预定义结构,具有一定的内存布局。通过将数组添加到结构中,数组的实际内存位于结构中而不是指针中。这就是为什么它必须与结构的其余部分一起复制的原因。
数组不是指针,数组有一个特定的不可改变的内存位置,而指针可以指向任何你想要的地方。
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
是的。
Why isn't just the pointer used instead?
因为没有指针。数组 不是 指针。 (More on this here.)
OP 的 "When an array is sent ..." 需要澄清。
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array. (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()
没有 "changing the array inside the function" 的概念,因为函数不知道 s1
指向数组内存、分配的内存或其他任何东西。 strcpy()
理解 s1
指向一个 char
.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
是的。当一个对象被传递给 C 中的函数时,它可能会被转换,然后按值传递。这很像任何作业。对象的内容,在转换后被复制到目的地。转换后,如果对象是 struct, union, int, double, void*, int(*)()
等或包含数组 .
的 a 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
在 C 中:
当 struct 按值发送(通过参数)到函数时,一个新的 struct已创建,因此更改函数内部的结构不会更改原始结构。
当 array 按值发送(通过参数)到函数时,一个新的 pointer已创建,因此更改函数内的数组不会更改原始数组,但更改函数内的数组值(因为我们有指向原始数组的指针)将更改原始数组中的值。
当带有 array 字段的 struct 按值发送(通过参数)到函数中时, ?????? 被创建,这样改变函数内部的数组(指针)不会改变原来的数组,改变数组的值也不会改变原来的值数组.
第三点是否意味着 struct 的 array 字段在发送到函数时将被完全克隆?为什么不只使用指针呢?规范对此有何规定?
我玩过的一段代码:
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
在 C
中,一切都是按值传递。
当我们按值传递时,我们将变量的副本传递给函数。
当我们通过引用传递时,我们将变量的别名传递给函数。
就是把指针的值,也就是地址,复制到函数中。
If a
struct
is passed by value to a function thebytes
of thestruct
are copied as the function parameter. Anything done to thatstruct
within the function changes the copy, not the originalstruct
结构体是内存的预定义结构,具有一定的内存布局。通过将数组添加到结构中,数组的实际内存位于结构中而不是指针中。这就是为什么它必须与结构的其余部分一起复制的原因。
数组不是指针,数组有一个特定的不可改变的内存位置,而指针可以指向任何你想要的地方。
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
是的。
Why isn't just the pointer used instead?
因为没有指针。数组 不是 指针。 (More on this here.)
OP 的 "When an array is sent ..." 需要澄清。
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array. (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()
没有 "changing the array inside the function" 的概念,因为函数不知道 s1
指向数组内存、分配的内存或其他任何东西。 strcpy()
理解 s1
指向一个 char
.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
是的。当一个对象被传递给 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