分支和循环语句-C语言

该博客主要介绍C语言的分支和循环语句。分支语句包括if - else和switch,讲解了语法、使用场景及注意事项;循环语句有while、for和do...while,阐述了执行流程、break和continue的作用。此外,还给出多个相关练习,如计算阶乘、二分查找等。

目录

1.分支语句(选择结构)

1.1.if-else

1.2.switch

2.循环语句

2.1 while

2.2 for

2.3 do...while

3.练习


1.分支语句(选择结构)

1.1.if-else

1.1.1语法结构:

(1)if(表达式)

                语句;

(2)if(表达式)

                语句1;

        else(表达式)

                语句2;

(3)多分支:

if(表达式1)

        语句1;

else if(表达式2)

        语句2;

 else

        语句3;

1.1.2

int main()
{
	int age = 0;
	scanf_s("%d", &age);
	if (age >= 18)
		printf("成年人");
	else 
		printf("未成年人 ");
        printf("不能谈恋爱");
	return 0;
}

输出:20        输出:成年人 不能谈恋爱

if/else只能控制一条语句,当需要if/else执行多条语句时,要加上 {}

int main()
{
	int age = 0;
	scanf_s("%d", &age);
	if (age >= 18)
		printf("成年人");
	else
	{
		printf("未成年人 ");
		printf("不能谈恋爱");
	}
	return 0;
}

输出:20        输出:成年人

1.1.3

int main()
{
	int age = 0;
	scanf_s("%d", &age);
	if (age<=18)
		printf("成年人");
	else if (18<=age<26)
		printf("青年");
	return 0;
}

输入:40        输出:青年

语句18<=age<26中语法上age两边为或的关系,只要当age>=18或者age<26都可满足,但逻辑上为age>=18和age<26都满足方可执行语句,因此,应写为 age >= 26 && age < 40) 的形式

int main()
{
	int age = 0;
	scanf_s("%d", &age);
	if (age < 18)
		printf("未成年");
	else if (age >= 18 && age < 26)
		printf("青年");
	else if (age >= 26 && age < 60)
		printf("中年");
	else 
		printf("老年");
	return 0;
}

输入:40        输出:中年

1.1.4 悬空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;
}

无输出

else的匹配:else是和它离的最近的if匹配的,不是看对齐哪个if

适当的使用 {} 可以使代码的逻辑更加清楚,代码的书写和风格很重要,要让别人容易看懂

int main()
{
  int a = 0;
  int b = 2;
  if(a == 1)
 {
    if(b == 2)
   {
      printf("hehe\n");
   }
 }
  else
 {
    printf("haha\n");
 }   
  return 0;
}

🐖:当两个整型变量在一起比较时,最好将常量放在前面

if(5==num)
    return("hhh");

练习1: 判断一个数是否为奇数

int main()
{
	int num = 0;
	scanf_s("%d", &num);
	if (num % 2 == 0)
	{
		printf("%d不是奇数\n",num);
	}
	else
	{
		printf("%d是奇数\n",num);
	}
	return 0;
}

练习2:输出1-100之间的奇数

int main()
{
	int i=0;
    printf("1-100之间的奇数有:\n");
	for (i = 1; i <= 100; i++)
	{
		if (i % 2 == 1)
		{
			printf("%d\n", i);
		}
	}
	return 0;
}

1.2.switch

常用于多分支的场景

1.2.1 语法结构:

switch(整型表达式)

        case 整型常量表达式:
                 语句;

}

1.2.2 case决定入口,break决定出口


