选择结构、循环结构及其相关

代码块

代码块就是用大括号包起来的一段代码,可以随意嵌套。

#include <stdio.h>

int a = 9;  //全局域中的a
int main()
{
 	int a = 10; //main域中的a
 	{
 		int a = 11;  //自由代码块中的a
		printf("%d\n", a); //访问时采用就近原则,使用了自己代码块中的a
 	}
	 printf("%d\n", a); //使用的是main域中的a
 	 return 0;
}

可以看到代码块中可以存在和父域中重名的变量,使用时会就近选择。即本域中有就使用本域的,否则就逐级向上查找。

※一个局部变量其生命周期只在自己的大扩号中,即大括号结束,这个代码块中所有的临时变量都会被销毁。如,以下代码就无法通过编译:

{
 int b = 10;
 }
 printf("%d", b);

由于b的生命周期只在代码块内,所以外面就无法访问了。

※存在一些语句,如if、 while 等可以拥有一个属于自己的代码块。

选择结构

if结构

if 结构是一种多选一的结构,其基本框架为:

if (表达式)
 {
语句;
 }

如果表达式成立则语句执行,如果表达式不成立则语句不执行。

if 的完整结构:

if (表达式1)
 {
	语句1;
 }
 else if (表达式2)
 {
	语句2:
 }
 else
 {
	语句3;
 }

其执行逻辑是:如果表达式1为真,则执行语句1,否则判断表达式2,如果表达式2成立则执行语句2, 否则执行语句3。

使用逻辑运算符编写复杂逻辑的基本思想

1、先找一定成立的逻辑,再找有前提成立的逻辑

2、将逻辑和前提间用&&连接,将逻辑和逻辑间用||连接

课堂练习

1、输入一个字符,判断其是:

(1)不可见字符

(2)数字字符

(3)大写字母

(4)小写字母

(5)其他可见字符

#include <stdio.h>
 int main()
 {
 	char ch = getchar();
 	if (ch <= ' ')
 	{
 		printf("不可见字符\n");
 	}
 	else if (ch >= '0' && ch <= '9')
 	{
 		printf("数字字符\n");
 	}
 	else if (ch >= 'a' && ch <= 'z')
 	{
 		printf("小写字母\n");
	}
 	else if (ch >= 'A' && ch <= 'Z')
 	{
 		printf("大写字母\n");
 	}
 	else
 	{
 		printf("其他可见字符\n");
 	}
 	return 0;
 }

使用 #include 中的函数判断:

#include <stdio.h>
#include <ctype.h>
 
int main()
 {
	 char ch = getchar();
 	if (isspace(ch))
 	{
 		printf("不可见字符\n");
 	}
 	else if (isdigit(ch))
 	{
 		printf("数字字符\n");
 	}
 	else if (islower(ch))
	{
		 printf("小写字母\n");
 	}
 	else if (isupper(ch))
 	{
 		printf("大写字母\n");
 	}
 	else
 	{
 		printf("其他可见字符\n");
 	}
 	 return 0;
 }

2、输入一个年份,判断其是否为闰年

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

3、输入一个年月日,判断其是否合法

#include <stdio.h>

int main()
 {
 	int year, month, day;
	int leapflag = 0;
 	scanf("%d%d%d", &year, &month, &day);
 	if (year % 400 == 0 ||year % 4 == 0 && year % 100 != 0)
 	{
 		leapflag = 1;
 	}
 	if (month < 1 || month > 12 || day < 1 || day > 31 ||
 		day > 30 && (month == 4 || month == 6 || month == 9 || month == 11) ||
		day > 28 + leapflag && month == 2)
 	{
		 printf("不合法");
 	}
 	else
 	{
 		printf("合法");
 	}
 	return 0;
}

switch结构

switch也是选择结构的一种,基本框架:

switch (表达式) //表达式的值必须是整型、枚举
{
 case 1:
 	break;
 case 2:
	 break;
 case 3:
 	break;
 default:;
 }

break 负责跳出 switch 的代码块。如果break所在的代码块不属于 switch ,它就会继续逐级向上查找,直到找到它可以跳出的代码块为止。

※一个 break 只能跳出一层 switch

课堂练习

1、输入学生的成绩,根据学生的具体成绩评级,标准如下:

90分以上:A

80~89:B

70~79:C

60~69:D

60以下:E

#include <stdio.h>

int main()
 {
 	int score;
	scanf("%d", &score);
 	switch (score / 10)
 	{
	 case 10:
 	 case 9:
 		putchar('A');
 		break;
	 case 8:
 		putchar('B');
 		break;
 	 case 7:
 		putchar('C');
 		break;
 	 case 6:
 		putchar('D');
		 break;
 	 default:
 		putchar('E');
	 }
 	 return 0;
}

2、输入一个简单的四则运算算式,输出结果

#include <stdio.h>
 
