C Tricks 1 1 條件運算子

2021-04-13 09:29:04 字數 3162 閱讀 9248

條件運算子

(?:)

是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 ...