none
變數的宣告離使用該變數的程式碼越近越好 ? RRS feed

  • 一般討論

  • 個人在撰寫function時 , 常會宣告許多變數 , 而變數的位置都是統一放到該function的最前面 , 因為這樣較為易讀 ,
    但最近跟同事討論一件事情 : 變數的宣告離使用該變數的程式碼越近越好?  
    請問真的是這樣嗎 ?  


    • 已變更類型 Lolota Lee 2010年3月9日 上午 09:50
    2010年3月2日 上午 08:56

所有回覆

  • Hi,

    你自己覺得呢?
    Code Complete這本書記得也是這樣的說法
    我是覺得這種東西見仁見智
    像是.NET設計規範就有很多種不同的說法
    找到一種適合自己其它人也能接受的方法就好
    不過若是函式很大的狀態下
    建議還是照這個原則做
    這樣變數生命週期也可以比較短一些
    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月2日 上午 09:07
  • 第一次看到這種說法 ...

    這要看變數的使用性質才對吧。
    如果依這樣的論調,那全域變數怎麼辦?

    變數是系統自動在記憶體中配置的一個區域,你不會也不可能操縱它配置的地方 ...
    而變數的使用都是靠指標,這和程式區塊離變數多近或多遠一點關係都沒有。
    初學不是問題,但用不正確的態度來問問題,那就是很大的問題。
    請不要藉新手之名行小白之實,否則只會讓更多無辜的新手得不到幫助而已。
    如果不知道什麼是小白,請參閱:何謂小白
    2010年3月2日 上午 09:28
    版主
  • Hi,

    翻了一下,記得沒錯
    Code Complete 2 第10.3節變數初始化原則中有提到在靠近變數第一次使用的位置初始化它

    下面這篇文章也有提到
    http://www.cis.nctu.edu.tw/chinese/doc/research/c++/C++FAQ-Chinese/c-cppfaq-3.html
    Q84:我該在函數中間或是開頭來宣告區域變數?

    在第一次用到它的地方附近。

    物件在宣告的時候就會被初始化(被建構)。如果在初始化物件的地方沒有足夠的資
    訊,直到函數中間才有的話,你可以在開頭處初始個「空值」給它,等以後再「設定
    」其值;你也可以在函數中間再初始個正確的東西給它。以執行效率來說,一開始就
    讓它有正確的值,會比先建立它,搞一搞它,之後再重建它來得好。以像 "String"
    這種簡單的例子來看,會有 350% 的速度差距。在你的系統上可能會不同;當然整個
    系統可能不會降低到 300+%,但是“一定”會有不必要的性能衰退現象。

    常見的反駁是:「我們會替物件的每個資料提供 "set" 運作行為,則建構時的額外
    耗費就會分散開來。」這比效能負荷更糟,因為你添加了維護的夢靨。替每個資料提
    供 "set" 運作行為就等於對資料不設防:你把內部實作技巧都顯露出來了。你隱藏
    到的只有成員物件的實體“名字”而已,但你用到的 List﹑String 和 float(舉例
    來說)型態都曝光了。通常維護會比 CPU 執行時間耗費的資源更多。

    區域變數應該在靠近它第一次用到之處宣告。很抱歉,這和 C 老手的習慣不同,但
    是「新的」不見得就是「不好的」。

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月2日 上午 09:45
  • 如同上面所說的這是見仁見智的問題,效能上不一定會差到哪,上面的文章是針對C++編譯器,但不代表.Net這類非原生碼的程式會有類似情況.
    我個人的心得是,一個function程式碼不應該太長(通常不會超過100),如果一個function程式太攏長代表這個function本身的內聚力就不足,表示這個function有多個以上之意義.
    如果function不攏長也代表每個function做的事情很明確,自然程式碼易讀,如果有空可以反組譯一下.Net Framework的 source code,會發現每段程式都很簡短.

    2010年3月2日 上午 09:59
  • 沒記錯的話,我有在某本重構的書上看到這講法。
    基本上我也是依照這風格去撰寫

    因為是function內宣告的變數,都是暫時性的變數。
    它的生命週期只有在function裡,其實可以靠許多重構的手法來消除它
    讓架構或是可讀性變好。

    萬一一定要宣告暫時性變數,就是離使用該變數的程式碼越近越好。
    第一,如果你的變數命名沒有包含型態,這樣你可以很快的找到它的宣告。
    第二,這樣不會忘了這個變數宣告的用途為何。
    第三,將來要改寫把暫時性變數消除時比較快速。
    2010年3月2日 上午 10:20
  • 我覺得應該是分成兩種,實值型別跟參考型別。

    參考型別會有個 pointer 算實值型別,這部分應該跟實值型別相同,當編譯完成後,所需要的記憶體就宣告在執行檔內,放在哪宣告沒啥意義。
    參考型別參照到變數時,才真正宣告到個體。

    所以
    Dim myArray As String() 放哪都沒差。
    myArray = New(){"1", "2"}
    才可能會影響。

    我自己是覺得爽就好,因為感覺不出來,那幹嘛自找麻煩...
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年3月2日 下午 03:35
  • 數值型別,參考型別.
    編譯程式,直譯程式.
    Java,C#....每一個都不同.
    另外考量可維護姓.
    Team Work...
    變數離程式碼越近越好.
    我的答案也是?
    2010年3月3日 上午 01:00
  • 我記得我之前看到的文章也大都是:

    把變數宣告集中在一區,但是在使用他的地方初始化。

    而不是把變數宣告在靠近使用他的地方...這樣容易到處都有變數宣告,看起來很亂吧??@@
    My Blog:http://www.dotblogs.com.tw/alonstar
    解決問題之後,別忘了回到論壇把正確回應標示成解答哦!
    2010年3月3日 上午 01:58
  • HI,

    這是程式寫作風格的議題, 我是採用[變數的宣告離使用該變數的程式碼越近越好]的做法, 但是我認為整個開發團隊採用一致的寫作風格即可.
    2010年3月3日 上午 02:22
  • 我一直認為是, 在開頭做宣告 , 到真的要使用的時候 , 才做new , 才開始占resource. 所以把變數宣告一起放在開頭 , 等真的要用時 , 才開始 new , 或給初始值 . 

    請大家幫我釐清一個疑問 :
       一個變數要做宣告(ex: StringBuilder sb;) , 以及給初始值(sb = new StringBuilder();) , 請問甚麼時候才是開始占resource(記憶體空間) ?   
    2010年3月3日 上午 02:56
  • 如果以OO的原則.
    內部的實作已被封起來了.所以不會錯亂.

    變數有變數範圍的問題.
    同一個變數名稱可能在多個地方被宣告.如巢狀,遞迴...
    你不可能在外面就宣告.

    我的用法是內部(私有)變數,方法變數.要用時在宣告.變數名稱也不用那麼嚴謹.

    但Public等跟外面溝通的變數.就要依Team的規範開發.
    2010年3月3日 上午 03:09
  • 忘記說了 .  我們是使用C#.net , VS2008 .

    2010年3月3日 上午 03:09

  • 我大部份都會集中一區,再後面加上註解,這樣也不會很亂,
    而直接擺在前面(例如該方法的上面),可能有特別的情況我才會這麼做。
    所以我可能是很 Free Style 吧?! 參考囉~


    萬丈高樓平地起,只要有心不艱辛
    2010年3月3日 上午 05:43
  • 僅宣告只佔 4 bytes (pointer)
    初始化後,是 4 bytes + 物件描述器 + 物件靜態變數
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年3月3日 上午 11:56