分支和循环(上)

目录

1. if语句

1.1 if

​1.2 else

1.3 分支中包含多条语句

1.4 嵌套if

1.5 悬空else问题

2. 关系操作符

3. 条件操作符

4. 逻辑操作符

4.1 逻辑取反操作符

4.2 逻辑与运算符

4.3 逻辑或运算符

4.4 连续:闰年的判断

4.5 短路

5. switch语句

5.1 if语句和switch语句的对比

5.2 switch语句中的break

5.3 switch语句中的default

5.4 case和default的顺序

6. while循环

6.1 if和while的对比

6.2 while语句的执行流程

6.2 while循环的实践

6.4 练习

7. for循环

7.1 语法形式

 7.2 for循环的执行流程

7.3 for循环的实践

7.4 while循环和for循环的对比

7.5 练习

8. do while循环

8.1 语法形式

8.2 do while循环的执行流程

8.3 do while循环的实践

8.4 练习

9. break和continue语句

9.1 while循环中的continue和break

9.1.1 break举例

9.1.2 continue举例

9.2 for循环中的continue和break

9.2.1 break举例

9.2.2 continue举例

9.3 do while循环中的continue和break

9.3.1 break举例

9.3.2 continue举例

10. 循环的嵌套

10.1 练习

10.2 题目解析:

10.3 代码

 11. goto语句


C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构、C语言是能够实现这三种结构的,其实我们如果仔细分析,我们日常中的事情都可以拆分为这三种结构或者这三种结构的组合。

我们可以使用if、switch实现分支结构,使用for、while、do while、实现循环结构。

1. if语句

1.1 if

if的语法形式:

if(表达式)
    语句;

表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行。

在C语言中,0为假,非0为真,也就是说表达式的结构如果是0,则语句不执行,表达式的结构如果为非0,则语句执行。

#include <stdio.h>
int main()
{
	if (1 == 2)
		printf("hello world\n");
	return 0;
}

这段代码是不会输出任何结果的,因为1是不可能等于2的。 

#include <stdio.h>
int main()
{
	if (2 == 2)
		printf("hello world\n");
	return 0;
}

那如果改成2和2判断相等,条件肯定为真,所以屏幕上就输出hello world。

例子:输入一个整数,判断是否为奇数

#include <stdio.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a % 2 != 0)
		printf("%d是奇数\n", a);
	return 0;
}

1.2 else

如果一个数不是奇数,那么就肯定是偶数,对于任意一个数,我们要清楚的判断是奇数还是偶数,那么这个时候就需要用到if....else....语句了。

if(表达式)
    语句1;
else
    语句2;

例子:输入一个整数,判断是否为奇数,如果是奇数就打印奇数,是偶数就打印偶数。

#include <stdio.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a % 2 != 0)
		printf("%d是奇数\n", a);
	else
		printf("%d是偶数\n", a);
	return 0;
}

练习:输入一个年龄,>=18岁就输出:成年,否则就输出:未成年

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
		printf("成年\n");
	else
		printf("未成年\n");
	return 0;
}

1.3 分支中包含多条语句

默认在if和else语句中默认都控制一条语句。所以我们要控制一条语句以上的化就得加大括号。

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
		printf("成年\n");
		printf("可以谈恋爱了\n");
	return 0;
}

上面的代码,你会发现输入的值不管是>=18还是<18,"可以谈恋爱"都会打印在屏幕上。

这是因为 if 语句只能控制⼀条语句,就是 printf(" 成年了 \n"); ,if语句为真,则打印成年了, if语句为假,则不打印,对于 printf(" 可以谈恋爱了 \n"); 是独⽴存在的,不管if语句的条件的真假,都会被执⾏。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使⽤ else 后也可以跟上大括号。如下:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
	{
		printf("成年\n");
		printf("可以谈恋爱了\n");
	}
	else
	{
		printf("未成年\n");
		printf("不可以谈恋爱\n");
	}
	return 0;
}

1.4 嵌套if

在if else语句中,else可以与另一个if语句连用,构成多重判断。

比如:要求输入一个整数,判断输入的整数时是0,还是正数或者负数。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num == 0)
		printf("输入的值是0\n");
	else
	{
		if (num > 0)
			printf("输入的值是正数\n");
		else
			printf("输入的值是负数\n");
	}
	return 0;
}

这段代码我们还可以改造一下。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num == 0)
		printf("输入的值是0\n");
	else if (num > 0)
		printf("输入的值是正数\n");
	else
		printf("输入的值是负数\n");
	return 0;
}

有了嵌套if语句,就可以完成更多复杂逻辑的判断。

练习:

输⼊⼀个⼈的年龄

如果年龄 <18 岁,打印 " 少年 "

如果年龄在 18 岁⾄ 44 岁打印 " ⻘年 "

如果年龄在 45 岁⾄ 59 岁打印 " 中⽼年 "

如果年龄在 60 岁⾄ 89 岁打印 " ⽼年 "

如果 90 岁及以上打印 " ⽼寿星 "

代码:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
		printf("少年\n");
	else if (age >= 18 && age <= 44)
		printf("青年\n");
	else if (age >= 45 && age <= 59)
		printf("中老年\n");
	else if (age >= 60 && age <= 89)
		printf("老年\n");
	else
		printf("老寿星\n");
	return 0;
}

1.5 悬空else问题

如果有多个if和else,可以记住这样一条规则,else总是跟最近的if匹配。

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hehe\n");
	else
		printf("haha\n");
	return 0;
}

 a是0,不等于1,条件为假,走else,打印哈哈,当你这样想的时候就错了。

当我运行代码的时候,发现什么都不输出。 

这就是悬空else的问题,如果有多个 的 if 匹配。上⾯的代码排版,让 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的if匹配。

else 和第⼀个 if 语句对齐,让我们以为 语句不成立的时候,⾃然想到的就是执行else子句,打印 else 是和第⼀个if匹配的,当 进⾏匹配的,这样后边的 haha ,但实际上 if...else 语句是嵌套在第⼀个if else 是和第⼆个 if 成立,嵌套 if 和 if 语句中的,如果第⼀个 if 语句就不 else 就没机会执⾏了,最终啥都不打印。

如果代码改成下⾯这样就更加容易理解了。

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
			printf("hehe\n");
		else
			printf("haha\n");
	}
	return 0;
}

 只要带上适当的大括号,代码的逻辑就会更加清晰。

2. 关系操作符

C语言用于比较的表达式,称为"关系表达式"(relational expression),里面使用的运算符就称为"关系运算符"(relational operator),主要有下面6个。

  • > 大于运算符
  • < 小于运算符
  • >= 大于等于运算符
  • <= 小于等于运算符
  • == 相等运算符
  • != 不相等运算符

例子:

 a == b;
 a != b;
 a < b;
 a > b;
 a <= b;
 a >= b;

关系表达式通常返回0或1,表示真假。

C语言中,0表示假,所有非0表示真,比如20 > 12返回1,12 > 20返回0。

关系表达式常用于if或while结构。

 if (x == 3) {
     printf("x is 3.\n");
 }

注意:相等运算符 == 与赋值运算符 = 是两个不一样的运算符,不要混淆,有可能会写成下面的代码,但是这种代码可以运行,结构就是意料之外的。

if (a = 3)
{
    //....
}

上面的示例中,原本是x == 3,但是不小心写成x = 3。这个式子的意思就是对变量x 进行赋值,它的返回值为3,所以if判断总是为真。 

为了防止这种错误,有的程序员喜欢将变量写在等号的右边。

if(x == x)
{
    //......
}

如果这样写的化吧 == 写成  = ,编译器就会报错。

if(3 = x)
{
    //.....err - 常量不能赋给变量
}

另一个需要避免的错误是:多个关系运算符不宜连用。

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 8;
	int c = 5;
	if (a < b < c)
		printf("hello world!\n");
	return 0;
}

这种代码能输出是因为表达式是从左到右依次计算,a < b条件为假,也就是为0,0 < 5,条件为真,大于输出。

所以我们应该这样写。

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 8;
	int c = 5;
	if (a < b && b < c)
		printf("hello world!\n");
	return 0;
}

 比如:我们输入一个年龄,如果年龄在18岁~36岁之间,我们输出青年。

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	//if ( 18 <= age <= 36) - err
	if (age >= 18 && age <= 36)
	{
		printf("青年\n");
	}
	return 0;
}

3. 条件操作符

条件操作符也叫三目操作符,需要接收三个操作数的。

exp1 ? exp2 : exp3

条件操作符的计算逻辑是:如果exp1为真,exp2计算,计算的结果是整个表达式的结果。如果exp1为假,exp3计算,计算的结果是整个表达式的结果。

例子:如果a大于10的话b是1,否则b就是-1。

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	if (a > 10)
		b = 1;
	else
		b = -1;
	printf("b = %d\n", b);
}

那么针对这段代码,我们就可以使用三目操作符。

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	b = a > 10 ? 1 : -1;
	printf("b = %d\n", b);
	return 0;
}

使用条件表达式实现找两个数中的较大值。

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = a > b ? a : b;
	printf("较大值是:%d\n", max);
	return 0;
}

4. 逻辑操作符

逻辑操作符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。

  • ! : 逻辑取反运算符(改变单个表达式的真假)。
  • && :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
  • || : 逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。

注 :在C语言中,非0表示真,0表示假

4.1 逻辑取反操作符

 代码:

#include <stdio.h>
int main()
{
	int flag = 0;
	scanf("%d", &flag);
	if (!flag)
	{
		printf("hello world!\n");
	}
	return 0;
}

输入1,为真,逻辑反操作变成假,不进入判断,则什么都不输出。

输入0,为假,逻辑反操作变成真,进入判断,输出hello world。

4.2 逻辑与运算符

&& 就是与运算符,也是并且的意思, && 是一个双目操作符,使用的方式是a&&b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一个为假,则整个表达式为假。 

比如:如果我们用代码实现判断春天,我们应该怎么写呢?

#include <stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month >= 3 && month <= 5)
	{
		printf("春天\n");
	}
	return 0;
}

 这里表达的意思是month既要大于等于3,又要小于等于5,必须同时满足。

4.3 逻辑或运算符

|| 就是或运算符,也就是或者的意思, || 也是一个双目操作符,使用的方式是 a || b, ||两边的表达式只要有一个是真的,整个表达式就是真的,两边的表达式都为假的时候,才为假。

比如:我们说一年中月份是12月或者1月或则2月是冬天,那么我们怎么使用代码体现呢?

#include <stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month == 1 || month == 2 || month == 12)
		printf("冬天\n");
	return 0;
}

4.4 连续:闰年的判断

输入一个年份year,判断year是否是闰年。

  1. 能被4整除并且不能被100整除是闰年
  2. 能被400整除是闰年

代码:

#include <stdio.h>
int main()
{
	int year = 0;
	scanf("%d", &year);
	if (year % 4 == 0 && year % 100 != 0)
	{
		printf("%d年是闰年\n", year);
	}
	else if (year % 400 == 0)
	{
		printf("%d年是闰年\n", year);
	}
	return 0;
}

这个代码我们还可以优化一下。

#include <stdio.h>
int main()
{
	int year = 0;
	scanf("%d", &year);
	if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
		printf("%d年是闰年\n", year);
	return 0;
}

4.5 短路

C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。

如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值,这种情况称为"短路"。

if(month >= 3 && month <= 5)
{
    //.........
}

表达式中&&的做操作数是month >= 3,右操作数是month <= 5,当左操作数month >= 3的结果是0的时候,即使不判断month <= 5,整个表达式的结果也是0,不是春天。

所以对于&&操作符来说,左边操作数是0的时候,右边操作数不再执行。

那么对于||操作符是怎么样呢?

if(month == 1 || month == 2 || month == 12)
{
    //..........
}

 如果month == 1,则不用再判断month是否等于1或者2,整个表达式的结果也是1,是冬季。
所以, || 操作符的左操作数的结果不为0时,就无需执行右操作数。

像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。

下面代码的执行结果是什么?

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("i = %d\n a = %d\n b = %d\n c = %d\nd = %d\n",i, a, b, c, d);
	return 0;
}

因为a++是后置++,所以是先用,后++,此时第一个表达式的结果为0,对于&&来说,第一个表达式为0,后面的表达式则不用计算,整体表达式为0,那么第一个&&的结果就是0,第二个&&的左边是0,那么右边也是0,所以整个表达式的结果就是0,所以i = 0,a = 1,b = 2,c = 3.d = 4。 

当我们把&&改为||结果又是什么呢?

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++||++b||d++;
	printf("i = %d\n a = %d\n b = %d\n c = %d\nd = %d\n",i, a, b, c, d);
	return 0;
}

a++,后置++,先使用,后计算,第一个表达式为假,则计算第二个表达式,前置++,先++,后使用,所以b = 3,则第一个||为真,对于||运算来说左边的表达式为真 ,则不再计算右边的表达式,所以整体表达式为真,则i = 1,a = 1,b = 3,c = 3,d = 4

5. switch语句

除了if语句外,C语言还提供了switch语句来实现分支结构,switch就是开关的意思。

switch语句是一种特殊形式的if....else结构,用于判断条件有多个结果的情况,它把多重的else if改写成易用,可读性更好的形式,但是有的else if语句改成switch的话特别别扭。

switch(expression)
{
    case value1: statement
    case value2: statement
    default: statement
}

上面代码中,根据表达式expression不同的值,执行相应的case分支,如果找不到对应的值,就执行default分支。

注:

  • switch后的expression必须是整型表达式
  • case后的值,必须是整型常量表达式
  • 比如浮点数就不行,字符类型可以,因为字符类型也是归类到整型家族的,因为字符本质就是ASCII码值,而ASCII码值是整数。

5.1 if语句和switch语句的对比

输入任意一个整数值,计算除3之后的余数。

代码:

#include <stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	if (n % 3 == 0)
		printf("余数是0\n");
	else if (n % 3 == 1)
		printf("余数是1\n");
	else if (n % 3 == 2)
		printf("余数是2\n");
	return 0;
}

如果用switch写的话就可以这样写。

#include <stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	switch (n % 3)
	{
	case 0:
		printf("余数是0\n");
		break;
	case 1:
		printf("余数是1\n");
		break;
	case 2:
		printf("于是是2\n");
		break;
	}
	return 0;
}

上述的代码中,我们要注意的点有:

  1. case和后边的数字之间必须有空格
  2. 每一个case语句中的代码执行完成后,需要加上break,才能跳出这个switch语句 。

5.2 switch语句中的break

break是打断,停止的意思。

前面的代码,如果我们去掉break,会出现什么情况呢?

#include <stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	switch (n % 3)
	{
	case 0:
		printf("余数是0\n");
	case 1:
		printf("余数是1\n");
	case 2:
		printf("于是是2\n");
	}
	return 0;
}

switch语句具有透传功能,所以要加上break,当我们输入3,余数是0,从case0进入,打印,打印完成没有遇到break,就继续执行case2,直到遇到break,或者代码运行完成。

当然,break也不是每个case语句都得有,这就得根据实际情况来看了。

练习:

输⼊⼀个1~7的数字,打印对应的星期⼏

例如:

输⼊:1 输出:星期⼀ 输⼊:

2 输出:星期⼆ 输⼊:

3 输出:星期三 输⼊:

4 输出:星期四 输⼊:

5 输出:星期五 输⼊:

6 输出:星期六 输⼊:

7 输出:星期天 

代码:

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch(day)
	{
		case 1:
			printf("星期一\n");
			break;
		case 2:
			printf("星期二\n");
			break;
		case 3:
			printf("星期三\n");
			break;
		case 4:
			printf("星期四\n");
			break;
		case 5:
			printf("星期五\n");
			break;
		case 6:
			printf("星期六\n");
			break;
		case 7:
			printf("星期天\n");
			break;
	}
	return 0;
}

 如果需求发生了变化,变为:

  1. 输入1~5,输出的是"工作日";
  2. 输如6~7,输出的是"休息日";

代码:

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	}
	return 0;
}

5.3 switch语句中的default

在使用switch语句的时候,我们这里经常可能遇到一种情况,比如switch后的表达式中的值无法匹配代码中的case语句的时候,这个时候要不就不做处理,要不就在switch中加入default子句。

switch (expression) {
     case value1: statement
     case value2: statement
     default: statement
 }

switch后面的expression的结果不是value1,也不是value2的时候,就会执行default子句。

就比如前面写的打印星期的代码,如果day的值不是1~7的时候,我们就要提示。

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期一\n");
		break;
	case 2:
		printf("星期二\n");
		break;
	case 3:
		printf("星期三\n");
		break;
	case 4:
		printf("星期四\n");
		break;
	case 5:
		printf("星期五\n");
		break;
	case 6:
		printf("星期六\n");
		break;
	case 7:
		printf("星期天\n");
		break;
	default:
		printf("输入错误,输入的范围应在1~7");
		break;
	}
	return 0;
}

5.4 case和default的顺序

在switch语句中case子句和default子句是没有顺序要求的,只要顺序是满足实际需求的就可以。

不过我们通常是把default子句放在最后处理的。

6. while循环

C语言提供了3种循环语句,while就是其中一种,while语句的语法结构和if语句非常相似。

6.1 if和while的对比

if(表达式)
    语句;

while(表达式)
    语句;//如果循环体要包含更多的语句,就要加上大括号

对比:

//if
#include <stdio.h>
int main()
{
	if (1)
		printf("hello world!\n");//条件满足,打印一次
	return 0;
}
//while
#include <stdio.h>
int main()
{
	while (1)
		printf("hello world!\n");//条件满足,循环打印
	return 0;
}

while是实现循环的。

6.2 while语句的执行流程

 首先上来就是执行判断表达式,表达式的值为0,循环直接结束,表达式的值不为0,则执行循环语句,语句执行完后再继续判断,是否进入循环。

6.2 while循环的实践

在屏幕上打印1~10的值。

#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d ", i);
		i++;
	}
	return 0;
}

6.4 练习

输⼊⼀个正的整数,逆序打印这个整数的每⼀位

例如:

输⼊:1234,输出:4321

输⼊:521,输出:125 

题目解析:

  1. 要想得到n的最低位,可以使⽤n%10的运算,得到的余数就是最低位,如:1234%10得到4
  2. 要想去掉n的最低位,找出倒数第⼆位,则使⽤ n=n/10操作就可以去掉最低位的,如: n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第⼆位3。
  3. 循环1和2两个步骤,在n变成0之前,就能到所有的位。
#include <stdio.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	while (a)
	{
		printf("%d ", a % 10);
		a /= 10;
	}
	return 0;
}

7. for循环

7.1 语法形式

for循环时三种循环种使用最多的。

for(表达式1; 表达式2; 表达式3)
    语句;//如果循环体想包含更多的语句,可以加上⼤括号
  • 表达式1用于循环变量的初始化
  • 表达式2用于循环结束条件的判断
  • 表达式3用于循环变量的调整

 7.2 for循环的执行流程

⾸先执⾏ ==0,则循环结束; 表达式 2 的判断部分,表达式 2 的结果如果表达式2的结果如果!=0则执⾏循环语句,循环语句执行完后,再去执行表表达式2 的执行执⾏判断,3调整循环变量,然后再去达式表达式2的结果是否为0,决定循环是否继续。 

整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2、循环语句、表达式3,再循环。

7.3 for循环的实践

在屏幕上打印1~10的值。

 代码:

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

运行结果:

 

7.4 while循环和for循环的对比

for和while在实现循环的过程中都有初始化、判断、调整这三个部分,但是 分⾮常集中,便于代码的维护,而如果代码较多的时候式上for 循环要更优⼀些。 

7.5 练习

计算1~100之间3的倍数的数字之和。

代码:

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

其实我们还可以对这个代码优化一下。

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

8. do while循环

8.1 语法形式

在循环语句中do while语句使用最少。

do
    语句;
while(表达式);

while和for这两种循环都是先判断,条件满足就进入循环,执行循环语句,如果不满足就跳出循环。

而do while循环则是先直接进入循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,就会进行下一次循环,表达式为假,则不再继续循环。

8.2 do while循环的执行流程

在do while循环中先执⾏图上的“语句”,执⾏完语句,在去执⾏“判断表达式”,判断表达式的结果是!=0,则继续循环,执⾏循环语句;判断表达式的结果==0,则循环结束。

所以在do while语句中循环体是⾄少执行⼀次的,这是 do while 循环比较特殊的地方。 

8.3 do while循环的实践

在屏幕上打印1~10的值。

#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

一般do while使用在循环体至少被执行一次的场景下,所以较少一些。

8.4 练习

输⼊⼀个正整数,计算这个整数是几位数?

例如:

输⼊:1234 输出:4

输⼊:12 输出:2 

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	do
	{
		i++;
		num /= 10;
	} while (num);
	printf("%d\n", i);
	return 0;
}

这里并非使用do while语句,但是这个代码就比较适合使用do while语句,因为即使n是0,也是1位数。

9. break和continue语句

在循环执行的过程中,如果某些状况发生的适合,需要提前终止循环,这是非常常见的现象。C语言中提供了break和continue两个关键字,就是应用到循环中的。

  • break的作用是用于永久的终止循环,只要break被执行,直接就会跳出循环,继续往后执行。
  • continue的作用是跳过本次循环中的continue后面的代码,在for循环和while循环中有所差异。

9.1 while循环中的continue和break

9.1.1 break举例
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			break;
		printf("%d ", i);
		i++;
	}
	return 0;
}

运行结果:

打印了1,2,3,4后,当i等于5的时候,循环在 break 的地地方终止,不再打印,不再循环。

