第六章語句

語句基礎(chǔ)

  • 語句的常見類別

    • 表達(dá)式語句:表達(dá)式后加分號(hào)朴读,對(duì)表達(dá)式求值后丟棄瀑晒,可能產(chǎn)生副作用

    • 空語句:僅包含一個(gè)分號(hào)的語句清蚀,可能與循環(huán)一起工作

    • 復(fù)合語句(語句體):由大括號(hào)組成泡孩,無需在結(jié)尾加分號(hào)赚瘦,形成獨(dú)立的域(語句域)

      ——>更好的控制對(duì)象的生命周期

    int main()
    {
        // 注意下面實(shí)際上是兩條語句:復(fù)合語句和空語句
        {cc  
            // ...
        };
    }
    
  • 順序語句與非順序語句

    • 順序語句
      • 從語義上安裝先后順序執(zhí)行
      • 實(shí)際的執(zhí)行順序可能產(chǎn)生變化(編譯器優(yōu)化粟誓、硬件亂序執(zhí)行)
      • 與硬件流水線緊密結(jié)合,執(zhí)行效率較高
    • 非順序執(zhí)行
      • 在執(zhí)行過程中引入跳轉(zhuǎn)起意,從而產(chǎn)生復(fù)雜的變化
      • 分支預(yù)測錯(cuò)誤可能導(dǎo)致執(zhí)行性能降低
  • 最基本的非順序語句:goto

    #include <iostream>
    int main()
    {
        int x = 3;
        if (x) goto label;
        x = x + 1;
    label:
        return 0;
    }
    
    • 通過標(biāo)簽指定跳轉(zhuǎn)到的位置
    • 具有若干限制
      • 不能跨函數(shù)跳轉(zhuǎn)
      • 向前跳轉(zhuǎn)時(shí)不能越過對(duì)象初始化語句
    • 向后跳轉(zhuǎn)可能會(huì)導(dǎo)致對(duì)象銷毀與重新初始化
  • goto本質(zhì)上對(duì)應(yīng)了匯編語言中的跳轉(zhuǎn)指令

    • 缺乏結(jié)構(gòu)性的含義
    • 容易造成邏輯混亂
    • 除特殊情況外鹰服,應(yīng)避免使用

分支語句

if

  • 語法:https://zh.cppreference.com/w/cpp/language/if

  • 使用語句塊表示復(fù)雜的分支邏輯

  • ifif-else

    • 實(shí)現(xiàn)多重分支
    • else會(huì)與最近的if匹配
    • 使用大括號(hào)改變匹配規(guī)則
// 一個(gè)不合原意的應(yīng)用
// grade > 80 --> Excellent
// grade <= 60 --> Bad

int grade = 65;
if (grade > 60)
    if (grade > 80)
        std::cout << "Excellent\n";
else
    std::cout << "Bad\n";
  • if V.S. constexpr if —— 運(yùn)行期與編譯器分支
constexpr int grade = 80;
if constexpr (grade < 60)
{
    //...
}
  • 帶初始化的if
int x = 3;
// y的作用域?yàn)閕f-else語句范圍內(nèi)
if (int y = x * 3; y > 100)
{
    std::cout << y << '\n';
}
else
{
    std::cout << -y << '\n';
}

switch

  • 語法:https://zh.cppreference.com/w/cpp/language/switch
  • 條件部分應(yīng)當(dāng)能夠隱式轉(zhuǎn)換為整型或枚舉類型,可以包含初始化的語句
  • case/default標(biāo)簽
    • case后面跟常量表達(dá)式(即在編譯期可以求值的式子)揽咕,用于匹配switch中的條件悲酷,匹配時(shí)執(zhí)行后續(xù)的代碼
    • 可以使用break跳出當(dāng)前的switch執(zhí)行
    • default用于定義缺省情況下的邏輯
    • case/default中定義對(duì)象要加大括號(hào)
int x;
switch (std::cin >> x; x)
{
    case 3:
        std::cout << "Hello\n";  // fall through
    case 4:
        std::cout << "World\n";
}
  • [[fallthrough]]屬性