int main()
{
	int day = 0;
	scanf_s("%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;
}

输入:5        输出:星期五

1.2.3 break不是一定要加,看具体需求

int main()
{
	int day = 0;
	scanf_s("%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        输出:工作日

1.2.4 如果表达的值与所有的case标签的值都不匹配,程序并不会终止,也不会报错,当并不想忽略不匹配所有标签的表达式的值时,可以在语句列表中增加一条default子句,把 default:写在任何一个 case 标签可以出现的位置。当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。


int main()
{
	int day = 0;
	scanf_s("%d", &day);
	switch(day)
	{
	case 1:
	case 2:	
	case 3:		
	case 4:		
	case 5:
		printf("工作日\n");
		break;
	case 6:	
	case 7:
		printf("休息日\n");
		break;
	default:
		printf("输入错误!\n");
		break;
	}
	return 0;
}

输入:9        输出:输入错误!

练习:

int main()
{
	int n = 1;
	int m = 2;
	switch (n)
	{
	case 1:
		m++;//m=3
	case 2:
		n++;//n=2
	case 3:
		switch (n)
		{//switch允许嵌套使用
		case 1:
			n++;
		case 2:
			m++;//m=4
			n++;//n=3
			break;
		}
	case 4:
		m++;//m=5
		break;
	default:
		break;
	}
	printf("m = %d, n = %d\n", m, n);
	return 0;
}

输出:m=5 , n=3

2.循环语句

2.1 while

2.1.1 语法结构:

while(表达式)
        循环语句;

2.1.2 while语句执行的流程:

2.1.3 break

在while循环中,break用于永久的终止循环

int main()
{
	int i = 1;
	while (i < 10)
	{
		if (i == 5)
			break;
		printf("%d", i);
		i++;
	}
	return 0;
}

输出:1234

2.1.4 continue

在while循环中,continue用于跳过本次循环后面的代码

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

输出:1234_(无限循环)

分析代码1:

#include <stdio.h>
int main()
{
    int ch = 0;
    while ((ch = getchar()) != EOF)
       putchar(ch);
      return 0;
}

getchar:获取字符(从键盘获取字符),返回类型为int类型

putchar:输出字符

EOF:-1,end of file-文件的结束标志

含义:getchar读取一个字符,putchar打印一个字符,当输入一个A字符时,相当于把 A\n 放入了缓冲区,此时getchar()先读入A,输出A,getchar()再读入\n,输出\n(即换行),再键入下一个字符,直至键盘按下Ctrl+Z,结束。相当于:

int ch = getchar();
printf("%c", ch);

这里的代码适当的修改是可以用来清理缓冲区的

例:

int main()
{
	char password[9] = { 0 };
	printf("请输入密码:");
	scanf_s("%s", password,8);
	printf("请确认密码(Y/N):");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功");
	}
	else
	{
		printf("确认失败");
	}
	return 0;
}

输出:

 原因:getchar()需要从缓冲区获取数据,当缓冲区没有数据时,需要从键盘输入到缓冲区里,当执行scanf_s()语句时,键盘输入 12345678 ,回车会触发scanf_s()读取数据,当scanf_s()读取数据时,scanf_s()只读取 12345678 ,放入password字符串中,但实际上缓冲区内有 12345678\0 共九个字符,这时剩下的 \0 就会被getchar()读取,直接放到ch字符串中,而在if判断语句中发,\0 不等于 Y ,所以会执行else语句,直接输出确认失败

因此,当scanf_s()读取完字符 12345678 后,多使用一个getchar(),清理掉多余的 \0 ,即可实现想要的结果

int main()
{
	char password[9] = { 0 };
	printf("请输入密码:");
	scanf_s("%s", password,8);
	printf("请确认密码(Y/N):");
	//清理缓冲区
	getchar();//处理'\n'
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

输出:

但是,我们发现当输入的password中有空格时,仍然会失败

 这是因为,当输入 123 abc 时,缓存区会放入 123 abc\n ,但是scanf_s()只能读取 123 ,此时缓存区内仍有 abc\n ,一个getchar()无法完全清理掉缓存区

因此,需要多个getchar()来清理缓冲区,本题的这段代码就派上用场了


int main()
{
	char password[9] = { 0 };
	printf("请输入密码:");
	scanf_s("%s", password,8);
	printf("请确认密码(Y/N):");
	//清理缓冲区
	int tmp = 0;
	while ((tmp = getchar()) != '\n')
	{
		;
	}
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

输出:

分析代码2:

#include <stdio.h>
int main()
{
	char ch = '\0';
    //int ch=0;
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch > '9')
			continue;
		putchar(ch);
	}
	return 0;
}

含义:只打印数字字符,跳过其他字符

2.2 for

2.2.1 语法结构:

for(表达式1; 表达式2; 表达式3)
        循环语句;

表达式1为初始化部分,用于初始化循环变量的。
表达式2为条件判断部分,用于判断循环时候终止。
表达式3为调整部分,用于循环条件的调整。

2.2.2 for循环的执行流程图:

 2.2.3break和continue在for循环中

我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。

但是还是有些差异:

int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		/*if (i == 5)
			break;*/
		if (i == 5)
			continue;

		printf("%d ", i);
	}
	return 0;
}

输出:1 2 3 4 6 7 8 9 10

这是因为for循环里的continue 跳到调整部分进行i的自增,while循环的continue可能会把i的自增这一步跳过去,导致死循环

