控制语句之分支和循环

1、什么是控制语句

控制语句用于控制程序的执行流程,以实现程序的顺序结构、选择结构和循环结构,它们由特定的语句定义符组成。

C语言有九种控制语句,可以分为以下3类:

(1)分支语句:if语句、switch语句
(2)循环执行语句:do while语句、while语句、for语句;

(3)转向语句:break语句、goto语句、continue语句、return语句。

2、分支语句

2.1if语句

if语句用来判定是否满足所给的条件,根据判定结果来执行后续操作。if语句有三种基本形式,分别为单分支if语句、双分支if语句和多分支if语句。

单分支if语句基本形式为:

if(表达式)
    语句;

执行过程:若表达式为真,则执行语句;否则不执行。

代码示例:

int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)  //当只有单个语句时,可以不加大括号
		printf("未成年\n");
	return 0;
}

双分支if语句基本形式为:

if(表达式)
    语句1;
else
    语句2;

执行过程:若表达式为真,则执行语句1;否则执行语句2。

代码示例:

int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
		printf("未成年\n");
	else
		printf("成年\n");
	return 0;
}

多分支if语句基本形式为:

if(表达式1)
    语句1;
else if(表达式2)
    语句2;
else if(表达式3)
    语句3;
...

else if(表达式n)
    语句n;
else
    语句n+1;

执行过程:若表达式1为真,则执行语句1;若表达式2为真,则执行语句2;以此类推。如果所有的表达式均为假,则执行语句n+1。

代码示例:

int main()
{
	int score = 0;
	scanf("%d", &score);
	if (score < 60)
		printf("不及格\n");
	else if (score >= 60 && score < 70)
		printf("及格\n");
	else if (score >= 70 && score < 85)
		printf("良好\n");
	else
		printf("优秀\n");
	return 0;
}

注意,else总是与距离它最近的if匹配。下面这段代码乍一看输出结果可能是“haha”,实际输出结果为空,因为else与最近的if匹配。

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

加上适当的{ }可以使代码逻辑更加清楚。所以在写代码的时候要养成良好的习惯,增强代码的可读性。

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

2.2switch语句

一个switch语句允许测试一个变量等于多个值时的情况,每个值称为一个case

switch语句的基本形式为:

switch(表达式)
{
    case 常量表达式1:
        语句1;
        break;
    case 常量表达式2:
        语句2;
        break;
    case 常量表达式3:
        语句3;
        break;
        ...
    default:
        语句n;
        break;
}

执行过程:首先计算表达式的值,然后逐次与常量表达式比较。当表达式的值与某个常量表达式的值相等时,执行后面的语句,然后跳出switch case语句;若表达式的值与所有常量表达式的值都不相等,则执行default后的语句。

注意:(1)switch后面表达式必须为整型表达式;

(2)case后面跟的是整型常量表达式,可以使用字符类型,因为字符在内存中以ASCII码值存储;

(3)case后的各常量表达式不能相同;

(4)case后允许有多个语句,可以不用{ }括起来;

(5)case和default的先后顺序可以变动;

(6)每个switch语句中只能出现一条default子句,default子句可以省略。

代码示例:

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:
		break;
	}
	return 0;
}

switch语句为如下形式时,case的值为1、2、3、4、5时输出的结果是相同的,case的值为6、7时输出的结果是相同的。

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;
	default:
		break;
	}
	return 0;
}

switch语句还可以嵌套使用。下面代码中,输出结果为m = 5,n = 3。

n = 1,进入case 1语句,此时m = 3,然而并没有遇到break,所以继续执行下面case语句;进入case 2语句,n = 2;进入case 3语句,此时嵌套了一个switch语句,n为2,进入case 2语句中,m = 4,n = 3,这里的break是跳出嵌套的switch语句,而外层的switch语句还要继续;进入case 4语句,m = 5,n = 3,break跳出外出swtich语句。

int main()
{
	int n = 1;
	int m = 2;
	switch (n)
	{
	case 1:m++;
	case 2:n++;
	case 3:
		switch (n)
		{
		case 1:n++;
		case 2:
			m++;n++;
			break;
		}
	case 4:
		m++;
		break;
	default:
		break;
	}
	printf("m = %d, n = %d\n", m, n);
	return 0;
}

3、循环语句

3.1do while语句

do while循环的基本形式为:

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

执行过程:先执行循环体语句,再判断表达式是否为真,若为真,则继续循环;若为假,则跳出循环。

3.2while语句

while循环的基本形式为:

while(表达式)
{
    循环体语句;
}

