• switch_case,&&,||,条件操作符和逗号操作符,循环语句


    一.switch-case

    switch-case语句主要用在多分支条件的环境中,在这种环境中使用if语句会存在烦琐且效率不高的弊端。

    switch(expression)

    {

      case const expression1:

        ....

      case const expression2;

        ...

      default:

        ...

    }

    在执行过程中,expression的值会与每个case的值比较,实现switch语句的功能。关键字case和它所关联的值被称作case标号。每个case标号的值都必须是一个整形常量表达式且不能存在两个case标号相同的情形。除此之外,还有一个特殊的case标号-default标号。

    如果expression的值与其中一个case标号相匹配,则程序将从该标号后面的第一个语句开始执行各个语句,直到switch结束或者遇到break语句为止,如果没有发生与之匹配的case标号(并且也没有default标号),则程序会从switch语句后面的一条语句继续执行。

    关于switch一般存在这样的误解:以为程序只会执行匹配的case标号相关的语句。实际上并非如此,该标号只是程序会执行的起始点,程序会从该点执行,并跨越case边界继续执行其他语句,直到switch结束或遇到break语句为止。

    break语句的使用,是switch-case语句的核心。因为在大多数情况下,在下一个case标号前面必须加上一个break语句。

    故意省略break是一种特别罕见的用法,因此在这种形式的代码附近,请务必添加一些注释,说明其运行逻辑。

    在switch-case结构中,只能在最后一个case标号或default中定义内部变量。指定这种规则是为了避免出现代码跳过变量定义和初始化的情况。

    这个规则存在的原因:一般如果定义一个变量,此变量便从此定义开始有效,直到所在的语句块结束。如果在两个case中间定义一个变量,那么对于定义变量的case标号后面的其他标号都可以使用这个变量。但是如果switch从那些后续case标号开始执行呢?可能这个变量没有定义就使用了,这是我们所不想看到的。为了实现在case中可以定义变量,可以引进语句块思想实现。在该语句块中定义变量,从而保证这个变量在使用前定义和初始化。而出了这个语句块该变量就是非法了。所以,在case语句块中,最好不要定义变量,所需的变量应在switch之前进行定义和初始化。如果必须定义变量,请谨慎而为,请采用语句块方式实现内部变量的定义。

    对于那些哪怕没有语句在default标号下执行的环境中,定义default标号依然是有用的,定义default标号可明确地告诉读者,这种情况已考虑到,只是没有什么可以执行的。default标号不能单独存在,它必须位于语句之前,如果switch以default结束,而default分支没有什么任务需要执行,那么default标号后面必须添加 个空语句。

    二.&&,||

    &&和||是C++逻辑或和逻辑与操作符。在求值过程中,仅当a不能确定表达式的值时,才会求解b。在逻辑与表达式中,a的计算结果是true。如果a的计算结果是false,则无论b的值是什么,逻辑表达式的值都为false。当a的值为true时,只有b的值也为true时,逻辑与表达式的值才为true。在逻辑或中同样,这就是短路求值。

    &&和&,||和|的区别:&和|是位与和位或操作符。需要两个整型操作数。&,在每个位的位置,如果两个操作数对应的位都为1,则操作结果中该位为1,否则为0。|操作,在每个位的位置,如果两个操作数对应的位只有一个为1,则操作结果中该位为1,否则为0;位操作符和逻辑操作符的每一个区别是||和&&操作符具有短路性质,如果表达式的值根据左操作数就可以决定,则它就不再对右操作数进行求值。与之相反,|和&操作符两边的操作数都需要进行求值。

    在C++中,;标示一条语句的结束。如果不小心多写了一个分号,可能不会造成什么不良的后果。这个分号可能会被当做一个不会产生任何效应的空语句;或者这个多余的分号被编译器识别,编译器会因为这个多余的分号产生一条警告语句,根据这个警告语句你可以很快找到并去掉它。但在if,for,while语句之后多加了一个分号,那么原来紧跟在if或者while子句之后的语句与条件判断部分就没有任何关系了。例如

    int a = 1;

    while(a == 1);

    {

      a--;

    }

    正常编译,且循环

    同样少了分号也会带来错误,例如

    int arrIntMatrix[3] = {0,1,3}

    void main()

    {

      int iIndex = 3;

      if(iIndex<3)

      return

      arrIntMaxtrix[0] = 3;

    }

    分号标示C++语句结束,多了一个分号和少了一个分号都可能造成不良后果。应小心谨慎。

    三.条件运算符和逗号运算符

    条件运算符是C++语言唯一的"三目运算符"。其接受3个操作数,同样条件的操作符会控制表达式的求值顺序。用法如下:

    expression1?expression2:expression3;       (1)

    (expression1)?(expression2):(expression3);   (2)

    条件运算符的优先级非常低,所以它的各操作数即使不加括号,一般也不会产生问题。但是为了表达的清楚性,还是倾向于在各个表达式两端加上括号。首先计算expression1,如果值为真,那么整个表达式的值就是expression2的值,而expression3不会进行求值。否则,如果expression1的值为假,那么整个条件语句的值就是expression3的值,而expression2不会进行求值。

    逗号操作符将两个或多个表达式分隔开来,这些表达式自左向右逐个进行求值,而整个表达式的值是最后那个表达式的值。用法如下:

    expression1,expression2,expression3,...,expressionn;

    逗号操作符中的每个表达式会被求值,而整个表达式的值却是最后一个表达式的值。因为这些表达式的求值顺序已经固定,即采用从左到右的求值顺序。常用在for语句的增量部分,即如果迭代变量不止一个的话,它就派上用场了, for(int i = 0,j=MAX;i<=j;++i,--j)

    四.循环语句

    不可在for循环全内修改循环变量,防止for循环失去控制,最终导致死循环等奇怪现象

    建议for语句的循环控制变量的取值采用"半开半闭区间"写法,因为这种写法更加直观。

    x值属于半开半闭区间"0<=x<N",起点到终点的间隔为N,循环次数为N      x值属于闭区间"0<=x<=N-1",起点到终点的间隔为N-1,循环次数为N

    for(int x=0;x<N;x++)                          for(int x=0;x<=N-1;x++)      //代码1更加直观

    在C/C++循环语句中,for语句使用的频率最高,while语句次之,do..while语句很少用。

    在多重循环中,如果有可能,应将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。原因如下:最长循环放到内部可以提高I cache的效率,降低因为循环跳转造成cache的miss以及流水线flush造成的延时,多次相同循环后也能提高跳转预测的成功率,提高流水线效率。

    示例1:for(row = 0;row<100;row++)            示例2:for(row = 0;row<100;row++)

      for(col=0;col<5;col++)                 for(col=0;col<5;col++)

      {                            {

        sum = sum+a[row][col];                sum = sum+a[row][col];

      }                            }

    示例1低效率,长循环在最外层,示例2高效率,长循环在最内层

    如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。

    示例3:for(i = 0;i<100;i++)            示例4:if(condition)

      {                           {

        if(condition)                     for(i = 0;i<100;i++) 

          DoSomething();                  DoSomething();

        else                        }else

          DoOtherthing();                {

      }                             for(i = 0;i<100;i++)

                                      DoSomething();

                                  }

    示例3的程序比示例4多执行了N-1次逻辑判断。并且由于前者总要进行逻辑判断,打断了循环"流水线"作业,使得编译器不能对循环进行做优化处理,降低了效率。如果N非常大,最好采用示例4的写法,可以提高效率。如果N非常小,两者效率差别并不明显,采用示例3的写法比较好。因为程序更加简洁。

  • 相关阅读:
    WebStorm 2018版本破解方法
    C# WMI通过网络连接名称获取IP掩码网关
    c# 调用RDP和SSH实现远程登陆
    LabVIEW中开放隐藏属性的inikey
    LabVIEW类方法浏览器-Class Method Browser
    hive split 注意事项
    机器学习三大框架对比
    Windows环境下搭建Nginx和多版本PHP共存
    javascript : location 对象
    ora-00031:session marked for kill处理oracle中杀不掉的锁
  • 原文地址:https://www.cnblogs.com/fenghuan/p/4854735.html
Copyright © 2020-2023  润新知