C语言基础 流程控制

一.流程控制
1.概念:

流程控制就是指程序代码执行的顺序

2.流程控制的分类:

①顺序执行:从上往下执行,如果不使用流程控制语句,默认就是顺序执行
②选择执行:有选择地执行某些代码,不执行另一些代码,又称分支结构
③循环执行:多次执行某些代码

二.选择执行
1.if语句
在这里插入图片描述
(1)语法:

//语法1:如果表达式为真,执行pass,否则不执行
  //如果pass中只有1个语句,可以省略{...},这样if只能控制其后的第1个语句
if (<表达式>) {
    //pass1
}
//实例:
if (2>1)
    printf("%d\n",33);//结果:33
if (2)
	printf("AAA\n");//结果:AAA
if (2>3)
	printf("AAA\n");//结果:[未执行]
    printf("BBB\n");//结果:BBB
if (2>3) {
	printf("AAA\n");//结果:[未执行]
    printf("BBB\n");//结果:[未执行]
}

//语法2:如果表达式为真,则执行pass1,否则执行pass2
  //如果不加{...},else也只能控制其后的第1个语句
if (<表达式>) {
    //pass1
}
else {
    //pass2
}
//实例:
if (2>3) {
    printf("AAA\n");//结果:[未执行]
} else {
	printf("BBB\n");//结果:BBB
}

//语法3:执行第1个为真的表达式对应的pass,如果所有表达式均为假,则执行else对应的pass
  //注意:else和else if需要配合if使用,不能单独使用;也可以只使用if和else if
if (<表达式1>) {
    //pass1
} else if (<表达式2>) {
    //pass2
} else {//没有<表达式>
    //pass3
}
//实例:
double delta=-1;
if (delta>0) {
    printf("有2个解\n");//结果:[未执行]
} else if (delta==0) {
	printf("有1个解\n");//结果:[未执行]
} else {
	printf("无解\n");//结果:无解
}
double alpha=2;
if (alpha>0) {
    printf("大于0\n");//结果:大于0
} else if (alpha>=0) {
	printf("大于等于0\n");//结果:[未执行]//只执行第1个为真的分支中的语句
} else {
	printf("其他\n");//结果:[未执行]
}
double beta=2;
if (3<beta && alpha<10) {//不能写成3<beta<10,否则无论beta为何值,均为真
    printf("AAA\n");//结果:[未执行]
} else if (beta>=0) {
	printf("BBB\n");//结果:BBB
} else {
	printf("CCC\n");//结果:[未执行]
}

(2)一些格式问题:

if (3>2);
    A;
//等价于:
if (3>2)
    ;//这是1个空语句,什么都不执行
A;
//
if (<表达式>)//合法
    A;
else
    B;
if (<表达式>);//不合法
    A;
else
    B;
//
if (<表达式1>)
    A;
else if (<表达式2>)
    B;
else (<表达式3>)//不合法
    C;
//
if (<表达式1>)
    A;
else (<表达式2>);
    B;
//等价于:
if (<表达式1>)
    A;
else
    (<表达式2>);
B;

2.switch语句:
在这里插入图片描述

//语法:执行表达式的值对应的语句然后退出,如果表达式的值不为任何列出的值,执行default对应的语句然后退出
  //如果某行结尾处不加break,则会执行下1个条件的语句;故除非在最后1行,不得省略break
  //实际上case和default只是程序的入口,进入后从上往下连续执行,直到碰到break就退出
switch (<表达式>) {
    case <1>:<语句1>;break;
              ...
    default:语句4;break;//其他均不成立时执行;如果在最后1行,可以省略break
}

//注意:
1.case对应的值即常量表达式,也可称为标签
标签只能是:①枚举常量(枚举元素)②数值常量③字符常量④常变量⑤宏名
  //注意:1个枚举常量就是某个枚举中某个可能的值,如enum Boolean(Y,N)中的Y和N
标签不能是:①普通变量②枚举变量
2.switch语句是选择执行,不是循环执行
break表示退出switch语句,switch语句中不能出现continue
3.每行有2个分号(;),1个冒号(:),每行至少是2个语句
4.可以没有default语句
5.每行都可以执行多个语句

//实例:电梯程序
int i
scanf("%d",&i);//输入: ①3 ②9
switch (i) {
	case 1:printf("这是1层\n");break;
	case 2:printf("这是2层\n");break;
	case 3:printf("这是3层\n");break;//输入①后执行
	case 4:printf("这是4层\n");break;
	default:printf("没有这1层\n");//输入②后执行
}

