背景
C++中提供了很多操作符且定義了什么時候可以用于操作基本類型,其還允許我們定義用于操作class類型的操作符,接下來幾篇文章將會介紹C++中用于基本類型的操作符,與此同時也會介紹一些庫中操作符。一個表達式是由一個或多個操作符組成的并且返回一個結(jié)果。一個最簡單的表達式就是一個變量或者字面量,更加復雜的表達式是由一個操作符和一個或多個操作數(shù)組成。
基礎(chǔ)知識
C++中有一些影響表達式計算的基礎(chǔ)概念,所以我們在使用前需要先了解一下這些基本概念。
基本概念
C++中有一元運算符也有二元運算符,一元運算符就像是地址操作符&或者是解引用操作符,都是作用于一個操作數(shù)。類似==就是二元操作符,是作用在兩個操作數(shù)上的。還有一個三元運算符,其可以操作三個操作數(shù),函數(shù)調(diào)用則不限制操作數(shù)的數(shù)量。其中像即可以是一元運算符(解引用符),也可以是二元運算符(乘法符號),在實際使用中由其所處的上下文環(huán)境決定。
理解這么多運算符需要理解運算符的優(yōu)先級和結(jié)合性,這取決于操作數(shù)的運算順序,以下就是一個例子,*操作符的操作數(shù)可以是10和20,也可以是是10和20/2,或者是15和20/2,該如何理解這個表達式呢,接下來我們詳細說明。
操作數(shù)轉(zhuǎn)換
作為計算表達式的一部分,操作數(shù)會經(jīng)常從一個類型轉(zhuǎn)換為另一個類型,例如二元運算符通常希望兩個操作數(shù)是同一個類型,這些運算符可以用于不同類型的操作數(shù)只要兩個操作可以轉(zhuǎn)化為同一個類型。例如我們可以將一個整型轉(zhuǎn)化成一個浮點型,但是我們無法將一個指針類型轉(zhuǎn)化為一個浮點型。
運算符重載
C++定義了應(yīng)用于基本類型和復合類型的操作符含義,我們自己可以定義操作符作用于class類型時操作符的含義,這種定義給了已有操作符的其他含義,這種我們稱之為運算符重載。IO庫中的<<和>>操作符就是重載遠算符。
當我們使用重載運算符時,運算符的含義。操作數(shù)和最后的結(jié)果都取決于運算符是如何定義的,但是操作數(shù)的數(shù)量和優(yōu)先級和結(jié)合性是不會改變的。
左值和右值
C++中的表達式不是左值(rvalue)就是右值(rvalue),這個名稱是從C中繼承過來的,其是為了好記憶,左值可以在賦值的左邊,右值則不可以。在C++中左值和右值更好區(qū)分,一個左值表達式代表一個對象或者一個函數(shù),然而需要注意的是一些左值表達式如const對象不能作為賦值操作符的左操作數(shù)。而且一些表達式產(chǎn)生對象但是是返回右值而不是返回左值??偟膩碚f,當我將一個對象當作右值使用時返回的他的值,當作左值使用時返回的是其地址。
操作符在需要左值或者右值以及返回左值或者右值時是不同的,我們可以將一個左值當作右值使用,但是卻不能將右值當作左值使用。
當使用decltype時左值和右值也不同,當我對一個表達式使用decltype,如果表達式返回的是左值,函數(shù)返回則是引用,例如如果p 是int 類型,decltype(p)返回的時int&,如果運算表達式是右值如地址操作符如decltype(&p)返回int , 這是一個指針,指向一個指向int類型的指針。
優(yōu)先級和結(jié)合性
一個表達式包含兩或兩個個以上的操作符的表達式是復合表達式,計算一個復合表達式需要將利用操作符將操作數(shù)分組,優(yōu)先級和結(jié)合性決定如何分組,開發(fā)者也可以通過括號來強制分組。
通常表達式的值依賴于子表達式如何分組,操作數(shù)將會和優(yōu)先級高的操作符結(jié)合在一起,例如乘和除的優(yōu)先級相同,但是他們的優(yōu)先級比加高,所以要先算乘除,后算加減。在優(yōu)先級的相同的情況下由結(jié)合性決定如何分組,算術(shù)操作符是向左結(jié)合,這意味著在優(yōu)先級相同的情況下從左向右分組:
- 因為優(yōu)先級所以3 + 4 * 5結(jié)果是23而不是35
- 因為結(jié)合性所以20 - 15 - 3是2而不是8
運算順序
優(yōu)先級決定了操作數(shù)如何被分組,但是其并未確定哪一個操作數(shù)先被運算,在絕大多數(shù)情況下這個順序是不固定的,例如在下面的例子中,我們知道f1和f2必須要在乘法執(zhí)行前調(diào)用,然后將他們的結(jié)果相乘,但是我們并不知道f1和f2哪個先調(diào)用:
int i = f1() * f2();
對于沒有指定運算順序的操作符而言,一個表達式指向并改變同一個對象會發(fā)生錯誤,這么做的表達式會引發(fā)未定義的錯誤。一個簡單的例子,<< 操作符并不指定操作數(shù)的運算順序,其結(jié)果就是輸出表達式未知。
int i = 0;
std::cout<
有四個運算符是保證操作數(shù)的遠算順序,&&操作符先運算左邊,只有左邊為true才會運算右邊,|| , ?:和,也會確定操作順序。
成員獲取操作符
點操作符.和箭頭操作符->都能獲取到成員,點操作符可以獲取到class類型的成員,而箭頭操作符可以獲取到指針的成員:
string s1 = "a string", *p = &s1;
auto n = s1.size();
n = (*p).size();
n = p->size(); //等價于(*p).size()
?由于解引用符有優(yōu)先級低于點操作符,所以我們需要使用括號改變遠算順序
?
條件操作符
條件操作符能夠簡化if-else的邏輯結(jié)構(gòu),通常的使用形式如下
cond?expr1 : expr2;
其中cond是一個條件,如果cond為true,運算expr1,反之則運算expr2,例子如下
string finalgrade = (grade < 60)? "failed" : "pass";
條件操作符也可以嵌套:
finalgrade = (grade > 90) ? "high pass": (grade < 60) ? "fail" : "pass";
-
C++
+關(guān)注
關(guān)注
22文章
2119瀏覽量
75040 -
Class
+關(guān)注
關(guān)注
0文章
53瀏覽量
20062 -
操作符
+關(guān)注
關(guān)注
0文章
21瀏覽量
9137
發(fā)布評論請先 登錄
正則表達式入門知識科普
Linux內(nèi)核中C語法擴展-語句表達式
C,C++表達式求值順序超詳解
防范表達式的失控
深入淺出boost正則表達式
快速入門IPv6和正則表達式

C++入門教程之數(shù)據(jù)類型、運算符和表達式的詳細資料說明

C++程序設(shè)計教程之數(shù)據(jù)類型與表達式的詳細資料說明

Python正則表達式指南

Lambda表達式詳解
Linux入門之正則表達式

評論