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

PCB聯盟網

搜索
查看: 45|回復: 0
收起左側

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

[復制鏈接]

448

主題

448

帖子

537

積分

二級會員

Rank: 2

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

" C7 }9 E3 `. v% h7 V, Q/ |0 d) l* t/ ~
要問對策,只有兩個原則  D( ^) s3 {+ w0 l1 A  X
能不用全局變量盡量不用,我想除了系統狀態(tài)和控制參數、通信處理和一些需要效率的模塊,其他的基本可以靠合理的軟件分層和編程技巧來解決。
, l4 z0 X4 `  u如果不可避免需要用到,那能藏多深就藏多深。. Q$ }4 C, S2 k6 q  q  \2 S& u/ B) k
如果只有某.c文件用,就static到該文件中,順便把結構體定義也收進來;如果只有一個函數用,那就static到函數里面去;) @" a( T- |5 P% h
如果非要開放出去讓人讀取,那就用函數return出去,這樣就是只讀屬性了;
& R; W8 ?5 a3 F" I如果非要遭人蹂躪賦值,好吧,我開放函數接口讓你傳參賦值;實在非要extern侵犯我,我還可以嚴格控制包含我.h檔的對象,而不是放到公共的includes.h中被人圍觀,丟人現眼。4 j& q$ |$ Z: H& ~/ Y# m" ]
如此,你可明白我對全局變量的感悟有多深刻,悲催的我,已經把當年那些“老人”交給我維護的那些案子加班全部重新翻寫了。5 ]% g; [5 d1 s6 |1 o" C8 }
最后補充
+ Q! y# {( J3 n1 |全局變量是不可避免要用到的,每一個設備底層幾乎都需要它來記錄當前狀態(tài),控制時序,起承轉合。但是盡量不要用來傳遞參數,這個很忌諱的。
4 m% _! u% q/ M盡量把變量的作用范圍控制在使用它的模塊里面,如果其他模塊要訪問,就開個讀或寫函數接口出來,嚴格控制訪問范圍。- c; Z& g5 Z- h$ H$ m; u0 @2 h
這一點,C++的private屬性就是這么干的,這對將來程序的調試也很有好處。6 \$ N# S' |" @$ \/ t  ?) i
C語言之所以有++版本,很大原因就是為了控制它的靈活性,要說面向對象的思想,C語言早已有之,亦可實現。% F1 p$ e; W5 j3 N7 S+ p1 n
當一個模塊里面的全局變量超過3個(含)時,就用結構體包起來吧,要歸0便一起歸0,省得丟三落四的。
4 U& w! _4 ~3 ]8 s. W+ d在函數里面開個靜態(tài)的全局變量,全局數組,是不占用?臻g的,只是有些編譯器對于大塊的全局數組,會放到和一般變量不同的地址區(qū)。& H% H. J, l1 h4 f- R  Q( t
若是在keil C51,因為是靜態(tài)編譯,棧爆掉了會報警,所以大可以盡情馳騁,注意交通規(guī)則就是了。5 m8 F2 {# {! [1 D
單片機的os-less系統中,只有棧沒有堆的用法,那些默認對堆分配空間的“startup.s”,可以大膽的把堆空間干掉。
9 ?- |4 g/ {# v. o程序模型?如何分析抽象出來呢,從哪個角度進行模型構建呢?很愿意聆聽網友的意見。3 Q/ a8 W( j3 H9 _6 v
本人一直以來都是從兩個角度分析系統,事件--狀態(tài)機遷移圖 和 數據流圖,前者分析控制流向,完善UI,后者可知曉系統數據的緣起緣滅。  o4 R, F6 P  x# ^; z
這些理論,院校的《軟件工程》教材都有,大家不妨借鑒下。只不過那些理論,終究是起源于大型系統軟件管理的,牛刀殺雞,還是要裁剪一下的。
# F# B5 O$ X5 b  S$ A來源:網絡。% o9 \+ c- d5 Z  K! Z( |4 T' Y
-END-
9 \5 u) @+ C% {1 Y往期推薦:點擊圖片即可跳轉閱讀
/ R7 a: w0 V+ A- E) E                                                        $ K9 f! m7 u/ p8 D% L/ }6 q
                                                               
3 M% z7 x+ E# M5 V: x1 P' L                                                                       
' ~  [7 m/ f. b                                                                               
3 [2 ^: J4 q: s1 p0 `) Z
% L( i* k* i4 W2 F                                                                               
8 C1 {/ O8 P6 m5 R5 C                                                                                        嵌入式大佬分享,簡單易用的開發(fā)工具及解決方案!
/ h2 w, V; \0 B2 t, J9 `                                                        ! x# i9 k' K; z) J' e9 h
                                                                , r/ }8 j0 A3 s( u2 L8 k1 u  z
                                                                        ; z" H6 z5 H. N- O: G% w
                                                                                $ j4 c0 `: O# P
- X* R8 z( C3 \! o+ Q  G8 ~4 M
                                                                                6 p. B7 M! ~; R+ [
                                                                                        一些非常全面的嵌入式軟件開發(fā)工具!2 O: R; ]1 d) A3 I* C  U7 a
                                                                7 f  E/ a$ U. n& P6 f" o
                                                                        : u3 _2 Y- Q8 y% s+ V: g0 \# Z
                                                                                ' U* [6 y8 i. t( }4 z

: @* g; e4 p$ ]9 f                                                                                9 d: ?" U1 v. A6 [8 }
                                                                                        探討一下,嵌入式邊緣計算技術,前景何在?3 s- J, r: p+ i: u
                                                                                % x5 b* f8 c) Z3 m( b6 \4 \
                                                                        % z7 i! }5 i- e9 p3 Q
                                                                1 n1 \4 I9 p+ q+ @" D" k% V
                                                        我是老溫,一名熱愛學習的嵌入式工程師
% R+ e8 V% q8 t$ K關注我,一起變得更加優(yōu)秀!
回復

使用道具 舉報

發(fā)表回復

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

本版積分規(guī)則

關閉

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


聯系客服 關注微信 下載APP 返回頂部 返回列表