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

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

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

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

[復(fù)制鏈接]

448

主題

448

帖子

537

積分

二級會員

Rank: 2

積分
537
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 昨天 17:50 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
我是老溫,一名熱愛學(xué)習的嵌入式工程師- t6 O3 ?) T1 W. ]' L* {
關(guān)注我,一起變得更加優(yōu)秀!嵌入式開發(fā),特別是單片機os-less的程序,最易范的錯誤是全局變量滿天飛。
4 v1 L( f& i1 ^9 c9 @這個現(xiàn)象在早期匯編轉(zhuǎn)型過來的程序員以及初學(xué)者中常見,這幫家伙幾乎把全局變量當作函數(shù)形參來用。( C/ R4 b  m7 \7 \) _: e# N" V
在.h文檔里面定義許多雜亂的結(jié)構(gòu)體,extern一堆令人頭皮發(fā)麻的全局變量,然后再這個模塊里邊賦值123,那個模塊里邊判斷123分支決定做什么。
' \7 [6 Q; N3 @" q' g3 U每當看到這種程序,我總要戚眉變臉而后拍桌怒喝。沒錯,就是怒喝。+ ^: P' r# G2 j, w; O+ A$ w' b
不否認全局變量的重要性,但我認為要十分謹慎地使用它,濫用全局變量會帶來其它更為嚴重的結(jié)構(gòu)性系統(tǒng)問題。; [  u0 Z5 o, Z+ V2 l4 v

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

: F1 }. f% f  ]7 c
# |! t  V% \# `* B( s
要問對策,只有兩個原則
% `4 T. [" W& {- m- h' `4 v6 b能不用全局變量盡量不用,我想除了系統(tǒng)狀態(tài)和控制參數(shù)、通信處理和一些需要效率的模塊,其他的基本可以靠合理的軟件分層和編程技巧來解決。
) G! }8 L! r1 L2 n; ^2 R+ \如果不可避免需要用到,那能藏多深就藏多深。6 e; \/ l3 }1 G+ U7 o
如果只有某.c文件用,就static到該文件中,順便把結(jié)構(gòu)體定義也收進來;如果只有一個函數(shù)用,那就static到函數(shù)里面去;
0 A- U6 N, i2 u& Z9 i如果非要開放出去讓人讀取,那就用函數(shù)return出去,這樣就是只讀屬性了;2 Y) b9 S1 g1 b4 C5 o
如果非要遭人蹂躪賦值,好吧,我開放函數(shù)接口讓你傳參賦值;實在非要extern侵犯我,我還可以嚴格控制包含我.h檔的對象,而不是放到公共的includes.h中被人圍觀,丟人現(xiàn)眼。. u* @4 H  a- b; P- \2 ?
如此,你可明白我對全局變量的感悟有多深刻,悲催的我,已經(jīng)把當年那些“老人”交給我維護的那些案子加班全部重新翻寫了。: i* d( A0 u* P
最后補充  H# _# v4 n6 G% u4 P. q5 I+ M
全局變量是不可避免要用到的,每一個設(shè)備底層幾乎都需要它來記錄當前狀態(tài),控制時序,起承轉(zhuǎn)合。但是盡量不要用來傳遞參數(shù),這個很忌諱的。
8 O/ j7 E/ ^1 E( Q盡量把變量的作用范圍控制在使用它的模塊里面,如果其他模塊要訪問,就開個讀或?qū)懞瘮?shù)接口出來,嚴格控制訪問范圍。  D9 r# |) g( u/ h' D# H( S: v
這一點,C++的private屬性就是這么干的,這對將來程序的調(diào)試也很有好處。
( ?8 G" X5 k3 y5 W/ d: GC語言之所以有++版本,很大原因就是為了控制它的靈活性,要說面向?qū)ο蟮乃枷耄珻語言早已有之,亦可實現(xiàn)。
& K; W5 `7 F; n當一個模塊里面的全局變量超過3個(含)時,就用結(jié)構(gòu)體包起來吧,要歸0便一起歸0,省得丟三落四的。2 I+ R/ A9 ~) W8 u8 P
在函數(shù)里面開個靜態(tài)的全局變量,全局數(shù)組,是不占用?臻g的,只是有些編譯器對于大塊的全局數(shù)組,會放到和一般變量不同的地址區(qū)。. P1 @2 Q  y5 P, ^, d  h
若是在keil C51,因為是靜態(tài)編譯,棧爆掉了會報警,所以大可以盡情馳騁,注意交通規(guī)則就是了。3 k9 X* P5 _* W9 Q
單片機的os-less系統(tǒng)中,只有棧沒有堆的用法,那些默認對堆分配空間的“startup.s”,可以大膽的把堆空間干掉。, e& W" w5 V: g
程序模型?如何分析抽象出來呢,從哪個角度進行模型構(gòu)建呢?很愿意聆聽網(wǎng)友的意見。
5 V4 Z$ e& p9 k( L% l+ j* z* B本人一直以來都是從兩個角度分析系統(tǒng),事件--狀態(tài)機遷移圖 和 數(shù)據(jù)流圖,前者分析控制流向,完善UI,后者可知曉系統(tǒng)數(shù)據(jù)的緣起緣滅。( g% C+ M2 t- p7 U# Y+ N
這些理論,院校的《軟件工程》教材都有,大家不妨借鑒下。只不過那些理論,終究是起源于大型系統(tǒng)軟件管理的,牛刀殺雞,還是要裁剪一下的。
! I) Z3 x& P6 ^( Y; t! d來源:網(wǎng)絡(luò)。8 |. W+ [- o8 m3 m
-END-
  T9 @6 I  @, \( w" |5 _7 M往期推薦:點擊圖片即可跳轉(zhuǎn)閱讀; J/ j5 X' ^! a' m: O8 o& a" O5 M
                                                       
( Y) V" c6 p' a* k6 u4 l0 R                                                               
& Y' C2 r/ g6 _2 j6 n5 f6 t7 z  N                                                                        6 \. F5 \6 {# f3 s& O4 x3 Z
                                                                                7 m; C0 S' O8 [) o

7 c! D# M4 v8 k; V4 g( i1 l                                                                                $ x8 k5 Y+ z9 o2 A2 `' B
                                                                                        嵌入式大佬分享,簡單易用的開發(fā)工具及解決方案!) m5 V5 Z* z/ K+ v
                                                       
