功能
一個函式是的程式碼單元表示的語句序列。
函式可以接受引數或值並返回單個值(或不返回 )。要使用函式,函式呼叫將用於引數值,函式呼叫本身的使用將替換為其返回值。
每個函式都有一個型別簽名 - 其引數的型別和返回型別的型別。
函式的靈感來自過程和數學函式的概念。
- 注意:C++函式本質上是過程,不遵循數學函式的確切定義或規則。
功能通常用於執行特定任務。並且可以從程式的其他部分呼叫。必須先宣告和定義函式,然後才能在程式中的其他位置呼叫它。
- 注意:流行的函式定義可能隱藏在其他包含的檔案中(通常為了方便和在許多檔案中重用)。這是標頭檔案的常見用法。
功能宣告
一個函式宣告中宣告其名稱和型別簽名的編譯器功能的存在。語法如下:
int add2(int i); // The function is of the type (int) -> (int)
在上面的示例中,int add2(int i)
函式向編譯器宣告以下內容:
- 在返回型別為
int
。 - 該函式的名稱是
add2
。 - 數量的引數的函式為 1:
- 第一個引數是
int
型別。 - 第一個引數將在函式的內容中以名稱
i
引用。
- 第一個引數是
引數名稱是可選的; 該功能的宣告也可以如下:
int add2(int); // Omitting the function arguments' name is also permitted.
根據單定義規則,具有特定型別簽名的函式只能在 C++編譯器可見的整個 C++程式碼庫中宣告或定義一次。換句話說,具有特定型別簽名的函式無法重新定義 - 它們只能定義一次。因此,以下是無效的 C++:
int add2(int i); // The compiler will note that add2 is a function (int) -> int
int add2(int j); // As add2 already has a definition of (int) -> int, the compiler
// will regard this as an error.
如果函式不返回任何內容,則其返回型別將寫為 void
。如果不帶引數,則引數列表應為空。
void do_something(); // The function takes no parameters, and does not return anything.
// Note that it can still affect variables it has access to.
功能呼叫
宣告後可以呼叫一個函式。例如,以下程式在 main
的函式中呼叫 add2
,其值為 2
:
#include <iostream>
int add2(int i); // Declaration of add2
// Note: add2 is still missing a DEFINITION.
// Even though it doesn't appear directly in code,
// add2's definition may be LINKED in from another object file.
int main()
{
std::cout << add2(2) << "\n"; // add2(2) will be evaluated at this point,
// and the result is printed.
return 0;
}
這裡,add2(2)
是函式呼叫的語法。
功能定義
一個函式定義 *類似宣告,但它也包含在函式被它的身體內呼叫時執行的程式碼。
add2
的函式定義示例可能是:
int add2(int i) // Data that is passed into (int i) will be referred to by the name i
{ // while in the function's curly brackets or "scope."
int j = i + 2; // Definition of a variable j as the value of i+2.
return j; // Returning or, in essence, substitution of j for a function call to
// add2.
}
功能過載
你可以建立具有相同名稱但不同引數的多個函式。
int add2(int i) // Code contained in this definition will be evaluated
{ // when add2() is called with one parameter.
int j = i + 2;
return j;
}
int add2(int i, int j) // However, when add2() is called with two parameters, the
{ // code from the initial declaration will be overloaded,
int k = i + j + 2 ; // and the code in this declaration will be evaluated
return k; // instead.
}
這兩個函式都使用相同的名稱 add2
呼叫,但呼叫的實際函式直接取決於呼叫中引數的數量和型別。在大多數情況下,C++編譯器可以計算要呼叫的函式。在某些情況下,必須明確說明型別。
預設引數
函式引數的預設值只能在函式宣告中指定。
int multiply(int a, int b = 7); // b has default value of 7.
int multiply(int a, int b)
{
return a * b; // If multiply() is called with one parameter, the
} // value will be multiplied by the default, 7.
在此示例中,可以使用一個或兩個引數呼叫 multiply()
。如果只給出一個引數,則 b
的預設值為 7.預設引數必須放在函式的後面引數中。例如:
int multiply(int a = 10, int b = 20); // This is legal
int multiply(int a = 10, int b); // This is illegal since int a is in the former
特殊功能呼叫 - 運算子
在 C++中存在特殊的函式呼叫,它們的語法與 name_of_function(value1, value2, value3)
不同。最常見的例子是運算子。
某些特殊字元序列將被編譯器縮減為函式呼叫,例如 !
,+
,-
,*
,%
和 <<
等等。這些特殊字元通常與非程式設計用法相關聯或用於美學(例如,+
字元通常被認為是 C++程式設計和初等數學中的加法符號)。
C++使用特殊語法處理這些字元序列; 但實際上,每次出現的運算子都會縮減為函式呼叫。例如,以下 C++表示式:
3+3
相當於以下函式呼叫:
operator+(3, 3)
所有運算子函式名稱都以 operator
開頭。
雖然在 C++的前一個 C 中,通過提供具有不同型別簽名的附加定義,操作符函式名稱不能被賦予不同的含義,在 C++中,這是有效的。在一個唯一的函式名稱下隱藏其他函式定義在 C++中稱為運算子過載,並且是 C++中相對常見但不通用的約定。