结构有什么特别之处?

What is special about structs?

我知道在 C 中我们不能 return 来自函数的数组,而是指向数组的指针。但我想知道 structs 的特殊之处是什么使它们 return- 即使它们可能包含数组也可以通过函数使用。

为什么 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;
}

首先,引用C11,章节§6.8.6.4,return声明,(强调我的

If a return statement with an expression is executed, the value of the expression is returned to the caller as the value of the function call expression.

返回结构变量是可能的(并且是正确的),因为结构 value 是 returned。这类似于 returning 任何原始数据类型(例如 returning int)。

另一方面,如果您 return 一个 数组 ,通过使用 return <array_name>,它实际上 return 是 数组的第一个元素的地址注意,如果数组是本地的,它在调用者中变得无效被调用的函数。因此,return不可能以这种方式创建数组。

所以,TL;DR,没有什么特别structs,特长在数组.


注意:

再次引用C11,章节§6.3.2.1,(我的重点

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]

提出相同问题的更好方法是 "what is special about arrays",因为它是附加了特殊处理的数组,而不是 structs。

通过指针传递和返回数组的行为可以追溯到 C 的原始实现。数组 "decay" 指向指针,造成很多混淆,尤其是在刚接触该语言的人中。另一方面,结构的行为就像 ints、doubles 等内置类型。这包括 struct 中嵌入的任何数组,但 flexible array members,未复制。

struct 类型没有什么特别之处; array 类型有一些特殊之处,可以防止它们直接从函数中 returned。

A struct 表达式被视为任何其他非数组类型的表达式;它的计算结果为 struct。所以你可以做

struct foo { ... };

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

表达式 someFoo 的计算结果为 struct foo 对象的 value;对象的内容是从函数 return 编辑而来的(即使这些内容包含数组)。

数组表达式被区别对待;如果它不是 sizeof 或一元 & 运算符的操作数,或者如果它不是用于在声明中初始化另一个数组的字符串文字,则表达式被转换("decays" ) 从类型 "array of T" 到 "pointer to T",表达式的值是第一个元素的地址。

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

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