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


在c#或java里面,我們通常會這樣寫for循環:

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

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

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

 因為我覺得最上面的那種方式,每次循環都會聲明一個變量,說不定會影響效率,於是百度了一下,發現其他人也有這個疑惑,特意百度了一些資料,在此做個綜合。

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

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

  一般來說, 在進入函數時, 所有的棧變量都分配好空間了. 所以那個for變量寫在哪里都是一樣的. 具體你可以看一下反匯編代碼, 全部就展現在你眼前了,我查看過C#的IL代碼,發現兩種寫法的IL代碼是一樣的,說明沒有區別。

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

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

最后總結:

  1. 對於使用int等基本數據類型作為循環變量,只要你用的優化方面足夠給力的主流的編譯器,完全不需要關心在循環外還是循環內定義循環變量。
  2. 如果循環變量本身是復雜的對象,建議在循環外定義好,並且在for循環的賦值語句、判斷語句中,都要避免重復創建對象。  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM