2011-10-10(adventures in functions i)
1、內聯函式(inline function)。
序執行到要呼叫程式的指令是,系統會將這條指令位址儲存,而後跳到要呼叫函式**記憶體單元,執行完後再跳回,每次遇到函式呼叫均如此。如此跳來跳去是
要時間的。所以內聯函式的方法時將函式**直接鑲嵌到主函式中,當然,如果是遞迴函式是不能鑲嵌的。這樣做的結果是占用更大的記憶體。
可以想象,當乙個函式執行的時間遠遠大於呼叫的時間時是不適合使用內聯函式的;當乙個函式短而經常使用則非常適合。宣告乙個函式是內聯函式,使用關鍵
字inline
,一般的做法是將內聯函式的宣告和定義放在與本放函式原型的地方:
#include inline int add(int a, int b)
int main()
內聯函式的用法和巨集很像,不過內聯函式更為方便。
2、引用變數(reference variable)。c++中用符號
&來宣告乙個引用變數,主要用於在變數為函式的引數是,傳遞的是原始資料而不是其拷貝,這樣就可以改變變數
的值。i、基本語法。通過一程式說明:
#include int main()
輸出:
a = 5; ar = 5
after incrementing, a = 6; ar = 6
a adress = 0012ff60; ar adress = 0012ff60
after assigning, a = 10; ar = 10; b = 10
a adress = 0012ff60; ar adress = 0012ff60; b adress = 0012ff54
①6、7行,引用必須在器宣告時初始化,即不能使用下面語句:
int a = 5;
int& b;
b = a;
②對應於的操作即對其變數本身;
③引用不能重新改變其「指向」。第13行,ar = b等價於a = b;
ii、引用作為函式引數。
如前述,引用是直接使用原始資料而非拷貝,這種傳遞方式稱為按引用傳遞。舉例:
#include void swap(int&, int&);
int main()
void swap(int& a, int& b)
輸出:
a = 5; b = 10
不同之處在於多了乙個符號
&,其他操作不變。對函式引數的操作,即是對資料本體的操作,因為引數就是資料的引用。
按引用傳遞也有尷尬之時:
#include int doublevalue(int&);
int main()
int doublevalue(int& a)
輸出:
a = 5
2 * 10= 10
即經過函式呼叫後,a的值亦隨之而變。如此相當於將函式的**直接寫在主函式中,無區域性變數之說。到目前為止,所接觸到的按引用傳遞函式的引數都是「確
定」是引用型別。即不會像下面的情況(以上面的doublevalue為例):
doublevalue(a + 5);
long c = 6;
doublevalue(c); //type mismatching
編譯會對此上報錯誤,除非是將形參定義為
const
,即:doublevalue(const int& a);
當然,定義為
const
後,函式就不能改變形參的值了。其工作原理是這樣的,編譯將生成乙個匿名變數用於儲存「非法」值,並是a成為這個匿名變數的引用,而再繼
續操作。在說明為什麼必須要定義為
const
前,先說明怎麼樣的值傳遞到函式時要建立乙個匿名變數:
①實參型別正確,但不是可以被引用的物件(如上面的a + 5);
②實參型別不正確,但可轉換為正確型別(如上面的6l);
下面在說形參為何必須為
const
。首先假設不為const時發生的情況:上面的
swap(int&, int&)
,加入傳了兩個
long
型值,執行這函式時要建立兩個匿名變數,那麼交
換的不是a、b本體而是這兩個匿名變數,整個函式將無意義。所以設定為
const
後,引數將不能改變,匿名變數也不能改變,避免了這種無意義的事情發生。
但如此設定為
const
後,將極大的限制了函式的功能,與一般函式無異。
3、返回結構體引用。
#include using namespace std;
struct scii
;const scii& rankup(scii&);
int main()
; scii mvp2 = rankup(mvp1);
cout << "mvp1.rank = " << mvp1.rank << endl;
cout << "mvp2.rank = " << mvp2.rank << endl;
cout << "rankup(mvp1).rank = " << rankup(mvp1).rank << endl;
return 0;
}const scii& rankup(scii& player)
race: terran
mvp1.rank = 2
mvp2.rank = 2
race: terran
rankup(mvp1).rank = 1
①這裡要注意的是按引用傳遞的性質:對引數的操作即對資料本體的操作;
②雖名為「返回結構體引用」,但返回的還是它的真身,因為引用只是乙個資料的第二個名字。所以函式返回的是乙個真真實實的mvp1被修改以後的結構體。
③因為返回的是被修改後的mvp1,而且函式本身也要求返回這樣型別,所以一下語句:
const scii& rankup(scii& player)
編譯器將發出警告:warning: 返回區域性變數或臨時變數的位址。應避免返回臨時變數。當然可以這樣解決:
const scii& rankup(scii& player)
不過這麼搞很容忘記使用
delete()
來釋放記憶體。
④使用
const
的原因
:不能對返回值進行直接操作:
rankup(mvp1).rank = 10; //invalid
這個等效於:
rankup(mvp1);
mvp1.rank = 10;
如此看來邏輯比較清楚,不容易犯錯。
4、乙個返回區域性變數的例子。
#include #include using namespace std;
string& crash(string&);
int main()
string& crash(string& str)
如3③,將發出不能返回臨時變數的警告。執行,程式直接崩潰。因為返回的是乙個引用,而程式呼叫crash()
後,臨時變數temp將不復存在,所以程式要做的是
,引用乙個已經釋放的記憶體,導致崩潰。
C 高階程式設計第八天 Main 函式
main 方法.c 程式是以 main 開始執行的 這個方法必須是類或結構的靜態方法 並且其返回型別必須是 int或者 void.雖然顯示指定public 修飾符很常見 但是我們也可以把該方法標記為 private,也可以執行.main 方法只能有乙個 如果有多個就會出現錯誤.如果非得寫兩個main...
開課第八天
開課第八天,今天因為遲到問題被老師訓了,呵呵,說實話是真的感覺前一周有點懶散鬆懈,今天被訓之後又感覺到了緊迫感,嗯,堅持就是勝利,加油。上午講題,下午講新知識,以下就是本寶寶吸收的新養料 方法 可以被稱作函式,也可以被稱作功能。1 main 是我們學習的第乙個簡單的方法,public static ...
彙編第八天
彙編形式目標 main proc push ebp mov ebp,esp 建立堆疊框架 push offset msg 匯入引數位址 call printf 呼叫函式 xor eax,eax 返回0 pop epb 扯掉框架 ret 0 返回主程式 main endp 結束 1.條件語句 cmp ...