不必要的优化

来源:互联网 发布:阿沁的淘宝店链接 编辑:程序博客网 时间:2024/05/21 06:22
<span style="font-size:18px;">#include <iostream.h>void main(){    int i=1,sum=0;  //初始化    while(i<=100){      sum=sum+i;      i=i+1;    }    cout <<"sum = " <<sum <<endl;}</span>

While循环中的继续条件,是一个表达式,并没有更多的限定,所以,上例可以在继续条件处放上一个逗号表达式以完成同样的功能:
i=1;
while(sun+=i++,i<100);
cout<<”sum=”<<sum<<endl;
   该代码的while语句中的循环体为一个分号,代表空语句。
   根据逗号表达式的概念,C++中将顺序执行逗号表达式中的每个子表达式,并以最后一个子表达式的值作为整个逗号表达式的值。因此,继续条件中的表达式之值是i<=100,它在前一个表达式sum+=i++执行后取值,i在此处无副作用。
C++中有足够的能耐让代码最大限度的优化。该代码也显示了C++的灵活与技巧,但可读性较差,所以它不是现代程序设计所追求的。、

  do while 中while中的分号不要遗忘。



                     For语句
for(表达式1;表达式2;表达3)  
语句:
    表达式1 通常用来给循环变量赋初值,一般是赋值表达式。也允许在for语句外给循环变量赋初值,此时可以省略该表达式。
    表达式2 通常是循环条件,一般为关系表达式或逻辑表达式。
    表达式3 通常可用来修改循环变量的值,一般是赋值语句。 
    这三个表达式都可以是逗号表达式, 即每个表达式都可由多个表达式组成。三个表达式都是任选项,都可以省略。
一般形式中的“语句”即为循环体语句。for语句的语义是:
1.首先计算表达式1的值。
2.再计算表达式2的值,若值为真(非0)则执行循环体一次, 否则跳出循环。 
3.然后再计算表达式3的值,转回第2步重复执行。在整个for循环过程中,表达式1只计算一次,
表达式2和表达式,3则可能计算多次。循环体可能多次执行,也可能一次都不执行。for 语句的执行过程如图所示。
#include<stdio.h>
void main(){
int n,s=0;
for(n=1;n<=100;n++)
s=s+n;
printf("s=%d\n",s);
}  
用for语句计算s=1+2+3+...+99+100
int n,s=0;
for(n=1;n<=100;n++)
s=s+n;
printf("s=%d\n",s);  
本例for语句中的表达式3为n++,实际上也是一种赋值语句,相当于n=n+1,以改变循环变量的值。
void main(){
int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;n>0;a++,n--)
printf("%d ",a*2);

