在進行變量說明的時候,我們還應該注意到以下兩點:
1.注意變量的使用範圍(即:變量的作用域)。不允許超出變量的作用域使用變量。變量的作用域是從該變量被說明的地方起,直到此說明所在的程序塊結束為止,包括其中的子程序塊。例如:在例3.5中,變量total的作用域是從定義它的語句開始直到結束函數定義的花括號為止,而變量的作用域是整個for循環語句。
2.最好在靠近變量使用的地方說明變量,不要在程序中隨便的地方去說明變量。否則,別人會很難讀你的程序。
4.5內聯函數
在C語言中對那些簡短的而使用頻率很髙的表達式,可以用define宏定義來處理它們。預處理器會把宏名展開成相應的字符串或表達式。請看下麵C語言中宏定義的例子。
例4.6下麵定義的宏MAX(X,Y)將返回X和Y中的較大者。
在上麵的例子中,預處理器將對main()函數中的MAX(x,y)表達式進行宏展開,處理後的main()函數如下所示:
在C++中,可以利用內聯函數達到類似的效果。內聯函數主要是解決程序運行效率的問題。函數調用需要建立環境,進行參數傳遞等,這些工作需要一定的時間開銷,對於經常使用的餚單的函數,這種開銷可能讓人不可接受。內聯函數對這個問題作了很好的解決。
內聯函數是使用inline關鍵字聲明的一個函數。inline是一種函數修飾符。當在函數定義頭一行的函數名前加上這個關鍵字後,編譯器將在該函數被調用的每個地方都插入它的一份拷貝,而不是編譯為一個單獨的可調用的代碼。這樣可以減少調用函數所需要的時間開銷(如將參數裝入棧中),從而程序更快地運行。同時它仍然允許程序以結構化的方式組織。但是,這樣做的結果是使程序變得更大了。下麵我們給出一個使用內聯函數的例子。
例4.7在Visual C++中通過內聯函數來實現例3.4同樣的效果。
可見,內聯函數可以被編譯程序所識別,而宏則是通過簡單的正文替換來實現的。內聯函數的一個好處是編譯程序可以對其參數作類型檢查;另一個好處是內聯函數的行為與普通的函數一樣,沒有宏定義帶來的那些副作用。
在使用內聯函數時,應注意以下幾點:
1.當調用一個函數時,參數要裝入桟中,各個寄存器的內容和狀態都需要保存。當函數返回時,還要恢複它們的內容和狀態。所以函數的調用需要一定的開銷。使用內聯函數時,函數的調用是進行代碼的擴展,而不是簡單的函數調用。這將提高運行效率,所以把那些使用頻繁的函數說明成內聯函數是非常有用的。
2.由於內聯函數的調用是進行代碼的擴展,這必將造成重複代碼的生成,而使程序過長。所以最好對那些小的函數使用內聯函數。
3.inline對編譯器來說,隻是一種請求而不是命令。即編譯器可以忽略內聯請求而把它作為真正的函數處理來處理。例如,如果一個函數包含了歸調用時,編譯器就會忽略內聯請求而把它作為真正的函數去處理。
4.不同的編譯器對內聯的態度有所不同。例如,有的編譯器不允許內聯函數中包含有循環語句,還有的編譯器限定了內聯函數的大小。
5.最好在對內聯函數的所有調用之前定義該函數,即內聯函數的定義必須出現在它被第一次調用之前。如果有幾個源文件中的代碼都要調用某個內聯函可將這個內聯函數的定義放在一個頭文件中。這樣才能確保編譯器找到內聯擴展所需要的代碼。例如,下麵的內聯請求可能是無效的。
所以,對於上麵的例子,最好在main()函數之前定義add()函數。
和宏定義相比,內聯函數的形式更像普通的函數,可讀性增強,因此,建議在Visual C++中使用內聯函數替代宏定義。
4.6函數原型、
我們可以在定義一個函數之前先對它進行說明,即給出它的函數名和函數的返回值以及它的參數數目和類型,這種對函數的說明方式稱為函數的原型定義。函數原型使編譯器可以將函數調角與函數原型作比較,並強製做類型檢查。在c語言中,並不要求每個函數都要給出它的原型定義,但是,C++對函數原型的要求是必須的。請看下麵例子:
例4.8下麵的程序為打印字符串“Hello VC”時的一個正常例子。
當我們把這段程序在C語言的編譯器中進行編譯時,並不會產生語法錯誤,最多編譯器會給出一條警告信息。但是,如果我們把它放在Visual C++編譯器下進行編譯時,卻不能通過,是什麼原因呢?這是因為缺少了一個函數的原型定義。如果我們給上例的程序加上一個函數原型定義,則能在Visual C++編譯器上通過。