语句

语句根底

常见类别

表达式语句:表达式后加分号

表达式求值,后抛弃

可能产生副作用

    2 + 3; //表达式;    int x;    x = 3;  //表达式求值,返回值x后抛弃            //副作用:x值的扭转

空语句:仅蕴含一个分号的语句

    罕用在循环体    

复合语句(语句体):{ ......} 结尾无分号

{    int x = 3;    x+=1;    std::cout << x << "\n";}    //一条复合语句    //造成独立的域(语句域)    //域中可定义长期变量,准确管制生命周期    {    ...};//两条语句 ;为空语句
int x = 2;{    int x = 3;    x++;}

程序语句与非程序语句

程序语句

语义上依照先后顺序执行理论的执行程序可能产生变动,编译器优化/硬件乱序执行等与硬件流水线紧密结合,执行效率较高

非程序语句

在执行过程中引入跳转,产生简单变动**分支预测**晋升性能,预测谬误可能导致执行性能升高会限度编译器优化

goto

通过标签指定跳转地位限度:    不能跨函数跳转    向前(下)跳转时,不能越过初始化语句向后跳转可能导致对象的销毁与从新初始化goto实质对应汇编中的跳转指令    不足结构性的含意    容易造成逻辑凌乱    防止应用
int main(){    int x = 1;    if(x) goto label;    x++;label:    return 0'}

分支语句

非程序语句分为分支语句与循环语句

if 与 switch

if

if (){ } else { } 双分支if (){ } else { if (){ } else{ } }多分支if (){ } else   if (){ } else{ }  省去大括号 等价

else会与最近的if进行匹配

int grade = 65;if (grade > 60)    if(grade >80)        std::cout << "Excellent\n";else                            //缩进有效,与第二个if匹配    std::cout <<"Bad\n";

应用大括号明确 防止匹配谬误,

constexpr if
c++17 开始可退出 constexpr
编译期优化

constexpr int grade = 59;if constexpr(grade <60){    std:cout <<"fail \n";}else{    std::cout <<"pass\n";    if constexpr (grade == 100)    {        std::cout << "excellent \n";    }    else    {        std::cout << "not bad \n";    }}

带初始化语句的if (c++17)

int x = 3;if(int y = x*3; y>100)    //y作用域到else完结{    //......}else{    //......}

switch

条件:任何整型或枚举类型,或可按语境隐式转换到整型或枚举类型的表达式语句:任何语句。 case: default: break;

case/default 标签

case:跟常量表达式,匹配switch中条件,匹配执行后续break: 防止fall through    -Wimplicit-fallthrough 产生编译正告default: 地位任意,放前边留神加break
int x ;switch(std::cin >> x; x)//可选初始化 (c++17){    case 2+1:        std::cout<<"3\n";        break;}

case/default 定义对象必须加{}

case 1:{    int x = 1;        break;}

共享逻辑

switch(std::cin >> x; x){    case 4:    case 5:        //expression        break;}

[[falthrough]]属性 (c++17)

switch (x){    case 1:        //......        [[fallthrough]];//表明的确不须要break;    case 2:        //......        break;}

switch与if比照

switch能做的if都能够,反之不肯定switch肯定水平上可在通过跳转进行优化,运行期效率比if更高

循环语句

对一系列语句重复执行

while/do while

条件:任何能按语境转换为bool的表达式,     或带花括号或等号初始化器的单个变量的申明语句:任何语句,它是循环体
while(int x = 3)//等号初始化器,返回3                //每次循环都会初始化{    std::cout << x << std::endl;    --x;}

不蕴含额定的初始化内容(for循环蕴含初始化,不会反复初始化)

do while

条件:不能带花括号或等号初始化表达式(do未初始化)结尾加分号

for

正式语法:
attr(可选) for( 初始化语句 条件(可选);迭代表达式(可选))语句
非正式语法:
attr(可选) for(申明或表达式(可选); 申明或表达式(可选);表达式(可选))语句

初始化语句:     一条表达式语句(可为空 ;)            一条简略申明,通常为带初始化器的循环计数变量的申明,能够任意多个变量条件:          可按语境转换到bool的表达式。每次循环 之前 反复求值迭代表达式:    任何表达式。每次循环 之后 反复求值,通常为循环计数器表达式语句:          任何语句。作为循环体
for(int i = 0, *p = &i;i < 9; i+=2)    //能够申明多个名字                                    //只有它们能用领有雷同的申明说明符序列                                    //根底类型不能扭转{    std::cout <<i <<":"<<*p << " ";}//不倡议,会引入歧义int* p,q;//p为int* q为intfor(int x = 0,double y = 0.1; ;)//error {}for( ; ; )    //均可为空            //条件为空,主动判true//=======================================================            char cstr[] = "Hello";        for(int n = 0; char c = cstr[n]; ++n)//遍历完cstr后'\0'返回0{    std::cout << c;}std::cout << "\n";//=======================================================    std::vector<int> v = {3,1,4,1,5,9};for(auto iter = v.begin();iter != v.end();++iter){}//=======================================================    //非典型应用int n = 0;for(std::cout << "循环开始\n";    std::cout << "循环测试\n";                //输入失常返回true    std::cout << "迭代" << ++n << '\n')    if(n>1)        break;/*        循环开始    循环测试    迭代1    循环测试    迭代2    循环测试*/

基于范畴的for循环(range for loop)

C++11/17/20
语法: 属性(可选) for(范畴申明:范畴表达式)循环语句

  属性(可选) for(初始化语句(可选)范畴申明:范畴表达式)循环语句  --c++20    

实质: 语法糖,编译器转换为for循环模式

int main(){    std::vector<int> arr{1,2,3,4,5};    for(int v : arr)        std::cout << v << '\n';}

range for 不同版本转换/解释

{    auto && __range = range-expression ;//范畴表达式    for (auto __begin = begin_expr, __end = end_expr;//首表达式,尾表达式         __begin != __end; ++__begin) {        range-declaration = *__begin;//范畴申明        loop-statement                //循环语句    }}(until C++17)//================================================================={    //首表达式,尾表达式可能返回不同类型,c++17通过离开申明解决    auto && __range = range-expression ;    auto __begin = begin_expr ;    auto __end = end_expr ;    for ( ; __begin != __end; ++__begin) {        range-declaration = *__begin;        loop-statement    }}(since C++17)(until C++20)//================================================================={   //c++20引入初始化语句,解决长期范畴表达式问题    init-statement    auto && __range = range-expression ;    auto __begin = begin_expr ;    auto __end = end_expr ;    for ( ; __begin != __end; ++__begin) {        range-declaration = *__begin;        loop-statement    }}(since C++20)//=================================================================//长期范畴表达式for(auto& x : foo().items()){ /*......*/}//行为可能不确定//若foo返回右值,可能被销毁,x援用绑定生效,循环产生未定义的行为//c++20引入初始化语句解决for(T thing = foo();auto& x : thing.items()){/*......*/}//foo()产生的右值被保留到thing中,thing生命周期到循环完结

应用常量左值援用读元素
应用“万能援用(universal reference)”批改元素

std::vector<std::string> arr{"h","e","l","l","o"};for (const std::string& v : arr)//应用常量左值援用,防止从新结构string,更高效                                //const auto& v : arr    std::cout << v << '\n';    std::vector<bool> arr1{true,false,true};for(auto& v : arr1) {}    //error bool迭代器解援用不是boolfor(auto&& v : arr1) {}    //万能援用 

break/continue

break:continue:
for (int j = 0; j < 2; j++) {    for (int k = 0; k < 5; k++) {         // break 只会影响此循环        if (k == 2) break;        std::cout << j << k << " ";    }}//00 01 10 11for (int i = 0; i < 10; i++) {    if (i != 5) continue;    std::cout << i << " ";       // 每次 i!=5 时跳过此语句}std::cout << '\n'; for (int j = 0; j < 2; j++) {    for (int k = 0; k < 5; k++) {   // continue 只会影响此循环        if (k == 3) continue;        std::cout << j << k << " "; // 每次 k==3 时跳过此语句    }}

break;continue;不能用于多重嵌套循环
多重嵌套循环跳转思考应用goto

for(int j = 0; j < 2; j++){    for(int k = 0;k < 5;k++){        if(k == 2) goto label;        std::cout << j << k << " ";    }}label://......

达夫设施

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_vlaue = (max_value > buffer[i]) ? max_value : buffer[i];}std::cout << max_vlaue << "\n";//==============================================================//循环展开for(size_t i = 0; i + 8 < buffer_count; i+=8)//循环解决缩小,程序性能晋升{    max_vlaue = (max_value > buffer[i]) ? max_value : buffer[i];    max_vlaue = (max_value > buffer[i+1]) ? max_value : buffer[i+1];    max_vlaue = (max_value > buffer[i+2]) ? max_value : buffer[i+2];    max_vlaue = (max_value > buffer[i+3]) ? max_value : buffer[i+3];    max_vlaue = (max_value > buffer[i+4]) ? max_value : buffer[i+4];    max_vlaue = (max_value > buffer[i+5]) ? max_value : buffer[i+5];    max_vlaue = (max_value > buffer[i+6]) ? max_value : buffer[i+6];    max_vlaue = (max_value > buffer[i+7]) ? max_value : buffer[i+7];}//然而内存拜访越界//解决残余for(size_t i = buffer_count / 8 *8;i< buffer_count;++i){    max_vlaue = (max_value > buffer[i]) ? max_value : buffer[i];}//=======================================================================//指针优化,switch优化auto ptr = buffer.begin();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(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;}//====================================================================//持续优化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;}//====================================================================//达夫设施 switch 套循环size_t i = 0;switch(buffer_count % 8)    for(;i<(buffer_count+7)/8;++i)    {    [[fallthrough]];    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外部,再触发循环