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

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

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

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

[復(fù)制鏈接]

448

主題

448

帖子

537

積分

二級會員

Rank: 2

積分
537
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 昨天 17:50 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師1 Z5 F5 C0 w; E( H$ H: a
關(guān)注我,一起變得更加優(yōu)秀!嵌入式開發(fā),特別是單片機os-less的程序,最易范的錯誤是全局變量滿天飛。$ Q5 Z) a; D2 D* d1 _% G
這個現(xiàn)象在早期匯編轉(zhuǎn)型過來的程序員以及初學(xué)者中常見,這幫家伙幾乎把全局變量當(dāng)作函數(shù)形參來用。# [4 A  U; A4 q; Z, V
在.h文檔里面定義許多雜亂的結(jié)構(gòu)體,extern一堆令人頭皮發(fā)麻的全局變量,然后再這個模塊里邊賦值123,那個模塊里邊判斷123分支決定做什么。) @9 _' I6 c' Y7 z
每當(dāng)看到這種程序,我總要戚眉變臉而后拍桌怒喝。沒錯,就是怒喝。+ d$ m! m) v  l, k0 l
不否認全局變量的重要性,但我認為要十分謹慎地使用它,濫用全局變量會帶來其它更為嚴重的結(jié)構(gòu)性系統(tǒng)問題。6 X1 F7 b2 U1 f9 w  t5 O5 P( e

8 \6 z) l; b3 F. c" H4 i+ z為什么全局變量要越少越好?
5 x8 `! R; E: n3 T它會造成不必要的常量頻繁使用,特別當(dāng)這個常量沒有用宏定義“正名”時,代碼閱讀起來將萬分吃力。
' u" L; h5 }7 V% i' B& h它會導(dǎo)致軟件分層的不合理,全局變量相當(dāng)于一條快捷通道,它容易使程序員模糊了“設(shè)備層”和“應(yīng)用層”之間的邊界。寫出來的底層程序容易自作多情地關(guān)注起上層的應(yīng)用。& b: a" L4 X. g4 J+ K1 z1 B
這在軟件系統(tǒng)的構(gòu)建初期的確效率很高,功能調(diào)試進度一日千里,但到了后期往往bug一堆,處處“補丁”,雷區(qū)遍布。說是度日如年舉步維艱也不為過。
- ?  U7 z0 J/ R1 K由于軟件的分層不合理,到了后期維護,哪怕僅是增加修改刪除小功能,往往要從上到下掘地三尺地修改,涉及大多數(shù)模塊,
+ \) h: m5 A5 a4 B: ^而原有的代碼注釋卻忘了更新修改,這個時候,交給后來維護者的系統(tǒng)會越來越像一個“泥潭”,注釋的唯一作用只是使泥潭上方再加一些迷煙瘴氣。
. b4 x5 |9 q6 n+ |* X% d& O$ I全局變量大量使用,少不了有些變量流連忘返于中斷與主回圈程序之間。
' {: }4 g' J+ r, C' W這個時候如果處理不當(dāng),系統(tǒng)的bug就是隨機出現(xiàn)的,無規(guī)律的,這時候初步顯示出病入膏肓的特征來了,沒有大牛來力挽狂瀾,注定慢性死亡。' t- M+ L1 @  R1 H4 X7 {
無需多言,您已經(jīng)成功得到一個畸形的系統(tǒng),它處于一個神秘的穩(wěn)定狀態(tài)!( f2 Q$ ?. M4 {; ?% h
你看著這臺機器,機器也看著你,相對無言,心中發(fā)毛。你不確定它什么時候會崩潰,也不曉得下一次投訴什么時候道理。
! q2 k/ a% U4 C: U  U9 C全局變量大量使用有什么后果?# x+ E0 v& G$ X
“老人”氣昂昂,因為系統(tǒng)離不開他,所有“雷區(qū)”只有他了然于心。當(dāng)出現(xiàn)緊急的bug時,只有他能夠搞定。你不但不能辭退他,還要給他加薪。
$ x' E7 u4 S; U: f. C  c新人見光死,但凡招聘來維護這個系統(tǒng)的,除了改出更多的bug外,基本上一個月內(nèi)就走人,到了外面還宣揚這個公司的軟件質(zhì)量有夠差夠爛。% R2 B$ z* ^, z+ {; A3 Q7 k$ [/ J
隨著產(chǎn)品的后續(xù)升級,幾個月沒有接觸這個系統(tǒng)的原創(chuàng)者會發(fā)現(xiàn),很多雷區(qū)他本人也忘記了,于是每次的產(chǎn)品升級維護周期越來越長,) y: D6 W: f4 i* d6 e
因為修改一個功能會冒出很多bug,而按下一個bug,會彈出其他更多的bug。在這期間,又會產(chǎn)生更多的全局變量。
1 q: u* m7 E1 g4 A終于有一天他告訴老板,不行啦不行啦,資源不夠了,ram或者flash空間太小了,升級升級。
' x( Z: a) H: i& _客戶投訴不斷,售后也快崩潰了,業(yè)務(wù)員也不敢推薦此產(chǎn)品了,市場份額越來越小,公司形象越來越糟糕。+ K! p/ J% y3 t6 I' I

5 H6 ]5 ]3 h3 D& X. z  Y" ^- N: O. |
要問對策,只有兩個原則
8 W- B" y! ^, g) q5 E2 E能不用全局變量盡量不用,我想除了系統(tǒng)狀態(tài)和控制參數(shù)、通信處理和一些需要效率的模塊,其他的基本可以靠合理的軟件分層和編程技巧來解決。
) H5 s$ {5 W  [6 z+ c4 b如果不可避免需要用到,那能藏多深就藏多深。# W" \/ @& `6 [3 k2 M
如果只有某.c文件用,就static到該文件中,順便把結(jié)構(gòu)體定義也收進來;如果只有一個函數(shù)用,那就static到函數(shù)里面去;
+ c" E$ |4 J/ }( [; }$ ]* R& q0 n如果非要開放出去讓人讀取,那就用函數(shù)return出去,這樣就是只讀屬性了;% z# ]0 l2 E- s: J2 }( |7 P+ _6 k) D
如果非要遭人蹂躪賦值,好吧,我開放函數(shù)接口讓你傳參賦值;實在非要extern侵犯我,我還可以嚴格控制包含我.h檔的對象,而不是放到公共的includes.h中被人圍觀,丟人現(xiàn)眼。
$ f6 F3 |$ M/ N! b4 N+ b+ e. P
如此,你可明白我對全局變量的感悟有多深刻,悲催的我,已經(jīng)把當(dāng)年那些“老人”交給我維護的那些案子加班全部重新翻寫了。
. n. w$ y+ O( m最后補充8 Z- s% i$ w4 L6 G4 X: P
全局變量是不可避免要用到的,每一個設(shè)備底層幾乎都需要它來記錄當(dāng)前狀態(tài),控制時序,起承轉(zhuǎn)合。但是盡量不要用來傳遞參數(shù),這個很忌諱的。5 D+ Q5 G. X& m  L
盡量把變量的作用范圍控制在使用它的模塊里面,如果其他模塊要訪問,就開個讀或?qū)懞瘮?shù)接口出來,嚴格控制訪問范圍。$ h) k1 Q/ c9 c! F- ^
這一點,C++的private屬性就是這么干的,這對將來程序的調(diào)試也很有好處。2 P5 _  u  j3 l  o8 G
C語言之所以有++版本,很大原因就是為了控制它的靈活性,要說面向?qū)ο蟮乃枷,C語言早已有之,亦可實現(xiàn)。, @: E  T' i6 O  T* Q# @3 {
當(dāng)一個模塊里面的全局變量超過3個(含)時,就用結(jié)構(gòu)體包起來吧,要歸0便一起歸0,省得丟三落四的。
. ^% q! e+ _* S4 A; c8 w- r在函數(shù)里面開個靜態(tài)的全局變量,全局數(shù)組,是不占用棧空間的,只是有些編譯器對于大塊的全局數(shù)組,會放到和一般變量不同的地址區(qū)。3 D4 o7 o* L: n4 X$ K: S$ J% U
若是在keil C51,因為是靜態(tài)編譯,棧爆掉了會報警,所以大可以盡情馳騁,注意交通規(guī)則就是了。2 M. C% k6 q: `% k% I- b5 U% Q4 Q% h
單片機的os-less系統(tǒng)中,只有棧沒有堆的用法,那些默認對堆分配空間的“startup.s”,可以大膽的把堆空間干掉。1 V4 K+ j( d& q8 `9 _1 a
程序模型?如何分析抽象出來呢,從哪個角度進行模型構(gòu)建呢?很愿意聆聽網(wǎng)友的意見。8 ^$ m6 \2 J  s- s4 X) H0 y
本人一直以來都是從兩個角度分析系統(tǒng),事件--狀態(tài)機遷移圖 和 數(shù)據(jù)流圖,前者分析控制流向,完善UI,后者可知曉系統(tǒng)數(shù)據(jù)的緣起緣滅。, W) |( i% o7 z0 S+ K) X+ S
這些理論,院校的《軟件工程》教材都有,大家不妨借鑒下。只不過那些理論,終究是起源于大型系統(tǒng)軟件管理的,牛刀殺雞,還是要裁剪一下的。" n8 R, [0 W  b" p0 }
來源:網(wǎng)絡(luò)。
+ A8 |7 x( t" J4 `* x+ K) [: `6 `7 N-END-
' b2 Y( F$ Q# I5 h) v+ N" q往期推薦:點擊圖片即可跳轉(zhuǎn)閱讀3 r6 u" A( f3 \1 q
                                                        - V$ k2 A2 e: z! ]2 Z
                                                               
