C零基础自学笔记<3>

上一篇中提到:

流程控制  1.顺序结构 2.选择结构 3.循环结构

第三部分

3.循环结构


▶定义


        某些代码会被重复执行

循环之for

①for  (重点讲)

▶格式

for(1; 2; 3)
        语句A

顺序: 1 2 A 3  

执行3表示循环一次结束

是否执行下次循环看2是否成立,若不成立,跳出循环


首先明确一点:

笔记<2>中说过    if 控制一个语句,for也是如此
所以下图中⑤不受for的控制
下图中的for只需看前两行

▶循环实现顺序(重要)

        ▷执行①,②条件成立,进入循环,执行④,再执行③,③执行完标志着一次循环结束
        ▷是否执行下一次的循环要看②是否成立,若成立,则执行循环,执行④,再执行③,③执行完标志着一次循环结束

        自己跟着图顺一遍,再看图下面具体的执行步骤,记忆的会更牢固(一定要思考)

依照上图,若设sum初始值为0

代码中顺序为:
i=1   1<=4  √  sum=1+0→1      i=1+1→2  
i=2   3<=4  √  sum=2+1→3      i=2+1→3  
i=3   3<=4  √  sum=3+3→6      i=3+1→4  
i=4   4<=4  √  sum=6+4→10    i=4+1→5  
i=5   5<=4   X  不成立 循环结束  sum为10 

▶for循环的最简单的用法


例:求1-10的奇数和
 
#include <stdio.h>

int main()
{
    int i;
    for(i=0;i<4;++i)
        printf("喵喵喵喵\n");
    return 0;
}


回顾笔记<2>中“如何看懂一个程序”的三个步骤:   流程→每个语句的功能→试数

尝试计算下列代码中i和sum的值

#include <stdio.h>

int main()
{
	int i;
    int sum=0;
    for(i=1;i<10;i+=2)  //假设将中间i<10改成i<10000  则计算1-10000的奇数和
    { //{ }内只有一句,删掉并不影响程序的执行,但未了直观,加上最好
	    sum=sum+i;   //本行换成 printf("今天我很高兴!\n");  可以发现,共循环了五次
    }
    printf("i=%d\n",i);
    printf("sum=%d\n",sum);
    return 0;
}

/*----输出结果-----------

i=11
sum=25

-------------------------*/

▶for和if的嵌套使用

例一:范围问题


下列代码循环了几次?

#include <stdio.h>

int main()
{
    int i;
    for(i=0;i<4;++i)
        printf("喵喵喵喵\n");
    return 0;
}
/*----输出结果-----------
喵喵喵喵
喵喵喵喵
喵喵喵喵
喵喵喵喵
-------------------------*/

答:共4次
因此,将for中语句进行修改
.将i<4的条件修改为i<10000,则循环了10000次   
.将i=0;i<4; 的条件改为i=5;i<8;  则循环了3次
.将i=0;i<4; 的条件改为i=5;i<90;  则循环了85次

▷代码添加一行输出,结果为?

#include <stdio.h>

int main()
{
    int i;
    for(i=0;i<4;++i)
        printf("喵喵喵喵\n");
        printf("哈哈哈哈\n");
    return 0;
}
/*----输出结果-----------
喵喵喵喵
喵喵喵喵
喵喵喵喵
哈哈哈哈

-------------------------*/

▷代码for的语句添加{ },结果为?

#include <stdio.h>

int main()
{
    int i;
    for(i=0;i<4;++i)
    {
        printf("喵喵喵喵\n");
        printf("哈哈哈哈\n");
    }
    return 0;
}
//一定注意是交替输出

/*----输出结果-----------
喵喵喵喵
哈哈哈哈
喵喵喵喵
哈哈哈哈
喵喵喵喵
哈哈哈哈
喵喵喵喵
哈哈哈哈
-------------------------*/
例二:求1-100的和
#include <stdio.h>

int main()

{   
    int i;

    int sum=0;

    for(i=1;i<=100;++i)   //若为1+2+..+10最终结果为55

        sum=sum+i;

    printf("sum=%d\n",sum);

    return 0;
}

/*----输出结果-----------

sum=5050

-------------------------*/

例三:求1-100所有能被3整除的数字之和
#include <stdio.h>

int main()
{

    int i;
    int sum=0;
    for(i=3;i<=100;++i) //若想检验代码是否正确,可将i<=100改为i<=12尝试运行。
    {
        if(i%3==0)//如果i能被3整除
            sum+=i;
    }
    printf("sum=%d\n",sum);
    return 0;
}
/*----输出结果-----------
sum=1683
-------------------------*/

