C 控制流 之 條件判斷

我恍然覺得,我低估了C語言中的知識(shí)量。想要用一篇文章解決控制流部分,文章就會(huì)變得很長,內(nèi)容也顯得很雜亂了。為了保證文章的條理清晰,我把控制流分解成了兩篇:上篇介紹條件判斷,下篇介紹循環(huán)。

那么就讓我們開始吧!

什么是控制流

上回中,C語言里最基本的元素——變量閃亮登場(chǎng)。通過使用運(yùn)算符,我們進(jìn)行了簡單的數(shù)學(xué)運(yùn)算。接下來,為了使它能夠完成更復(fù)雜的任務(wù),我們要用到控制流。

什么是控制流?簡單地說,控制流就是對(duì)程序運(yùn)行流程的控制,它決定了什么時(shí)候程序會(huì)執(zhí)行什么功能。在生活中,我們總是著面臨多種可能性,例如,明天可能會(huì)下雨,也可能不下雨。如果不下雨,你需要給樹苗澆水,但如果下雨就不澆了。想讓程序能和人類一樣處理多種情況,就需要控制流中的條件判斷功能。

有些時(shí)候,你需要重復(fù)地做一些事情,一直到任務(wù)完成為止。例如你要吹個(gè)氣球,在吹起來之前要重復(fù)吹氣這個(gè)動(dòng)作。吹的不夠,氣球就癟癟的,吹太多,氣球就會(huì)爆炸,因此你需要在合適的時(shí)機(jī)停止。在計(jì)算機(jī)的工作中也有很多這樣的任務(wù),這需要循環(huán)語句來控制。

就像開頭說的,為了讓文章比較好讀,我就專注于介紹條件判斷了。

bool類型與邏輯運(yùn)算符

在介紹條件判斷的語句之前,我們需要了解一些基礎(chǔ)知識(shí):bool類型與邏輯運(yùn)算符。

程序在不同的情況下采取不同的行為,我們可以理解為有一個(gè)開關(guān)控制著它。如果開關(guān)打開,它會(huì)做出A行為,如果開關(guān)關(guān)上了,他就會(huì)做出B行為。bool類型(譯作布爾類型)就是用于描述開關(guān)狀態(tài)的一種變量,它只有兩個(gè)取值,true和false,對(duì)應(yīng)于開關(guān)的打開和關(guān)上。定義和使用bool類型的方法與其他類型相同:

bool isSunny = true; //定義了一個(gè)bool變量,初始化為true
isSunny = false;     //下雨了,把它賦值為false,-v-

作用于bool類型的運(yùn)算符稱為邏輯運(yùn)算符,正因?yàn)檫@個(gè)類型與程序的運(yùn)行邏輯息息相關(guān)。邏輯運(yùn)算符包括 ||、&&和!。

先把代碼列出來,結(jié)合代碼來看這些運(yùn)算符的功能:

bool isMale = true;
bool isChild = false;
bool isHuman = isMale || isChild;
bool isBoy = isMale && isChld;
bool isFemale = !isMale;

|| 被稱為“邏輯或”,代表了“或者”的功能,它的定義是這樣的:如果isMale和isChild中有至少一個(gè)是true,那么isHuman將是true;只有當(dāng)兩者都是false時(shí),isHuman才是false。這里的例子是,如果一個(gè)人是男人,或者是個(gè)孩子,他就滿足了是人類的條件(當(dāng)然這是充分條件,但是不是必要條件)。

&& 被稱為“邏輯與”,代表了“并且”的功能,同樣看上面的幾行代碼。只有isMale和isChild同時(shí)是true,isBoy才會(huì)是true;如果兩者中至少有一個(gè)是false,那么isBoy就是false。解釋就是,只有一個(gè)人同時(shí)是男性且是孩子時(shí),他才是一個(gè)男孩。

! 被稱為“邏輯非”,代表了“非”的功能。它只作用在單個(gè)操作數(shù)上,對(duì)true的運(yùn)算結(jié)果是false,對(duì)false的運(yùn)算結(jié)果是true。所以一個(gè)人如果不是男性,那么他就是女性。(啊不過,現(xiàn)實(shí)中是存在很多跨性別的人的,所以這里只是舉個(gè)例子而已,不要太認(rèn)真。)

