電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 24|回復(fù): 0
收起左側(cè)

嵌入式 C 語言,為什么全局變量越少越好?

[復(fù)制鏈接]

448

主題

448

帖子

537

積分

二級會員

Rank: 2

積分
537
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 昨天 17:50 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
* J6 t7 z9 S8 @: W關(guān)注我,一起變得更加優(yōu)秀!嵌入式開發(fā),特別是單片機os-less的程序,最易范的錯誤是全局變量滿天飛。+ G! z" V2 ^# S. x: W" F) J
這個現(xiàn)象在早期匯編轉(zhuǎn)型過來的程序員以及初學(xué)者中常見,這幫家伙幾乎把全局變量當(dāng)作函數(shù)形參來用。" _8 o% x' O3 }
在.h文檔里面定義許多雜亂的結(jié)構(gòu)體,extern一堆令人頭皮發(fā)麻的全局變量,然后再這個模塊里邊賦值123,那個模塊里邊判斷123分支決定做什么。, f0 b2 V, l4 [7 G- s, c
每當(dāng)看到這種程序,我總要戚眉變臉而后拍桌怒喝。沒錯,就是怒喝。
; M$ s7 X7 F3 _9 H, I5 V" Y不否認全局變量的重要性,但我認為要十分謹慎地使用它,濫用全局變量會帶來其它更為嚴重的結(jié)構(gòu)性系統(tǒng)問題。
+ }& H$ A# \: e  v; R* q1 w6 `! Z 5 ~7 F  |( H* Q+ G
為什么全局變量要越少越好?
7 J: s2 V# x! y% K3 P1 t) p" e0 i$ _1 W它會造成不必要的常量頻繁使用,特別當(dāng)這個常量沒有用宏定義“正名”時,代碼閱讀起來將萬分吃力。
0 T3 j3 {2 ~. N& h它會導(dǎo)致軟件分層的不合理,全局變量相當(dāng)于一條快捷通道,它容易使程序員模糊了“設(shè)備層”和“應(yīng)用層”之間的邊界。寫出來的底層程序容易自作多情地關(guān)注起上層的應(yīng)用。: F  L7 w$ H( E; ~8 D
這在軟件系統(tǒng)的構(gòu)建初期的確效率很高,功能調(diào)試進度一日千里,但到了后期往往bug一堆,處處“補丁”,雷區(qū)遍布。說是度日如年舉步維艱也不為過。
$ `8 Q7 s; v& N- I+ A5 {2 U由于軟件的分層不合理,到了后期維護,哪怕僅是增加修改刪除小功能,往往要從上到下掘地三尺地修改,涉及大多數(shù)模塊,
1 @+ t: D# ^0 @/ J! n而原有的代碼注釋卻忘了更新修改,這個時候,交給后來維護者的系統(tǒng)會越來越像一個“泥潭”,注釋的唯一作用只是使泥潭上方再加一些迷煙瘴氣。5 w. @. t5 }8 [  W
全局變量大量使用,少不了有些變量流連忘返于中斷與主回圈程序之間。
" v: ~+ A; B& J# W! r這個時候如果處理不當(dāng),系統(tǒng)的bug就是隨機出現(xiàn)的,無規(guī)律的,這時候初步顯示出病入膏肓的特征來了,沒有大牛來力挽狂瀾,注定慢性死亡。8 w; e/ l7 Z3 h& C
無需多言,您已經(jīng)成功得到一個畸形的系統(tǒng),它處于一個神秘的穩(wěn)定狀態(tài)!
- K- D+ x3 \( w, f# x' Q& Q) [; L你看著這臺機器,機器也看著你,相對無言,心中發(fā)毛。你不確定它什么時候會崩潰,也不曉得下一次投訴什么時候道理。
0 k* ^" `4 R, e3 k全局變量大量使用有什么后果?* Q, V9 Q: R" V+ F9 @" T
“老人”氣昂昂,因為系統(tǒng)離不開他,所有“雷區(qū)”只有他了然于心。當(dāng)出現(xiàn)緊急的bug時,只有他能夠搞定。你不但不能辭退他,還要給他加薪。) X1 ^" S9 H' Y7 n6 U) T3 e. ^5 }
新人見光死,但凡招聘來維護這個系統(tǒng)的,除了改出更多的bug外,基本上一個月內(nèi)就走人,到了外面還宣揚這個公司的軟件質(zhì)量有夠差夠爛。
" a; r7 D7 [9 ?6 \; A7 ^5 q隨著產(chǎn)品的后續(xù)升級,幾個月沒有接觸這個系統(tǒng)的原創(chuàng)者會發(fā)現(xiàn),很多雷區(qū)他本人也忘記了,于是每次的產(chǎn)品升級維護周期越來越長,, b) \2 H% i5 h& H4 S7 v# b/ u
因為修改一個功能會冒出很多bug,而按下一個bug,會彈出其他更多的bug。在這期間,又會產(chǎn)生更多的全局變量。6 p/ F) a2 V+ Q* N6 I7 ~  }
終于有一天他告訴老板,不行啦不行啦,資源不夠了,ram或者flash空間太小了,升級升級。
# |# ?' a& y0 |: r8 q* Q. c4 h客戶投訴不斷,售后也快崩潰了,業(yè)務(wù)員也不敢推薦此產(chǎn)品了,市場份額越來越小,公司形象越來越糟糕。7 O$ p1 I4 [' F4 b* a/ p

