內聯函式是c++為提高程式執行速度所做的一項改進。
編譯過程的最終產品是可執行程式(由一組機器語言指令組成)。程式執行時,作業系統將這些指令載入到計算機記憶體中,因此每條指令都有特定的記憶體位址。
常規函式呼叫過程---程式跳到函式的位址,並在函式結束時返回。即,程式執行到函式呼叫指令時,將在函式呼叫後立即儲存該指令的記憶體位址,並將函式引數複製到堆疊,跳到標記函式起點的記憶體單元,執行函式**,返回值放入暫存器中,然後跳回到位址被儲存的指令處(這與閱讀文章時停下來看標註,並在閱讀完標註後返回到之前閱讀的地方類似)
內聯函式是將相應的**替換函式呼叫。優點是內聯函式執行速度比常規函式稍快,缺點是占用更多記憶體。
要使用內聯函式,需要:
(1)在函式宣告前加上關鍵字inline
(2)在函式定義前加上關鍵字inline
注:內聯函式不能遞迴
另:內聯函式與巨集的區別
內聯函式引數傳遞方式與常規函式一樣,巨集是簡單的文字替換來完成
例如:inline double square(double x)
#define square(x) x*x
square(0.5) //->0.5*0.5
square(4.5+7.5)
square(c++) //c++*c++
引用時已定義的變數的別名(如土豆,又叫馬鈴薯)。引用的主要用途是用作函式的形參。通過引用傳遞引數,函式會訪問使用原始資料,而不是像按值傳遞一樣使用副本。
intrats;
int & rodents = rats;//rodents為rats的引用,即別名 這兩個值表明的是同乙個事物,同一塊記憶體同乙個位址同乙個值
特點:與const指標比較接近,必須在宣告引用變數時進行初始化。一旦與某個變數關聯,就將一直效忠與它。
引用與變數一體,共用同一塊記憶體,看好引用的記憶體和值即可。陣列不能宣告引用
引用作為函式引數,原理是將函式中變數名成為呼叫程式中的變數的別名。
按值傳遞void sneezy(int
x);int
main()
void sneezy(int x)//建立x變數,將傳遞來的值賦值給x
2個變數,兩個名字,x和times除了值相同,完全兩個變數,沒有任何聯絡
按引用傳遞void grumpy(int
&x);
intmain()
void grumpy(int &x)//x為times的別名
times和x是同乙個變數,只不過有兩個名稱
函式呼叫使用實參初始化形參,因此函式的引用引數被初始化為函式呼叫傳遞的實參。
如果實參和引用引數型別不匹配,c++將生成臨時變數。僅當引數為const引用時,c++才允許這樣使用不會報錯。
關於臨時變數,如果引用引數時const,則下面兩種情況下生成臨時變數(匿名變數)
實參的型別正確,但不是左值。
實參的型別不正確,但可以轉換為正確的型別
double refcube(constdouble &ra)//僅當為常量引用,可以允許下面的情況,因為不修改ra的值,所以是不是臨時變數無所謂
intmain()
; refcube(side);
refcube(lens[
2]);
refcube(*pd);
refcube(edge);//生產臨時變數
refcube(
7.0);//生產臨時變數
refcube(side+7.0
);//生產臨時變數
const
double & p12 = 0.1+0.2
; system(
"pause");
return0;
}
為什麼非const引用不可以這樣操作?
理解如下:
void swapr(int &a, int &b)long a = 3, b = 5;
swapr(a,b);
上述實參型別和形參的引用型別不匹配,編譯器會建立兩個臨時int變數,將其初始化為3和5,然後交換臨時變數的值,實參的值不變
乙個接受引用引數的函式的目的就是修改實參的值,如果建立臨時變數,就阻止了函式的這一作用。
實際上,對於形參為const引用的c++函式,如果實參不匹配,則其行為類似於按值傳遞,為確保原始資料不被修改,將使用臨時變數來儲存值。
將引用引數宣告為常量資料的引用的理由:
1)使用const可以避免無意中修改資料的程式設計錯誤
2)使用const使函式能夠處理const和非const實參,否則將只能接受非const資料
3)使用const引用能使函式能夠正確生成並使用臨時變數
引用非常適合用於結構和類,引用主要是為了用於這些型別,而不是基本的內建型別
struct free_throwsfree_throws dup;
free_throws four = ;
free_throws five = ;
free_throws & accumulate(free_throws & target, const free_throws & source);
accumulate(dup, five) = four;//不常用,作為乙個例子解釋下面問題
1.函式形參為引用:與按值傳遞相比,引用傳遞少了複製拷貝原始結構這一步,可以節省時間和記憶體。
2.函式返回值為引用:傳統返回機制會計算return後變數(這個值被複製到乙個臨時位置),並將結果返回給呼叫函式,
例:dup = accumulate(four, five);
如果accumulate返回乙個結構,不是引用,會將整個結構複製到乙個臨時位置,再將這個拷貝複製給dup
現在是引用,會直接把函式中return的值複製給dup,效率更高
4.返回引用時應注意:避免返回函式終止時不再存在的記憶體單元引用。1)返回乙個作為引數傳遞給函式的引用 2)用new來分配新的儲存空間,返回指向該空間的指標
5.可以將const用於引用返回型別,避免返回值被改變
accumulate(dup, five) = four;可以通過編譯,但是若此函式返回值為結構體,則不能通過編譯類中有乙個特徵,基類引用可以指向派生類物件,無需進行強制型別轉換。原因:在賦值語句中,左邊必須是可以修改的左值,即左邊的子表示式必須標識乙個可修改的記憶體塊,此函式返回值為結構體引用時,函式返回dup的引用,它確實標識的時乙個這樣的記憶體塊,所以
可以編譯通過
常規(非引用)返回型別是右值---不能通過位址訪問的值,這種表示式可以出現在賦值語句的右邊,但是不能出現在左邊。其他右值包括字面值如10.0和表示式如x+y。獲取字面值的位址
沒有意義,但是為何常規函式返回值是右值呢,因為這種返回值位於臨時記憶體單元中,執行到下一條語句時,它們可能就不在存在了。
可以定義乙個接受基類引用作為引數的函式,呼叫該函式時,可以將基類物件作用引數,也可以將派生類物件作為引數。
內聯inline函式和引用
inline函式 函式呼叫點 直接展開 文字替換 沒了開棧和清棧的開銷,效率高 inline int sum int a,int b return a b 1.inline 函式和普通函式的區別 inline函式只能在本檔案可見 2.inline函式和static修飾的函式的區別 有呼叫函式的開銷 ...
C 內聯函式和引用變數
內聯函式和普通函式的使用方法沒有本質區別,我們來看乙個例子,下面展示了內聯函式的使用方法 include using namespace std 下面展示內聯函式的使用 inline double square doublex intmain 從上面我們可以看到我們定義乙個內聯函式只需要在普通函式的...
函式過載 引用 內聯函式
預設引數 在定義或者宣告乙個函式的時候,給它的形參賦上乙個預設值,呼叫這個函式的時候,如果沒有把實參傳入,函式就會使用我們指定的預設引數,如果傳入實參,就會使用傳入的引數。預設引數可分為 全預設引數 在這個函式中,給所有的形參都指定了預設值。半預設引數 在這個函式中,只給一部分的形參指定了預設值。注...