若将代码printf的位置进行调整,结果为?  

#include <stdio.h>

int main()
{
    int i;
    int sum=0;
    for(i=3;i<=10;++i) //为更好讲解换成1-10的范围
    {
        if(i%3==0)//如果i能被3整除
            sum=sum+i;
            printf("sum=%d\n",sum);
    }
    return 0;
}
/*----输出结果-----------
sum=3
sum=3
sum=3
sum=9
sum=9
sum=9
sum=18
sum=18


-------------------------*/

流程(最关键)
  ▷执行①,②条件成立,进入循环,执行④,④成立则执行⑤,⑤后执行⑥,⑥后执行③,③执行完标志着一次循环结束
      但是,若进入循环后,④不成立,则执行⑥,⑥后执行③,③执行完标志着一次循环结束。
   ▷是否执行下一次的循环要看②是否成立,若成立,则执行循环,执行④,再判断④是否成立,来确认下一步的执行

因此:

        若所有条件都成立,循环一次的顺序为:①②④⑤⑥③

        若 if 的条件不成立,循环一次的顺序为:①②④⑥③

i为3时,i<=10 √    i%3==0 √   sum=0+3=3     ++i后i为4     输出3

i为4时,i<=10 √    i%3==0  X   sum不执行     ++i后i为5     输出3(以前的值)
 
i为5时,i<=10 √    i%3==0  X   sum不执行     ++i后i为6     输出3(以前的值)

i为6时,i<=10 √    i%3==0 √   sum=6+3=9     ++i后i为7     输出9

i为7时,i<=10 √    i%3==0  X   sum不执行     ++i后i为8     输出9(以前的值)

i为8时,i<=10 √    i%3==0  X   sum不执行     ++i后i为9     输出9(以前的值)

i为9时,i<=10 √    i%3==0 √   sum=9+9=18  ++i后i为10   输出18

i为10时,i<=10 √  i%3==0  X   sum不执行     ++i后i为11   输出18(以前的值)

i为11时,i<=10  X   条件不成立,循环结束

学for循环的思路,思维方式很重要
先执行什么后执行什么一定要捋清楚
掌握如何看懂程序(动笔写)

作业:4个程序


求1-100之间的奇数之和
求1-100中间的奇数的个数
求1-100中间的奇数的平均值
求1-100之间的奇数之和与偶数之和

▶强制类型转换和对初学者很重要要求和程序讲解

作业答案:

求1-100之间的奇数之和

#include <stdio.h>

int main()

{  
    int i;
    int sum =0;
    for(i=1;i<101;++i)
    {
    	if(i%2==1)
	    	sum+=i;  //sum=sum+i
    }

    printf("sum=%d\n",sum);
    return 0;
}
/*----输出结果-----------
sum=2500
-------------------------*/


求1-100中间的奇数的个数

#include <stdio.h>

int main()

{  
    int i;
    int cnt=0;//个数一般用cnt表示  (count)
    for(i=1;i<101;++i)
    {
	    if(i%2==1)
	    	++cnt;
    }   
    printf("cnt=%d\n",cnt);
    return 0;
}

/*----输出结果-----------
cnt=50
-------------------------*/

补充:将“求1-100之间的奇数之和”、“求1-100中间的奇数的个数”两个问题用一段代码表示出来:

#include<stdio.h>

int main()

{  
    int i;
    int sum=0;
    int cnt=0;
    for(i=1;i<101;++i)
    {
    	if(i%2==1)
    	{   //一定要加{ },若不加,当if不成立,仍会执行++cnt,结果会cnt为100,导致出错
	    	sum+=i;
	    	++cnt;
    	}
    }
    printf("sum=%d\n",sum);
    printf("cnt=%d\n",cnt);
    return 0;
    }
/*----输出结果-----------

sum=2500
cnt=50

-------------------------*/


求1-100中间的奇数的平均值

#include <stdio.h>

int main()

{  
    int i;
    int sum=0;
    int cnt=0;
    float avg;//average的缩写
    for(i=1;i<101;++i)  //条件中的i<101也可替换为i<=100
    {
    	if(i%2==1)
	    {
	    	sum+=i;
	    	++cnt;
	    }
    }
    avg=1.0*sum/cnt;  //1.0是默认的double类型
    printf("sum=%d\n",sum);
    printf("cnt=%d\n",cnt);
    printf("avg=%f\n",avg);
    return 0;
}

/*----输出结果-----------

sum=2500
cnt=50
avg=50.000000

-------------------------*/


求1-100之间的奇数之和与偶数之和

#include <stdio.h>