這里還需要解釋的一個(gè)概念是運(yùn)算的優(yōu)先級(jí)。在C語言中,會(huì)有這樣的問題:

int c = 5 * 10 + 6;

與現(xiàn)實(shí)中的數(shù)學(xué)算式一樣,乘法的優(yōu)先級(jí)會(huì)大于加法。為了讓加法先算,我們必須添加括號(hào):

int c = 5 * (10 + 6);

對(duì)于邏輯運(yùn)算符,它們的優(yōu)先關(guān)系是這樣的:

邏輯非 > 邏輯與 > 邏輯或

bool isGirl = !isMale && isChild; //先判定!,再判定&&
bool isFood = isBread || isMeat && isCooked; //先判定&&,再判定||

對(duì)于isGirl,只有isMale為false,isChild為true時(shí),結(jié)果才是true。
對(duì)于isFood,不論isMeat和isCooked是什么值,只要isBread為true,結(jié)果就是true。

雖然優(yōu)先關(guān)系不難理解,但是為了看著舒服,加些括號(hào)也是可以的。例如:

bool isGirl = (!isMale) && isChild; //先判定!,再判定&&
bool isFood = isBread || (isMeat && isCooked); //先判定&&,再判定||

但是如果括號(hào)加錯(cuò)了,結(jié)果就會(huì)變得很奇怪。

if 語句

這些bool變量和邏輯運(yùn)算符能夠如此正確地表達(dá)事情的邏輯關(guān)系,真是挺不可思議的一件事。關(guān)于這個(gè)話題,還有專門的一個(gè)學(xué)科,叫做“數(shù)理邏輯”,但因?yàn)槲乙矝]有學(xué)過,所以沒辦法介紹了。嗯,不管了,來看看這些東西怎么應(yīng)用在條件判斷中吧。

條件判斷的語句中,最常用的就是if 語句和switch 語句。先看代碼:

int a = 5;

if(a == 0)
    printf("a is zero.\n");
else
    printf("a is not zero.\n");

printf("Oh, I am hungry.\n");

這就是一個(gè)典型的if語句。

if 后面跟一個(gè)括號(hào),其中包含了一個(gè)表達(dá)式 a==0。== 是一個(gè)運(yùn)算符,判斷兩邊的值是否相等,結(jié)果是一個(gè)bool類型的值。如果是true,程序會(huì)選擇執(zhí)行下一行中,然后跳過else 的部分。但如果是false,程序就會(huì)選擇執(zhí)行else中的部分。如果不寫else的部分,程序就會(huì)在false的情況下什么都不做。

如果需要處理很多種情況,就需要請(qǐng)出else if 了。

int age = 50;

if(age < 18) // < 表示判斷是否小于,小于等于就用 <=
    printf("he is a teenager!");
else if(age > 50)  // > 表示判斷是否大于,大于等于就用 >=
    printf("he is old!");
else
    printf("he is neither young nor old");

這里只出現(xiàn)了一個(gè)else if,實(shí)際上可以加入任意數(shù)量的else if,以處理各種各樣的情況。要確保else if一定要在else之前出現(xiàn)。

條件表達(dá)式的一些瑣碎

括號(hào)中的表達(dá)式,也可以用變量或者數(shù)值代替。

bool isPig = true;
if(isPig){
    printf("It is a pig.\n");
    printf("只是為了加一句話。\n");
    printf("別忘了用花括號(hào)!\n");
}

這里使用bool變量作為判斷依據(jù)。其實(shí)也可以用整數(shù)類型的變量,0對(duì)應(yīng)于false,值不為0的情況則都會(huì)被視為true。

另一個(gè)注意事項(xiàng)是花括號(hào)的使用,如果if或者else后面跟了多行代碼,必須要用花括號(hào)包起來。如果不用花括號(hào)包起來,只有第一句會(huì)被當(dāng)做特定條件下才會(huì)執(zhí)行的語句,后面的代碼不再屬于if或者else。對(duì)于else if也是同理。

