国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++中函數使用的基本知識學習教程

2020-05-23 14:10:01
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++中函數使用的基本知識學習教程,涵蓋了函數的聲明和參數以及指針等各個方面的知識,非常全面,需要的朋友可以參考下
 

函數是執行某種操作的代碼塊。函數可以選擇性地定義使調用方可以將實參傳遞到函數中的輸入形參。函數可以選擇性地返回值作為輸出。函數可用于在單個可重用塊中封裝常用操作(理想情況是使用可清晰地描述函數行為的名稱)。以下函數從調用方接受兩個整數并返回其總和;a 和 b 是 int 類型的參數。

int sum(int a, int b){  return a + b;}

可以從程序中任意數量的位置調用函數。傳遞給函數的值是實參,其類型必須與函數定義中的形參類型兼容。

int main(){  int i = sum(10, 32);  int j = sum(i, 66);  cout << "The value of j is" << j << endl; // 108}

對于函數長度沒有實際限制,不過良好的設計應以執行單個明確定義的任務的函數為目標。復雜算法應盡可能分解成易于理解的更簡單函數。
在類范圍中定義的函數稱為成員函數。在 C++ 中(與其他語言不同),函數還可以在命名空間范圍中定義(包括隱式全局命名空間)。這類函數稱為 free 函數或非成員函數;它們在標準庫中廣泛使用。
函數聲明的各個部分
最小函數聲明包含返回類型、函數名和參數列表(可能為空),以及向編譯器提供附加說明的可選關鍵字。函數定義包含聲明以及函數體(這是大括號之間的所有代碼)。后接分號的函數聲明可以出現在程序中的多個位置處。它必須在每個翻譯單元中對該函數的任何調用之前出現。根據單個定義規則 (ODR),函數定義必須僅在程序中出現一次。
函數聲明的必需部分有:
返回類型,指定函數將返回的值的類型,如果不返回任何值,則為 void。在 C++11 中,auto 是有效返回類型,可指示編譯器從返回語句推斷類型。在 C++14 中,還允許使用 decltype(auto)。有關詳細信息,請參閱下面的“返回類型中的類型推導”。
函數名,必須以字母或下劃線開頭,不能包含空格。一般而言,標準庫函數名中的前導下劃線指示私有成員函數,或不是供你的代碼使用的非成員函數。
參數列表(一組用大括號限定、逗號分隔的零個或多個參數),指定類型以及可以用于在函數體內訪問值的可選局部變量名。
函數聲明的可選部分有:
constexpr,指示函數的返回值是常量值,可以在編譯時進行計算。

       constexpr float exp(float x, int n){  return n == 0 ? 1 :    n % 2 == 0 ? exp(x * x, n / 2) :    exp(x * x, (n - 1) / 2) * x;};

其 linkage 規范(extern 或 static)。

Declare printf with C linkage.extern "C" int printf( const char *fmt, ... );

inline,指示編譯器將對函數的每個調用替換為函數代碼本身。在某個函數快速執行并且在性能關鍵代碼段中重復調用的情況下,內聯可以幫助提高性能。

inline double Account::GetBalance(){  return balance;}

noexcept,指定函數是否可以引發異常。在下面的示例中,函數在 is_pod 表達式計算結果為 true 時不引發異常。

#include <type_traits>template <typename T>T copy_object(T& obj) noexcept(std::is_pod<T>) {...}

僅限成員函數)cv 限定符,指定函數是 const 還是 volatile。
(僅限成員函數)virtual、override 或 final。 virtual 指定可以在派生類中重寫函數。 override 表示派生類中的函數在重寫虛函數。 final 表示函數不能在任何進一步的派生類中進行重寫。

(僅限成員函數僅)應用于成員函數的 static 表示函數不與類的任何對象實例關聯。
(僅限非靜態成員函數)ref 限定符,向編譯器指定隱式對象參數 (*this) 是右值引用與左值引用時要選擇的函數重載。
下圖顯示了函數定義的各個部分?;疑珔^域是函數體。

C++中函數使用的基本知識學習教程

 

函數定義部分
函數定義

函數體內聲明的變量稱為局部變量。它們會在函數退出時超出范圍;因此,函數應永遠不返回對局部變量的引用!
函數模板
函數模板類似于類模板;它基于模板參數生成具體功能。在許多情況下,模板能夠推斷類型參數,因此無需顯式指定它們。

template<typename Lhs, typename Rhs>auto Add2(const Lhs& lhs, const Rhs& rhs){  return lhs + rhs;}auto a = Add2(3.13, 2.895); // a is a doubleauto b = Add2(string{ "Hello" }, string{ " World" }); // b is a std::string有關詳細信息,請參閱函數模板

函數形參和實參
函數具有零種或多種類型的逗號分隔參數列表,其中每個參數都具有可以用于在函數體內訪問它的名稱。函數模板可以指定其他類型或值參數。調用方傳遞實參(其類型與形參列表兼容的具體值)。
默認情況下,參數通過值傳遞給函數,這意味著函數會收到所傳遞的對象的副本。對于大型對象,創建副本可能成本高昂,并非始終必要。若要使實參通過引用(特別是左值引用)進行傳遞,請向形參添加引用限定符:

void DoSomething(std::string& input){...}

當函數修改通過引用傳遞的參數時,它會修改原始對象,而不是本地副本。若要防止函數修改這類實參,請將形參限定為

const&:void DoSomething(const std::string& input){...}

