1. 程式人生 > >C++複習(C和C++的區別1)

C++複習(C和C++的區別1)

函式的預設值引數

C語言中沒有帶預設值的函式,C++支援帶預設值的函式

1.預設值的傳入過程

  在函式呼叫點,如果沒有傳遞全部的實參,則會預設傳遞預設值作為實參。

2.預設值的賦值

  必須從右向左,依次賦值。

  預設值只在本檔案有效。

  引數預設值在同一作用域下只允許賦值一次,給多次相同的預設值也不可以

#include<iostream>
using namespace std;

int sum(int a = 10, int b = 20, int c = 30)
{
	return a + b + c;
}

int main()
{
	int a = 1, b = 2, c = 3;
	cout << sum(a,b,c) << endl;
	cout << sum(c) << endl;
	return 0;
}

由該程式可以看出,如果變數被賦初值,那麼預設值就將不會再被賦給變數,並且賦初值是按照從右向左的順序賦給變數的。

行內函數(inline)

1.行內函數的定義

  在函式定義處加上inline關鍵字

2.行內函數在函式呼叫點展開(編譯過程)

3.行內函數不生成符號,僅可以在本檔案可見

4.如果想在其他檔案使用該行內函數,可以在函式定義處加上extern關鍵字(不推薦)。最好將行內函數寫在.h中

5.inline函式只在release版本中起作用。在debug版本中,inline函式的呼叫也是需要棧幀的開闢和回退(主要是為了方便除錯)。而且inline只是對編譯器的一個建議,最終是由編譯器來決定是否處理成內聯。遞迴的函式不能處理成內聯。

               

我們在main.cpp中寫了一個函式sum,在main1.cpp中用了這個函式,可以看出編譯連線過程沒問題,答案也沒問題。

但如果在sum函式定義處加上inline關鍵字,你就會發現系統報了一個“無法解析外部符號”的錯誤。

這是因為行內函數在呼叫點展開,不產生外部符號,只在本檔案可見,在另一個檔案不能通過在連結階段宣告定位到另一個檔案中的行內函數,所以行內函數一般可以寫在標頭檔案中。

1.行內函數和普通函式的區別?

   1.行內函數沒有標準的函式棧幀的開闢和回退,而普通函式有。

   所以函式過於短時,一般處理成行內函數,當呼叫函式的開銷(棧幀的開闢和回退)大於函式執行的開銷時,用行內函數可以省去呼叫函式的開銷。

   2.行內函數不產生符號。

2.行內函數和static函式的區別?

   1.都是檔案可見(作用域)

   2.棧幀的開闢和回退不一樣。呼叫static函式時有正常的棧幀開闢和回退,和普通函式一樣。

   3.static函式產生符號local。

3.static函式和普通函式的區別?

   1.static函式產生的符號是local的,連結器不處理

   2.普通函式產生global符號

4.inline函式和巨集的區別?

   1.都是本檔案可見

   2.都不產生符號

   3.在函式呼叫點展開(預編譯期)

   4.巨集函式沒有型別檢查,無法除錯

因此,行內函數相當於一種更安全的巨集,因為在預處理階段不進行檢查,只是進行替換,而編譯階段會進行型別檢查,所以更安全。有行內函數後,儘量不使用巨集,因為用巨集寫的程式碼無法除錯,也沒有型別檢查。

函式的過載

在C語言中,函式產生符號是由函式名來決定的;

在C++中,函式產生符號,是由函式名稱+函式的引數列表(型別和個數函式)來決定的。

(1)函式名相同,引數列表不同的一組函式稱作一組過載的函式。

(不能僅通過返回值的不同來進行過載,因為函式符號的產生和返回值沒關係)

(2)過載必須處於同一個作用域之內

   在C和C++中,全域性和區域性作用域可以定義同名的函式,在區域性使用時,優先使用區域性的。

   C和C++允許不同的作用域產生相同名的符號

(3)對實參的值是否有影響

  const/volatile 所修飾的指標或者引用可以作為函式過載的前提條件。