C++函數預設引數(詳解版)

2020-07-16 10:04:39
函數可以為形參分配預設引數,這樣當在函數呼叫中遺漏了實際引數時,預設引數將傳遞給形參。

函數預設引數通常設定在函數原型中,範例如下:

void showArea(double length = 20.0, double width = 10.0);

因為在函數原型中不需要形參名稱,所以範例原型也可以這樣宣告:

void showArea(double = 20.0, double = 10.0);

在這兩種情況下,預設引數必須是常數值或常數,在它們前面有一個賦值運算子(=)。 請注意,在這兩個範例原型中,showArea 函數具有兩個 double 引數。第一個被賦給了預設引數 20.0,第二個被賦予預設引數 10.0。以下是函數的定義:
void showArea(double length, double width)
{
    double area = length * width;
    cout <<"The area is " << area << endl;
}
length 的預設實參為 20.0,width 的預設實參為 10.0。因為這兩個形參都有預設實參,所以可以在函數呼叫中省略它們,如下所示:

showArea();

在該函數呼叫中,這兩個預設實參將被傳遞給形參。形參 length 將接收值 20.0,width 將接收值 10.0。該函數的輸出將是:

The area is 200

預設實參僅在呼叫函數時省略實際引數的情況下使用。在下面的呼叫語句中,指定了第一個實參,而第二個實參則被忽略:

showArea(12.0);

值 12.0 將被傳遞給 length,而 width 則將被傳遞預設值 10.0。函數的輸出將是:

The area is 120

當然,所有的預設實參都可以被覆蓋。在以下函數呼叫中,為兩個形參都提供了實參:

showArea(12.0,5.5);

此函數呼叫的輸出將為:

The area is 66

注意,函數的預設實參應在函數名稱最早出現時分配,這通常是函數原型。但是,如果一個函數沒有原型,則可以在函數頭中指定預設實參。例如,showArea 函數可以定義如下:
void showArea(double length = 20.0, double width = 10.0)
{
    double area = length * width;
    cout << "The area is " << area << endl;
}
下面的程式說明了預設函數實參的用法。它有一個在螢幕上顯示星號的函數,該函數接收 2 個實參,指定要顯示多少行星號,以及在每一行上列印多少個星號。提供的預設實參是顯示 1 行 10 個星號:
//This program demonstrates the use of default function arguments.
#include <iostream>
using namespace std;

//Function prototype with default arguments
void displayStars(int starsPerRow = 10,int numRows = 1);

int main()
{
    displayStars(); // starsPerRow & numRows use defaults (10 & 1)
    cout << endl;
    displayStars (5); // starsPerRow 5. numRows uses default value 1
    cout << endl;
    displayStars (7, 3); // starsPerRow 7. numRows 3. No defaults used.
    return 0;
}
void displayStars(int starsPerRow, int numRows)
{
    for (int row = 1; row <= numRows; row++)
    {
        for (int star = 1; star <= starsPerRow; star++)
            cout << '*';
        cout << endl;
    }
}
程式輸出結果:

**********
*****
*******
*******
*******

雖然 C++ 的預設實參非常方便,但它們在使用中並不完全是靈活的。當一個實參在一個函數呼叫中被遺漏時,它之後的所有實參也必須被省略。例如,上面程式的 displayStars 函數中,不可能只省略 starsPerRow 實參而不省略 numRows 實參,換句話說,以下函數呼叫是非法的:

displayStars ( , 3); // 非法函數呼叫

但是,使函數的某些形參有預設實參,而某些形參則沒有,這是可能的。例如,在下面函數中,只有最後一個形參具有預設實參:
//函數原型
void calcPay(int empNum, double payRate, double hours = 40.0);
//函數calcPay的定義
void calcPay(int empNum, double payRate, double hours)
{
    double wages;
    wages = payRate * hours;
    cout << "Gross pay for employee number ";
    cout << empNum << " is " << wages << endl;
}
呼叫此函數時,必須始終為前 2 個形參(empNum 和 payRate)指定實參,因為它們沒有預設實參,以下是有效呼叫的範例:
calcPay (769, 15.75);  // 使用 hours 的預設實參
calcPay (142, 12.00, 20); //指定 hours 數位
當函數使用了帶預設實參和不帶預設實參這兩種混合的形參時,帶預設實參的形參必須最後宣告,因此以下原型是非法的:
//非法原型
void calcPay(int empNum, double hours = 40.0, double payRate);
//非法原型
void calcPay(double hours = 40.0, int empNum, double payRate);
以下是關於預設實參的重點總結:
  1. 預設實參的值必須是常數值或命名常數。
  2. 當在函數呼叫中遺漏了一個實參時(因為它有預設值),它後面的所有實參也必須 被省略。
  3. 當函數使用了帶預設實參和不帶預設實參這兩種混合的形參時,帶預設實參的形參 必須最後宣告。