第三章 选择与循环

本文介绍了程序员在编程中应掌握的基本技能,包括增量编写法,运算符优先级(如逻辑非、算术运算符、关系运算符),以及if语句的使用,强调了逻辑运算的短路特性。同时,文章讲解了while和for循环的工作原理,以及如何避免死循环。此外,还讨论了continue和break语句在循环控制中的作用,并提供了相关练习题来巩固这些概念。
摘要由CSDN通过智能技术生成

程序员必备技能(思想):增量编写法。每写一部分代码要及时运行看结果是否正确,对于复杂程序很重要。

常用的运算符优先级:

逻辑非 !> 算术运算符 > 关系运算符 > && > || > 赋值运算符

  • 单目运算符 逻辑非 !
  • 算术运算符 +、-、×、/、%
  • 关系运算符 >、<、>=、<=、==、!=
  • 逻辑运算符 &&、||

由于初试中大题极大概率会用到算术运算符、关系运算符和逻辑运算符,因此三者的优先级顺序必须牢记。算术运算符的优先级高于关系运算符、关系运算符的优先级高于逻辑与和逻辑或运算符,相同优先级的运算符从左至右进行结合

if语句

选择结构程序中 if( 表达式 ) 括号中的表达式99%的情况下都是填关系表达式或逻辑表达式。剩下1%的情况是直接放入一个值,如 if(i),如果 i 非零则为真,条件满足,进入if语句;如果 i 为0则为假,条件不满足,不会进入if语句[C语言中0代表假,非零代表是真];类似的也可以写 if( i + 3 )。

一个表达式中优先级最低的运算符是什么,则该表达式就是该运算符表达式。如5>3&&8<4-!0 其中优先级最低的是逻辑与运算符,所以这是逻辑表达式。该表达式的计算过程如下图:

在这里插入图片描述

不是说逻辑非 ! 的优先级是这里最高的吗?为什么还先算5>3?

原因在于这是一个短路运算。短路运算一般有:&&、||,其原理是:当有多个表达式时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值。所以需要先算左边表达式的值,左边表达式值为1,又这是逻辑与&&运算符,确定不了最终结果,所以需要继续计算右边的表达式。【注:短路运算初试不考,故了解即可】

判断闰年:闰年指能被400整除或者能被4整除但不能被100整除。具体的表达式为year%4==0&&year%100!=0||year%400==0,也可以写成(year%4==0&&year%100!=0)||year%400==0,后者虽然可行,但括号显然是多余的,因为逻辑与的优先级是比逻辑或的优先级高。

练习使用if语句:

int main(){
	int i;
	while (scanf("%d", &i) != EOF)
	{
		if (i > 0) //在if的括号后面不可以加"分号 ; ",这会造成表达式无论是真还是假,都会执行后面的语句
		{
			printf("i is bigger than 0\n");
		}else{
			printf("i is not bigger than 0\n");
		}
	}
	
}

if语句和else语句也可以多个同时使用(多分支语句),如图所示。

在这里插入图片描述

但是无论有多少各if语句或else if语句,程序都只会执行其中的一个语句

练习多分支语句:

int main(){
	int number;
	float cost;
	scanf("%d", &number);
	if (number > 500)
	{
		cost = 0.15;
	}else if (number > 300){
        //程序从上至下依次执行,当执行到这里时就说明number已经<=500了,所以不必再判断number<=500
		cost = 0.10;
	}else if (number > 100) {
		cost = 0.075;
	}else {
		cost = 0;
	}

	//%0.2f表示小数点后保留两位
	printf("电费单价cost=%0.2f\n", cost);
}

if语句也支持多层嵌套,在if语句中又包含一个或多个if语句称为if语句的嵌套,如下图所示:

在这里插入图片描述

if语句嵌套练习:

int main(){
	int i;
	if (i > 1)
		if (i < 10)
			printf("i > 1 and i < 10\n");
		else
			printf("no,they are not\n");
	
	/*
	“就近原则”:else子句从属于最靠近它的不完整的if语句。上例中的else子句从属于第二个if语句,
	如果想让它从属于第一个if语句,可以用一个花括号把第二个if语句包含在一个单独的代码块内,	如下所示

	在编写代码时应遵守规范,都加上{}
	*/

	if (i > 1){
		if (i < 10)
			printf("i > 1 and i < 10\n");
	}else
		printf("no,they are not\n");
}

while循环

while语句用来实现“当型”循环结构,其一般形式为“while(表达式) 语句”,当表达式的值非0时(即条件为真时),执行while语句中的内嵌语句。其特点是:先判断表达式,后执行语句

在这里插入图片描述

当控制台(黑窗口)卡住后,只有两种情况,一种是卡在scanf了(这种情况下键盘输入内容是可以输入进去的);另一种情况是死循环,死循环在控制台(黑窗口)中是输入不进去内容的。

while循环练习:

//从1加到100
int main(){
	int i = 1;
	int total = 0;//存储最终的和
	while (i <= 100)//while后面不能加“分号;”,否则会死循环
	{
		total = total + i;
		i++;
	}
	printf("total=%d\n", total);
}

while循环出现死循环的常见的原因有:

  1. while( ) 后面加了分号。
  2. while语句体内没有让表达式趋近于假的操作。(如在上面的代码中将i++去掉即是这种情况,while语句体内没有让表达式趋近于假的操作,所以陷入死循环。亦或者判断条件错写为i >= 0,则也会陷入死循环)。

for循环

for循环的一般形式为:

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

在这里插入图片描述

for循环练习:

//从1加到100
int main(){
	int i, total;//total存储最终的和

	//for语句中只能有两个分号 
	for (i = 1, total = 0; i <= 100; i++){
		total = total + i;
	}

	printf("total=%d\n", total);
}

continue

continue的作用提前结束本轮循环,直接开始下一轮循环。

在for循环中练习continue:

//从1到100之间奇数求和
int main(){
	int i, total;//total存储最终的和

	//for语句中只能有两个分号 
	for (i = 1, total = 0; i <= 100; i++){

		if (i % 2 == 0)//i是偶数
		{
			continue;//continue的作用提前结束本轮循环,直接开始下一轮循环
		}
		total = total + i;
	}

	printf("total=%d\n", total);
}

在while循环中练习continue:

//从1到100之间奇数求和
int main() {
	int i = 0;
	int total = 0;//存储最终的和
	while (i <= 100)//while后面不能加“分号;”,否则会死循环
	{
		if (i % 2 == 0)
		{
			i++;
			continue;
		}
		total = total + i;
		i++;
	}
	printf("total=%d\n", total);
}

break

break语句的作用是结束整个循环过程,不再判断执行循环的条件是否成立。

break练习:

//从1加100,当和大于2000,就终止循环
int main() {
	int i, total;//total存储最终的和

	//for语句中只能有两个分号 
	for (i = 1, total = 0; i <= 100; i++) {

		if (total > 2000)
		{
			break;//当求和大于2000,就终止循环
		}
		total = total + i;
	}

	printf("total=%d,i=%d\n", total,i);
}

作业练习:

练习一

Description:

输入一个整型数,判断是否是对称数,如果是,输出yes,否则输出no,不用考虑这个整型数过大,int类型存不下,不用考虑负值;

例如 12321是对称数,输出yes,124421是对称数,输出yes,1231不是对称数,输出no

[分析]:把最初输入的整型数a,反过来后再存到另外一个整型数b中,判断a和b是否相等,如果相等就输出yes,不相等输出no。

实现整型数反转的方法:

int main() {
    int a;
	scanf("%d", &a);
	printf("a=%d\n", a);

	/*
	如果输入的是1234,那么现在将让输出4321,该如何操作?
	思路如下:1234%10=4,余数是4,商是123;得到的商再重复%4,余数得到3,商是12,重复上述步骤;
	当商为0时,跳出循环.(最后是1%10,余数是1,商是0,此时可以结束循环了)。
	*/

	//对于循环结束条件不知道如何写,可以先写循环体,等循环体写好了,循环结束条件也就大概知道了
	while (a!=0) //当a不等于0时就可以进入循环
	{
		printf("%d", a % 10);
		a = a / 10;
	}
}

