關於變量在for循環內外定義的思考

在c#或java裏面,咱們一般會這樣寫for循環:java

for(int i = 0;i<10;i++)
{
     Console.WriteLine(i);      
}

前一陣子,我突發奇想,若是按照下面這樣寫,會不會比上面的運行效率高一些:程序員

int i = 0;
for(; i<10 ;i++)
{
      Console.WriteLine(i);      
}

 由於我以爲最上面的那種方式,每次循環都會聲明一個變量,說不定會影響效率,因而百度了一下,發現其餘人也有這個疑惑,特地百度了一些資料,在此作個綜合。編程

   首先是在內層循環中定義變量到底會不會存在重複分配的問題,這涉及到編譯器的優化,不過主流編譯器(如vs和gcc)這一塊優化都比較好,不會反覆分配變量。函數的定義是編譯器的事情,運行的時候不存在什麼定義,更沒有什麼開銷。c#

 除非是類對象或者結構體對象, 在for循環裏面與外面, 開銷可能會不同.基本數據類型, 那是同樣的, 編譯器確定會優化這個東西。markdown

  通常來講, 在進入函數時, 全部的棧變量都分配好空間了. 因此那個for變量寫在哪裏都是同樣的. 具體你能夠看一下反彙編代碼, 所有就展示在你眼前了,我查看過C#的IL代碼,發現兩種寫法的IL代碼是同樣的,說明沒有區別。函數

      棧中的空間在編譯這個代碼的時候大小就肯定下來了,運行這個方法時空間就已經分配好了,不要想固然的覺得聲明一次就要分配一次空間,那是c語言,java能夠重用這些超出做用域的空間。只要用javap查看方法字節碼,看看使用的局部變量表的大小和使用方式即知java這種基於虛擬機的語言,是跟單純的C不一樣,C語言的原則是相信程序員能作好一切,所以它不會幫你作多少事情,須要考慮代碼優化,內存佔用等。優化

  不過,本身在編程的時候要注意不要讓上一次的結果影響到下一次循環,好比上一次 a = 3, 當下一次循環在給a賦值的時候出了錯誤,而你捕獲了錯誤,卻沒修正a的值,程序繼續執行,那麼這時候a=3還成立,可能就會有問題了,若是是每次都從新定義,那就不存在這樣的問題。spa

最後總結:code

  1. 對於使用int等基本數據類型做爲循環變量,只要你用的優化方面足夠給力的主流的編譯器,徹底不須要關心在循環外仍是循環內定義循環變量。
  2. 若是循環變量自己是複雜的對象,建議在循環外定義好,而且在for循環的賦值語句、判斷語句中,都要避免重複建立對象。  
相關文章
相關標籤/搜索