执行过程:先判断表达式,若为真,则执行循环体语句;若为假,则跳出循环。

代码示例:打印0~9的数字。

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

while循环中的break和continue:

break永久终止循环;continue终止本次循环,进行下一次循环。下面通过代码观察一下break和continue的区别。
代码1:

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

代码2:

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

代码1中当i=5时,直接终止循环,运行结果为0 1 2 3 4。

代码2中当i=5时,跳过本次循环后面的语句,进入下次循环,i的值并没有改变,所以陷入死循环。

3.3for语句

for循环的基本形式为:

for(初始化表达式;条件表达式;更新表达式)
{
    循环体语句;
}

执行过程:先求解初始化表达式,然后求解条件表达式,若为真,则执行循环体语句,接着执行更新表达式;若为假,则跳出循环。

注意:(1)for循环中的三个表达式都可以省略,但“;”不能省略;

(2)初始化表达式和更新表达式可以是一个简单表达式,也可以是逗号表达式;

(3)条件表达式一般是关系表达式或者逻辑表达式,也可以是数值表达式或者字符表达式;

(4)一个for循环可以有多个循环控制变量。

代码示例:

int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)
		k++;
	return 0;
}

这个代码循环0次,首先条件表达式"k=0"是赋值而不是判等,其次表达式的值为0,而0为假,所以循环一次都不会进入。

for循环中的break和continue:

break和continue在for循环中和在while循环中的作用相同,但在使用时结果有些差异。

代码1:

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

代码2:

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

代码1的执行结果为0 1 2 3 4,代码2的执行结果为0 1 2 3 4 6 7 8 9。可以看出,使用break时,当i=5直接终止循环,使用continue时,当i=5跳过当前循环,执行更新表达式进入下一次循环。

4、goto语句

goto语句的基本形式为:

goto 语句标号;

...

语句标号:
    语句;

执行过程:无条件跳到语句标号处,然后执行后面代码。

注意:(1)语句标号可由字母、数字和下划线组成,第一个字符必须是字母或者下划线;

(2)goto语句可以用来跳出深层循环,但也会让代码结构层次模糊,不易读,所以要合理运用goto语句。

5、练习

1、计算n!

int main()
{
	int n = 0;
	scanf("%d", &n);
	int mul = 1;
	for (int i = 1; i <= n; i++)
	{
		mul *= i;
	}
	printf("mul = %d\n", mul);
	return 0;
}

2、计算1!+2!+3!+...+10!

方法一:

int main()
{
	int sum = 0;
	for (int i = 1; i <= 10; i++)
	{
		int mul = 1;
		for (int j = 1; j <= i; j++)
		{
			mul *= j;
		}
		sum += mul;
	}
	printf("sum = %d\n", sum);
	return 0;
}

方法二(优化):

int main()
{
	int mul = 1;
	int sum = 0;
	for (int i = 1; i <= 10; i++)
	{
		mul *= i;
		sum += mul;
	}
	printf("sum = %d\n", sum);
	return 0;
}

3、折半查找

int main()
{
	int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = len - 1;
	int k =7;
	int flag = 0;
	while (left <= right)
	{
		//int mid = (right + left) / 2;    
		//当left和right过大时,二者的和可能会超出整型所能表示的最大范围,发生越界
		//所以采用下面这种方式
		int mid = left + (right - left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了!下标是%d\n", mid);
			flag = 1;
			break;
		}
	}
	if (flag == 0)
		printf("没找到!\n");
	return 0;
}

4、实现多个字符从两端移动,向中间汇聚

#include <stdio.h>
#include <string.h>
#include <Windows.h>
int main()
{
	char arr1[] = "hello world!";
	char arr2[] = "************";
	int left = 0;
	int right = strlen(arr1) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);  //停止1000毫秒
		system("cls");  //清屏
		left++;
		right--;
	}
	printf("%s\n", arr2);
	return 0;
}

5、猜数字游戏(1~100)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
	printf("********************\n");
	printf("******1.0 start*****\n");
	printf("******0.0  exit*****\n");
	printf("********************\n");
}

void game()
{
	//设置随机数
	int ret = rand() % 100 + 1;
	//猜数字
	int input = 0;
	while (1)
	{
		printf("请输入->");
		scanf("%d", &input);
		if (input < ret)
		{
			printf("猜小了\n");
		}
		else if (input > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("猜对了!\n");
			break;
		}
	}
}

int main()
{
	int input = 0;
	//随机数生成器
	srand((unsigned)time(NULL));
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/minLi_/article/details/131600533