0 P% a% v7 r' f) G* F9 m: {% @                                                                       
; Y# ~( C7 f$ ^* b0 j                                                                               
( O* b7 @7 y+ @& x  ?. c % K  u- c8 v: q3 `
                                                                                0 r  [) V% o! ~
                                                                                        嵌入式大佬分享,簡單易用的開發(fā)工具及解決方案!: W" p6 z0 A; I  ~8 K/ V  X
                                                       
3 h6 s5 b- U$ ]7 M- s                                                               
6 H4 {, d; ?7 Q4 O6 o                                                                       
/ I# G& H2 V* O- {3 l                                                                               
7 f+ h% F: @5 ?% l0 {% ?- q3 Q 2 L( l0 z& S, E5 ~, ]
                                                                               
; _4 M$ E$ U1 i5 P8 n9 G                                                                                        一些非常全面的嵌入式軟件開發(fā)工具!0 C. r0 E& h4 c( [2 S$ ~
                                                               
2 h. \2 j  e1 y% K                                                                       
; u. O5 y; h. f3 v# G* L8 C1 m                                                                               
" H; a. ~8 X1 N' u
  Y& @% M" A  q; D; ?( O4 a                                                                               
7 q+ h/ ^0 ]  d) C2 ~  M. k                                                                                        探討一下,嵌入式邊緣計算技術(shù),前景何在?
! F/ E* Z+ J$ p/ R7 N                                                                                8 t# E; p6 y/ ?8 {
                                                                       
* I3 h" [0 h9 q" f                                                               
" o2 S. ?# |* ]  j                                                        我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
! e) b8 O4 R- a; z關(guān)注我,一起變得更加優(yōu)秀!
回復(fù)

使用道具 舉報

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

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

本版積分規(guī)則

關(guān)閉

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


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