詳解C++編程中的主表達(dá)式與后綴表達(dá)式編寫基礎(chǔ)
主表達(dá)式
主表達(dá)式是更復(fù)雜的表達(dá)式的構(gòu)造塊。它們是文本、名稱以及范圍解析運(yùn)算符 (::) 限定的名稱。主表達(dá)式可以具有以下任一形式:
literal this :: name name ( expression )
literal 是常量主表達(dá)式。其類型取決于其規(guī)范的形式。
this 關(guān)鍵字是指向類對象的指針。它在非靜態(tài)成員函數(shù)中可用,并指向?yàn)槠湔{(diào)用函數(shù)的類的實(shí)例。 this 關(guān)鍵字只能在類成員函數(shù)體的外部使用。
this 指針的類型是未特別修改 this 指針的函數(shù)中的 type *const(其中 type 是類名)。以下示例演示成員函數(shù)聲明以及 this 的類型:
// expre_Primary_Expressions.cpp // compile with: /LD class Example { public: void Func(); // * const this void Func() const; // const * const this void Func() volatile; // volatile * const this };
范圍解析運(yùn)算符 (::) 后跟名稱構(gòu)成了主表達(dá)式。此類名稱必須是全局范圍內(nèi)的名稱,而不是成員名稱。此表達(dá)式的類型由名稱的聲明決定。如果聲明的名稱是左值,則該類型是左值(即,它可以出現(xiàn)在賦值運(yùn)算符表達(dá)式的左側(cè))。范圍解析運(yùn)算符允許引用全局名稱,即使該名稱隱藏在當(dāng)前范圍中也如此。
用括號括起的表達(dá)式是與不帶括號的表達(dá)式具有相同的類型和值的主表達(dá)式。如果不帶括號的表達(dá)式是左值,則用括號括起的表達(dá)式也是左值。
在上面給出的主表達(dá)式語法的上下文中,name 表示為 name 描述的語法中的任何內(nèi)容,不過,當(dāng)在名稱前使用范圍解析運(yùn)算符時(shí),不允許使用只能在類中出現(xiàn)的名稱的類型。這包括用戶定義的轉(zhuǎn)換函數(shù)名稱和析構(gòu)函數(shù)名稱。
主表達(dá)式的示例包括:
100 // literal 'c' // literal this // in a member function, a pointer to the class instance ::func // a global function ::operator + // a global operator function ::A::B // a global qualified name ( i + 1 ) // a parenthesized expression
下面的示例是所有考慮的 name 以及各種形式的主表達(dá)式:
MyClass // a identifier MyClass::f // a qualified name operator = // an operator function name operator char* // a conversion operator function name ~MyClass // a destructor name A::B // a qualified name A<int> // a template id
后綴表達(dá)式
后綴表達(dá)式包含主表達(dá)式或者其中的后綴運(yùn)算符跟在主表達(dá)式之后的表達(dá)式。 下表列出了后綴運(yùn)算符。
后綴運(yùn)算符
運(yùn)算符名稱
運(yùn)算符表示法
下標(biāo)運(yùn)算符
[ ]
函數(shù)調(diào)用運(yùn)算符
( )
顯式類型轉(zhuǎn)換運(yùn)算符
type-name ( )
成員訪問運(yùn)算符
. 或 –>
后綴遞增運(yùn)算符
++
后綴遞減運(yùn)算符
––
以下語法描述了可能的后綴表達(dá)式:
primary-expression postfix-expression [ expression ] postfix-expression ( expression-list) simple-type-name ( expression-list) postfix-expression . name postfix-expression –> name postfix-expression ++ postfix-expression –– cast-keyword < typename > (expression ) typeid ( typename )
上面的 postfix-expression 可能是主表達(dá)式或另一個(gè)后綴表達(dá)式。 請參閱主表達(dá)式。 后綴表達(dá)式從左到右進(jìn)行分組,這允許表達(dá)式按如下方式鏈接起來:
func(1)->GetValue()++
在上面的表達(dá)式中,func 是主表達(dá)式,func(1) 是函數(shù)后綴表達(dá)式,func(1)->GetData 是指定類成員的后綴表達(dá)式,func(1)->GetData() 是另一個(gè)函數(shù)后綴表達(dá)式,整個(gè)表達(dá)式是增加 GetData 的返回值的后綴表達(dá)式。 該表達(dá)式的整體含義是作為參數(shù)傳遞 1 的 "call func,并作為返回值獲取一個(gè)指向類的指針。 然后調(diào)用此類上的 GetValue(),接著遞增返回的值。
上面列出的表達(dá)式是賦值表達(dá)式,這意味著這些表達(dá)式的結(jié)果必須為右值。
后綴表達(dá)式形式
simple-type-name ( expression-list )
指示構(gòu)造函數(shù)的調(diào)用。 如果 simple-type-name 是基本類型,則表達(dá)式列表必須是單個(gè)表達(dá)式,并且該表達(dá)式指示表達(dá)式的值將轉(zhuǎn)換為基礎(chǔ)類型。 此類強(qiáng)制轉(zhuǎn)換表達(dá)式模仿構(gòu)造函數(shù)。 由于此形式允許使用相同的語法來構(gòu)造基本類型和類,因此它在定義模板類時(shí)特別有用。
cast-keyword 是 dynamic_cast、static_cast 或 reinterpret_cast 之一。 可在 dynamic_cast、static_cast 和 reinterpet_cast 中找到更多信息。
typeid 運(yùn)算符被視為后綴表達(dá)式。 請參閱 typeid 運(yùn)算符。
形參和實(shí)參
調(diào)用程序會將信息傳遞到“實(shí)參”中的已調(diào)用函數(shù)。 已調(diào)用函數(shù)使用對應(yīng)的“形參”訪問信息。
當(dāng)調(diào)用函數(shù)時(shí),將執(zhí)行以下任務(wù):
計(jì)算所有實(shí)參(調(diào)用方提供的參數(shù))。 沒有計(jì)算這些參數(shù)的隱含順序,但所有參數(shù)都會計(jì)算,并且所有副作用都會在進(jìn)入該函數(shù)前完成。
使用每個(gè)形參在表達(dá)式列表中對應(yīng)的實(shí)參來初始化該形參。 (形參是在函數(shù)頭中聲明并在函數(shù)體中使用的參數(shù)。) 轉(zhuǎn)換就像是通過初始化完成的一樣 - 標(biāo)準(zhǔn)的和用戶定義的轉(zhuǎn)換在將實(shí)參轉(zhuǎn)換為正確的類型時(shí)執(zhí)行。 以下代碼從概念上演示了所執(zhí)行的初始化:
void Func( int i ); // Function prototype ... Func( 7 ); // Execute function call
調(diào)用前的概念性初始化為:
int Temp_i = 7; Func( Temp_i );
請注意,初始化就像使用等號語法(而不是括號語法)一樣執(zhí)行。 在將值傳遞到函數(shù)之前制作了 i 的副本。
因此,如果函數(shù)原型(聲明)對 long 類型的參數(shù)進(jìn)行調(diào)用,并且調(diào)用程序提供了 int 類型的實(shí)參,則會使用到 long 類型的標(biāo)準(zhǔn)類型轉(zhuǎn)換提升該實(shí)參。
如果提供了一個(gè)實(shí)參,但它沒有到形參的類型的標(biāo)準(zhǔn)的或用戶定義的轉(zhuǎn)換,則是一個(gè)錯(cuò)誤。
對于類類型的實(shí)參,將通過調(diào)用類的構(gòu)造函數(shù)初始化形參。
執(zhí)行函數(shù)調(diào)用。
以下程序片段演示了函數(shù)調(diào)用:
// 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 ) { }
當(dāng)從 main 調(diào)用 func 時(shí),將使用 param1(i 將轉(zhuǎn)換為類型 ilong 以對應(yīng)使用標(biāo)準(zhǔn)轉(zhuǎn)換的正確類型)的值初始化形參 ,并使用 param2(j 將轉(zhuǎn)換為使用標(biāo)準(zhǔn)轉(zhuǎn)換的類型 jdouble)的值初始化形參 。
參數(shù)類型的處理
不能在函數(shù)主題內(nèi)更改聲明為 const 類型的形參。 函數(shù)可以更改類型不是 const 的任何參數(shù)。 但是,更改對于函數(shù)而言是本地進(jìn)行的,且不會影響實(shí)參的值,除非實(shí)參是對非 const 類型的對象的引用。
以下函數(shù)闡釋了其中的一些概念:
// 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; }
省略號和默認(rèn)參數(shù)
通過使用下列兩種方法之一,可以聲明函數(shù)以接受比函數(shù)定義中指定的參數(shù)更少的參數(shù):省略號 (...) 或默認(rèn)參數(shù)。
省略號表示可能需要參數(shù),但聲明中未指定數(shù)目和類型。 這通常是較差的 C++ 編程做法,因?yàn)樗鼓鸁o法獲得 C++ 的一個(gè)優(yōu)點(diǎn),即類型安全。 不同的轉(zhuǎn)換將應(yīng)用于使用省略號聲明的函數(shù),而不是應(yīng)用于那些已知其形參和實(shí)參類型的函數(shù):
如果實(shí)參的類型為浮點(diǎn),則在函數(shù)調(diào)用前將其提升為雙精度類型。
使用整型提升將所有有符號或無符號的 char、short、枚舉類型或位域轉(zhuǎn)換為有符號或無符號的 int。
類類型的所有參數(shù)都作為數(shù)據(jù)結(jié)構(gòu)通過值進(jìn)行傳遞;副本是由二進(jìn)制復(fù)制創(chuàng)建的,而不是通過調(diào)用類的復(fù)制構(gòu)造函數(shù)(如果存在)創(chuàng)建的。
如果使用省略號,則必須在參數(shù)列表中最后聲明它。
如果函數(shù)調(diào)用中沒有提供值,則可通過默認(rèn)參數(shù)指定參數(shù)應(yīng)采用的值。 以下代碼片段演示默認(rèn)參數(shù)的工作方式。
// expre_Ellipses_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; }
上面的程序聲明一個(gè)采用兩個(gè)參數(shù)的函數(shù) print。 而第二個(gè)參數(shù) terminator 具有默認(rèn)值 "\n"。 在 main 中,對 print 的前兩個(gè)調(diào)用允許默認(rèn)的第二個(gè)參數(shù)提供新行以終止打印的字符串。 第三個(gè)調(diào)用為第二個(gè)參數(shù)指定顯式值。 該程序的輸出為
hello, world! good morning, sunshine.
相關(guān)文章
詳解C++中實(shí)現(xiàn)繼承string類的MyString類的步驟
這篇文章主要介紹了C++中實(shí)現(xiàn)繼承string類的MyString類的步驟,其中的要點(diǎn)是要實(shí)現(xiàn)運(yùn)算符的重載,需要的朋友可以參考下2016-04-04VSCode與Keil聯(lián)合開發(fā)STM32的流程
這篇文章主要介紹了VSCode與Keil聯(lián)合開發(fā)STM32的流程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02c++只保留float型的小數(shù)點(diǎn)后兩位問題
這篇文章主要介紹了c++只保留float型的小數(shù)點(diǎn)后兩位問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11使用UDP協(xié)議實(shí)現(xiàn)單詞翻譯服務(wù)器
這篇文章主要為大家詳細(xì)介紹了如何使用UDP協(xié)議實(shí)現(xiàn)英文單詞翻譯服務(wù)器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2023-08-08