我知道在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;
}
答案 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中的数据,但不能在类的情况下访问数据。因此,结构包装是有效的。