C++ 基础与深度分析 Chapter5 语句(语句基础、分支、循环语句、达夫设备)


在这里插入图片描述

语句基础

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
复合语句不需要加分号了。复合语句通过}告诉编译器,语句结束。复合语句会形成一个独立的域,称为:语句域。域的概念,我们在域中可以定义变量,防止名称冲突。域是变量的定义与销毁。

分号的作用,是标识语句的结束。所以只要加分号,编译器才知道语句结束了。多个语句也可以放在同一行。

在这里插入图片描述

int main()
{
    int x = 1;
    {
        int x = 2;
        x += 1;
        cout << x << endl; // 3 x在语句块内,是x=2的初始化
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int main()
{
    int x = 1;
    if (x) goto label;
    ++x;
label:
    return 0;
}

在这里插入图片描述

分支语句

if语句

在这里插入图片描述
在这里插入图片描述

int main()
{
    int x = 3;
    if (x > 2)
        cout << "x > 2" << endl;
}
int main()
{
    int x = 1;
    if (x > 2)
        cout << "x > 2" << endl;
    else
        cout << "x <= 2" << endl;
}

引用更复杂的逻辑,必须引用语句块实现

int main()
{
    int x = 3;
    if (x > 2)
    {
        int y = 3 * x;
        cout << "y = " << y << endl;
    }
    else
    {
        cout << "x <= 2" << endl;  
    }

在这里插入图片描述
在这里插入图片描述
为了避免上述错误,使用大括号。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Switch 语句

在这里插入图片描述
在这里插入图片描述

int main()
{
    int x = 1;
    cin >> x;
    switch (x)
    {
    case 1:
        cout << "Hello world !" << endl;
    }
}
int main()
{
    int x = 1;
    
    switch (cin >> x; x) // c++17
    {
    case 1:
        cout << "Hello world !" << endl;
    }
}
int main()
{
    int x = 1;
    
    switch (cin >> x; x) // c++17
    {
    case 1:
    {
        int y = 4;
        cout << "Hello world !" << endl;
    }
    // 如果输入1,后面的也会打印,因为case是执行后续的代码,所以必须用break;
    case 2:
        cout << "Jammy !" << endl;
        cout << "I love you !" << endl;
    
    }
}
int main()
{
    int x = 1;
    
    switch (cin >> x; x) // c++17
    {
    case 1:
    {
        int y = 4;
        cout << "Hello world !" << endl;
        break;
    }
    case 2:
        cout << "Jammy !" << endl;
        cout << "I love you !" << endl;
        break;
    }
}
int main()
{
    int x = 1;
    
    switch (cin >> x; x) // c++17
    {
    case 1:
        cout << "Hello world !" << endl;
        break;
    case 2:
        cout << "Jammy !" << endl;
        cout << "I love you !" << endl;
        break;
    default: // 缺省情况下的逻辑
        cout << "China" << endl;
    }
}

default一般放在最后一个分支,这样可以不写break。如果default放在最前面,还要在default中加一个break。
写switch,case后面都要加break。

int main()
{
    int x = 1;
    
    switch (cin >> x; x) // c++17
    {
    case 1:
        cout << "Hello world !" << endl;
        break;
    case 2:
        {
            int y = 4; // case中定义变量,要加大括号
            cout << "Jammy !" << endl;
            cout << "I love you !" << endl;
            break;
        }
    default: // 缺省情况下的逻辑
        cout << "China" << endl;
    }
}

case中定义变量,要加大括号.

int main()
{
    int x = 1;
    
    switch (cin >> x; x)
    {
    case 1:
        cout << "Hello world !" << endl;
        break;
    case 2: // 输入2或者3,都执行下面的代码
    case 3:
        cout << "Jammy !" << endl;
        cout << "I love you !" << endl;
        break;
    }
}
int main()
{
    int x = 1;
    
    switch (cin >> x; x)
    {
    case 1:
        cout << "Hello world !" << endl;
        [[fallthrough]]; // fallthrough 执行完这个,跳到下一个标签
    case 2:
        cout << "Jammy !" << endl;
        cout << "I love you !" << endl;
        break;
    }
}

c++17 [[fallthrough]]; 执行完这个,跳到下一个标签

所有switch都可以用if写出来。

循环语句

while

在这里插入图片描述

int main()
{
    int x = 3;
    while (x)
    {
        cout << x << endl; // 3 2 1
        --x;
    }
}

while 和 do-while 不包含额外的初始化,如果要包含额外的初始化,用for循环即可。
在这里插入图片描述

int main()
{
    int x = 3;
    do
    { 
        cout << x << endl; // 3 2 1 不论条件是否满足,都先执行一次循环体
        --x;
    }while (x);
}
int main()
{
    int x = 0;
    do
    { 
        cout << x << endl;
        --x;
    }while (x > 0);
}
int main()
{
    int x = 0;
    while (x > 0)
    { 
        cout << x << endl; // 没有执行 不像 do while 执行了一次
        --x;
    }
}

在这里插入图片描述
在这里插入图片描述

for循环

在这里插入图片描述
在这里插入图片描述

int main()
{
    for (int x = 0; x < 5; ++x)
    {
        cout << x << endl; // 0 1 2 3 4
    }
}

在这里插入图片描述
在这里插入图片描述
for循环括号里的3个语句,都可以为空。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int main()
{
    std::vector<int> arr = {1, 2, 3, 4, 5};
    for (int v : arr)
    {
        cout << v << endl; // 1 2 3 4 5
    }
}

在这里插入图片描述
C++17以前
在这里插入图片描述
C++17
在这里插入图片描述
C++2a
在这里插入图片描述

int main()
{
    std::vector<std::string> arr = {"h", "e", "l"};
    for (const std::string& v : arr) // 如果不修改arr的值,用常量引用,增加效率
    {
        cout << v << endl; // h e l
    }
}
int main()
{
    std::vector<std::string> arr = {"h", "e", "l"};
    for (const auto& v : arr) // auto也是可以的
    {
        cout << v << endl; // h e l
    }
}

int main()
{
    std::vector<int> arr = {1, 2, 3};
    for (auto& v : arr) 
    {
        v = v + 1;
    }
    for (const auto& v : arr) 
    {
        cout << v << endl; // 2 3 4 说明上面对v的操作成功了
    }
}
int main()
{
    std::vector<int> arr = {1, 2, 3};
    for (auto&& v : arr)  // auto&& 是万能引用,如果要修改arr的话,推荐万能引用
    {
        v = v + 1;
    }
    for (const auto& v : arr) 
    {
        cout << v << endl; // 2 3 4 说明上面对v的操作成功了
    }
}

break 和 continue

在这里插入图片描述
while example
在这里插入图片描述
continue example
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

语句的综合应用——达夫设备

下面是达夫设备的演化代码:

int main()
{
    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];
    for (size_t i = 0; i < buffer_count; ++i)
    {
        max_value = (max_value < buffer[i]) ? buffer[i] : max_value; 
    }
    cout << max_value << endl; // 9999
}

我们让循环体内的程序多一些,这些程序计算不太耗时,让循环的步骤少一些。增加了循环体处理的工作量,减少了for的条件和表达式的工作量。


int main()
{
    constexpr size_t buffer_count = 10001;
    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];

    // 0-7 8-15 ... 9992-9999
    for (size_t i = 0; i < buffer_count; i += 8)
    {
        max_value = (max_value > buffer[i]) ? max_value : buffer[i];
        max_value = (max_value > buffer[i + 1]) ? max_value : buffer[i + 1];
        max_value = (max_value > buffer[i + 2]) ? max_value : buffer[i + 2];
        max_value = (max_value > buffer[i + 3]) ? max_value : buffer[i + 3];
        max_value = (max_value > buffer[i + 4]) ? max_value : buffer[i + 4];
        max_value = (max_value > buffer[i + 5]) ? max_value : buffer[i + 5];
        max_value = (max_value > buffer[i + 6]) ? max_value : buffer[i + 6];
        max_value = (max_value > buffer[i + 7]) ? max_value : buffer[i + 7];
    }
    cout << max_value << endl; // 如果改成10001,那么有7个数是超出范围的,那么会到一个不知道的内存去取值
}

写一个for循环来处理多出来的部分 10001 / 8 * 8 -> 1250 * 8 = 10000
初始值 i = 10000 这里buffer_count = 10001


int main()
{
    constexpr size_t buffer_count = 10001;
    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];

    // 0-7 8-15 ... 9992-9999
    for (size_t i = 0; i + 8 < buffer_count; i += 8)
    {
        max_value = (max_value > buffer[i]) ? max_value : buffer[i];
        max_value = (max_value > buffer[i + 1]) ? max_value : buffer[i + 1];
        max_value = (max_value > buffer[i + 2]) ? max_value : buffer[i + 2];
        max_value = (max_value > buffer[i + 3]) ? max_value : buffer[i + 3];
        max_value = (max_value > buffer[i + 4]) ? max_value : buffer[i + 4];
        max_value = (max_value > buffer[i + 5]) ? max_value : buffer[i + 5];
        max_value = (max_value > buffer[i + 6]) ? max_value : buffer[i + 6];
        max_value = (max_value > buffer[i + 7]) ? max_value : buffer[i + 7];
    }

    // 写一个for循环来处理多出来的部分 10001 / 8 * 8 -> 1250 * 8 = 10000
    // 初始值 i = 10000 这里buffer_count = 10001
    for (size_t i = (buffer_count / 8 * 8); i < buffer_count; ++i)
    {
        max_value = (max_value > buffer[i]) ? max_value : buffer[i];
    }

    cout << max_value << endl; // 10000, 程序处理了多出的余数部分
}

引入switch


int main()
{
    constexpr size_t buffer_count = 10001;
    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();

    // 0-7 8-15 ... 9992-9999
    for (size_t i = 0; i + 8 < buffer_count; i += 8)
    {
        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;
    }

    // 引用switch
    switch (buffer_count % 8)
    {
        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;
    }
    cout << max_value << endl; // 10000, 程序处理了多出的余数部分
}

先让数组处理前面的,后面处理8的整数倍。


int main()
{
    constexpr size_t buffer_count = 10001;
    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
    switch (buffer_count % 8)
    {
        // case 0 就是8的倍数,从8次先,剩下的数还是8的倍数,case0必须放在最前面
        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;
    }

    // 31 -> (31 - 1) / 8 = 3 循环了3次,24个。前面7个swich处理了
    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;
    }
    cout << max_value << endl; // 10000
}

将下面的for循环,写到上面switch里面


int main()
{
    constexpr size_t buffer_count = 10001;
    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)
        // 这里+7是算出来的。原来-1,+8 -> +7
        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;
        }
    cout << max_value << endl; // 10000
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值