C++ 11:若要顯式處理通過右值引用或通過左值引用傳遞的實參,請對形參使用雙與號以指示通用引用:

void DoSomething(const std::string&& input){...}

只要關鍵字 void 是實參聲明列表中的第一個也是唯一一個成員,那么在形參聲明列表中使用單個關鍵字 void 聲明的函數就沒有實參。列表中的其他地方的 void 類型的參數產生錯誤。例如:

// OK same as GetTickCount()long GetTickCount( void ); 

請注意,盡管指定 void 參數是非法(此處所述的除外),但派生自類型 void 的類型(如指向 void 的指針和 void 的數組)可以出現在參數聲明列表中的任何位置。
默認參數
函數簽名中的最后一個或幾個形參可能會分配有默認實參,這意味著調用方可能會在調用函數時省略實參(除非要指定某個其他值)。

int DoSomething(int num,   string str,   Allocator& alloc = defaultAllocator){ ... }// OK both parameters are at endint DoSomethingElse(int num,   string str = string{ "Working" },   Allocator& alloc = defaultAllocator){ ... }// C2548: 'DoMore': missing default parameter for parameter 2int DoMore(int num = 5, // Not a trailing parameter!  string str,  Allocator& = defaultAllocator){...}

函數返回類型
函數可能不會返回另一個函數或內置數組;但是,它可以返回指向這些類型的指針,或生成函數對象的 lambda。除了這些情況,函數可以返回處于范圍內的任何類型的值,或者它可以返回任何值(在這種情況下返回類型是 void)。
結尾返回類型
“普通”返回類型位于函數簽名左側。結尾返回類型位于簽名的最右側,前面帶有 -> 運算符。當返回值的類型取決于模板參數時,結尾返回類型在函數模板中尤其有用。

template<typename Lhs, typename Rhs>auto Add(const Lhs& lhs, const Rhs& rhs) -> decltype(lhs + rhs){  return lhs + rhs; }

當 auto 與結尾返回類型結合使用時,它對于 decltype 表達式生成的任何內容都只用作占位符,本身不執行類型推導。
返回類型中的類型推導 (C++14)
在 C++14 中,可以使用 auto 指示編譯器從函數體推斷返回類型,而不必提供結尾返回類型。請注意,auto 始終推導為按值返回。使用 auto&& 可指示編譯器推導引用。
在此示例中,auto 會推導為 lhs 和 rhs 之和的非常量值副本。

template<typename Lhs, typename Rhs>auto Add2(const Lhs& lhs, const Rhs& rhs){  return lhs + rhs; //returns a non-const object by value}

請注意,auto 不會保留它推導的類型的常量性。對于返回值需要保留其參數的常量性或引用性的轉發函數,可以使用 decltype(auto) 關鍵字,該關鍵字使用 decltype 類型推斷規則并保留所有類型信息。 decltype(auto) 可以用作左側的普通返回值,或結尾返回值。
下面的示例(基于來自 N3493 的代碼)演示的 decltype(auto) 用于采用在模板實例化之前未知的返回類型實現函數參數的完美轉發。

template<typename F, typename Tuple = tuple<T...>, int... I>decltype(auto) apply_(F&& f, Tuple&& args, index_sequence<I...>) {  return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);}template<typename F, typename Tuple = tuple<T...>,  typename Indices = make_index_sequence<tuple_size<Tuple>::value >>  decltype( auto)  apply(F&& f, Tuple&& args)  {  return apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices());}}

函數局部變量
在函數主體內聲明的變量稱為局部變量。非靜態局部變量僅在函數體中可見,如果它們在堆棧上聲明,則會在函數退出時超出范圍。構造局部變量并通過值返回它時,編譯器通常可以執行返回值優化以避免不必要的復制操作。如果通過引用返回局部變量,則編譯器會發出警告,因為調用方為使用該引用而進行的任何嘗試會在局部變量已銷毀之后進行。
局部靜態對象將在 atexit 指定的終止期間銷毀。如果某個靜態對象由于程序的控制流跳過了其聲明而未構造,則不會嘗試銷毀該對象。
靜態局部變量
在 C++ 中,局部變量可以聲明為靜態。變量僅在函數體中可見,但是對于函數的所有實例,存在變量的單個副本。
函數指針
C++ 通過與 C 語言相同的方式支持函數指針。但是更加類型安全的替代方法通常是使用函數對象。
建議使用 typedef 聲明函數指針類型的別名(如果聲明返回函數指針類型的函數)。例如

typedef int (*fp)(int);fp myFunction(char* s); // function returning function pointer

如果不執行此操作,則函數聲明的正確語法可以通過用函數名稱和參數列表替換標識符(上例中為 fp)來從函數指針的聲明符語法推導出,如下所示:

int (*myFunction(char* s))(int);

前面的聲明與使用上面的 typedef 的聲明等效。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤峰县| 乌拉特后旗| 资源县| 通州市| 运城市| 平原县| 安乡县| 临夏市| 泽州县| 平乐县| 富川| 双牌县| 乡宁县| 天镇县| 汉川市| 神木县| 买车| 鸡西市| 滕州市| 昌乐县| 辽源市| 常山县| 铜陵市| 新昌县| 拜泉县| 乌审旗| 桓仁| 河南省| 达孜县| 若尔盖县| 云南省| 吉林市| 炎陵县| 三明市| 崇义县| 广南县| 黎川县| 鲜城| 桂阳县| 玉环县| 蒲江县|