欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2016年01月18日 16:10:54   投稿:goldensun  
這篇文章主要介紹了C++中函數使用的基本知識學習教程,涵蓋了函數的聲明和參數以及指針等各個方面的知識,非常全面,需要的朋友可以參考下

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

對于函數長度沒有實際限制,不過良好的設計應以執(zhí)行單個明確定義的任務的函數為目標。復雜算法應盡可能分解成易于理解的更簡單函數。
在類范圍中定義的函數稱為成員函數。在 C++ 中(與其他語言不同),函數還可以在命名空間范圍中定義(包括隱式全局命名空間)。這類函數稱為 free 函數或非成員函數;它們在標準庫中廣泛使用。
函數聲明的各個部分
最小函數聲明包含返回類型、函數名和參數列表(可能為空),以及向編譯器提供附加說明的可選關鍵字。函數定義包含聲明以及函數體(這是大括號之間的所有代碼)。后接分號的函數聲明可以出現在程序中的多個位置處。它必須在每個翻譯單元中對該函數的任何調用之前出現。根據單個定義規(guī)則 (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 規(guī)范(extern 或 static)。

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

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

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

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

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

2016118160651476.jpeg (420×117)

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

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 double
auto b = Add2(string{ "Hello" }, string{ " World" }); // b is a std::string
有關詳細信息,請參閱函數模板

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

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 end
int DoSomethingElse(int num, 
  string str = string{ "Working" }, 
  Allocator& alloc = defaultAllocator)
{ ... }

// C2548: 'DoMore': missing default parameter for parameter 2
int 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 表達式生成的任何內容都只用作占位符,本身不執(zhí)行類型推導。
返回類型中的類型推導 (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 不會保留它推導的類型的常量性。對于返回值需要保留其參數的常量性或引用性的轉發(fā)函數,可以使用 decltype(auto) 關鍵字,該關鍵字使用 decltype 類型推斷規(guī)則并保留所有類型信息。 decltype(auto) 可以用作左側的普通返回值,或結尾返回值。
下面的示例(基于來自 N3493 的代碼)演示的 decltype(auto) 用于采用在模板實例化之前未知的返回類型實現函數參數的完美轉發(fā)。

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());
}
}

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

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

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

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

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

相關文章

  • C++中如何使用引用避免內存復制

    C++中如何使用引用避免內存復制

    C++引用是一種強大的工具,可以避免在函數調用過程中發(fā)生的常見內存復制問題,本文主要介紹了C++中如何使用引用避免內存復制,感興趣的可以了解一下
    2023-10-10
  • 詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧
    2018-10-10
  • C語言?超詳細講解算法的時間復雜度和空間復雜度

    C語言?超詳細講解算法的時間復雜度和空間復雜度

    算法復雜度分為時間復雜度和空間復雜度。其作用:?時間復雜度是度量算法執(zhí)行的時間長短;而空間復雜度是度量算法所需存儲空間的大小
    2022-03-03
  • C語言實現單鏈表的基本功能詳解

    C語言實現單鏈表的基本功能詳解

    鏈表是一個結構體實現的一種線性表,它只能從前往后,不可以從后往前,在實現單鏈表的操作時,需要用指針來操作。本文主要介紹了實現單鏈表的基本功能的代碼示例,具有一定價值,感興趣的同學可以學習一下
    2021-11-11
  • 詳解Matlab繪制3D玫瑰花的方法(內附旋轉版本)

    詳解Matlab繪制3D玫瑰花的方法(內附旋轉版本)

    這篇文章主要為大家介紹了如何利用Matlab繪制3D版的玫瑰花以及旋轉版的3D玫瑰花,文中的示例代碼講解詳細,感興趣的小伙伴可以動手試一試
    2022-03-03
  • C++11 Unicode編碼轉換

    C++11 Unicode編碼轉換

    這篇文章主要介紹了C++11 Unicode編碼轉換的相關資料,幫助大家更好的理解和學習c++11,感興趣的朋友可以了解下
    2020-08-08
  • 十個C++惡搞朋友的代碼合集

    十個C++惡搞朋友的代碼合集

    這篇文章主要為大家整理了十個C++中可以惡搞朋友的代碼合集(注意!從第五個開始為危險/永久性程序,請慎重使用),感興趣的小伙伴可以收藏一下
    2023-02-02
  • C++貪心算法實現活動安排問題(實例代碼)

    C++貪心算法實現活動安排問題(實例代碼)

    貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。這篇文章主要介紹了C++貪心算法實現活動安排問題,需要的朋友可以參考下
    2019-11-11
  • c++ 動態(tài)內存分配相關總結

    c++ 動態(tài)內存分配相關總結

    這篇文章主要介紹了c++ 動態(tài)內存分配相關的相關資料,幫助大家更好的理解和學習和使用c++,感興趣的朋友可以了解下
    2021-02-02
  • c++基礎使用STL的注意點詳解

    c++基礎使用STL的注意點詳解

    這篇文章主要為大家介紹了c++基礎使用STL的注意點,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12

最新評論