int x;
switch (std::cin >> x; x)
{
    case 3:
        std::cout << "Hello\n";
        [[fallthrough]];
    case 4:
        std::cout << "World\n";
}
  • if相比的優(yōu)劣
    • 分支描述能力較弱
    • 在一些情況下能引入更好的優(yōu)化

循環(huán)語句

while

  • 語法:https://zh.cppreference.com/w/cpp/language/while
  • 處理邏輯:
    1. 判斷條件是否滿足,如果不滿足則跳出循環(huán)
    2. 如果條件滿足則執(zhí)行循環(huán)體
    3. 執(zhí)行完循環(huán)體后轉(zhuǎn)向步驟1
  • 注意:在while的條件部分不包含額外的初始化內(nèi)容

do-while

  • 語法:https://zh.cppreference.com/w/cpp/language/do
    • 注意結(jié)尾處要有分號(hào)亲善,表示一條語句的結(jié)束
  • 處理邏輯:
    1. 執(zhí)行循環(huán)體
    2. 斷條件是否滿足设易,如果不滿足則跳出循環(huán)
    3. 如果條件滿足則轉(zhuǎn)向步驟1
  • 注:do-while中條件處不支持帶花括號(hào)或等號(hào)初始化器的單個(gè)變量的聲明。
// 錯(cuò)誤的語句
do
{
    // ...
} while (int x = 0);

for

  • 語法:https://zh.cppreference.com/w/cpp/language/for

  • 處理邏輯:

    1. 初始化語句會(huì)被首先執(zhí)行
    2. 條件部分會(huì)被執(zhí)行蛹头,執(zhí)行結(jié)果如果為false顿肺,則終止循環(huán)
    3. 否則執(zhí)行循環(huán)體
    4. 迭代表達(dá)式會(huì)被求值,之后轉(zhuǎn)向2
  • 在初始化語句中聲明多個(gè)名字

for (int i = 0, *p = &i; i < 9; i += 2)
{
    std::cout << i << ' : ' << *p << ' ';
}
std::cout << '\n';
  • 初始化語句渣蜗、條件屠尊、迭代表達(dá)式可以為空
    • 條件若為空語句則系統(tǒng)默認(rèn)為TRUE
  • for的更多示例

基于范圍的for循環(huán)

  • 語法:https://zh.cppreference.com/w/cpp/language/range-for
  • 本質(zhì):語法糖,編譯器會(huì)轉(zhuǎn)換為for循環(huán)的調(diào)用方式
  • 轉(zhuǎn)換形式的衍化:C++11/C++17/C++20
  • 使用常量左值引用讀元素袍睡;使用“萬能引用(universal reference)-> auto &&”修改元素
{
    // C++17標(biāo)準(zhǔn)
    auto && __range = 范圍表達(dá)式;
    for (auto __begin = 首表達(dá)式, __end = 尾表達(dá)式; __begin != __end; ++__begin)
    {
        范圍聲明 = *__begin;
        // 循環(huán)語句...
    }
}
std::vector<std::string> arr{"h", "e", "l"};
for (const std::string & v : arr)
    std::cout << v << '\n';

break/continue

  • 含義(轉(zhuǎn)自cpp reference)
    • break:導(dǎo)致外圍的for知染、范圍forwhiledo-while循環(huán)或switch語句終止
    • continue:用于跳過整個(gè)for斑胜、whiledo-while循環(huán)體的剩余部分
  • 注意這二者均不能用于多重嵌套循環(huán)控淡,多重嵌套循環(huán)的跳轉(zhuǎn)可以考慮goto語句

語句的綜合應(yīng)用——達(dá)夫設(shè)備

  • 使用循環(huán)展開提升系統(tǒng)性能
  • 處理無法整除的情形
    • 額外增加一個(gè)循環(huán)語句 ——> 循環(huán)展開
    • 將switch與循環(huán)結(jié)合——達(dá)夫設(shè)備
#include <iostream>
#include <vector>