還有一點(diǎn)就是==是兩個(gè)等于號(hào)連在一起,如果只寫一個(gè)=,那就變成了賦值表達(dá)式。因?yàn)楹苤匾栽僬f一遍,在判斷相等的場(chǎng)合,一定要確保自己真的寫了“==”。

switch語句

為了處理多種情況,我們還可以使用switch語句,用法如下:

int a = 0;
switch(a){
case -1:
    printf("a is -1.\n");
    a += 7; //a = a + 7的簡寫
    break;
case 7:
    a -= 7; //a = a - 7 的簡寫
    break;
case 20000:
    printf(" a is 20000!\n");
    break;
default:
    printf("a default case.\n");
    break;
}

switch關(guān)鍵字后面的括號(hào)中應(yīng)包含一個(gè)變量,程序?qū)⒏鶕?jù)這個(gè)變量的值執(zhí)行不同的代碼。為了處理某一情況,例如a等于-1,就在switch語句的花括號(hào)中添加一個(gè)對(duì)應(yīng)的段落:

case -1: //case 需處理的數(shù)值:
    printf("a is -1.\n");
    a += 7; 
    break; //處理完畢,結(jié)束switch語句

程序會(huì)根據(jù)a的值尋找處理的代碼,如果每個(gè)case都沒遇到,就會(huì)執(zhí)行default中的代碼作為默認(rèn)的處理方式。default這一段也可以不寫,這樣在默認(rèn)的情況下,程序就會(huì)什么都不做。

break語句在這里非常重要,如果忘了寫,程序就會(huì)繼續(xù)執(zhí)行下一個(gè)case中的代碼,然后程序就亂了套了。

舉個(gè)例子,如果在case -1中忘了寫break,

...
case -1:
    printf("a is -1.\n");
    a += 7; 
    //忘了寫break!
case 7:
    a -= 7;
    break;
default:
...

如果a恰好等于1,執(zhí)行到了a加7,之后沒有跳出switch語句,接著就會(huì)執(zhí)行case 7中的printf語句。這肯定不是我們想要的結(jié)果。你可能要問了,那case 7:這一行到底是干嘛的?事實(shí)上,這一行只能被switch關(guān)鍵字用來定位,不能阻止程序從上一行運(yùn)行下來。

switch語句的功能其實(shí)if也能做到,之所以存在這么一種寫法,基本上是為了使程序更整齊、容易閱讀。雖然對(duì)于計(jì)算機(jī)來說沒什么分別,但是程序終究還是人類使用的語言,保證代碼的易讀性,能大大降低我們維護(hù)代碼的難度。

小結(jié)

現(xiàn)在程序能根據(jù)不同情況選擇不同的行為了。循環(huán)是在此基礎(chǔ)上自然形成的另一種功能,它將機(jī)器強(qiáng)大的能力展露無遺。下一篇我們將認(rèn)識(shí)這一功能,讓計(jì)算機(jī)強(qiáng)大的力量開始為自己所用。

那么,就先寫到這里吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • FreeCodeCamp - Basic JavaScript 寫在前面: 我曾經(jīng)在進(jìn)谷前刷過這一套題,不過當(dāng)時(shí)只...
    付林恒閱讀 16,577評(píng)論 5 28
  • 作者 謝恩銘,公眾號(hào)「程序員聯(lián)盟」(微信號(hào):coderhub)。轉(zhuǎn)載請(qǐng)注明出處。原文:https://www.ji...
    程序員聯(lián)盟閱讀 3,462評(píng)論 3 29
  • 基礎(chǔ) .NET概述 參考:http://www.cnblogs.com/yplong/p/3279934.html...
    donite閱讀 1,730評(píng)論 0 8
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,544評(píng)論 19 139
  • 非暴力溝通的第一個(gè)要素是觀察。 我們仔細(xì)觀察正在發(fā)生的事情,并清楚地說出觀察結(jié)果。非暴力溝通只是強(qiáng)調(diào)區(qū)分觀察和評(píng)論...
    陳果1225閱讀 454評(píng)論 1 0

友情鏈接更多精彩內(nèi)容