用for语句修改例题。从0开始,输出n个连续的偶数。
int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;n>0;a++,n--)
printf("%d ",a*2); 
本例的for语句中,表达式1已省去,循环变量的初值在for语句之前由scanf语句取得,表达式3是一个逗号表达式,
由a++,n-- 两个表达式组成。每循环一次a自增1,n自减1。a的变化使输出的偶数递增,n的变化控制循次数。
在使用for语句中要注意以下几点
1.for语句中的各表达式都可省略,但分号间隔符不能少。如:for(;表达式;表达式)省去了表达式1。
for(表达式;;表达式)省去了表达式2。
for(表达式;表达式;)省去了表达式3。
for(;;)省去了全部表达式。
2.在循环变量已赋初值时,可省去表达式1,如例3.27即属于这种情形。
3.如省去表达式2或表达式3则将造成无限循环, 这时应在循环体内设法结束循环。例题即属于此情况。
void main(){
int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;n>0;)
{ a++;n--;
 printf("%d ",a*2);
}
} int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;n>0;)
{ a++;n--;
printf("%d ",a*2);
}
本例中省略了表达式1和表达式3,由循环体内的n--语句进行循环变量n的递减,以控制循环次数。
void main(){
int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;;){
a++;n--;
printf("%d ",a*2);
if(n==0)break;
}
}
int a=0,n;
printf("\n input n: ");
scanf("%d",&n);
for(;;){
a++;n--;
printf("%d ",a*2);
if(n==0)break;

本例中for语句的表达式全部省去。由循环体中的语句实现循环变量的递减和循环条件的判断。
当n值为0时,由break语句中止循环,转去执行for以后的程序。在此情况下,for语句已等效于while( 1)语句。
如在循环体中没有相应的控制手段,则造成死循环。
3.循环体可以是空语句。
#include"stdio.h"
void main(){
 int n=0;
 printf("input a string:\n");
 for(;getchar()!='\n';n++);
  printf("%d",n);

 本例中,省去了for语句的表达式1,表达式3也不是用来修改循环变量,而是用作输入字符的计数。
这样, 就把本应在循环体中完成的计数放在表达式中完成了。因此循环体是空语句。应注意的是,
空语句后的分号不可少,如缺少此分号,则把后面的printf 语句当成循环体来执行。反过来说,如循环体不为空语句时, 
决不能在表达式的括号后加分号, 这样又会认为循环体是空语句而不能反复执行。这些都是编程中常见的错误,要十分注意。
4.for语句也可与while,do-while语句相互嵌套,构成多重循环。以下形成都合法的嵌套。
(1)for(){…
  while()
   {…}
  …
    }
(2)do{
   …
  for()
   {…}
  …
  }while();
(3)while(){
      …
      for()
       {…}
      …
     }
(4)for(){
    …
    for(){
    …
     }
    }
void main(){
int i,j,k;
for(i=1;i<=3;i++)
{
 for(j=1;j<=3-i+5;j++)
  printf(" ");
  for(k=1;k<=2*i-1+5;k++)
  {
   if(k<=5) printf(" ");
   else printf("*");
  }
  printf("\n");
 }

For循环使所有的循环细节都可在语句的描述。使得程序又精炼又可读。
只要循环变量不在程序的其他地方使用,在for头部定义循环变量是最好的,该变量只在循环体中有效,循环体退出后自行消失。



switch-case语句用法 
if语句处理两个分支,处理多个分支时需使用if-else-if结构,但如果分支较多,则嵌套的if语句层就越多,
程序不但庞大而且理解也比较困难.因此,C语言又提供了一个专门用于处理多分支结构的条件选择语句,
称为switch语句,又称开关语句.使用switch语句直接处理多个分支(当然包括两个分支).其一般形式为: 
switch(表达式)

      case 常量表达式1:
         语句1;
      break;
      
      case 常量表达式2:
         语句2;
      break; 


……
      case 常量表达式n:
         语句n;
      break; 


      default:
         语句n+1;
      break;
}
switch语句的执行流程是:首先计算switch后面圆括号中表达式的值,然后用此值依次与各个case的常量表达式比较
,若圆括号中表达式的值与某个case后面的常量表达式的值相等,就执行此case后面的语句,执行后遇break语句就退出switch语句;
若圆括号中表达式的值与所有case后面的常量表达式都不等,则执行default后面的语句n+1,然后退出switch语句,
程序流程转向开关语句的下一个语句.如下程序,可以根据输入的考试成绩的等级,输出百分制分数段: 
switch(grade)

    case 'A': /*注意,这里是冒号:并不是分号;*/
       printf("85-100\n");
    break; /*每一个case语句后都要跟一个break用来退出switch语句*/
    case 'B': /*每一个case后的常量表达式必须是不同的值以保证分支的唯一性*/
       printf("70-84\n");
    break;
    case 'C':
       printf("60-69\n");
    break;
    case 'D':
       printf("<60\n");
    break;
    default:
       printf("error!\n");

(2) 如果在case后面包含多条执行语句时,也不需要像if语句那样加大括号,进入某个case后,
会自动顺序执行本case后面的所有执行语句.如: 

    case 'A':
     if(grade<=100)
       printf("85-100\n");
     else
       printf("error\n");
    break;


(3) default总是放在最后,这时default后不需要break语句.并且,default部分也不是必须的,如果没有这一部分,当switch后面圆括号中表达式的值与所有case后面的常量表达式的值都不相等时,则不执行任何一个分支直接退出switch语句.此时,switch语句相当于一个空语句.例如,将上面例子中switch语句中的default部分去掉,则当输入的字符不是"A","B","C"或"D"时,此switch语句中的任何一条语句也不被执行. 


(4) 在switch-case语句中,多个case可以共用一条执行语句,如: 




case 'A':
case 'B':
case 'c':
printf(">60\n");
break;
…… 


在A,B,C3种情况下,均执行相同的语句,即输出">60". 


(5) 最开始那个例子中,如果把每个case后的break删除掉,则当greak='A'时,程序从printf("85-100\n")开始执行,输出结果为: 


85-100
70-84
60-69
<60
error 




这是因为case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即"只是开始执行处的入口标号".因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行,而且执行完一个case后面的语句后,若没遇到break语句,就自动进入下一个case继续执行,而不在判断是否与之匹配,直到遇到break语句才停止执行,退出break语句.因此,若想执行一个case分之后立即跳出switch语句,就必须在此分支的最后添加一个break语句. 




main() /*完成两个数简单的四则运算*/

   float a,b;
   char c1;
   printf("Please enter a,b and op:");
   scanf("%f%c%f",&a,&c1,&b);
   switch(c1)
   { 
      case '+':
        printf("%f+%f=%f\n",a,b,a+b);
      break;
      case '-':
        printf("%f-%f=%f\n",a,b,a-b);
      break;
      case '*':
        printf("%f*%f=%f\n",a,b,a*b);
      break;
      case '/':
        if(b!=0.0) /*分母不能等于0*/
          printf("%f/%f=%f\n",a,b,a/b);
        else
        printf("error!\n");
      break;
      default:
        printf("error!\n");
      break;
   }
}  


 在循环语句中break用来从最近的封闭循环中跳出。而不是跳出所有的循环。



Continue语句用在循环语句中,作为本次循环,即跳出循环体中尙未执行的语句,接着进行下一次是否执行循环的判定。
   事实上,由于C++中,有块语句的支持,所以·,经常使用if语句,把continue后面的语句以块的形式包含在if语句之中,
可以避免使用continue语句。
Continue语句和break语句的区别是:continue语句只结束本次循环,而不是终止整个循环的执行;而break语句则是终止循环,
不在进行条件判断。
goto语句也称为无条件转移语句,其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 
放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。
label: i++;
loop: while(x<7);
C语言不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向, 转去执行语句标号所标识的语句。
goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
//统计从键盘输入一行字符的个数。
#include"stdio.h"
int main(void)
{
   int n=0;
   printf("input a string :\n");
   loop: 
      if(getchar()!='\n'){
        n++;
      goto loop;
 }
   printf("%d",n);
}
用goto语句实现的循环完全可以用while或for循环来表示。现代程序设计方法主张限制goto语句,
因为,滥用goto语句将使程序流程无规则,可读性差。Goto语句只在一个地方有使用价值:
当要从多重循环深处直接跳转到循环之外时,如果用break语句,将要用多次,而且可读性不好,这是goto可以发挥作用。
例如:
 for(int i;i<10;i++)
  for(int j=1;j<10;j++)
   if(i*j==27)
         goto End;
End:
   cout<<i<*<<j<<”27\n”;

0 0
原创粉丝点击