C语言—程序流程控制

203 阅读8分钟

第四章:程序流程控制

mindmap
      Root
          程序流程控制
            4.2顺序结构
           4.1语句与程序流程
           4.3选择结构
           4.4循环结构
           4.5break与continue
           4.6应用举例
    

4.1语句与程序流程

4.1.1语句的分类

结尾加分号;

语句分类
表达式语句表达式+";" (赋值表达式加分号构成的赋值语句是最常用的表达式语句)
函数调用语句函数名(如scanf,printf..)+";"
控制语句控制各语句执行顺序及次数的语句(包括条件if/switch,循环,中转等)
复合语句指一对大括号括起的0条或多条语句
空语句";"

4.1.2程序流程及其表示

C语言源程序的三大基本结构: 顺序结构,选择结构,循环结构

算法:也就是指为解决某个问题而采取的有限操作步骤它是程序设计的灵魂与核心

4.2顺序结构(最基本的程序结构)

思想是:从前往后依次执行每一条语句,且每一条语句只执行一次

4.3选择结构(if,switch)

if

if语句主要包括两类:if语句 和 if...else语句1

(其语句本身在语法上理解为一条语句)

tip:勾股定理的表达

并没有用edge1*edge1+edge2*edge2==edge3*edge3这种的逻辑。这是因为edge1/2/3均为double型数据,而double型数据是不精确的,一般不使用"=="来判断相等。

合理做法是: 计算1和2的平方与3平方的差,如果该差值的绝对值小于一个较小的数(如IE-2),就可以近似认为他们相等

微信图片_20231118124427.jpg

2. **case后面必须为常量值且唯一**,且类型应与switch中表达式的类型相同
3. switch语句的执行过程是:**首先**计算switch后面表达式的值,**然后** 与各case分支的常量进行匹配,,与哪个常量相等,就从该分支的语句序列开始执行,直到遇到break或者switch语句块的右边大括号
4. 由上一条可知,**break并不是必须的**
5. **default分支**主要用于处理switchswitch表达式与所有case都不匹配的情况,**它在语句中可以省略**,但推荐使用
## 4.4循环结构
分为whiledo...whilefor
### 1.while

