C語言函數(shù)為什么不能返回?cái)?shù)組?
C語言函數(shù)為什么不能返回?cái)?shù)組?
在C語言程序開發(fā)中,我們不可以編寫下面這樣的代碼:
char f(void)[8] {char ret;// ...fill...return ret;}int main(int argc, char ** argv) {char obj_a[10];obj_a = f();}

不可以編寫這樣的代碼
struct s { char arr[10]; };struct s f(void) {struct s ret;// ...fill...return ret;}int main(int argc, char ** argv) {struct s obj_a;obj_a = f();}

函數(shù)可以返回結(jié)構(gòu)體
結(jié)構(gòu)體 s 只有一個(gè)數(shù)組成員 arr,顯然,函數(shù)可以返回結(jié)構(gòu)體,即使結(jié)構(gòu)體只有一個(gè)數(shù)組成員,這是為什么呢?
因?yàn)镃語言沒有嚴(yán)格意義上的“數(shù)組類型”!
基本上,C語言中的數(shù)據(jù)結(jié)構(gòu)可以分為兩類,第一類數(shù)據(jù)結(jié)構(gòu)可以被賦值,而第二類數(shù)據(jù)結(jié)構(gòu)不可以被賦值,數(shù)組屬于第二類數(shù)據(jù)結(jié)構(gòu)。
除了數(shù)組,還有其他第二類數(shù)據(jù)結(jié)構(gòu)嗎?我想基本上沒有了,除非把函數(shù)算上。
char a[10], b[10];a = b;
a = &b[0];
顯然,左邊是數(shù)組 a,而右邊其實(shí)是一個(gè)指針。即使數(shù)組在某種程度上可以看作能夠被賦值,但我們有很大幾率得到類型不匹配,例如下面這段C語言代碼:
a = f();
char ret[10];/* ... fill ... */return ret;
return &ret[0];
為什么把數(shù)組塞入結(jié)構(gòu)體,情況就不同了呢?
文章開頭提到,雖然C語言的數(shù)組不可以被賦值,但是將其塞入結(jié)構(gòu)體就可以賦值了。這是什么原因呢?
其實(shí),這涉及到C語言的設(shè)計(jì)初衷,以及相關(guān)的一些發(fā)展歷史了。C語言在語法和語義上與機(jī)器硬件很接近,它的基本操作可以被編譯為一個(gè)或者幾個(gè)機(jī)器指令,占用若干個(gè)處理器周期。
C語言中的數(shù)組是特殊的,它與指針一直都是非常曖昧的。這種曖昧的關(guān)系從C語言的前身B語言就開始了,并一直延續(xù)至今,而今天的結(jié)構(gòu)體語法最初并不是包含在C語言中的。
因?yàn)镃語言數(shù)組與指針的曖昧關(guān)系,編譯器也很難區(qū)分它們,所以我們不可能為C語言數(shù)組賦值。而且由于“賦值”操作也屬于C語言的基本操作,為了貼合硬件,要求其必須在幾個(gè)處理器周期完成,所以單個(gè)的“賦值”運(yùn)算符 = 基本上不可能擴(kuò)展到需要幾千乃至幾萬個(gè)機(jī)器周期,以對成千上萬個(gè)數(shù)組元素賦值。
基于這樣的原理,早期的C語言其實(shí)連結(jié)構(gòu)體賦值都是不支持的。
到這里,相信不少讀者又有疑問了,既然C語言的基本操作需要控制在少量的機(jī)器周期內(nèi),那為什么結(jié)構(gòu)體賦值卻是支持的呢?畢竟C語言中的結(jié)構(gòu)體也是可以包含多個(gè)字節(jié)信息的。
C語言中的結(jié)構(gòu)體也可包含多個(gè)字節(jié)信息
正如前文所說,早期的C語言的確不支持結(jié)構(gòu)體賦值,但是在后來的發(fā)展中卻增加了結(jié)構(gòu)體賦值能力。對此只能說是結(jié)構(gòu)體幸運(yùn),“將C語言基本操作控制在少量機(jī)器周期內(nèi)”只是一個(gè)準(zhǔn)則,而不是限制。
要知道,C語言結(jié)構(gòu)體通常很小,只有幾十到幾百字節(jié),增加結(jié)構(gòu)體賦值能力無疑能夠大大方便程序員編寫代碼。大多數(shù)情況下,結(jié)構(gòu)體賦值操作并不會(huì)嚴(yán)重“超時(shí)”,這其實(shí)是一種平衡。
我之前的文章曾經(jīng)討論過,程序設(shè)計(jì)語言一般都要處理一個(gè)天平,天平的兩端分別是機(jī)器和程序員,如果追求極致的機(jī)器效率,將編程語言設(shè)計(jì)的十分精簡,那么程序員就會(huì)非常痛苦。因此,即使是C語言,在追求高效率的同時(shí),也要兼顧程序員的感受,所以稍稍違背一些設(shè)計(jì)準(zhǔn)則,增加一些便利操作也是無可厚非的。
小結(jié)
C語言不支持?jǐn)?shù)組賦值,更多的原因是C語言本身的特點(diǎn)(貼合硬件)以及一些歷史原因。不過,如果真的希望對數(shù)組賦值,也是有一些技巧的,例如將數(shù)組塞入結(jié)構(gòu)體。這一點(diǎn)我之前的文章已經(jīng)討論過,不再贅述了。

評論
圖片
表情