完整的代码实现:

int main() {
	int a,b,c,tmp;
	scanf("%d", &a);
	b = 0;//将输入的整型数a进行反转之后存到整型数b中
	c = a;//将输入的整型数a暂存到整型数c中

	/*
	while (a != 0)也可以用while(a)替代,当循环判断条件是"某个变量不是0时"都可以用"直接填该变量"的方法
	进行替代,因为在C语言中任何非0值都是真,只有0为假。
	*/

	while (a != 0) //当a不等于0时就可以进入循环。  
	{
		tmp = a % 10;
		b = b * 10 + tmp;//将a进行反转之后存到b中需要借助中间变量tmp。可以借助例子 输入1234,进行反转将4321赋值给b
		a = a / 10;
	}
	if (c == b)
	{
		printf("yes\n");
	}
	else {
		printf("no\n");
	}
	return 0;
}

练习二

Description:利用while或者for循环计算n!的值。提示:n!=123…*n
Input:一个正整数n,1≤n≤10。(再次强调,OJ中的输入范围这些不用自己在代码中进行实现,除非题目明确指明需要在代码中实现限制输入范围。)
Output:n!的值。

int main() {
	int n, acc;
	acc = 1;//存阶乘值n!
	scanf("%d", &n);//读取输入
	for (int i = 1; i <= n; i++)
	{
		acc = i * acc;
	}
	printf("%d\n", acc);
	return 0;

	/*
	用while方式实现
	int n, acc = 1, i = 1;
	scanf("%d", &n);
	while (i<=n)
	{
		acc *= i;
		i++;
	}
	printf("%d\n", acc);
	*/
}

练习三

这个题用到的穷举的思想很重要。

Description:

某人想将手中的一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张,且每种票子至少一张。问:有几种换法?

穷举法(枚举法)

用枚举法即穷举法。将所有的情况穷举一遍,当出现某一种情况恰好符号条件时,那么这种情况就成立。[在初试或复试中如果想不到其他方法就用穷举法,所以穷举法很重要。]

//穷举法(暴力循环):分别列出每一种情况,看哪种情况符号条件。
int main() {
	int a, b, c, d, e = 0;//a,b,c,d分别表示10元,5元,2元,1元分别有多少张
	for (a = 1; a <= 40; a++)
	{
		for (b = 1; b <= 40; b++)
		{
			for (c = 1; c <= 40; c++)
			{
				for (d = 1; d <= 40; d++)
				{
					if (10 * a + 5 * b + 2 * c + d == 100 && a + b + c + d == 40) {
						e++;//e代表的是有多少种换法
					}
				}
			}
		}
	}
	printf("%d\n", e);
    
	/*
	对上面的代码再进行优化:总面值为100,那么10元的不可能超过10张,又每种钞票至少有一张,
	那么10元的事实上是不能超过7张的。同理总面值为100,那么5元的不可能超过20张,又每种钞票
	至少有一张,那么5元的事实上是不能超过17张的。2元的不可能超过37张,1元的不可能超过37张。
	这样处理之后可以减少循环的次数。
	int a, b, c, d, e = 0;//a,b,c,d分别表示10元,5元,2元,1元分别有多少张
	for (a = 1; a <= 7; a++)
	{
		for (b = 1; b <= 17; b++)
		{
			for (c = 1; c <= 37; c++)
			{
				for (d = 1; d <= 37; d++)
				{
					if (10 * a + 5 * b + 2 * c + d == 100 && a + b + c + d == 40) {
						e++;//e代表的是有多少种换法
					}
				}
			}
		}
	}
	printf("%d\n", e);
	*/
}

结果:共有34种。

提醒:在输出输出中不要加入额外的内容,前面已经提高,OJ输入输出的匹配是很严格的,一点不符合就不能AC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值