int main()

{  
    int i;
    int sum1=0;	//奇数和
    int sum2=0;	//偶数和 

    for(i=1;i<101;++i)
    {  
    	if(i%2==1)
    	{
	    	sum1 += i;
    	}
	    else
	    {
	    	sum2 += i;
	    }   
    }

    printf("奇数和=%d\n",sum1);
    printf("偶数和=%d\n",sum2);

    return 0;
}
/*----输出结果-----------

奇数和=2500
偶数和=2550
-------------------------*/
练习:1+1/2+1/3+...+1/100
#include <stdio.h>

int main()

{   
    int i;
    
    float sum=0;  //浮点型
    
    for(i=1;i<=100;++i)
    
    {
    	sum=sum + 1.0/i;   //也可写为sum=sum + 1/(float)i;,但前面那个最简单
    	
        //sum=sum + (float)(1/i)这样写是不对的
        
    }
    
    printf("sum=%f\n",sum);   //float型必须用%f输出

    return 0;
}

先看懂程序→模仿程序
一开始学的时候写不出来很正常,看懂背会,模仿多了就会了
想看懂程序,要培养“三步看程序”的方法,前两步都会,还是看不懂就要关注第三步:试数

试数详细步骤举例
试数时注意:
- 不要问为什么,就把自己当做计算机,一步一步去执行

- 不要把某一步省略了

- 写的时候写整齐

1->  i=1  1<=100 成立
     sum=0+1/1.0=1   ++i  i=2
2->  i=2  2<=100 成立
     sum=1+1/2.0   ++i  i=3    
3->  i=3  3<=100 成立
     sum=1+1/2.0+1/3.0   ++i  i=4
......依此类推,一般写5步就够了

▶浮点数的存储所带来的问题

#include <stdio.h>

int main()

{   
    float i;
    float sum=0;  
    for(i=1.0;i<=100;++i)
    {
    	sum=sum + 1/i;   
    }
    printf("sum=%f\n",sum);   

    return 0;
}

输出结果跟上面的结果一致,所以不正确,循环中更新的变量(float i)不能定义为浮点型


float 和 double 都不能保证可以精确的存储一个小数


例如x=6.234,可能存为x=6.23339



举例一:有一个浮点型变量x,如何判断x的值是否为零


if(0 == x)
  是零
else
 不是零
上述做法错误,因为它的是一个近似值

举例二:为什么循环中更新的变量不能定义成浮点型?


浮点型为非准确存储
自增时,i<=100,i和100进行比较,若为1/i,最终结果可能为100.00001,导致这一步就不会被执行进去
(如果这句话看不懂,可去看老师本节课的讲解)

if(|x-0.000001|<0.000001)
  是
else
 不是

▶多层for循环嵌套使用时的执行顺序问题(重难点)

形式一:

a行         for(1; 2; 3)
b行             for(4; 5; 6)
c行                A;
d行                B;


上面这四行,整体来看是两个语句 
bc行是一个语句,bc行是a行中的语句,所以abc看做是一个语句,d行是第二个语句。
1→ 2 ,2成立则执行bc部分(4→ 5 → A→ 6),bc只有在5不成立的情况下才会返回到a。

执行顺序 
语句全部成立:1 → 2→ 4 → 5→ A→ 6 →  5→ A→  6 ..

5不成立执行3 → 2→ 4→ 5→ A→ 6....


6之后绝对不可能到B,退出循环(2不成立时)才会到B

一定一定一定一定要理解!

形式二:


for(1; 2; 3)

    for(4; 5; 6)

    {
        A;

        B;
    }
整体是一个语句

形式三:
 

for(1; 2; 3)

    A;
    for(4; 5; 6)

    B;
    
整体是两个语句

形式四:


for(1; 2; 3)

{
    A;

    B;
    for(4; 5; 6)

        C;
}
整体是一个语句

形式五:

for(7; 8; 9)
        for(1; 2; 3)

        {
            A;

           B;
            for(4; 5; 6)

                C;
        }
整体是一个语句

▶进制


▷什么叫n进制  

逢n进一
n进制的范围中没有n
二进制 逢二进一  范围为0 1  没有2
十进制 逢十进一  范围为0-9  没有10


▷把r进制转换为十进制


二进制转换为十进制,从右向左依次标位2的n次方,上下相乘然后相加
八进制转换为十进制,从右向左依次标位8的n次方,上下相乘然后相加


▷把十进制转换为r进制


十进制转二进制:除二取余  商为0后,余数从下往上写
十进制转八进制:除八取余  商为0后,余数从下往上写