2.2.4 for语句的循环控制变量

 不可在for 循环体内修改循环变量,防止 for 循环失去控制

for (i = 1; i <= 10; i++)
{
	printf("%d ", i);
    i=5;
}

 建议for语句的循环控制变量的取值采用“前闭后开区间”写法

for (i = 1; i < 10; i++)

2.2.5 for循环的变种

代码1:for循环的初始化、条件判断、调整每个部分都可以省略,但是判断部分一旦省略,就会进入死循环

for (;;)
{
	printf("hehe\n");
}
return 0;

代码2:

int i = 0;
int j = 0;
//这里打印多少个hehe?
for(i=0; i<3; i++)
{
    for(j=0; j<3; j++)
   {
        printf("hehe\n");
   }
}

此时共打印9个 hehe

int i = 0;
int j = 0;
//如果省略掉初始化部分,这里打印多少个hehe?
for(; i<3; i++)
{
    for(; j<3; j++)
   {
        printf("hehe\n");
   }
}

此时共打印3个 hehe

这是因为当i=0时,j由0自增至2,跳出内层循环,进行外层循环,i自增为1,但此时的j仍然是3,不满足内层循环的条件,i自增至2,j=3,仍然不满足内层循环的条件,且此时外层循环的条件也不满足,跳出两层循环,所以一共输出三次 hehe

代码3:使用多个变量控制循环

int x, y;
for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
{
	printf("hehe\n");
}
return 0;

代码4:请问循环要循环多少次?

#include <stdio.h>
int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)
		k++;
	return 0;
}

0次

判断部分 k=0 ,把0赋值给k,k为假,不会进行循环

2.3 do...while

2.3.1 语法结构:
do
循环语句 ;
while ( 表达式 );

2.3.2执行流程图:

2.3.3 do while循环中的break和continue

int main()
{
	int i = 1;
	do
	{
		if (i == 5)
			break;
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

输出:1 2 3 4

int main()
{
	int i = 1;
	do
	{
		if (i == 5)
			continue;
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

输出:1 2 3 4_(无限循环)

2.3.4 do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用

3.练习

练习1:计算n的阶乘

int main()
{
	int n;
	scanf_s("%d", &n);
	int res1 = 1, res2 = 1, res3 = 1;
	int i = 1;
	//while循环
	while (i <= n)
	{
		res1 *= i;
		i++;
	}
	//for循环
	for (i = 1; i <= n; i++)
	{
		res2 *= i;
	}
	//do...while循环
	i = 1;
	do
	{
		res3 *= i;
		i++;
	} while (i <= n);
	printf("%d的阶乘为:%d\n", n, res1);
	printf("%d的阶乘为:%d\n", n, res2);
	printf("%d的阶乘为:%d\n", n, res3);
	return 0;
}

输出:

5的阶乘为:120
5的阶乘为:120
5的阶乘为:120

练习2:计算 1!+2!+3!+……+n!

while循环:

int main()
{
	int n;
	scanf_s("%d", &n);
	int i = 1, j = 1;
	int sum = 0;
	int res = 1;
	while (i <= n)
	{
		j = 1;
		res = 1;
		while (j <= i)
		{
			res *= j;
			j++;
		}
		sum += res;
		i++;
	}
	printf("%d", sum);
	return 0;
}

for循环:

int main()
{
	int n;
	scanf_s("%d", &n);
	int res = 1, sum = 0;
	for (int i = 1; i <= n; i++)
	{
		res = 1;
		for (int j = 1; j <= i; j++)
		{
			res *= j;
		}
		sum += res;

	}
	printf("%d", sum);
	return 0;
}

do...while循环:

int main()
{
	int n;
	scanf_s("%d", &n);
	int i=1,j = 1;
	int res = 1, sum = 0;
	do
	{
		res = 1;
		j = 1;
		do
		{
			res *= j;
			j++;
		} while (j <= i);
		sum += res;
		i++;
	} while (i <= n);
	printf("%d", sum);
	return 0;
}

练习3:在一个有序数组中查找具体的某个数字n-->二分查找

int main()
{
	int* arr;
	arr = (int*)malloc(sizeof(int));
	int n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf_s("%d", &arr[i]);
	}
	int k;//要查找的值
	scanf_s("%d", &k);
	int left = 0;
	int right = n - 1;
	
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("%d的下标为:%d", k, mid);
			break;
		}
	}
	if (left > right)
		printf("找不到");
	return 0;
}

输入:

10

1 2 3 4 5 6 7 8 9 10

7

输出:

6

练习4:编写代码,演示多个字符从两端移动,向中间汇聚

int main()
{
	char arr1[] = "welcome to csdn";
	char arr2[] = "###############";
	int left = 0;
	int right = strlen(arr1) - 1;
	printf("%s\n", arr2);
	//while循环实现
	while (left <= right)
	{
		Sleep(1000);//睡眠一秒
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		left++;
		right--;
		printf("%s\n", arr2);
		//system("cls");//清空屏幕
	}
	//for循环实现
	char arr3[] = "###############";
	printf("%s\n", arr3);
	for (left = 0, right = strlen(arr1) - 1;left <= right;left++, right--)
	{
		Sleep(1000);
		arr3[left] = arr1[left];
		arr3[right] = arr1[right];
		printf("%s\n", arr3);
		//system("cls");//清空屏幕
	}
	return 0;
}

练习5:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序)

