int root(int n) { return (int)sqrt((float)n); }
然後我們的求范圍內素數的函數可以這樣寫。
int prime(int n) { int i; for (i = 2; i <= root(n); i++) { if (n%i == 0) return 0; return 1; } }
當然,把root函數放在循環中不是個不明智的選擇,但想象一下,在某個程序上下文內必須頻繁地調用某個類似root的函數,其調用函數的花銷會有多大:當遇到普通函數的調用指令時,程序會保存當前函數的執行現場,將函數中的局部變量以及函數地址壓入堆棧,然後再將即將調用的新函數加載到內存中,這要經歷復制參數值、跳轉到所調用函數的內存位置、執行函數代碼、存儲函數返回值等過程,當函數執行完後,再獲取之前正在調用的函數的地址,回去繼續執行那個函數,運行時間開銷簡直太多了。 C++內聯函數提供了替代函數調用的方案,通過inline聲明,編譯器首先在函數調用處使用函數體本身語句替換了函數調用語句,然後編譯替換後的代碼。因此,通過內聯函數,編譯器不需要跳轉到內存其他地址去執行函數調用,也不需要保留函數調用時的現場數據。 inline函數的優缺點分析 通過下面這些優缺點總結你大概會更理解為什麼要使用inline函數: 優點: 它通過避免函數調用所帶來的開銷來提高你程序的運行速度。 當函數調用發生時,它節省了變量彈棧、壓棧的開銷。 它避免了一個函數執行完返回原現場的開銷。 通過將函數聲明為內聯,你可以把函數定義放在頭文件內。 缺點: 因為代碼的擴展,內聯函數增大了可執行程序的體積。 C++內聯函數的展開是中編譯階段,這就意味著如果你的內聯函數發生了改動,那麼就需要重新編譯代碼。 當你把內聯函數放在頭文件中時,它將會使你的頭文件信息變多,不過頭文件的使用者不用在意這些。 有時候內聯函數並不受到青睐,比如在嵌入式系統中,嵌入式系統的存儲約束可能不允許體積很大的可執行程序。 什麼時候該使用內聯函數 當程序設計需要時,每個函數都可以聲明為inline。下面列舉一些有用的建議: 當對程序執行性能有要求時,那麼就使用內聯函數吧。 當你想宏定義一個函數時,那就果斷使用內聯函數吧。 在類內部定義的函數會默認聲明為inline函數,這有利於 類實現細節的隱藏。 關鍵點 內聯聲明只是一種對編譯器的建議,編譯器是否采用內聯措施由編譯器自己來決定。甚至在匯編階段或鏈接階段,一些沒有inline聲明的函數編譯器也會將它內聯展開。 編譯器的內聯看起來就像是代碼的復制與粘貼,這與預處理宏是很不同的:宏是強制的內聯展開,可能將會污染所有的命名空間與代碼,將為程序的調試帶來困難。 所有中類中定義的函數都默認聲明為inline函數,所有我們不用顯示地去聲明inline。 虛函數不允許內聯。 雖然說模板函數放中頭文件中,但它們不一定是內聯的。(不是說定義在頭文件中的函數都是內聯函數)。