int main (void)
{
    constexpr size_t buffer_count = 10000;
    std::vector<size_t> buffer(buffer_count);
    for (size_t i = 0; i < buffer_count; ++i)
    {
        buffer[i] = i;
    }

    size_t max_value = buffer[0];
    auto ptr = buffer.begin();
    switch (buffer_count % 8)
    {
        case 0 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 7 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 6 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 5 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 4 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 3 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 2 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr; [[fallthrough]];
        case 1 : max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
    };

    for (size_t i = 0; i < (buffer_count - 1) / 8; ++i)
    {
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
        max_value = (max_value > *ptr) ? max_value : *ptr; ++ptr;
    }

    for (size_t i = buffer_count / 8 * 8; i < buffer_count; ++i)
    {
        max_value = (max_value > buffer[i])       ? max_value : buffer[i]      ;
    }
    std::cout << max_value << '\n';
}
#include <iostream>
#include <vector>

int main (void)
{
    constexpr size_t buffer_count = 10000;
    std::vector<size_t> buffer(buffer_count);
    for (size_t i = 0; i < buffer_count; ++i)
    {
        buffer[i] = i;
    }

    size_t max_value = buffer[0];
    auto ptr = buffer.begin();

    size_t i = 0;
    switch (buffer_count % 8) {
        for (; i < (buffer_count + 7) / 8; ++i) {
            case 0 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 7 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 6 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 5 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 4 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 3 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 2 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr; [[fallthrough]];
            case 1 :
                max_value = (max_value > *ptr) ? max_value : *ptr;
            ++ptr;
        }
    }

    std::cout << max_value << '\n';
}
```cc
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市止潘,隨后出現(xiàn)的幾起案子掺炭,更是在濱河造成了極大的恐慌,老刑警劉巖凭戴,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涧狮,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)者冤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門肤视,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涉枫,你說我怎么就攤上這事邢滑。” “怎么了愿汰?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵困后,是天一觀的道長。 經(jīng)常有香客問我衬廷,道長摇予,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任吗跋,我火速辦了婚禮侧戴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘小腊。我一直安慰自己救鲤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布秩冈。 她就那樣靜靜地躺著本缠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪入问。 梳的紋絲不亂的頭發(fā)上丹锹,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音芬失,去河邊找鬼楣黍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛棱烂,可吹牛的內(nèi)容都是我干的租漂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼颊糜,長吁一口氣:“原來是場噩夢啊……” “哼哩治!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衬鱼,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤业筏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后鸟赫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒜胖,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡消别,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了台谢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寻狂。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖朋沮,靈堂內(nèi)的尸體忽然破棺而出荆虱,到底是詐尸還是另有隱情,我是刑警寧澤朽们,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站诉位,受9級(jí)特大地震影響骑脱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苍糠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一叁丧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岳瞭,春花似錦拥娄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姚炕,卻和暖如春摊欠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柱宦。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工些椒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掸刊。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓免糕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親忧侧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子石窑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Basic 語句通常是順序執(zhí)行的,而 控制流 flow-of-control 可以支持更復(fù)雜的執(zhí)行路徑苍柏。 簡單語句...
    Kreat閱讀 466評(píng)論 0 0
  • 一尼斧、順序結(jié)構(gòu) Java的基本結(jié)構(gòu)就是順序結(jié)構(gòu),就是從頭到尾一句一句執(zhí)行的试吁,不用多說棺棵。 二楼咳、選擇結(jié)構(gòu) 1. 單分支結(jié)...
    碼匠_CodeArtist閱讀 330評(píng)論 0 0
  • Bookmarks 書簽欄 入職 華為新員工小百科(刷新時(shí)間202003023) - 人才供應(yīng)知多少 - 3MS知...
    Btrace閱讀 1,339評(píng)論 0 0
  • 流程控制 1. 分類 順序結(jié)構(gòu):自上而下順序執(zhí)行; 分支結(jié)構(gòu):滿足一定條件執(zhí)行烛恤,否則不執(zhí)行母怜; 循環(huán)結(jié)構(gòu):滿足一定條...
    eleven_Chen閱讀 233評(píng)論 0 1
  • 第06章 CG 表達(dá)式與控制語句 讀書之法,在循序而漸進(jìn)缚柏,熟讀而精思苹熏。------ 朱熹 在上一章中,我們已經(jīng)介...
    成都小蘿卜閱讀 512評(píng)論 0 2