▷不同进制所代表的数值之间的关系


十进制的3981转换为十六进制是 F8D ,二者所代表的本质都是同一个数字。

▶运算符补充

自增自减

自增  
前自增  ++i
后自增  i++
前自增和后自增的异同:
相同: 最终都使i的值加1例子

#include <stdio.h>
int main()
{
    int i;
    int j;
    int k;
    int m;
    i=j=3; //等价与i=3,j=3
    k=i++;
    m=++j;
    printf("i=%d,j=%d,k=%d,m=%d",i,j,k,m);
    return 0;
}
/*----输出结果-----------

i=4,j=4,k=3,m=4

-------------------------*/

不同:


前自增整体表达式的值是i加1之后的值
后自增整体表达式的值是i加1之前的值

为什么会出现自增:


代码更精炼
自增的速度更快

学习自增要明白的几个问题:


1.我们编程时应该尽量屏蔽掉前自增和后自增的差别
2.自增表达式最好不要作为一个更大的表达式的一部分来使用
  或者说
  i++和++i单独成一个语句,不要把它作为一个完整复合语句的一部分来使用
  例一:int n =i++ + ++i + i + i++    
     //这样写不但是不规范的代码,而且是不可移植的代码(换一个机器,结果可能就不一样)
  例二:printf("%d %d %d",i++,++i,i);
    //理由同上,是一种不好的写代码习惯,其他人也看不懂
  


自减同上

三目运算符

格式:


 形如:   A ? B : C
 等价于: if(A) 
         B;
      else
         C;

例子
#include <stdio.h>

int main()

{ 
    int i;
    i=(3>2 ? 5 : 1);//若改为0>2 结果为1
    printf("%d\n",i) ;

    return 0;
}
/*----输出结果-----------

5

-------------------------*/

逗号表达式

格式


A ,B ,C ,D
功能:  从左到右执行

例一
#include <stdio.h>

int main()

{ 
    int i;
    i=(3, 2, 5, 6);
    printf("%d\n",i) ;

    return 0;
}
/*----输出结果-----------

6

-------------------------*/

例二
#include <stdio.h>

int main()

{ 
    int i;
    int j=2;
    i=(j++, ++j, j+2, j-3); //j+2不等于j=j+2
    printf("%d\n",i) ;

    return 0;
}
/*----输出结果-----------

1

-------------------------*/


复习多个for循环嵌套使用时执行顺序

格式一:

for(1; 2; 3)
    A;
    B;
1永远只执行一次
1之后执行2,2成立执行A,A之后执行3,3执行后标记着一次循环结束
是否再次循环需在此执行2,看条件是否成立,若成立,继续上面步骤
若2不成立,退出循环,执行B.
 

格式二:

for(1; 2; 3)
    for(4; 5; 6)
        A;
        B;

整体分为两个语句
前三行为第一个,第四行为第二个语句
顺序:
l后执行2
2成立,进入循环,整个循环结束后执行3,3后执行2,2成立再次进入循环
若2不成立,跳出循环,执行B
第二行for循环内,先执行4,4后执行5   
5成立,执行A,A后执行6,6后判断5,只要5成立,一直执行A和6
5不成立,跳出循环,执行3

多个for循环嵌套使用举例

用已学的知识去编写程序

例一:
#include <stdio.h>

int main()

{
int i,j;
    for(i=0;i<3;++i) //循环3次
        for(j=2;j<5;++j)//循环3次,共9次
            printf("哈哈!\n"); //本行之前为第一个语句
        printf("喵喵!\n");  //第二个语句
    return 0;
}

/*----输出结果-----------
哈哈!
哈哈!
哈哈!
哈哈!
哈哈!
哈哈!
哈哈!
哈哈!
哈哈!
喵喵!
-------------------------*/

例二:
 

#include <stdio.h>

int main()

{
int i,j;
    for(i=0;i<3;++i) //循环3次
        printf("嘿嘿!\n");
        for(j=2;j<5;++j)//循环3次
            printf("哈哈!\n"); 
        printf("喵喵!\n"); 

 return 0;
}

/*----输出结果-----------

嘿嘿!
嘿嘿!
嘿嘿!
哈哈!
哈哈!
哈哈!
喵喵!

-------------------------*/

例三:

#include <stdio.h>

int main()

{
int i,j;
    for(i=0;i<3;++i)
    {
        printf("1\n");
        for(j=2;j<5;++j)
        {
            printf("2\n"); 
            printf("3\n"); 
        }
        printf("4\n");
    }
    return 0;  //结果 12323234 重复三次
}

