條件運算子
(?:)
是c++
中唯一的三目運算子
(trinary operator)
,用於在表示式中作條件判斷,通常可以替換
if語句,與
visual basic
中的iif
函式、excel
中的if
函式有同樣的作用。語法形式如下:
condition
? true_value : false_value
其中condition
條件是任何可以轉換為
bool
型別的表示式,包括但不僅限於
bool
、int
、指標。與
if
和while
的條件部分稍顯不同的是,這裡不能定義變數,否則會導致語法錯誤。
另外,條件語句會切實地控制執行流程,而不僅僅是控制返回值。也就是說,兩個返回值表示式中永遠只有乙個會被求值,在表示式的執行順序很重要時,這點尤為值得注意。比如:
int
*pi=getint();
int
i=pi
?
*pi:0;
這裡,只有當
pi的值不為
0時,它才會被提領
(dereference)
。這種語義保證了程式的正確性,因為提領乙個空指標將導致致命的執行期錯誤
(通常是非法操作的警告
)。同時,正因為條件運算子控制運算流程的特點,使得它不能用類似
iif的普通函式來模擬:
int
iif(
int
con,
int
t,int
f)//
試圖模擬?:
…//in some function
int
*pi=getint();
int
i=iif(pi,*pi,0);//error!
這段**會導致上文提到的致命執行期錯誤。
c/c++
標準規定,引數在被傳遞給函式之前求值,因此無論
pi為何值,都會被提領。又因為函式傳回乙個空指標的情況比較少見,所以這樣的錯誤在除錯時很難被發現,一旦發生又勢必造成重大災難。這樣的**在實踐中應盡量避免。
有時,條件運算子控制流程的特點會不知不覺影響我們的**。在
c時代,最大值
max通常用巨集實現:
#define
max(a,b) ((a)>(b)
?
(a):
(b))
需要用額外的括號將巨集引數和巨集本體保護起來,以免運算子優先順序擾亂邏輯,這是巨集醜陋的特點之一,這裡暫且不提。矛盾在於,用具有***的表示式呼叫巨集時,會出現問題:
int
i=5,j=6;
int
a=max(++i,++j);
**的作者原意顯然是想先將
i,j分別遞增,再將其中較大的乙個賦給
a。執行這段**,當
i=5,j=6
時,a=8
,知道為什麼嗎?通過巨集展開,賦值語句成這樣:
int
a=(++i)>(++j)
?
(++i)
:
(++j);//
刪除了多餘括號
在判斷之前,i、
j被分別自增一次,然後捨棄
:之前的部分,
j又被自增一次。執行之後,
i=6,j=8
。max
的更正確更安全的實現,是利用模板將型別引數化。
stl標準演算法中就有乙個這樣的工具級模版函式
std::max
。條件運算子是表示式而不是語句,這使得它可以出現在任何需要表示式的地方,這擴大了它的適用範圍。在那些語法上只能出現表示式而不能出現語句的地方(比如變數初始化),條件運算子有著不可替代的作用。
條件運算子優於
if
語句的另乙個場合是「模板元程式設計」
(tmp, template metaprogramming)
。在tmp
這個古怪奇異的編譯期運算程式設計技術中,一切舊有的技術和法則被全線擊破,我們所能仰仗的工具,只有模板特化
(specialization)
、typedef
s、函式宣告
(無法呼叫它們
)、以及編譯期常量運算。已經有人很深入地論證過,僅有以上這些,就已經形成了乙個「圖靈完善」的計算機語言。我們可以用模板特化技術,來模擬條件分支,迴圈迭代等一系列複雜的語言結構。由於可以參與編譯期常量運算,條件運算子在
tmp世界中很自然地扮演起重要角色。
比如,給與型別
t的乙個變數
t,我們想宣告乙個緩衝區存放
t和乙個
int,緩衝區的大小不小於
sizeof(t)
也不小於
sizeof(int)
,我們可以這樣寫:
char buffer[sizeof(t)>sizeof(int)? sizeof(t): sizeof(int)];
我們不能用乙個
if語句替換這個運算:
int i;
if(sizeof(t)>sizeof(int))i=sizeof(t);
else i=sizeof(int);
char buffer[i];//
語法錯誤!
原因在於陣列宣告中的下標必須是乙個編譯期常量,而不是乙個執行期的值,條件表示式的運算可以在編譯期進行,
if語句就只能在執行期執行。
C 學習 二 條件運算子
在c語言中,條件運算子有如下形式 e a b?c d 執行該語句,當a b成立時,將c賦值給e,當a b不成立時,將d賦值給e。所以c語言中條件運算子也叫三目雲演算法,將它作為乙個整體,它只能是作為右值,賦值給其它變數的。c 對其作了增強版。當條件運算子中?後面的兩個條件都是左值時候,條件運算子可以...
範仁義js課程 24 條件運算子
條件運算子的基本結構是 表示式?語句1 語句2 表示如果表示式的值為true,執行語句1,否則執行語句2,相當於if else結構的縮寫,例如a b alert a大 alert b大 var max a b a b 1 doctype html 2 html lang en 3 head 4 me...
第四章 4 7 條件運算子
4.21 編寫一段程式,使用條件運算子從vector int 中找到哪些元素的值是奇數,然後將這些奇數的值翻倍。0 ifelse更容易理解,條件運算子更簡潔。4.23修改語句 string s word string p1 s s s.size 1 s s err 優先順序高於 string p1 ...