结构有什么特别之处?

我知道在C中,我们不能从函数返回一个数组,而是一个指向数组的指针。 但是我想知道structs的特殊之处是什么使得它们可以通过函数返回,即使它们可能包含数组。

为什么struct包装使下面的程序有效?

 #include <stdio.h> struct data { char buf[256]; }; struct data Foo(const char *buf); int main(void) { struct data obj; obj = Foo("This is a sentence."); printf("%s\n", obj.buf); return 0; } struct data Foo(const char *buf) { struct data X; strcpy(X.buf, buf); return X; } 

询问相同问题的一个更好的方法是“数组有什么特别之处”,因为它是有特殊处理的数组,而不是struct

通过指针传递和返回数组的行为可以追溯到C语言的原始实现。对指针进行“衰减”,造成了很大的混乱,特别是在新语言的人之间。 另一方面,结构的行为与内置types相同,如int s, double s等。这包括embedded在struct中的任何数组,除了不复制的灵活数组成员外。

首先,引用C11 ,第6.8.6.4章, return语句,( 强调我的

如果执行带有expression式的return语句,则expression式的将作为函数调用expression式的值返回给调用者。

返回结构variables是可能的(并且是正确的),因为结构被返回。 这与返回任何原始数据types(例如,返回int )类似。

另一方面,如果使用return <array_name>返回一个数组 ,则返回数组 第一个元素地址 NOTE ,如果该数组对于被调用的函数是本地的,则在调用者中变为无效。 所以,以这种方式返回数组是不可能的。

所以, TL; DRstruct没有什么特别之处 ,专业是arrays


注意:

再次引用C11 ,第6.3.2.1章( 我强调

除了sizeof运算符, _Alignof运算符或一元运算符的操作数,或者是用于初始化数组的string字面值以外,具有types为'''的数组的expression式将转换为expression式键入“指向types”的指针指向数组对象的初始元素,而不是左值。 […]

structtypes没有什么特别之处; 这就是数组types有一些特殊的地方阻止它们直接从函数返回。

structexpression式被视为任何其他非数组types的expression式; 它评估的struct价值 。 所以你可以做一些事情

 struct foo { ... }; struct foo func( void ) { struct foo someFoo; ... return someFoo; } 

someFooexpression式求值为 struct foo对象的 ; 该对象的内容从函数返回(即使这些内容包含数组)。

数组expression式的处理方式不同; 如果它不是sizeof或unary &运算符的操作数,或者如果它不是用来在声明中初始化另一个数组的string文本,则将expression式从“ T ”数组转换(“decays”)为“指向T指针“,expression式的值是第一个元素的地址。

所以你不能通过函数的值返回一个数组,因为对数组expression式的任何引用都会被自动转换为一个指针值。

结构默认情况下是公共数据成员,所以在struct的情况下可以访问main中的数据,但不能在class中访问数据。 所以,结构包装是有效的。