/*----输出结果-----------
1
2
3
2
3
2
3
4
1
2
3
2
3
2
3
4
1
2
3
2
3
2
3
4

-------------------------*/


代码有些绕,多看几遍

for循环到此结束

循环之while

②while


执行顺序


while(表达式)
    语句;
表达式成立,执行语句,执行后判断表达式是否成立
因此,只要表达式成立一直执行,不成立则跳出
与if和for一样,while默认控制一个语句


与for的相互比较


求1+2+3+..+100 用for来实现

#include <stdio.h>
int main()
{ 
    int sum;
    int i;
    sum=0;
    for (i=1;i<101;++i)
    {
        sum=sum+i;
    }
    printf("sum=%d\n",sum);
    return 0;
}

/*----输出结果-----------

sum=5050

-------------------------*/



求1+2+3+..+100 用while来实现

#include <stdio.h>
int main()
{ 
    int sum;
    int i;
    i=1;
    while(i<101)
    {
        sum=sum+i; //这两行顺序不可互换
        ++i;
    }

    printf("sum=%d\n",sum);
    return 0;
}

/*----输出结果-----------

sum=5050

-------------------------*/


因此,for和while可以相互转换,但for逻辑性更强,更不易出错,推荐多使用for

for(1;2;3)
    A;
等价于




1
while(2)
{      //一定要加这个大括号,不加while无法控制3
   A;
   3;
}

举例

从键盘输入一个数字,如果该数字是回文数,则返回yes,否则返回no
回文数:正着写和倒着写都一样
例:121  12321 都是回文数
- 求回文数

#include <stdio.h>

int main()

{ 
    int val;//存放带判断的数字
    int m;
    int sum =0;
    printf("请输入您需要判断的数字:");
    scanf("%d",&val);
    m=val;
    while(m) //m只要非零即为真
    {
        sum=sum*10+m%10;
        m/=10; //被除数和除数如果两个都是整数,则没有小数
    }
    if(sum == val)
        printf("Yes!\n");
    else
        printf("No!\n");
    return 0;
}

/*----输出结果-----------
请输入您需要判断的数字:1234
No!

-------------------------*/

试数:把自己当做计算机一步步去试,试的时候写整齐,写详细
1> m=1234 成立
   sum=0*10+1234%10=4
   m=m/10=1234/10=123
2> m=123 成立
   sum=4*10+123%10=43
   m=m/10=123/10=12
3> m=12 成立
   sum==43*10+12%10=432
   m=m/10=12/10=1
4> m=1 成立
   sum=432*10+1%10=4321
   m=m/10=1/10=0
5> m=0 不成立
最终sum=4321 

1234=4321     X  故输出No

- 斐波那契数列

/*
斐波那契数列
1 2 3 5 8 13 21 34
*/

#include <stdio.h>

int main()

{   
   int n;  //保存用户的值
   int f1, f2, f3;  //最终输出的值用f3表示
   int i;
   f1 = 1;
   f2 = 2;
   
   printf("请输入您需要求的项的序列:");  //第n项的值为多少
   scanf("%d",&n);  
   
   if(1 == n)
   {
      f3 = 1;   
   }
   else if(2 == n)
   {
       f3 = 2;  
   }
   else
   {
      for (i=3; i<=n; ++i)
      {
         f3 = f1 + f2;
         f1 = f2;
         f2 = f3;
      }
    }
    printf("%d\n",f3);
    return 0;
}

/*----输出结果-----------
请输入您需要求的项的序列:6
13


-------------------------*/

试数:

假设输入n为6
1>i=3 3<=6 成立
  f3=1+2=3
  f1=f2=2
  f2=f3=3
  ++i  i=4
2>i=4 4<=6 成立
  f3=2+3=5
  f1=f2=3
  f2=f3=5
  ++i  i=5
3>i=5 5<=6 成立
  f3=3+5=8
  f1=f2=5
  f2=f3=8
  ++i  i=6
4>i=6 6<=6 成立
  f3=5+8=13
  f1=f2=8
  f2=f3=13
  ++i  i=7
5>i=7 7<=6 不成立
故循环了4次,当n为6时,f3的值为13

试数可横着写可竖着写

i    i<=6    f1    f2    f3  ++i
3    √        1     2     3    4
4    √        2     3     5    5
5    √        3     5     8    6
6    √        5     8   13    7
7     X  

while和for使用场合

没法说,用多了自然而然就知道了(老师的原话,用的多了就好了,不用纠结)


循环之do..while

③do..while


场合:

主要用于人机交互

格式:


do
{
  ...
}while(表达式);

注意:

do..while和while不可相互转换
while和for有可能一次也不执行,若表达式为假,退出循环
do..while一定会执行一次,先执行语句,再判断

一元二次方程 


无do..while循环

仅执行一次


#include <stdio.h>
#include <math.h>

int main()

{   
   double a,b,c;
   double delta;
   double x1,x2;
  
   
  
    printf("请输入一元二次方程的三个系数:\n");
    printf("a = ");
    scanf("%lf",&a);

    printf("b = ");
    scanf("%lf",&b);

    printf("c = ");
    scanf("%lf",&c);
    delta=b*b-4*a*c;

    if(delta >0)
    {
        x1=(-b+sqrt(delta))/(2*a);
        x2=(-b-sqrt(delta))/(2*a);
        printf("有两个解,x1=%lf,x2=%lf\n",x1,x2);
    }
    else if(0 == delta)
    {
        x1=x2=(-b)/(2*a);
        printf("有唯一解,x1=x2=%lf\n",x1,x2);
    }
    else
    {
        printf("无实数解!\n");
    }    

        
return 0;
}
/*----输出结果-----------
请输入一元二次方程的三个系数:
a = 1
b = 5
c = 6
有两个解,x1=-2.000000,x2=-3.000000
-------------------------*/
有do..while循环

#include <stdio.h>
#include <math.h>

int main()

{   
   double a,b,c;
   double delta;
   double x1,x2;
   char ch;  
   
   do
   {
        printf("请输入一元二次方程的三个系数:\n");
        printf("a = ");
        scanf("%lf",&a);

        printf("b = ");
        scanf("%lf",&b);

        printf("c = ");
        scanf("%lf",&c);
        delta=b*b-4*a*c;

        if(delta >0)
        {
            x1=(-b+sqrt(delta))/(2*a);
            x2=(-b-sqrt(delta))/(2*a);
            printf("有两个解,x1=%lf,x2=%lf\n",x1,x2);
        }
        else if(0 == delta)
        {
            x1=x2=(-b)/(2*a);
            printf("有唯一解,x1=x2=%lf\n",x1,x2);
        }
        else
        {
            printf("无实数解!\n");
        }    
        printf("您想继续吗(Y/N):");
        scanf(" %c",&ch);  //%c前必须得加一个空格,原因略
    }while('y'==ch || 'Y'==ch);  //只要不是y就终止
        
    return 0;
}
/*----输出结果-----------
请输入一元二次方程的三个系数:
a = 1
b = 5
c = 6
有两个解,x1=-2.000000,x2=-3.000000
您想继续吗(Y/N):y
请输入一元二次方程的三个系数:
a = 1
b = 3
c = 4
无实数解!
您想继续吗(Y/N):n 

-------------------------*/

switch的用法简介

把电梯程看懂就可以了

#include <stdio.h>

int main()

{   
    int val;
    printf("请输入您要进入的楼层:");
    scanf("%d",&val);
    switch(val)
    {
    case 1:  //注意使用的是冒号
        printf("1层开!\n");
        break;
    case 2:
        printf("2层开!\n");
        break;
    case 3:
        printf("3层开!\n");
        break;
    default:  //默认
        printf("没有盖到这一层!\n");
        break;
    }
    return 0;
}

/*----输出结果-----------
请输入您要进入的楼层:5
没有盖到这一层!


-------------------------*/

 若将上述代码中的break注释掉,变成如下格式,结果为?

#include <stdio.h>

int main()

{   
    int val;
    printf("请输入您要进入的楼层:");
    scanf("%d",&val);
    switch(val)
    {
    case 1:  //注意使用的是冒号
        printf("1层开!\n");
        //break;
    case 2:
        printf("2层开!\n");
        break;
    case 3:
        printf("3层开!\n");
        break;
    default:  //默认
        printf("没有盖到这一层!\n");
        break;
    }
    return 0;
}

/*----输出结果-----------
请输入您要进入的楼层:1
1层开!
2层开!


-------------------------*/

 case1,case2,case3,default是程序的入口
val是输入的值
若val是1,从case1入口进入后,依次顺序执行,不再第二次找入口
若val是2,从case2入口进入后,依次顺序执行,不再第二次找入口
若val是3,从case3入口进入后,依次顺序执行,不再第二次找入口
因此,break起到终止switch的作用。

若将上述代码中的break重新注释掉,变成如下格式,结果为?

#include <stdio.h>

int main()

{   
    int val;
    printf("请输入您要进入的楼层:");
    scanf("%d",&val);
    switch(val)
    {
    case 1:  //注意使用的是冒号
        printf("1层开!\n");
        break;
    case 2:
        printf("2层开!\n");
        //break;
    case 3:
        printf("3层开!\n");
        //break;
    default:  //默认
        printf("没有盖到这一层!\n");
        break;
    }
    return 0;
}