( G: @6 }$ m5 B- v- E- }                                                                  P+ M0 h0 Q9 t4 `" p/ w. @+ _
                                                                       
* X8 O& s& p( T, w3 `' w                                                                                ! `. u% X5 [, p) o1 o, W% H5 ]/ {

: ?" [% p$ M; U  A! k                                                                               
9 |9 U! S9 K" I$ D3 `                                                                                        一些非常全面的嵌入式軟件開發(fā)工具!9 Y7 s9 e8 a7 s* r8 ?
                                                                . {" M( X1 j# ~4 F0 N7 ~7 i
                                                                        8 @# j9 J- I# T
                                                                               
$ W; }+ S- ^! z% B
5 k4 z) {& F" d5 |* a                                                                               
- M& F" l/ J: @. x! R. _+ R                                                                                        探討一下,嵌入式邊緣計算技術(shù),前景何在?
9 _# a! B! W( C% R" i7 z/ E$ R                                                                               
, \$ K4 ?7 m3 H, M                                                                       
* |) Y5 S6 R; S$ K2 [4 F                                                               
4 ^  \% u! n$ J2 K, M% y: d                                                        我是老溫,一名熱愛學(xué)習的嵌入式工程師6 B% @3 X6 {) t+ J6 R: L
關(guān)注我,一起變得更加優(yōu)秀!
回復(fù)

使用道具 舉報

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

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

本版積分規(guī)則

關(guān)閉

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


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