|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 行者~ABC 于 2019-12-10 10:41 编辑 ' a. {& E- f. V, l
! A: L0 v5 p4 |) o+ ]% i
C语言函数为什么不能返回数组?
7 L, q/ P( i" K$ o H' ^- D在C语言程序开发中,我们不可以编写下面这样的代码:1 ~" N+ n, W. S& e
4 y% k3 y! D$ B& k$ A
& G O5 A$ F9 x7 X+ ?不可以编写这样的代码6 A- _4 `1 U8 |4 f7 o
* I/ y3 f* s; G这其实就是不能在C语言函数中返回数组。但是如果将数组定义在结构体里面,就可以将其返回了,例如下面这段C语言代码,请看:! i; r& |: F; L4 {2 V
& ~9 j$ O4 @+ U; B/ c, p函数可以返回结构体
% Q" R: {* ^/ e( U2 ]! P结构体 s 只有一个数组成员 arr,显然,函数可以返回结构体,即使结构体只有一个数组成员,这是为什么呢?C语言没有严格意义上的“数组类型”* T. v8 V+ Y- W# F3 e
基本上,C语言中的数据结构可以分为两类,第一类数据结构可以被赋值,而第二类数据结构不可以被赋值,数组属于第二类数据结构。+ i, ]5 i! ]# |" P6 [8 N, m1 J
除了数组,还有其他第二类数据结构吗?我想基本上没有了,除非把函数算上。与函数不能返回数组密切相关的事实是,C语言没有严格意义上的“数组类型”。可能从C语言代码角度来看,似乎有数组类型的变量,但是如果尝试将该变量像其他变量一样使用,得到的实际上是指向数组第一个元素的指针。例如下面这段C语言代码:5 C0 i Z+ r! S G! C
* F( Q+ u; z2 z4 O$ r# d- Y! f r- b
( V5 H1 O$ _6 _
+ ?% `- o+ b. {5 m& T' b+ k9 s7 n
) |1 Q7 n. e! X( V$ o w# U/ k( S( p2 M, i
: X6 S/ M6 I# O6 r
同样的,我们若是尝试将数组赋值给 a,最终实际得到仍然是将指针赋值给 a,熟悉C语言语法的读者应该能够看出不妥之处。2 h6 R c5 g4 V2 _) A/ x
为什么把数组塞入结构体,情况就不同了呢?
" T o9 Z+ F5 z- p% i9 S文章开头提到,虽然C语言的数组不可以被赋值,但是将其塞入结构体就可以赋值了。这是什么原因呢?" e$ |" O+ b2 R
其实这涉及到C语言的设计初衷,以及相关的一些发展历史了。C语言在语法和语义上与机器硬件很接近,它的基本操作可以被编译为一个或者几个机器指令,占用若干个处理器周期。
7 y( k2 d b+ }! lC语言中的数组是特殊的,它与指针一直都是非常暧昧的。这种暧昧的关系从C语言的前身B语言就开始了,并一直延续至今,而今天的结构体语法最初并不是包含在C语言中的。. Q/ [% @0 k8 u* v B6 c
因为C语言数组与指针的暧昧关系,编译器也很难区分它们,所以我们不可能为C语言数组赋值。而且由于“赋值”操作也属于C语言的基本操作,为了贴合硬件,要求其必须在几个处理器周期完成,所以单个的“赋值”运算符 = 基本上不可能扩展到需要几千乃至几万个机器周期,以对成千上万个数组元素赋值。; _2 u/ N8 H2 O- T$ E
基于这样的原理,早期的C语言其实连结构体赋值都是不支持的。
, N* H; _, w& V5 ^4 D+ u7 C1 k! @1 `到这里,相信不少读者又有疑问了,既然C语言的基本操作需要控制在少量的机器周期内,那为什么结构体赋值却是支持的呢?毕竟C语言中的结构体也是可以包含多个字节信息的。
" ]4 q4 S+ i- r9 E+ a/ m1 bC语言中的结构体也是可以包含多个字节信息的; l3 L% k- b( m, R% r
正如前文所说,早期的C语言的确不支持结构体赋值,但是在后来的发展中却增加了结构体赋值能力。对此只能说是结构体幸运,“将C语言基本操作控制在少量机器周期内”只是一个准则,而不是限制。
9 u2 h o+ ?2 |7 b4 C要知道,C语言结构体通常很小,只有几十到几百字节,增加结构体赋值能力无疑能够大大方便程序员编写代码。大多数情况下,结构体赋值操作并不会严重“超时”,这其实是一种平衡。& \) I$ p0 ~) S: B
我之前的文章曾经讨论过,程序设计语言一般都要处理一个天平,天平的两端分别是机器和程序员,如果追求极致的机器效率,将编程语言设计的十分精简,那么程序员就会非常痛苦。因此,即使是C语言,在追求高效率的同时,也要兼顾程序员的感受,所以稍稍违背一些设计准则,增加一些便利操作也是无可厚非的。小结: ?. X8 Z& ~3 @
C语言不支持数组赋值,更多的原因是C语言本身的特点(贴合硬件)以及一些历史原因。不过,如果真的希望对数组赋值,也是有一些技巧的,例如将数组塞入结构体。这一点我之前的文章已经讨论过,不再赘述了。
7 [) b4 a/ `; Q* i0 i1 k7 x$ z# D
|
|