C零基础自学笔记<3>

发布时间:2024年01月18日

上一篇中提到:

流程控制? 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);

——第三部分完——

下一篇从数组开始

文章来源:https://blog.csdn.net/sinat_37181108/article/details/135427899
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。