结构有什么特别之处?

时间:2016-04-26 17:50:40

标签: c arrays struct return return-value

我知道在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;
}

4 个答案:

答案 0 :(得分:100)

提出相同问题的更好方法是“数组有什么特别之处”,因为它是附加特殊处理的数组,而不是struct s。

通过指针传递和返回数组的行为追溯到C的原始实现。数组“衰减”到指针,引起很多混乱,特别是对于刚接触该语言的人。另一方面,结构的行为与内置类型相似,例如int s,double等。这包括struct中嵌入的任何数组,class Account < ActiveRecord::Base private def balance=(the_balance) write_attribute(:balance, the_balance) end end 除外3}},不复制。

答案 1 :(得分:38)

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

  

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

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

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

所以, TL; DR ,没有特殊struct s,专业是数组

注:

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

  

除非它是sizeof运算符,_Alignof运算符或者&运算符的操作数。   一元Reference Assemblies\Microsoft\Framework\.NETPortable运算符,或者是用于初始化数组的字符串文字,一个表达式   type ''类型''的数组被转换为类型''指向类型''指针的表达式   到数组对象的初始元素并且不是左值。 [...]

答案 2 :(得分:11)

struct类型没有什么特别之处;它有 array 类型的特殊功能,可以防止它们直接从函数返回。

struct表达式被视为任何其他非数组类型的表达式;它评估struct。所以你可以做像

这样的事情
struct foo { ... };

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

表达式someFoo计算struct foo对象的;从函数返回对象的内容(即使这些内容包含数组)。

数组表达式的处理方式不同;如果它不是sizeof或一元&运算符的操作数,或者如果它不是用于在声明中初始化另一个数组的字符串文字,则转换表达式( &#34;衰变&#34;)来自类型&#34;数组T&#34; to&#34;指向T&#34;的指针,表达式的值是第一个元素的地址。

因此,您无法从函数返回值的数组,因为对数组表达式的任何引用都会自动转换为指针值。

答案 3 :(得分:-5)

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