所以break的作⽤就是永久的终止循环,只要break被执行, break 外的第⼀层循环就终止了。 那以后我们在循环中,想在某种条件下终止循环,则可以使⽤break来完成我们想要的效果。 

9.1.2 continue举例
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			continue;
			//当i等于5后,就执行continue,直接跳过后面的代码
			//使得调整部分也跳过了,所以代码会死循环
		printf("%d ", i);
		i++;
	}
	return 0;
}

到这⾥我们就能分析出来, continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,直接 到循环的判断部分,进行下⼀次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。

9.2 for循环中的continue和break

9.2.1 break举例

和while循环中的break一样,for循环中的break也是用于终止循环。

#include <stdio.h>
int main()
{
	for (int i = 1; i <= 10; i++)
	{
		if (5 == i)
			break;
		printf("%d ", i);
	}
	return 0;
}

 运行结果:

break的作用是永久的终止循环。

9.2.2 continue举例
#include <stdio.h>
int main()
{
	for (int i = 1; i <= 10; i++)
	{
		if (5 == i)
			continue;
		printf("%d ", i);
	}
	return 0;
}

 运行结果:

所以在 for 循环中continue 的作⽤是跳过本次循环中 continue 后的代码,直接去到循环的调 整部分。未来当某个条件发⽣的时候,本次循环⽆需再执行后续某些操作的时候,就可以使用 continue来实现。 

while循环中和for循环中continue的区别。

 

在while循环中continue跳过了调整部分,使得代码死循环,而在for循环中continue没有跳过调整部分,知识当i是5的适合,跳过打印而已,不会造成死循环。 

9.3 do while循环中的continue和break

9.3.1 break举例
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			break;
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

运行结果:

 当i为5的时候跳出循环,所以只打印1,2,3,4。

9.3.2 continue举例
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			continue;
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

 运行结果:

当i是5的时候执行continue,跳过了调整部分,使得代码死循环。

10. 循环的嵌套

 前⾯学习了三种循环 while 、 do while、 for ,这三种循环往往会嵌套在⼀起才能更好的解决问题,就是我们所说的:循环嵌套。

10.1 练习

找出100~200之间的素数,并打印在屏幕上。

注:素数又称质数,只能被1和本身整除的数字。

10.2 题目解析:

  1. 要从100~200之间找出素数,⾸先得有100~200之间的数,这⾥可以使⽤循环解决。
  2. 假设要判断i是否为素数,需要拿2~i-1之间的数字去试除i,需要产⽣2~i-1之间的数字,也可以使用循环解决。
  3. 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。

10.3 代码

#include <stdio.h>
#include <math.h>//sqrt头文件
//sqrt是一个库函数 - 计算平方根的
int main()
{
	int flag = 0;
	//for (int i = 100; i <= 200; i++) 
	for (int i = 101; i <= 200; i+=2)//优化:偶数都是素数 - 可以排除
	{
		flag = 0;//假设i是素数
		//for (int j = 2; j <= i - 1; j++)
		for (int j = 2; j <= sqrt(i); j++)//优化:
			/*
			如果 m = a * b
			那么a和b中至少有一个数字是<= 开平方m的(根号m)
			16 = 4 * 4
			   = 2 * 8
			如果要判断i是否是素数时,只要判断2~根号i之间
			有因子能整除i就说明不是素数
			*/
		{
			if (i % j == 0)
			{
				flag = 1;//不是素数
				break;
			}
		}
		if (!flag)//如果是素数就打印
			printf("%d ", i);
	}
	return 0;
}

 11. goto语句

C语言提供了一种非常特别的语法,就是goto语句和跳转标号,goto语句可以实现在同一函数内跳转到设置好的标号处。

例如:

#include <stdio.h>
int main()
{
	printf("1\n");
	goto next;
	printf("2\n");
next:
	printf("3\n");
	return 0;
}

输出结果: 

当执行到goto语句的地方,就直接到next地方,跳过了2的打印,所以打印1,3。

goto语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们的建议是能不⽤尽量不去使⽤;但是使⽤ goto 就⾮常的方便了。 

for (...)
{
	for (...)
	{
		for (...)
		{
			if (disaster)
				goto error;
		}
	}
}
error:
//...

for循环想提前退出得使用break,一个break只能跳出一层for循环,如果3层循环嵌套就得使用3个break才能跳出循环,所以在这种情况下我们使用goto语句就会更加的快捷。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值