分支和循环(上)

news2024/9/24 7:24:04

目录

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语句就会更加的快捷。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

28. 双耳配对 - 配置

1. 概述 通过MAC地址的最后一位的奇偶来判断左右耳 2. 验证 右耳:奇数(主耳)-》BT ADDR: 12:42:22:34:34:6d 左耳:偶数(从耳)-》BT ADDR: 12:42:22:34:34:6c

K8S - 理解volumeMounts 中的subpath

在上一篇文章中 springboot service如何动态读取外部配置文件 介绍了springboot 中如何实时读取外部配置文件的内容 部署在K8S 接下来我把它部署在k8s 首先&#xff0c; 我们把配置文件放入项目某个目录 这步部是必须的&#xff0c; 毕竟我们要引入是项目外部的文件&#xf…

TI DSP TMS320F280025 Note9:GPIO输入输出与外部中断功能原理与应用

TMS320F280025 GPIO输入输出与外部中断功能原理与应用 文章目录 TMS320F280025 GPIO输入输出与外部中断功能原理与应用GPIO原理输入输出模式的共同特性1. 复用设置2. 内部上拉设置3. GPIO状态读取 对于输出模式输出电平设置开漏输出设置 对于输入模式极性设置采样类型不同步(异…

CSS3换装达人原理

引言 换装或者是换皮肤是常见的行为&#xff0c;我们可以先看下效果&#xff1a; 选择不同的颜色&#xff0c;就可以秒变人物服装的颜色&#xff0c;原理其实非常简单 实现步骤 主要分为三步&#xff0c;即素材的提供、布局样式、动态控制 图片提供 提供两张图片&#xff…

每日OJ_牛客_红与黑(简单dfs)

目录 牛客_红与黑&#xff08;简单dfs&#xff09; 解析代码 牛客_红与黑&#xff08;简单dfs&#xff09; 红与黑__牛客网 解析代码 循环接收每组用例&#xff0c;对于每组用例进行如下操作&#xff1a; 1. 找到‘’所在的位置&#xff0c;即起始搜索的点 2. 使用DFS搜索地…

20240831-PostgreSQL小课持续更新

PostgreSQL 小课专栏介绍 PostgreSQL 小课目前已累积了近 21 万字。小课最新的大纲&#xff1a; 目前已完成大概 95% 的进度&#xff1a; (venv312) ➜ mypostgres git:(dev) sh scripts/word_statistics_pg_style.shFilename …

【微服务】限流、熔断和降级(持续更新中~)

1、限流 1.1 什么是限流 限流&#xff08;Rate Limiting&#xff09;是一种常用的技术手段&#xff0c;用于控制系统对资源的访问速率&#xff0c;确保系统的稳定性和可靠性。在分布式系统、Web服务、API接口等场景中&#xff0c;限流尤为重要。通过限制请求的频率或数量&…

uniapp u--input实现select下拉列表 input点击事件

背景&#xff1a; 技术框架&#xff1a; uniapp框架(vue2语法)uView组件库。 通过form表单实现数据列表的“查询”功能。注意&#xff1a; 1、<u--form>内部嵌套<u-form-item>&#xff0c;<u-form-item>内部嵌套<u--input>表单组件。 2、H5浏览器端&am…

华为 HCIP-Datacom H12-821 题库

有需要题库的可以看主页置顶 1.MSTP 有不同的端口角色&#xff0c;对此说法不正确的是&#xff1a; A、MSTP 中除边缘端口外&#xff0c;其他端口角色都参与 MSTP 的计算过程 B、MSTP 同一端口在不同的生成树实例中可以担任不同的角色。 C、MSTP 域边缘端口是指位于 MST 域的边…

QT实战项目之音乐播放器

项目效果演示 myMusicShow 项目概述 在本QT音乐播放器实战项目中&#xff0c;开发环境使用的是QT Creator5.14版本。该项目实现了音乐播放器的基本功能&#xff0c;例如开始播放、停止播放、下一首播放、上一首播放、调节音量、调节倍速、设置音乐播放模式等。同时还具备搜索功…

SPR系列单点激光测距传感器|模组之RS485串口调试说明

SPR系列单点激光测距传感器|模组是一款近程红外测距传感器&#xff0c;测距距离可达0-10米&#xff0c;可用于对物体进行非接触式距离测量&#xff0c;其应用场景十分广泛工业自动化&#xff1a;在生产线、传送带等工业自动化场景中&#xff0c;可以使用红外测距传感器进行物体…

Git安装及配置

Git安装 在你开始使用 Git 前,需要将它安装在你的计算机上。 即便已经安装,最好将它升级到最新的版本。 你可以通过软件包或者其它安装程序来安装,或者下载源码编译安装。 下面,我们将会介绍不同操作系统上 Git 的安装方法。 在 Windows 上安装 在 Windows 上安装 Git 的…

LangChain基础知识

这篇文档介绍了LangChain大模型应用开发框架的入门知识和核心内容&#xff0c;包括LangChain是什么、为什么需要它、典型使用场景、基础概念与模块化设计等。同时&#xff0c;还详细阐述了该框架的核心模块如标准化的大模型抽象、大模型应用的最佳实践、赋予应用记忆的能力、框…

JDBC |封装JDBCUtils|PreparedStatement|事务|批处理|数据库连接池| Blob类型数据的读写|Apache—DBUtils简介

一.概述 在Java中&#xff0c;数据库存取技术可分为如下几类&#xff1a; JDBC直接访问数据库JDO技术&#xff08;Java Data Object&#xff09;第三方O/R工具&#xff0c;如Hibernate, Mybatis 等 JDBC是java访问数据库的基石&#xff0c;JDO, Hibernate等只是更好的封装了J…

计算多图的等价无向图的邻接链表表示

计算多图的等价无向图的邻接链表表示 摘要:一、引言二、算法思路三、伪代码实现四、C代码实现五、算法分析六、结论摘要: 在图论中,多图(Multigraph)是一种允许边重复以及存在自循环边(即一个顶点到其自身的边)的图。给定一个多图的邻接链表表示,本文旨在探讨如何构造…

用EA和SysML一步步建模(03)创建包图和包的关系

用EA和SysML一步步建模的操作指南&#xff08;01&#xff09; 用EA和SysML一步步建模&#xff08;02&#xff09;导入ISO-80000 接下来&#xff0c;按照下图添加上其他的包&#xff1a; 步骤 2.2 选中Browser中的“蒸馏器项目”&#xff0c;点击New Package&#xff08;Br…

windows C++ 并行编程-C++ AMP 图形(二)

文中的"显存"还没有找到合适的中文翻译&#xff0c;它的英文名称是texture&#xff0c; 在应用开发者来看,texture是一个名词,在物理上指的是 GPU显存中一段连续的空间。 读取显存对象 可以使用 texture::operator[]、texture::operator() 运算符或 texture::get 方…

物流需求回复势头稳定,目前全国社会物流总额达197.7万亿元

中国物流与采购联合会29日公布今年1-7月份物流运行数据。数据显示&#xff0c;物流需求恢复势头基本稳定&#xff0c;7月份虽受部分地区高温多雨等短期因素扰动&#xff0c;但物流总额增速环比有所提升&#xff0c;呈现温和回升态势。 今年1-7月份&#xff0c;全国社会物流总额…

数据仓库系列17:元数据管理在数据仓库中的作用是什么?

想象一下,你正在管理一个巨大的图书馆,里面存放着数以万计的书籍。但是,这个图书馆没有任何目录、索引或分类系统。你能想象找到特定的一本书会有多困难吗?这就是没有元数据管理的数据仓库的真实写照。 目录 什么是元数据?元数据管理的重要性元数据在数据仓库中的类型1. 技术…

Open3D mesh Taubin滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 参数详解 返回值 2.2完整代码 三、实现效果 3.1加入噪声的mesh 3.2Taubin迭代10次 3.3Taubin迭代100次 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云…