int j
scanf("%d",&i);//输入:2
switch (j) {
	case 1:printf("这是1层\n");break;
	case 2:printf("这是2层\n");//执行
	case 3:printf("这是3层\n");break;//执行
	case 4:printf("这是4层\n");break;
	default:printf("没有这1层\n");
}

三.循环执行
1.for语句(入口条件循环):
在这里插入图片描述

//语法1:先执行初始化,条件为真时执行语句再完成增量,然后重新判断表达式是否为真;条件为假时跳出循环
  //初始化只在最开始执行1次;每次循环都是先执行语句再完成增量
  //默认只能控制1个语句,如果需要控制多个语句,需要加{...}
for (<初始化>;<条件>;<增量>) {
    <语句1>;
    <语句2>;
      ...
}//花括号内的称为"循环体"

//实例:
int i,sum=0;
for (i=1;i<=100;++i) {
    printf("%d\n",i);//结果:1 2 3 ... 100(如果是先完成增量,不应该有1而应该有101)
	sum+=i;
}
printf("%d\n",i);//结果:101
printf("%d\n",sum);//结果:5050

//注意:
int i;
//不要把i设为float(即不要把循环中的"计数变量"设为float),否则可能有误差
//使第100次循环时的i不为100,而为如99.999999/100.000001,使循环提前/延后结束
//还可能造成1/i的结果不准确
float sum=0.0;
for (i=1;i<=100;i++) {
    printf("%d\n",1/i);//结果:1 0 ... 0
    printf("%f\n",1/(float)(i));//结果:1.000000 0.500000 ... 0.010000
    printf("%f\n",(float)/(1/i));//结果:1.000000 0.000000 ... 0.000000
	sum+=1/(float)(i);
	//相当于:sum+=1.0/i;//1.0默认是double,所以会有警告
	printf("%f\n",sum);//结果:1.000000 1.500000 ... 5.187378
}
printf("%f\n",sum);//结果:5.187378

//

//语法2:for可以嵌套任意层
int i,j;
for (i=1;i<=100;i++)
    for (j=1;j<=100;j++)
        printf("%d",i+j);//结果:2 3 ... 11 3 ... 20

for (<c1>;<c2>;<c3>)
    for(<c4>;<c5>;<c6>)
        <A>;
        <B>;
//执行顺序:见下图

在这里插入图片描述

整个for循环是其所在块的"子块"(Sub-Block),循环体是整个for循环块的子块:
  //其他循环和分支语句也类似
#include <stdio.h>
int main(void) {
    int i=10;//第1个i(最外层的i)
    for (i=1;i<5;i++) {//第2个i(循环条件中的i)
        int i=100;//第3个i(循环体中的i)
        printf("%d\n",i);
        i++;
    }
    printf("%d\n",i);
    return 0;
}
//结果:
100
100
100
100
5

2.while语句(入口条件循环):

//语法:表达式为真时,执行语句,然后重新判断表达式是否为真;为假时,跳出循环
  //默认只能控制1个语句,如果需要控制多个语句,需要加{...}
while (<表达式>) {
    <语句>;
}

//实例:
int i=0;
while (i<10) {
	i++;
	printf("%d ",i);//结果:1 2 3 4 5 6 7 8 9 10
}

3.do…while语句(出口条件循环):

//语法:先执行语句,表达式为真时再次执行语句,然后重新判断表达式是否为真;为假时,跳出循环
  //注意: ①结尾的分号(;)不能省略,整体是1个语句 ②语句至少会被执行1次
  //主要用于人机交互
do {
  <语句>;
} while (<表达式>);

//实例:
int i=1;
do {
	printf("AAA ");//结果:AAA AAA AAA AAA
	i++;
} while (i<5);

int j=10;
do {
	printf("AAA ");//结果:AAA
	j++;
} while (j<5);

char m;
do {
    printf("ASD\n");//结果:ASD ASD ASD
    scanf("%c",&m);//输入:y Y k
    fflush(stdin);
} while (m=='Y'||m=='y')//注意:如果用" "包裹,必须输入y\n或Y\n,因为"y"结尾默认有\n

4.各种循环间的转换:

forwhile等价:
  //即任何for循环均可转换成while循环,反之亦然

for (1;2;3) {
    A;
}
//等价于:
1;
while (2) {
    A;
    3;
}

//

do while循环和for/while循环不等价
  //有些for/while循环无法转换成do while循环(因为do while至少执行1次语句)

