1.函式的呼叫完成兩項工作:一是用實參初始化函式對應的形參,二是將控制權轉移給被呼叫的函式。此時,主調函式的執行被暫時中斷,被調函式開始執行。
2.函式定義規定了實參與形參存在的對應關係,但是並沒有規定實參的求值順序。編譯器能以任意可行的順序對形參進行求值。
3.函式的返回值不能是陣列型別或函式型別,但可以是指向陣列或函式的指標。
4.區域性靜態物件在程式執行路徑第一次經過物件定義語句時初始化,並且直到程式終止才被銷毀,在此期間即使物件所在的函式結束執行也不會對它有影響。
#include using namespace std;
size_t count_calls()
int main()
9.const形參和實參:(頂層const作用於物件本身)和其他初始化過程一樣,當用實參初始化形參時會忽略掉頂層const。換句話說,形參的頂層const被忽略掉了。當形參有頂層const時,傳給它常量或非常量都是可以的:
void fcn(const int i) //fcn能夠讀取i,但不能向i寫值
void fcn(int i) //錯誤,重複定義了fcn
另一方面,如果形參是某種型別的指標或者引用,則通過區分其指向的是常量物件還是非常量物件可以實現函式過載,此時的const的底層的:
void loopup(account&); //函式作用於account的引用
void loopup(const account&); //新函式,函式作用於常量引用
10.我們可以使用非常量初始化乙個底層const,但是反過來不行;同時乙個普通的引用必須用同型別的物件初始化。
#include using namespace std;
void reset(int *ip)
void reset(int &i)
int main()
要想呼叫引用版本的reset,只能用int型別的物件,而不能使用字面值、求值結果為int的表示式、需要轉換的物件或者const int的物件。類似的,想要呼叫指標版本的reset只能用int*。
11.陣列的引用:(注意引用運算子的優先順序低於下標運算子)
#include using namespace std;
//void exa(int &a[5]) //將a宣告成了引用的陣列:編譯錯誤
void exa(int (&a)[5]) //對具有5個整數的整型陣列的引用
int main()
; exa(a);
for(int i=0;i<5;i++)
cout<
12.
int main(int argc,char *argv) //........(1)
int main(int argc,char **argv) //........(2)
式(1)中第二個形參argv是乙個陣列,它的元素是指向c風格字串的指標;第乙個引數argv表示陣列中字串的數量。由於第二個形參是陣列,所以main函式也可以定義
成式(2)這樣。
當實參傳遞給main函式之後,argv的第乙個元素指向程式的名字或者乙個空字串,接下來的元素以此傳遞給命令列提供的實參,最後乙個指標的元素保證為0(即空字串)。
13.return語句終止當前正在執行的函式並將控制權返回到呼叫該函式的地方。返回乙個值的方式和初始化變數或形參的方式完全一樣:返回的值用於初始化呼叫點的乙個臨時量,該臨時量就是函式呼叫的結果。函式返回的結果(即函式的返回值)將被拷貝到呼叫點。如果函式返回引用,則該引用僅是它所引物件的乙個別名:
const string& shorter_string(const string &s1,const string &s2)
其中形參和返回型別都是const string的引用,不管是呼叫函式還是返回結果都不會真正拷貝string物件。
14.函式完成後,它所佔的儲存空間也隨之被釋放掉,因此,函式終止意味著區域性變數的引用將指向不再有效區的記憶體區域。
15.函式的返回型別決定函式呼叫是否為左值。呼叫乙個返回引用的函式得到左值,其他返回型別得到右值。
16.c++11新標準規定,函式可以返回花括號包圍的值的列表:
vectorprocess()
; //返回乙個空vector物件
else if(expected==actual)
return ; //返回列表初始化的vector物件
else return ;
}
17.因為陣列不能被拷貝,所以函式不能返回陣列。不過,函式可以返回陣列的指標或引用:
typedef int arr[10]; //arr是乙個型別別名,表示的型別是含有10個整數的陣列
using arr=int[10]; //arr的等價宣告
arr* func(int i); //func返回乙個指向含有10個整數的陣列的指標
//如果不用型別別名,我們必須牢記被定義的名字後面陣列的維度
int arr[10]; //arr是乙個含有10個整數的陣列
int *p1[10]; //p1是乙個含有10個指標的陣列
int (*p2)[10]=&arr; //p2是乙個指標,指向含有10個整數的陣列
和這些宣告一樣,如果我們定義乙個返回陣列指標的函式,則陣列的維度必須跟在函式名字之後:
int (*func(int i))[10]; //如果沒有最外面的括號,函式的返回型別將是指標的陣列
18.c++中,名字查詢發生在型別檢查之前:
string read();
void print(const string&);
void print(double); //過載print函式
void example(int ival)
當我們呼叫print函式時,編譯器首先尋找對函式的宣告,一旦在當前作用域找到了所需的名字,編譯器就會忽略掉外層作用域的名字,剩下的工作就是檢查函式呼叫是否有效了。
19.呼叫含有預設實參的函式:
string func(int a=24,int b=45,char bk=' ');
string tmp;
tmp=func(); //等價於func(24,45,' ')
tmp=func(66); //等價於func(66,45,' ')
用作預設實參的名字在函式宣告所在的作用域內解析,而這些名字的求值過程發生在函式呼叫時。
20.函式指標指向的函式而非物件。和其他指標一樣,函式指標指向某種型別,其型別由它的返回型別和形參型別共同決定。
//比較兩個string物件的長度
bool length_compare(const string&,const string&);
該函式的型別是bool(const string&,const string&),想要宣告乙個可以指向該函式的指標,只需用指標替換函式名即可:
//pf指向乙個函式,該函式的引數是兩個const string的引用,返回值是bool型別
bool (*pf)(const string&,const string&);
21.使用函式指標:
當我們把函式名作為乙個值使用時,該函式自動地轉換成指標:
pf=length_compare; //pf指向名為length_compare的函式
pf=&length_compare; //等價的賦值語句:取位址符是可選的
此外,我們還能直接使用指向函式的指標呼叫該函式,無須提前解引用指標:
bool p1=pf("hello","goodbye"); //呼叫length_compare函式
bool p2=(*pf)("hello","goodbye"); //乙個等價的呼叫
bool p3=length_compare("hello","goodbye"); //另乙個等價呼叫
c primer, 5e 函式指標
簡單的示例 include using namespace std int sum int x,int y int main 遇到過載的情況,編譯器通過指標型別精確匹配函式。include using namespace std int sum int x,int y int sum int x,d...
c primer, 5e 函式匹配
練習 6.49 候選函式 與所呼叫的函式的名字相同的函式的集合。可行函式 給候選函式加上引數數量 引數型別的約束所得到的函式的集合。6.50 a 3 4可行,二義匹配 b 2 4可行,2是最佳匹配 c 3 4可行,3是最佳匹配 d 3 4可行,4是最佳匹配 6.51 測試 include using...
C Primer(5e)第13章習題
如果乙個建構函式的第乙個引數是自身類型別的引用,且任何額外引數都有預設值,則此建構函式是拷貝建構函式。使用時候 1.用 定義變數 2.將要給物件作為實參傳遞給乙個非引用型別的實參 3.從乙個返回型別為非引用型別的函式返回乙個物件 4.用花括號列表初始化乙個陣列中的元素或乙個聚合類中的成員 因為如果拷...