int main()
{
	int i = 0;
	char password[20] = { 0 };
	char right_ps[20] = "123456";
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf_s("%s", password,20);
		if (strcmp(password, right_ps) == 0)
		{
			printf("登录成功");
			break;
		}
		else
		{
			printf("密码错误,请重新输入密码\n");
		}
	}
	if (i == 3)
	{
		printf("三次密码均需哦呜,推出程序");
	}
	return 0;
}

练习6:自动生成一个1-100之间的随机数,若猜错,会知晓是猜大了还是猜小了,继续猜,直至猜对,游戏可以一直玩,除非退出游戏。

void game()
{	
	//1、生成随机数
	int ret = rand()%100+1;
	//2、猜数字
	int guess = 0;
	while (1)
	{
		printf("请猜数字:");
		scanf_s("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你!猜对了\n");
			break;
		}
	}
}
void menu()
{
	printf("*************************************\n");
	printf("************   1.play  **************\n");
	printf("************   0.exit  **************\n");
	printf("*************************************\n");
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//利用时间戳设置一个随机的起点
	do
	{
		menu();//打印菜单
		printf("请选择:>");
		scanf_s("%d", &input);
		switch(input) 
		{
		case 1:
			game();//猜数字游戏的实现
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误,请重新选择");
			break;
		}

	} while(input);
	return 0;
}
一、 内容概要 本资源提供了一个完整的“金属板材压弯成型”非线性仿真案例,基于ABAQUS/Explicit或Standard求解器完成。案例精确模拟了模具(凸模、凹模)与金属板材之间的接触、压合过程,直至板材发生塑性弯曲成型。 模型特点:包含完整的模具-工件装配体,定义了刚体约束、通用接触(或面面接触)及摩擦系数。 材料定义:金属板材采用弹塑性材料模型,定义了完整的屈服强度、塑性应变等真实应力-应变数据。 关键结果:提供了成型过程中的板材应力(Mises应力)、塑性应变(PE)、厚度变化​ 云图,以及模具受力(接触力)曲线,完整再现了压弯工艺的力学状态。 二、 适用人群 CAE工程师/工艺工程师:从事钣金冲压、模具设计、金属成型工艺分析与优化的专业人员。 高校师生:学习ABAQUS非线性分析、金属塑性成形理论,或从事相关课题研究的硕士/博士生。 结构设计工程师:需要评估钣金件可制造性(DFM)或预测成型回弹的设计人员。 三、 使用场景及目标 学习目标: 掌握在ABAQUS中设置金属塑性成形仿真的全流程,包括材料定义、复杂接触设置、边界条件与载荷步。 学习如何调试分析大变形、非线性接触问题的收敛性技巧。 理解如何通过仿真预测成型缺陷(如减薄、破裂、回弹),并与理论或实验进行对比验证。 应用价值:本案例的建模方法与分析思路可直接应用于汽车覆盖件、电器外壳、结构件等钣金产品的冲压工艺开发与模具设计优化,减少试模成本。 四、 其他说明 资源包内包含参数化的INP文件、CAE模型文件、材料数据参考及一份简要的操作要点说明文档。INP文件便于用户直接修改关键参数(如压边力、摩擦系数、行程)进行自主研究。 建议使用ABAQUS 2022或更高版本打开。显式动力学分析(如用Explicit)对计算资源有一定要求。 本案例为教学与工程参考目的提供,用户可基于此框架进行拓展,应用于V型弯曲
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值