某日二師兄參加XXX科技公司的C++工程師開發崗位第11面: > 面試官:在C++中,你都知道都哪些運算符? > > 二師兄:啥?運算符?`+-*/=`這些算嗎? > > 面試官:嗯,還有其他的嗎? > > 二師兄:當然還有,`+=,-=,*=,/=,==`,還有邏輯運算,位運算等。 > > 面試官 ...
某日二師兄參加XXX科技公司的C++工程師開發崗位第11面:
面試官:在C++中,你都知道都哪些運算符?
二師兄:啥?運算符?
+-*/=
這些算嗎?面試官:嗯,還有其他的嗎?
二師兄:當然還有,
+=,-=,*=,/=,==
,還有邏輯運算,位運算等。面試官:好的。那你知道這些運算的優先順序嗎?
二師兄:(面試官傻逼吧,這誰記得住)記不住了,一般我都會加括弧來表達我的意思。
面試官:好的。那你知道下麵這段程式會輸出什麼嗎?
#include <iostream>
int main(int argc, char const *argv[])
{
int i = 0;
std::cout << i++ + ++i << std::endl;
}
二師兄:應該是
2
吧。面試官:那你知道運算符的求值順序嗎?
二師兄:應該是從左向右?
面試官:
%
這個符號是求餘的你應該知道吧。如果使用一個int
型負數對另一個int
型負數求餘數,結果是正數還是負數?二師兄:應該是正數吧。
面試官:對一個整數判斷是否位
true
或者false
,可以用if(val == true)
或if(val == false)嗎?二師兄:不能,因為在使用
int
型與bool
型比較時,會把true
和false
轉換成int
型,上面兩個表達式等同於if(val == 1)
和if(val == 0),與我們的本意不符。面試官:你知道
a=a+1
和a+=1
這兩者的區別嗎?二師兄:兩者應該沒啥區別吧?
面試官:你知道
++i
和i++
的區別嗎?二師兄:前者返回
i+1
,後者返回i
。之後i
會被+1
。面試官:C++11中的左值右值你熟悉嗎?
二師兄:瞭解過一些(我很熟悉)。
面試官:那你知道算數運算符、邏輯運算符、位運算符返回的結果是左值還是右值嗎?
二師兄:額,讓我想想。。。應該都是右值。
面試官:好的。那你知道點(
.
)和箭頭(->
)運算符返回的結果是左值還是右值嗎?二師兄:額。。。應該都是左值。(應該是的吧。。。)
面試官:我們都知道,一個
int
型的負數,在最高(31
)位上的值是1
。那麼如果對這個負數進行右移(>>
)操作,最高位上的1
會被移動嗎?二師兄:應該不會。可能跟編譯器實現有關。
面試官:你知道重載運算符要註意哪些事項嗎?
二師兄:其實工作中很少重載運算符,我覺得最重要的事項就是儘量不要重載運算符。(我好機智。。)
面試官:好的,今天的面試結束了,回去等通知吧。
對於今日二師兄的表現,讓我們來回過頭看一下:
在C++中,你都知道哪些運算符?
除了算術運、邏輯、位、關係、等於運算符,如sizeof
,decltype
、new/delete
也屬於運算符。
知道下麵這段程式會輸出什麼嗎?
應該是
2
吧。
這裡程式的輸出的結果是不確定的。原因會在下麵講。
那你知道運算符的求值順序嗎?
在C++的標準中,大部分的運算符兩側的表達式的求值順序是不確定的。在上個例子中,可能會先計算i++,然後再計算++i,也可能反過來。所以這裡的結果不缺行,屬於未定義的行為(undefined behavior
)。
那麼C++中有沒有確定求值順序的二元運算符呢?答案是有的,而且僅有這四個:&&
,||
,:?
,,
。C++標準保證這四個運算符的求值順序是從左到右確定的。
你知道
a=a+1
和a+=1
這兩者的區別嗎?
此兩者有一點區別,那就是前者的a
會被求值2
次,而後者只會被求值1
次。如果開啟編譯器優化,有可能會被優化相同的效果。
你知道
++i
和i++
的區別嗎?
除了二師兄的回答外,前置++的效率要高於後者,因為前者不需要緩存值,以用來返回。
知道點(
.
)和箭頭(->
)運算符返回的結果是左值還是右值嗎?
這裡箭頭運算符的調用者肯定是左值(想想看為什麼),但是號運算符的調用者可不一定是左值。所以箭頭運算符的結果一定是左值,當點運算符的調用者是左值時,返回值時左值,當點運算符的調用者是右值時,返回值時右值。
負數進行右移(
>>
)操作,最高位上的1
會被移動嗎
很遺憾,這裡回答會和不會都不對,因為這也屬於未定義的行為(undefined behavior
)。 所以不要對有符號的類型進行按位操作,最好的情況是正好當前編譯器的實現和你的預期吻合,當前平臺運行無異常。一旦移植代碼,可能會遇到意想不到的問題。
你知道重載運算符要註意哪些事項嗎?
二師兄機智!非必要不需要重載運算符。如果一定要重載,請註意:(我還是不建議你重載運算符,回頭是岸。。。下麵的規則都不用看了)
- 重載運算符必須至少有一個操作數是用戶定義的類型,這意味著不能重載內置類型的運算符。
- 重載運算符必須具有與原始運算符相同的優先順序和關聯性。
- 重載運算符必須具有與原始運算符相同的參數數目。例如,二元運算符必須有兩個參數,一元運算符必須有一個參數。
- 重載運算符不能更改運算符的含義,例如,不能將“+”運算符用於減法操作。
- 重載運算符必須是類的成員函數或全局函數。如果是成員函數,則第一個參數必須是類的對象。
- 重載運算符不能更改操作數的數量或類型。例如,不能將二元運算符重載為一元運算符。
- 重載運算符不能具有預設參數。
- 重載運算符的返回類型應該是運算符執行後的結果類型。
今日份面試到這裡就結束了,小伙伴們,對於今天二師兄的表現能打幾分呢?如果是你,以上的問題都能回答的上來嗎?
關註我,帶你21天“精通”C++!(狗頭)