int main()
{
 	int a, b;
	char sign;
 	scanf("%d%c%d", &a, &sign, &b);
	switch (sign)
 	{
 	case '+':
 		printf("%d\n", a + b);
 		break;
 	case '-':
		 printf("%d\n", a - b);
	 	break;
	case '*':
 		printf("%d\n", a * b);
 		break;
	case '/':
 		printf("%d\n", a / b);
 		break;
 	default:;
 	}
	return 0;
}

循环结构

while

while 是循环的一种常见写法,基本结构:

while (表达式)
 {
	语句;
 }

如果表达式成立,则不断执行语句,直到表达式不成立为止。

使用while打印1到100:

int i = 1;
 while (i <= 100)
 {
	printf("%d ", i);
 	i++;
 }

for

for 语句在自己的括号中存在两个分号,将括号分成了三个部分,基本架构:

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

其执行的方式是先执行语句1,然后判断表达式进入循环,之后循环执行语句2和语句3,直到表达式不成立为止。

※语句1不参与循环,所以即使循环不进,也不影响语句1的执行。

※如果在语句1处定义变量,在MSVC环境下会将这个变量定义到for的代码块内,但不是所有的编译器都会这么做。所以建议不要在这个位置定义变量,以免影响代码的可移植性。

※for语句的表达式的位置可以留空,此时形成死循环

使用for打印1到100:

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

循环相关的两个关键字

break

这个关键字就是上面 switch 中的break,它也可以用来跳出循环。

※一旦 break 语句执行,则循环立即跳出,不会再次判断表达式。

continue

这个关键字的行为逻辑和 break 基本相同,但其不会简单粗暴的跳出循环,而是会打断本次循环,直接判断表达式开始下次循环。

※for语句的语句3不会被跳过 。

打印3的倍数:

 int i;
 for (i = 1; i <= 100; i++)
 {
 	if (i % 3)
	 {
	 continue;
	 }
	 printf("%d\n", i);
 }

do……while

基本架构:

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

do……while 语句和 while 语句的区别仅在于它至少会将语句执行一次,然后再根据表达式是否成立决定 是否继续循环执行语句。

goto

goto 语句是几乎已经被禁用的一个语句,因为滥用 goto 的代码可读性极差,且会毁掉程序员结构化代码的能力,所以暂且禁用。

使用goto打印1~100:

#include <stdio.h>

int main()
 {
 	int i = 1;
 sign:
 	printf("%d ", i);
	 i++;
 	if (i > 100)
 	{
 		goto end;
 	}
 	goto sign;
 end:
 	return 0;
 }

※可以看出这个代码相比for语句而言,可读性极差,这就是goto被禁用的原因。

循环头

数字遍历

循环头: for (i = a; i <= b; i++)

遍历者:i

遍历者i会遍历范围为 [a,b] 的数字区间。

数位遍历

循环头: for (i = n; i; i /= 10)

遍历者: i % 10

遍历者 i % 10会从个位开始取出数字n的每一位。

进阶用法

数位遍历其实就是短除法,所以通常可以用作进制转换

循环头: for (i = n; i; i /= m)

遍历者: i % m

遍历者 i % m会从最低位开始取出数字n在m进制下的每一位。

迭代法

迭代法是编写循环案例的基本方法,其思想是让一个量用来表示变化规律,另一个量用于统合。其基本框架为:

for (某个循环头)
 {
 	tmp = 某个变化规律;
 	sum = 某个统合规律;
 }

※变化规律的寻找方式通常是找两项之间的递推式,有些能一眼看到通项式的题目也可以直接使用通项式。

在迭代法中,只有三个位置需要讨论,即循环的跳出条件、变化规律和统合规律。

课堂案例

1、求1+2+3+…+100的值

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

2、求10!

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

3、求1!+2!+3!+…+10!

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

4、输入m和n(0 < m,n < 10),按照以下方法求和:

若m = 5,n = 2, ,求2 + 22 + 222 + 2222 +22222的值

若m = 3,n = 6,求6 + 66 + 666 的值

#include <stdio.h>
 
int main()
 {
 	int m, n;
 	scanf("%d%d", &m, &n);
	int i;
 	int tmp = 0, sum = 0;
 	for (i = 1; i <= m; i++)
 	{
 		tmp = tmp * 10 + n;
 		sum += tmp;
 	}
 	printf("%d", sum);
 	return 0;
 }

5、输入一个数,输出其各位之和。

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

6、输入一个数,判断它是不是回文数。

#include <stdio.h>
 
int main()
 {
 	int n;
 	scanf("%d", &n);

	int i;
 	int tmp, sum = 0;
	for (i = n; i; i /= 10)
	{
 		tmp = i % 10;
 		sum = sum * 10 + tmp;
 	}
 	if (sum == n)
	{
 		printf("是回文数\n");
 	}
 	else
 	{
 		printf("不是回文数\n");
 	}
 	return 0;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值