三.终止语句
1.break:

//语法:
break;

//功能:
1.跳出for/while循环
2.终止switch语句的执行

//实例:
while (1<2) {
	printf("aaa");//结果:aaa
	break;
}

int i;
scanf("%d",&i);
switch (i) {
	case 1:printf("这是1层\n");//结果:执行
	case 2:printf("这是2层\n");//结果:执行
	case 3:printf("这是3层\n");break;//结果:执行
	case 4:printf("这是4层\n");
}

//注意:break用于for循环时会直接终止,连增量语句一起跳过剩下的所有语句
int c;
char ch;
printf("input:");
for (c=0;c<10;c++) {
	ch=getchar();
	if (ch=='\n') {
		break;
	}
	putchar(ch);
	printf("%d ",c);
}
printf("%d\n",c);
//结果:
//input:ksjd
//k0 s1 j2 d3 4//c最终为d这1轮结束后的值,而没有再自增1次

2.continue:

//语法:
continue;

//功能:
终止本次循环,直接开始判断是否需要执行下次循环

//实例:
int i=0;
while (i<5) {
	if (i==3) {
	    i++;
		continue;
	}
	printf("%d",i);//结果:0 1 2 4
	i++;
}

//注意:continue用于for循环,终止本轮循环后,会先执行本轮的增量语句再进行下1轮循环
int c;
char ch;
printf("input:");
for (c=0;c<10;c++) {
	ch=getchar();
	if (ch=='\n') {
		continue;
	}
	putchar(ch);
	printf("%d ",c);
}
printf("%d\n",c);
//结果:
//input:klakd
//k0 l1 a2 k3 d4 sdsdfasas
//s6 d7 s8 d9 10//c最终是10,并没有跳过任何1次自增//并且第2次输入后c从6而不是5开始

四.跳转语句

谨慎使用goto语句,这会使程序的控制流变得难以追踪

1.语法:

//跳转到指定标签处(把控制转移到指定语句处):
goto <label>;
//定义标签:
<label>:{<cmd1>;<cmd2>;...}
  //注意:标签只是给相应语句做了标识,这些语句仍会在正常的流程中被执行
  //参数说明:
    label:指定标签
      //标签的命名遵循标识符的命名规则
    cmd:指定该标签对应的语句
      //如果goto只有1个语句要控制,可以省略{...}
      //对Fortran/BASIC来说,不能使用复合语句

//实例:
#include <stdio.h>

int main(void) {
	int a = 10;
    LOOP:do {
        if( a == 15) {
            a = a + 1;
            goto LOOP;
        }
        printf("%d ",a);
        a = a + 1;
    } while( a < 20 );
    P:printf("end");//即使被标签标识了,也会在正常的流程中执行
	return 0;
}
//结果:
10 11 12 13 14 16 17 18 19 end

2.退出嵌套循环:

#include <stdio.h>

int main(void) {
	int i;
	for (i=0;i<10;i++) {
		int j;
		for (j=0;j<10;j++) {
			int k;
			for (k=0;k<10;k++) {
				if (i-j+k==11) {
				    printf("goto end ");
					goto END;
				}
				printf("%d ",i-j+k);
			}
			printf("\n");
		}
	}
	END:printf("end");
	return 0;
}
//结果:
0 1 2 3 4 5 6 7 8 9
-1 0 1 2 3 4 5 6 7 8
-2 -1 0 1 2 3 4 5 6 7
-3 -2 -1 0 1 2 3 4 5 6
-4 -3 -2 -1 0 1 2 3 4 5
-5 -4 -3 -2 -1 0 1 2 3 4
-6 -5 -4 -3 -2 -1 0 1 2 3
-7 -6 -5 -4 -3 -2 -1 0 1 2
-8 -7 -6 -5 -4 -3 -2 -1 0 1
-9 -8 -7 -6 -5 -4 -3 -2 -1 0
1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
-1 0 1 2 3 4 5 6 7 8
-2 -1 0 1 2 3 4 5 6 7
-3 -2 -1 0 1 2 3 4 5 6
-4 -3 -2 -1 0 1 2 3 4 5
-5 -4 -3 -2 -1 0 1 2 3 4
-6 -5 -4 -3 -2 -1 0 1 2 3
-7 -6 -5 -4 -3 -2 -1 0 1 2
-8 -7 -6 -5 -4 -3 -2 -1 0 1
2 3 4 5 6 7 8 9 10 goto end end

3.与终止语句:

breakcontinuegoto的特殊形式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值