```c
while(表达式){
  语句块;
}

其中,表达式可以是任何合法的C语言表达式,它的计算结果用于判断语句块是否该被执行

语句块是需要重复执行语句的集合,也被称为循环体

其中变量i承载了控制循环次数的作用,对于这类变量,我们一般称之为循环控制变量

累加练习(典型循环案例)

#include<stdio.h>
int main() {
	int n;
	int i = 1;
	int sum = 0;
	printf("输入一个正整数:");
	scanf_s("%d", &n);
	if (n < 0) {
		n = -n;
	}
	while (i <= n) {
		sum += i;
		i++;
	}
	printf("%d的累加和为:%d\n", n, sum);
	return 0;
}

2.do...while(直到型循环语句)

do{
  语句块;
}while(表达式);

执行过程为:

  1. 先执行do语句块,即循环体

  2. 计算表达式的值,若为真,再次进行do步骤;否则退出循环,执行下一条语句

阶乘练习(典型循环案例)

#include<stdio.h>
int main() {
	int n;
	int i = 1;
	double fac = 1;
	printf("输入一个正整数:");
	scanf_s("%d", &n);
	if (n < 0) {
		n = -n;
	}
	do {
		fac *= i;
		i++;
	} while (i <= n);
	printf("%d!=%f\n", n, fac);
	return 0;
}

其中,将阶乘变量fac定义为double类型,这是因为阶乘运算很容易超出int的范围,选用double类型可支持大一些的数

3.for

是C语言中最常用,功能也最强大的循环控制语句

for(表达式;表达式;表达式;){
     语句块
}

执行顺序为表达式1和2——循环体——表达式3

数列求和练习

#include<stdio.h>
int main() {
	int i;
	double item;
	double sum = 0;
	int sign = 1;
	for (i = 1; i <= 1000; i++) {
		item = sign / (2.0 * i - 1);
		//分母记得记得记得加括号
		sum += item;
		sign = -sign;
	}
	printf("sum=%f\n", sum);

	return 0;
}

当然item也可以直接用幂函数来算

tip(重要): 整型乘以2.0和乘以2的区别在于结果的数据类型不同。

整型x2.0和2的区别
整型乘以2.0会得到一个浮点型的结果,而整型乘以2只会得到另一个整型的结果。
例如,如果有一个整型变量x=5,那么x2.0的结果是10.0,而x2的结果是10。虽然它们看起来相同,但实际上它们的数据类型是不同的。一个是浮点型,另一个是整型。
在编程中,数据类型的不同可能会影响到后续的计算和处理方式。因此,需要根据实际需求选择合适的数据类型和运算符。

break与continue

是两个较为特殊的流程控制关键词,主要用于循环的中断控制

区别:

break:是结束本层循环体的运行,退出本层循环

continue:只是提前结束本次循环体的运行,忽略循环体内其后面的语句,然后重新判断循环条件,并未退出循环体

【精选】break和continue的作用和区别是什么?(详细解答)-CSDN博客

4.6应用举例

第一个思想: 【循环嵌套】

广泛应用于例如:行列式求解,矩阵处理,排序,二维文本图形打印

案例一:九九加法表

分析: 微信图片_20231118143519.jpg

#include<stdio.h>
int main() {
	int i, j;
	for (i = 1; i <= 9; i++) {
		for (j = 1; j <= i;j++) {
			printf("%d+%d=%2d", i, j, i + j);
		}
		printf("\n");//换行符
	}

![微信图片_20231118143519.jpg](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04f21a3c2f7e444ba0086ddc70b790b9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2041&h=477&s=392479&e=jpg&b=dadcd7)
	return 0;
}

案例二:梯形打印

要求:

image.png 打印梯形的思路:

  1. 第一行j=1,符合j<=3的式子则打印一个空格,j=2/3也均符合,所以第一行总共会打印三个空格,随后不符合这个循环后跳出执行下一个打印星号的循环

  2. 第二行j=1/2,符合j<=2的式子,则打印两个空格

  3. 第三行j=1,符合j<=1的式子,打印一个空格

  4. 第四行i=4时,j也=4,但是j不满足j<4-i的条件了,所以最后一行不会打印空格

//对每一行来说,它由空格,星号和回车构成
#include<stdio.h>
int main() {
	int i, j;
	for (i = 1; i <= 4; i++) {
		for (j = 1; j <= 4- i;j++) {
			printf(" ");
		}
		for (j = 1; j <= 2 * i + 1; j++) {
			printf("*");
		}

		printf("\n");
	}

	return 0;
}

案例三:质数判断

基本思路是:对于正整数n(n>1),用2~根号n去除它,如果存在可以整除的情况,则n不是质数,否则必为质数

//假如这个数是103,那么经历过上面的for循环后,i已经=k了,但是此时依然没有i可以整除103,同时i++;然后i此时大于k了已经,那么此时就会跳出循环
//因为在你2-k的过程中都没有能整除的,所以i>k时自然也没有,也就不用for了,直接当i>k时的n,均为符合条件的
//跳出循环后,我们就可以进行打印的操作了
#include<stdio.h>
#include<math.h>
int main() {
	int i, n,k;
	do {
		printf("请输入一个正整数:");
		scanf_s("%d", &n);
	} while (n <= 0);


	if (n == 1) {
		printf("不是质数\n");
	}else {
		 //——————————————
		//k是给除数i做限制的
		k = (int)sqrt(n);

		//循环判断是否能被整除
		for (i = 2; i <= k; i++) {
			if (n % i == 0) {
				break;
			}

		}

			if (i>k) {
				printf("%d 是质数\n",n);
		}
			//这里这个else的情况就是上面的for循环的结果
			else {
				printf("%d 不是质数\n",n);
			}

      //————————————————
		}
	return 0;
}

如果再加一个限制条件,比如,输入的是三位整数的话,那么只需

do {

    printf("输入一个3位正整数:");

    scanf_s("%d", &n);

    if (n < 100 || n>999) {

        printf("输入的不是三位正整数,请重新输入。\n");

    }

} while (n <100||n>999);

案例四:百钱百鸡问题(穷举法)

问: a公鸡5钱1只,b母鸡3钱1只,c小鸡1钱3只。100钱买100只鸡,问公鸡、母鸡、小鸡各几只?

传统方法: 列两个方程组,算出未知数a、b、c的值

穷举法: 存在一个整体的解空间,解空间中有符合的也有不符合的。穷举法就是把解空间里的所有可能都试一遍,最后挑出符合条件的

———像本题中a、b、c的取值范围分别是[0,20],[0,33],[0,100],那么解空间就是[0,0,0]~[20,33,100],而符合方程组的就是问题的解。

我们这里是给abc三个数都限定了范围

#include<stdio.h>
#include<math.h>
int main() {
	int a, b, c;
	for (a = 0; a <= 20; a++) {
		for (b = 0; b <= 33; b++) {
			for (c = 0; c <= 100; c++) {
				if (a+b+c == 100 && 15*a+9*b+c==300) {
					printf("%d,%d,%d\n", a, b, c);
				}
			}
		}
	}
	return 0;
}

其实也可以优化的,因为当a,b确定之后,c自然也就确定了,也就不用再写c的那个for循环

#include<stdio.h>
#include<math.h>
int main() {
	int a, b, c;
	for (a = 0; a <= 20; a++) {
		for (b = 0; b <= 33; b++) {
			c = 100 - a - b;
		    if (15*a+9*b+c==300) {
					printf("%d,%d,%d\n", a, b, c);
			}
		}
	}
	return 0;
}

如果看完后还有哪里不懂的话,可以看这篇文章进行补充,希望大家都可以成功入门C语言^^

c语言入门这一篇就够了-学习笔记(一万字)-CSDN博客