找回密码
 注册
关于网站域名变更的通知
查看: 391|回复: 1
打印 上一主题 下一主题

C语言函数不能返回数组,但可以返回结构体,为什么!

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-12-10 10:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 行者~ABC 于 2019-12-10 10:41 编辑
( }$ z; T, c- k% H/ h4 P
+ {9 \/ V; I: M! v2 |C语言函数为什么不能返回数组?' d! L: p3 R, H/ I. y
在C语言程序开发中,我们不可以编写下面这样的代码:
/ k1 Q- s: U" a: f% [; f% \' M5 B

2 W+ N2 h  ]; |
% t+ a' r8 Q; n& R
不可以编写这样的代码
+ V: d  P0 |! m9 P( H/ T$ d  E4 h) `
这其实就是不能在C语言函数中返回数组。但是如果将数组定义在结构体里面,就可以将其返回了,例如下面这段C语言代码,请看:$ \& H  g: |) M7 I& L

6 h. S8 J( g% p- u" c
函数可以返回结构体
* E4 f$ C- F& S) u# L' r# p结构体 s 只有一个数组成员 arr,显然,函数可以返回结构体,即使结构体只有一个数组成员,这是为什么呢?
C语言没有严格意义上的“数组类型”
' K- H3 Z) T% ^1 z$ ?" u' X' n基本上,C语言中的数据结构可以分为两类,第一类数据结构可以被赋值,而第二类数据结构不可以被赋值,数组属于第二类数据结构。
7 m1 K7 q1 B8 R+ _& Z
除了数组,还有其他第二类数据结构吗?
我想基本上没有了,除非把函数算上。与函数不能返回数组密切相关的事实是,C语言没有严格意义上的“数组类型”。可能从C语言代码角度来看,似乎有数组类型的变量,但是如果尝试将该变量像其他变量一样使用,得到的实际上是指向数组第一个元素的指针。例如下面这段C语言代码:
' n( ^. b, v& j/ l
$ c- `4 R% ~& G" C8 U4 O% R$ c9 O
6 J4 k1 |6 l( ~) J4 t6 e: [

; D0 }, q0 s. h+ B

# {6 o' \& l3 w* N
1 e" u6 C" G4 H, b; k. M& @1 b% i# @! O* H* r7 q( J
3 H2 \1 j9 v+ O
同样的,我们若是尝试将数组赋值给 a,最终实际得到仍然是将指针赋值给 a,熟悉C语言语法的读者应该能够看出不妥之处。. w9 }  Y5 ]( ^
为什么把数组塞入结构体,情况就不同了呢?. J$ D; x% }' ~" |+ |
文章开头提到,虽然C语言的数组不可以被赋值,但是将其塞入结构体就可以赋值了。
这是什么原因呢?
" h. [2 C, C" G* k  L$ L: c其实这涉及到C语言的设计初衷,以及相关的一些发展历史了。
C语言在语法和语义上与机器硬件很接近,它的基本操作可以被编译为一个或者几个机器指令,占用若干个处理器周期。' P- K8 ^5 C9 Z2 |5 J$ U- w" {* G
C语言中的数组是特殊的,它与指针一直都是非常暧昧的。
这种暧昧的关系从C语言的前身B语言就开始了,并一直延续至今,而今天的结构体语法最初并不是包含在C语言中的。
  Z1 d3 m! _5 J/ f9 i因为C语言数组与指针的暧昧关系,编译器也很难区分它们,所以我们不可能为C语言数组赋值。
而且由于“赋值”操作也属于C语言的基本操作,为了贴合硬件,要求其必须在几个处理器周期完成,所以单个的“赋值”运算符 = 基本上不可能扩展到需要几千乃至几万个机器周期,以对成千上万个数组元素赋值。
3 w0 a# l5 a! u, @基于这样的原理,早期的C语言其实连结构体赋值都是不支持的。
& J$ L! ?7 k1 w) ~  M! |
到这里,相信不少读者又有疑问了,既然C语言的基本操作需要控制在少量的机器周期内,那为什么结构体赋值却是支持的呢?
毕竟C语言中的结构体也是可以包含多个字节信息的。
9 B/ F- n! R1 f" dC语言中的结构体也是可以包含多个字节信息的
. J5 `8 g1 C; R5 C% _. q
正如前文所说,早期的C语言的确不支持结构体赋值,但是在后来的发展中却增加了结构体赋值能力。
对此只能说是结构体幸运,“将C语言基本操作控制在少量机器周期内”只是一个准则,而不是限制。
3 C$ x: w! z/ [8 I" U6 }5 ~要知道,C语言结构体通常很小,只有几十到几百字节,增加结构体赋值能力无疑能够大大方便程序员编写代码。
大多数情况下,结构体赋值操作并不会严重“超时”,这其实是一种平衡。
5 N  g* {' |* Z4 n3 ~我之前的文章曾经讨论过,程序设计语言一般都要处理一个天平,天平的两端分别是机器和程序员,如果追求极致的机器效率,将编程语言设计的十分精简,那么程序员就会非常痛苦。
因此,即使是C语言,在追求高效率的同时,也要兼顾程序员的感受,所以稍稍违背一些设计准则,增加一些便利操作也是无可厚非的。小结' K& S5 S: t3 z, W9 d; w; [
C语言不支持数组赋值,更多的原因是C语言本身的特点(贴合硬件)以及一些历史原因。
不过,如果真的希望对数组赋值,也是有一些技巧的,例如将数组塞入结构体。这一点我之前的文章已经讨论过,不再赘述了。, a: Y3 Z: K# z; ?
  [! H: n( H4 ^! ]! e7 |+ }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-26 20:48 , Processed in 0.125000 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表