後置運算式

後置運算式包含主要運算式,或後置運算子後面接著主要運算式的運算式。 下表列出後置運算子。

後置運算子

運算子名稱 運算子標記法
下標運算子 [ ]
函式呼叫運算子 ( )
明確類型轉換運算子 type-name ( )
成員存取運算子 . ->
後置遞增運算子 ++
後置遞減運算子 --

下列語法描述可能的後置陳述式:

primary-expression
postfix-expression[expression]postfix-expression(expression-list)simple-type-name(expression-list)postfix-expression.namepostfix-expression->namepostfix-expression++postfix-expression--cast-keyword < typename > (expression )typeid ( typename )

上述後置運算式 可能是 主要運算式 或其他後置運算式。 後置運算式由左至右分組,因此可讓運算式鏈結在一起,如下所示:

func(1)->GetValue()++

在上述運算式中, func 是主要運算式,是函式後置運算式, func(1) 是指定類別成員的後置運算式, func(1)->GetValuefunc(1)->GetValue() 是另一個函式後置運算式,而整個運算式則是遞增 GetValue 傳回值的後置運算式。 整個運算式的意義是傳遞 1 做為呼叫 func 的引數,並取得類別的指標做為傳回值。 接著在該類別上呼叫 GetValue() ,然後遞增傳回的值。

以上列出的運算式為指派運算式,表示這些運算式的結果必須是右值。

後置運算式格式

simple-type-name ( expression-list )

表示建構函式的引動過程。 如果 simple-type-name 是一個基本類型,則運算式清單必須是單一運算式,而這個運算式表示將運算式的值轉型為基本類型。 此種轉型運算式會模擬建構函式。 由於這個格式允許使用相同的語法建構基本類型和類別,因此該格式在定義樣板類別時會特別有用。

cast-keyword 是 的其中 dynamic_cast 一個 , static_castreinterpret_cast 。 如需詳細資訊,請參閱 dynamic_caststatic_castreinterpet_cast

運算子 typeid 會被視為後置運算式。 請參閱 typeid 運算子

型式和實質引數

呼叫程式會將資訊傳遞至「實際引數」中呼叫的函式。呼叫的函式會使用對應的「正式引數」來存取訊號。

呼叫函式時,會執行下列工作:

  • 所有實質引數 (呼叫端所提供的引數) 都會進行評估。 這些引數並不需要遵循任何隱含的評估順序,但是會在所有引數都經過評估且所有副作用都已完成之後,才進入函式。

  • 每個型式引數都會使用它在運算式清單中的對應實質引數初始化 (正式引數是在函式標頭中宣告,並用於函式主體中的引數。轉換會如同透過初始化來完成 — 標準和使用者定義轉換都會在將實際引數轉換成正確的類型時執行。 所執行的初始化將以下列程式碼提供概念上的說明:

    void Func( int i ); // Function prototype
    ...
    Func( 7 );          // Execute function call
    

    呼叫之前的概念初始化為:

    int Temp_i = 7;
    Func( Temp_i );
    

    請注意,初始化的執行方式就如同使用等號語法,而不是括號語法。 將值傳遞至函式之前,會先製作 i 的複本 (如需詳細資訊,請參閱 初始化運算式 轉換

    因此,如果函式原型(宣告)呼叫 類型的引數,而且呼叫程式提供類型 long 的實際自 int 變數,則會使用標準類型轉換來 long 升級實際引數(請參閱 標準轉換 )。

    提供沒有轉換成型式引數類型之標準或使用者定義轉換的實質引數是不正確的做法。

    對於類別類型的實質引數,型式引數會藉由呼叫類別的建構函式進行初始化。 (請參閱 這些特殊類別成員函式的詳細資訊建 構函式。

  • 函式呼叫將會執行。

下列程式片段將示範函式呼叫:

// expre_Formal_and_Actual_Arguments.cpp
void func( long param1, double param2 );

int main()
{
    long i = 1;
    double j = 2;

    // Call func with actual arguments i and j.
    func( i, j );
}

// Define func with formal parameters param1 and param2.
void func( long param1, double param2 )
{
}

從 main 呼叫時 func ,會使用 的值 i 初始化型式參數 param1i 會轉換成型 long 別,以使用標準轉換對應至正確的型別),而型式參數 param2 會以 的值 j 初始化( j 使用標準轉換轉換成型 double 別)。

引數類型的處理方式

宣告為 const 型別的正式引數無法在函式主體內變更。 函式可以變更不是 類型 const 的任何引數。 不過,變更是函式的本機,而且不會影響實際引數的值,除非實際引數是非 型 const 別物件的參考。

下列函式將說明一些這類概念:

// expre_Treatment_of_Argument_Types.cpp
int func1( const int i, int j, char *c ) {
   i = 7;   // C3892 i is const.
   j = i;   // value of j is lost at return
   *c = 'a' + j;   // changes value of c in calling function
   return i;
}

double& func2( double& d, const char *c ) {
   d = 14.387;   // changes value of d in calling function.
   *c = 'a';   // C3892 c is a pointer to a const object.
    return d;
}

省略號和預設引數

如需傳遞可變引數數目的詳細資訊只要使用下列兩種方法的其中一種,函式就可以宣告為接受比函式定義中所指定數目少的引數:省略符號 (...) 或預設引數。

省略號表示可能需要引數,但宣告中未指定數位和類型。 一般來說,這並不是理想的 C++ 程式設計做法,因為它會失去其中一項 C++ 的優點:類型安全。 不同的轉換會套用至以省略號宣告的函式,而不是已知正式和實際引數類型的函式:

  • 如果實際引數的類型為 float ,則會在函式呼叫之前升階為 類型 double

  • 任何 signed charunsigned charsigned shortunsigned short 、列舉型別或位欄位會轉換成 signed intunsigned int 使用整數升階的 。

  • 任何類別類型的引數都會以傳值的方式做為資料結構傳遞,而複本會以二進位檔複製的方式建立,而不會以叫用類別之複製建構函式 (如果有的話) 的方式建立。

如果使用,省略號必須在引數清單中最後宣告。 如需傳遞變數數目變數的詳細資訊,請參閱執行時間程式庫參考 中的 va_arg、va_start和va_list 討論

如需 CLR 程式設計中預設引數的資訊,請參閱 變數引數清單 (...) (C++/CLI)

預設引數可讓您指定函式呼叫中未提供值時,引數應該假設的值。 下列程式碼片段將示範預設引數的運作方式。 如需有關指定預設引數之限制的詳細資訊,請參閱 預設自 變數。

// expre_Ellipsis_and_Default_Arguments.cpp
// compile with: /EHsc
#include <iostream>

// Declare the function print that prints a string,
// then a terminator.
void print( const char *string,
            const char *terminator = "\n" );

int main()
{
    print( "hello," );
    print( "world!" );

    print( "good morning", ", " );
    print( "sunshine." );
}

using namespace std;
// Define print.
void print( const char *string, const char *terminator )
{
    if( string != NULL )
        cout << string;

    if( terminator != NULL )
        cout << terminator;
}

上述程式會宣告接受兩個引數的函式 print。 不過,第二個引數 結束字元 的預設值為 "\n" 。 在 中 main ,前兩個呼叫允許 print 預設的第二個引數提供新的行來終止列印的字串。 第三個呼叫會為第二個引數指定明確的值。 程式的輸出為

hello,
world!
good morning, sunshine.

另請參閱

運算式的類型