/*----输出结果-----------
请输入您要进入的楼层:3
3层开!
没有盖到这一层


-------------------------*/

若将所有break注释掉,并输入1,会依次输出


#include <stdio.h>

int main()

{   
    int val;
    printf("请输入您要进入的楼层:");
    scanf("%d",&val);
    switch(val)
    {
    case 1:  //注意使用的是冒号
        printf("1层开!\n");
        //break;
    case 2:
        printf("2层开!\n");
        //break;
    case 3:
        printf("3层开!\n");
        //break;
    default:  //默认
        printf("没有盖到这一层!\n");
        //break;
    }
    return 0;
}

/*----输出结果-----------
请输入您要进入的楼层:1
1层开!
2层开!
3层开!
没有盖到这一层!


-------------------------*/

switch琐碎非重点知识介绍


switch(表达式)
{
    case 常量表达式1:
        语句1;
    case 常量表达式2:
        语句2;
    default:  //一般写的时候,default在case3后面
        语句3;
    case 常量表达式3:
        语句4;   
}

第一:所有case后面的常量表达式为便于描述,姑且称之为标签,
这些标签都只能是四种
1.枚举常量(有些书称之为枚举元素)
2.数值常量
3.字符常量
4.常变量
5.宏名的中的一种
注意普通变量,枚举变量是不能作为标签使用的。


第二:switch后面括号例“表达式”允许是任何类型。
但vc++只允许为int或char类型


第三:执行完一个case语句后,流程控制就转移到下一个case子句中继续执行。
“case”常量表达式只是起语句标号的作用,并不是在该处进行条件判断。
在执行switch语句时,根据switch()中表达式的值找到与之匹配的case子句,
就从此case子句开始执行下去,不再进行判断。
switch(i)
{
    case 1:
        语句1;
    case 2:
        语句2;
    default:
        语句3;
    case 3:
        语句4;   
}
当i==1时,从case1处开始往下,一个不落的执行
当i==2时,从case2处开始往下,一个不落的执行
当i==3时,只执行case3一句
当i==4时,从 default处开始往下,一个不落的执行
当i==0时,执行情况同i==4。


第四:switch是选择,不是循环,如果在switch中出现了break语句,
该语句的功能知识退出switch语句,转去执行它下面的语句,
在switch中出现continue是错误的,除非switch本身就属于for或while循环的一部分。

break的用法(重点)

break如果用于循环是用来终止循环
break如果用于switch,则是用于终止switch
break不能直接用于if,除非if属于循环内部的一个子句

break与if的错误例子

#include <stdio.h>

int main()

{   
    switch(2)
    {
    case 2:
          printf("哈哈!\n");
          break;
    }
    if (3>2)
        break;//错误
    return 0;
}


break与if的正确例子

#include <stdio.h>

int main()

{   
    int i;

    switch(2)
    {
    case 2:
          printf("哈哈!\n");
          break;  //ok,break可以用于switch
    }
    for(i=0; i<3; ++i)
    {    
        if (3>2)
            break;  //break虽然是if内部的语句,但终止的却是外部的for循环
        printf("嘿嘿!\n"); //永远不会输出
    }
    return 0;
}

break用于多层for循环时,只能终止距离它最近的循环

#include <stdio.h>

int main()

{   
    int i,j;
    for(i=0;i<3;++i)
    {
        for(j=1;j<4;++j)
            break;   //只能终止距离它最近的循环
        printf("喵喵喵!\n");
    }
    return 0;
}

/*----输出结果-----------

喵喵喵!
喵喵喵!
喵喵喵!
-------------------------*/

break用于多层switch嵌套时,只能终止距离它最近的switc


continue的用法

用于跳过本次循环余下的语句,转去判断是否需要执行下次循环

例一:
for(1;2;3)
{
    A;
    B;  
    continue;  //如果执行该语句,则执行完该语句后,会执行语句3,C和D都会被跳过去(不会被执行)
    C;
    D;
}
//若将for循环转换为while循环,3一定要放在continue上面
例二:
while(表达式)
{
    A;
    B;  
    continue;  //如果执行该语句,则执行完该语句后,会执行表达式,C和D都会被跳过去(不会被执行)
    C;
    D;

}

之前写过的代码:scanf时对用户非法输入的处理

//不用关注结果,只看while和continue的作用
#include <stdio.h>

int main()

