我想知道为什么不能在C中返回数组?毕竟,数组只是一个由大小信息支持的指针(以便sizeof工作).首先我认为这是为了防止我返回我的堆栈上定义的数组,但没有什么能阻止我将指针返回到我的堆栈上的东西(gcc警告我,但代码编译).而且我也可以返回字符串文字,这是静态存储的字符数组.顺便说一句,在lunux中存储它.rodata,并且const数组也存储在那里(检查它objdump),所以我可以返回数组(将它转换为指针)并且它可以工作,但是AFAIK这只是特定于实现的(另一个操作系统) /编译器可以在堆栈上存储const).
我有2个想法如何实现数组返回:只需将其复制为值(就像它为结构所做的那样.我甚至可以将数据包装到结构中!!),并自动创建指针或允许用户返回const数组和创建这样的数组应具有静态存储持续时间的合同(就像它对字符串所做的那样).这两个想法都是微不足道的!所以,我的问题是为什么K&R没有实现类似的东西?
M.M*_*M.M 13
数组不是"只是一个由大小信息支持的指针".
数组是某种类型的连续元素块.没有指针.
由于数组是一个对象,因此可以形成一个指向数组或指向数组元素之一的指针.但是这样的指针不是数组的一部分,并且不与数组一起存储.说"一个int只是一个由1int 大小支持的指针" 是很有意义的.
编译器已知数组的大小,其方式与已知任何对象的大小相同.如果我们double d;知道那sizeof d是sizeof(double)因为编译器会记住这d是一个类型的对象double.
什么都阻止我返回指向我的堆栈上的东西的指针
C标准阻止您执行此操作(并使用返回的指针).如果您编写的代码违反了标准,那么您就是自己的代码.
我也可以返回字符串文字
字符串文字是char数组.在return语句中使用数组时,它将转换为指向第一个元素的指针.
要按值返回(和分配)数组,必须更改有关将数组转换为指针(有时称为"衰减")的规则.这是可能的,但K&R决定在设计C时几乎无处不在.
事实上,有可能拥有像C这样的语言,但根本没有衰变.也许在后见之明可以省去很多困惑.然而,他们只是选择以他们的方式实施C.
在K&R C中,也无法按价值返回结构.任何非原始类型的复制操作都必须使用memcpy或等效的迭代副本完成.考虑到20世纪70年代硬件资源的方式,这似乎是一个合理的设计决策.
ANSI C增加了按值返回结构的可能性,但到那时,即使他们想要改变衰减规则也为时已晚; 它会破坏许多依赖于衰变规则的现有代码.
Dol*_*000 11
从技术上讲,你可以返回一个数组; 你不能"直接"做到这一点,但必须将它包装在一个结构中:
struct foo {
int array[5];
};
struct foo returns_array(void) {
return((struct foo) {
.array = {2, 4, 6, 8, 10}
});
}
Run Code Online (Sandbox Code Playgroud)
但是为什么C不允许你直接做到这一点,尽管它有能力仍然是一个很好的问题.它可能与它不支持整个数组赋值的事实相关:
void bar(int input[5]) {
int temp[5];
temp = input; <-- Doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
当然,更令人陌生的是,支持通过参数传递的全数组拷贝.如果有人知道如何找到ANSI委员会关于此事的决定,那将会很有趣.
然而,
毕竟,数组只是一个由大小信息支持的指针(使sizeof工作).
这是不正确的.数组没有显式指针,也没有任何存储的大小.数组存储为原始值,打包在一起; 大小只在编译器中已知,并且永远不会在程序中显式为运行时数据.当您尝试将其用作指针时,该数组会衰减为指针.