1 O  h" n( C6 C; y3 G
3 H8 k. O4 n8 B; z
要問對策,只有兩個原則( E) U  o+ P7 M! ]. o/ h' e5 q( j
能不用全局變量盡量不用,我想除了系統(tǒng)狀態(tài)和控制參數(shù)、通信處理和一些需要效率的模塊,其他的基本可以靠合理的軟件分層和編程技巧來解決。/ X; f$ x8 }9 E5 D) a1 s
如果不可避免需要用到,那能藏多深就藏多深。
& \3 {9 H% k& N* d4 T5 ~如果只有某.c文件用,就static到該文件中,順便把結(jié)構(gòu)體定義也收進來;如果只有一個函數(shù)用,那就static到函數(shù)里面去;+ F3 y1 M4 O( a) m+ k
如果非要開放出去讓人讀取,那就用函數(shù)return出去,這樣就是只讀屬性了;
4 D' j% s+ f' G) U2 `3 Y% o% Y: h+ A如果非要遭人蹂躪賦值,好吧,我開放函數(shù)接口讓你傳參賦值;實在非要extern侵犯我,我還可以嚴格控制包含我.h檔的對象,而不是放到公共的includes.h中被人圍觀,丟人現(xiàn)眼。7 P: t, j4 \9 M) B
如此,你可明白我對全局變量的感悟有多深刻,悲催的我,已經(jīng)把當(dāng)年那些“老人”交給我維護的那些案子加班全部重新翻寫了。$ L/ @8 N& t+ r
最后補充
7 v) i5 W0 X4 c! v2 \6 v- Q. Y全局變量是不可避免要用到的,每一個設(shè)備底層幾乎都需要它來記錄當(dāng)前狀態(tài),控制時序,起承轉(zhuǎn)合。但是盡量不要用來傳遞參數(shù),這個很忌諱的。& U  z. F5 I" E$ E8 f
盡量把變量的作用范圍控制在使用它的模塊里面,如果其他模塊要訪問,就開個讀或?qū)懞瘮?shù)接口出來,嚴格控制訪問范圍。
6 M; x8 d* `% O; p: r; \這一點,C++的private屬性就是這么干的,這對將來程序的調(diào)試也很有好處。# F' {1 @; U9 F
C語言之所以有++版本,很大原因就是為了控制它的靈活性,要說面向?qū)ο蟮乃枷耄珻語言早已有之,亦可實現(xiàn)。3 _3 n. Z) {. t4 k! U" @; y
當(dāng)一個模塊里面的全局變量超過3個(含)時,就用結(jié)構(gòu)體包起來吧,要歸0便一起歸0,省得丟三落四的。
9 r6 P* _$ e* A# ~& ?& S在函數(shù)里面開個靜態(tài)的全局變量,全局數(shù)組,是不占用棧空間的,只是有些編譯器對于大塊的全局數(shù)組,會放到和一般變量不同的地址區(qū)。: T$ G7 J; u3 g' n& I" s) g7 c  e
若是在keil C51,因為是靜態(tài)編譯,棧爆掉了會報警,所以大可以盡情馳騁,注意交通規(guī)則就是了。
7 O5 G/ e( D. l9 s- h單片機的os-less系統(tǒng)中,只有棧沒有堆的用法,那些默認對堆分配空間的“startup.s”,可以大膽的把堆空間干掉。/ c! Y" Y# K  I4 e! J
程序模型?如何分析抽象出來呢,從哪個角度進行模型構(gòu)建呢?很愿意聆聽網(wǎng)友的意見。
5 Q( O5 M" \" Y; N本人一直以來都是從兩個角度分析系統(tǒng),事件--狀態(tài)機遷移圖 和 數(shù)據(jù)流圖,前者分析控制流向,完善UI,后者可知曉系統(tǒng)數(shù)據(jù)的緣起緣滅。7 |9 W( X! I- e; o/ s  c$ d7 ~5 T
這些理論,院校的《軟件工程》教材都有,大家不妨借鑒下。只不過那些理論,終究是起源于大型系統(tǒng)軟件管理的,牛刀殺雞,還是要裁剪一下的。) z  j; g! k* P: r7 G  s
來源:網(wǎng)絡(luò)。
- R1 m( p% H3 @8 j; `: `# z-END-# x: Z# u7 s" ^' L- H8 U5 {. W, X
往期推薦:點擊圖片即可跳轉(zhuǎn)閱讀
7 j9 t, @9 c  v- k, A. v                                                        * L/ K$ B' e% t
                                                                - B* L! V+ u* U
                                                                        $ B! ?+ G$ x. A7 W8 X4 u% b
                                                                               
/ a2 c* ^" o$ h4 ?7 I, O$ R
( i/ Q% q$ b1 \& ?                                                                                ' c( [8 ~0 A  O9 _+ P3 u
                                                                                        嵌入式大佬分享,簡單易用的開發(fā)工具及解決方案!& l3 ]4 D# Z' s8 x2 E+ c% l( L
                                                        2 W  B: o6 ~/ P0 T. l
                                                               
; m) z* J+ {7 g1 z  i1 v8 N. S                                                                        : A9 d3 a6 Q% b" a# T
                                                                                & @+ A$ F: i) i% J
5 K& C- L% N5 n1 F
                                                                                # W' X3 Y2 E$ x
                                                                                        一些非常全面的嵌入式軟件開發(fā)工具!# n' }, W# u4 _/ A
                                                                5 P7 X! o; p  @8 {2 T5 b  e$ l, K5 ]
                                                                       
* z; S# {* b0 l2 W                                                                               
" }1 E; v, b6 ]
" [. {/ U0 M7 D. V% o                                                                               
6 T* e% ]. ^7 R                                                                                        探討一下,嵌入式邊緣計算技術(shù),前景何在?
# @- F& u# Y- v* j5 }0 h                                                                                0 ?4 \; G  {1 \; `4 [
                                                                          V, T0 s* f3 n: E) Z4 r
                                                                # y+ u' y0 r1 z- i& _8 ]0 m. [
                                                        我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師1 X& ~' o2 O, s5 ?6 \
關(guān)注我,一起變得更加優(yōu)秀!
回復(fù)

使用道具 舉報

發(fā)表回復(fù)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

關(guān)閉

站長推薦上一條 /1 下一條


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表