{   
    int i;
    char ch;
    
    scanf("%d",&i);
    printf("i=%d\n",i);
    //......
    while((ch=getchar())!='\n')   //getchar()从键盘上输入的字符  \n是回车
        continue;  //继续
    int j;
    scanf("%d",&j);
    printf("j=%d\n",j);

    return 0;
}

/*-----------------------

若未写while和continue,用户输入非法后,结果会出错
因此while语句,会将用户输入的垃圾信息清楚掉

-------------------------*/

C语言为什么无法做出像样的东西

和各门课程之间的关系

c中有很多东西是其他语言中学不到的,例如函数,指针(c++中的指针源自c语言)
学c有助于后续课程的学习,
面向过程的c,到后期学习面向对象的JAVA SE
其他语言的函数与c的函数不一样,学c之后视野更加开阔 
c语言短小精悍,学起来更易上手
前面枯燥,难以理解,但基础打牢,后面的内容越容易接受

流量控制总复习

不熟悉的再去回顾一下

顺序:自上而下的执行

----------------------------

选择:if和、witch

if的范围问题  语句是否成立取决于条件是否成立
if..else:只会执行其中的一个语句
空语句的问题——分号的位置
if..else..最后面的else结尾,不要用else if(语法没错,但逻辑有漏洞)
最后的else不要有表达式

switch 看懂电梯程序
与break的关系

----------------------------

循环:for、while、do..while
for循环的执行流程问题  
for(1;2;3)1永远只执行一次

1/2的结果0

while与for的转换,二者的比较,最常用的for

do..while,先执行内部,再判断是否成立,一定会执行一次
do..while与while不能相互转换

----------------------------

break作用
在循环中用于终止循环,多层循环时终止距离最近的循环
在switch中用于终止距离最近switch
在循环内部的if中,用于终止距离最近的那个循环,不是用来终止if的

----------------------------

continue作用
for(1;2;3) 中一旦执行continue,余下的语句都不执行,直接执行3
while中一旦执行continue,余下的语句都不执行,直接执行表达式

流量控制总测试

数据结构中的一些例子,不管代码含义,只看流程
注:下面的代码都不全


例一:折半查找
//折半查找

//if..else 的嵌套

if(low == high) //条件成立,执行下一个if
{
    if(p[mid] == val) //条件成立,语句终止(后面讲return的时候讲)
    {
        return mid;
    }
    else
    {
        return -1;
    }
}
else
{
    if(p[mid]<val)
    {
        Find(p,mia+1,high,val);
    }
    else if(p[mid]>val)
    {
        Find(p,low,mid-1,val);
    }
    else if(p[mid] == val)
    {
        return mid;
    }
}

例二:冒泡排序
 i=1;
    while(flag)
    for(j=0;j<n-i;++j)
    { 
        if(a[j]>a[j+1])  //若不成立,执行++j
        {
            temp=a[j];
            a[j]=a[j+1];
            continue;   //会跳去执行++j
            a[j+1]=temp;
            flag=1;
            break;  //1,跳出for循环,到第二个break位置
        }
    }
    break;  //2,跳出while循环
    ++i;
    }    
}
例三:快速排序
while(low<high) //语句成立,执行下一个while
{
    while(high>low && a[high] >=value)  //语句成立,执行high--,不成立执行if语句
        high--;  //执行完再次判断while是否成立  本行语句执行后不执行if
    if(high!=low)  //成立执行内部的三行语句,不成立执行下面的while
    {
        t=a[low];
        a[low]=a[high];
        a[high]=t;
    }

    while(low<high && a[low]<=value)//语句成立,执行low++,不成立执行下面的if语句
        low++;
    if(low!=high) //成立执行内部的三行语句,不成立返回最上面的while
    {
        t=a[low];
        a[low]=a[high];
        a[high]=t;
    }

}
例四:do..while与continue

int i=0,s=0;

do
{
    if(i%2) //成立,执行内部两行语句   第一次循环是i%2=0,所以直接跳到第二个i++位置
    {
        i++; //1
        continue;  //之后执行while(i<5)
    }
    i++;//2
    s+=i;
}while(i<5);
printf("%d\n",s); //s最终值为9
return 0;
}
/*
执行过程
i s
0 0
1 1
2 
3 4
4 
5 9
*/
例五:for与break和continue
int a=1,b;
for(b=1;b<=10;b++)
{
    if(a>=8)
        break;  //跳到最下面的printf
    if(1 == a%2)
    {
        a+=5;
        continue;//跳到for里面的b++
    }
    a-=3;
}
printf("b=%d\n",b);

——第三部分完——

下一篇从数组开始

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值