C:分支与循环

本文详细介绍了C语言中的语句类型,包括表达式语句、函数调用、控制语句(如if、switch、循环和转向语句)、复合语句和空语句。特别讨论了if语句的使用,包括单分支和双分支的情况,以及如何避免“悬空else”的问题。此外,还讲解了for循环和while循环的差异,以及break和continue在循环中的作用。最后提到了do...while循环和goto语句的使用场景,并给出了相关示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

语句:

C语言的语句可以分为以下五类:

1.表达式语句:

int a=10;

2.函数调用语句

printf("hello world!");

3.控制语句

 控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语 言有九种控制语句。

可分成以下三类:
1. 条件判断语句也叫分支语句: if 语句、 switch 语句;
2. 循环执行语句: do while 语句、 while 语句、 for 语句;
3. 转向语句: break 语句、 goto 语句、 continue 语句、 return 语句。

4.复合语句

5.空语句

;(一个分号就是一句空语句)

if语句

if语句的构成

语法结构:
if ( 表达式 )
    语句 ;
if ( 表达式 )
    语句 1 ;
else
    语句 2 ;
// 多分支    
if ( 表达式 1 )
    语句 1 ;
else if ( 表达式 2 )
    语句 2 ;
else
    语句 3 ;
int age = 0;
	scanf("%d", &age);
	if (age > 18)
	{
		printf("成年!");
	}
	return 0;

当我输入为2时,就不会打印成年 

 当我输入的值为20时,便会打印成年

当为双分支时:

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

当为多分支时:

int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age > 0 && age < 18)
	{
		printf("未成年!");
	}
	else if (age >= 18 && age <= 40)
	{
		printf("青年!");
	}
	else if (age > 40 && age <= 60)
	{
		printf("壮年!");
	}
	else
	{
		printf("老年!");
	}
	return 0;
}
解释一下:
如果表达式的结果为真,则语句执行。
C语言中如何表示真假?
0 表示假,非 0 表示真。
如果条件成立,要执行多条语句,怎应该使用代码块。
#include <stdio.h>
int main()
{
    if(表达式)
   {
        语句列表1;
   }
    else
   {
        语句列表2;
   }
    return 0;
}
这里的一对 { } 就是一个代码块。

悬空else

else 的匹配 else 是和它离的最近的 if 匹配的。

你认为下面的代码会怎样执行?

#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;
}

你是否会觉得它会打印haha?看一下代码的执行结果:

  它什么都不会打印!因为else是和离他最近的if匹配的,而不是和你想象中的跟if(a==1)匹配! 

这种代码的风格极具迷惑性是一种非常糟糕的写法,我们写代码的时候要规范!

日过想要达到想象中的效果,就需要对代码进行一定的规范:

//适当的使用{}可以使代码的逻辑更加清楚。
//代码风格很重要
#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;
}

 if书写形式的对比

//代码1
if (condition) {
    return x;
}
return y;
//代码2
if(condition)
{
    return x;
}
else
{    return y;
}
//代码3
//代码3的问题是你很容易会将代码写成这个样子:
//if(num = 5)  这是赋值操作,结果会恒为真,才用代码4的
//写法,就可以有效的避免这个问题
int num = 1;
if(num == 5)
{
    printf("hehe\n");
}
//代码4
int num = 1;
if(5 == num)
{
    printf("hehe\n");
}
1. 判断一个数是否为奇数
2. 输出 1-100 之间的奇数
//判断一个数是否是奇数
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 2 == 1)
	{
		printf("奇数!");
	}
	else
	{
		printf("偶数!");
	}
	return 0;
}
int main()
{
	for (int i = 0; i <= 100; i++)
	{
		if (i % 2 == 1)
		{
			printf("%d ", i);
		}

	}
}

switch

switch 语句也是一种分支语句。
常常用于多分支的情况。
比如:
输入 1 ,输出星期一
输入 2 ,输出星期二
输入 3 ,输出星期三
输入 4 ,输出星期四
输入 5 ,输出星期五
输入 6 ,输出星期六
输入 7 ,输出星期日
那我没写成 if...else if ...else if 的形式太复杂,那我们就得有不一样的语法形式。
这就是 switch 语句。
switch ( 整型表达式 )
{
    语句项;
}
语句项 是什么呢?
// 是一些 case 语句:
// 如下:
case 整形常量表达式 :
    语句 ;
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("周一!\n");
	case 2:
		printf("周二!\n"); 
	case 3:
		printf("周三!\n");
	case 4:
		printf("周四!\n");
	case 5:
		printf("周五!\n");
	case 6:
		printf("周六!\n");
	case 7:
		printf("周日!\n");
	}
	return 0;
}

为什么会出现这样的结果,由结果我们可以分析出来当我们输入值为3时,执行case3,4,5,6,7,为什么?

没有break能让它停止

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

 只有加入break后,才能让它停止

 有时候我们的需求变了:

1. 输入 1-5 ,输出的是 “weekday”;
2. 输入 6-7 ,输出 “weekend”
所以我们的代码就应该这样实现了:
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday!\n");
		break;
	case 6:
	case 7:
		printf("weekend!\n");
		break;
	}
	return 0;
}
break 语句 的实际效果是把语句列表划分为不同的分支部分。
编程好习惯
在最后一个 case 语句的后面加上一条 break 语句。
(之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break 语句)。
2.2.2 default 子句
如果表达的值与所有的 case 标签的值都不匹配怎么办?
其实也没什么,结构就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在 C 中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条 default 子句,把下面的标签
default
写在任何一个 case 标签可以出现的位置。
switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个 switch 语句中只能出现一条 default 子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个 case 标签一样执行 default 子句。
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday!\n");
		break;
	case 6:
	case 7:
		printf("weekend!\n");
		break;
	default:
		printf("输入错误!");
		break;
	}
	return 0;
}
编程好习惯
在每个 switch 语句中都放一条 default 子句是个好习惯,甚至可以在后边再加一个 break
//分析一段代码
#include <stdio.h>
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);//m=5,n=3
	return 0;
}

循环语句

  • while
  • for
  • do while

3.1 while循环

我们已经掌握了, if 语句:
当条件满足的情况下, if 语句后的语句执行,否则不执行。
if ( 条件 )
    语句 ;
但是这个语句只会执行一次。
由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。
那我们怎么做呢?
C 语言中给我们引入了: while 语句,可以实现循环。
while ( 表达式 )
循环语句 ;
比如我们实现:
在屏幕上打印 1-10 的数字。
int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d ", i);
		i++;
	}
	printf("\n");
	return 0;
}

while语句中的breakcontinue

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

这里代码的输出结果是什么?

A.1 2 3 4
B.1 2 3 4 5
C.1 2 3 4 5 6 7 8 9 10
D.1 2 3 4 6 7 8 9 10

总结:
break while 循环中的作用:
其实在循环中只要遇到 break ,就停止后期的所有的循环,直接终止循环。
所以: while 中的 break 是用于 永久 终止循环的。

continue介绍

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

这里的代码输出结果是什么?

A.1 2 3 4
B.1 2 3 4 5
C.1 2 3 4 5 6 7 8 9 10
D.1 2 3 4 6 7 8 9 10

总结 :
continue while 循环中的作用就是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,
而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。

看一组代码:

//输出0-9之间的字符
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch>'9')
		{
			continue;
		}
		putchar(ch);
	}
}

for循环

我们已经知道了 while 循环,但是我们为什么还要一个 for 循环呢?

首先来看看for循环的语法:

for ( 表达式 1 ; 表达式 2 ; 表达式 3 )
循环语句 ;
表达式 1
表达式 1 初始化部分 ,用于初始化循环变量的。
表达式 2
表达式 2 条件判断部分 ,用于判断循环时候终止。
表达式 3
表达式 3 调整部分 ,用于循环条件的调整。
实际的问题:
使用 for 循环 在屏幕上打印 1-10 的数字。
//用for循环打印1-10之间的数字
int main()
{
	for (int i = 1; i < 11; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

对比while和for循环

//对比一下for循环和while循环
int main()
{
	int i = 0;
	//实现相同的功能,使用while
	i = 1;//初始化部分
	while (i <= 10)//判断部分
	{
		printf("hehe\n");
		i = i + 1;//调整部分
	}
	//实现相同的功能,使用while
	for (i = 1; i <= 10; i++)
	{
		printf("hehe\n");
	}
	return 0;
}
可以发现在 while 循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较 远,这样查找修改就不够集中和方便。所以,for 循环的风格更胜一筹;for循环使用的频率也最高。

breakcontinuefor循环中

我们发现在 for 循环中也可以出现 break continue ,他们的意义和在 while 循环中是一样的。
但是还是有些差异:
//代码1
#include <stdio.h>
int main()
{
 int i = 0;
 for(i=1; i<=10; i++)
 {
 if(i == 5)
 break;
 printf("%d ",i);
 }
 return 0;
}

只会打印1,2,3,4然后跳出循环。

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

这段代码的结果如何呢?

for语句的循环控制变量

建议:
1. 不可在 for 循环体内修改循环变量,防止 for 循环失去控制。
2. 建议 for 语句的循环控制变量的取值采用 前闭后开区间 写法。
int i = 0;
//前闭后开的写法
//看起来更加的直观明显
for (i = 0; i < 10; i++)
{
}
//两边都是闭区间
for (i = 0; i <= 9; i++)
{
}

一些for循环的变种

//死循环
//for循环中的初始化部分,判断部分,调整部分是可以省略的,
//但是不建议初学时省略,容易导致问题
//如果省略了判断条件,就会判断恒为真
int main()
{
	for (;;)
	{
		printf("hehe\n");
	}
	return 0;
}
int main()
{
	//代码2
	int i = 0;
	int j = 0;
	int count = 0;
	//这里打印多少个hehe?
	for (i = 0; i < 10; i++)
	{
		for (j = 0; j < 10; j++)
		{
			printf("hehe\n");
			count++;
		}
	}
	printf("%d\n", count);//count=100
}
int main()
{
	//代码3
	int i = 0;
	int j = 0;
	int count = 0;
	//如果省略掉初始化部分,这里打印多少个hehe?
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe\n");
			count++;
		}
	}
	printf("%d", count);//10
	return 0;
}
//代码4-使用多余一个变量控制循环
int main()
{
	int x, y;
	for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
	{
		printf("hehe\n");
	}
	return 0;
}

笔试题练习

//请问循环要循环多少次?
#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,恒为假,根本就不会·执行下面的代码,会直接跳出来。

do...while()循环

do语句的语法:

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

do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用。
int main()
{
	int i = 10;
	do
	{
		printf("%d\n", i);
	} while (i < 10);
	return 0;
}

do while循环中的breakcontinue

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

跟while循环一样,都是跳到判断部分。

练习

1. 计算 n 的阶乘。
2. 计算 1!+2!+3!+……+10!
3. 在一个有序数组中查找具体的某个数字 n 。(二分查找)
4. 编写代码,演示多个字符从两端移动,向中间汇聚。
5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序。
//n的阶乘
int main()
{
	int n = 0;
	int ret = 1;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		ret = ret * i;
	}
	printf("%d\n", ret);
	return 0;
}
//计算 1!+ 2!+ 3!+ …… + 10!
int main()
{
	int n = 10;
	int ret = 1;
	int res = 0;
	for (int i = 1; i <= 10; i++)
	{
		ret = ret * i;
		res = res + ret;
	}
	printf("%d\n", res);
	return 0;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = 9;
	
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (6 > arr[mid])
		{
			left = mid + 1;
			
		}
		else if (6 < arr[mid])
		{
			 right= mid - 1;
		}
		else
		{
			printf("%d", mid);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到!\n");
	}
	return 0;
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<Windows.h>
int main()
{
	char arr1[] = "Hello Linux!";
	char arr2[] = "############";
	int left = 0;
	int right = strlen(arr2) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		left++;
		right--;
		printf("%s\n", arr2);
		Sleep(1000);
		system("cls");
	}
	printf("%s\n", arr2);
	return 0;

}
int main()
{
	char input[20] = { 0 };
	int count = 0;
	printf("请输入你的密码:\n");
	for (int i = 0; i < 3; i++)
	{
		scanf("%s", input);
		if (strcmp(input, "123456") == 0)
		{
			printf("登陆成功\n");
			break;
		}
		else
		{
			printf("密码错误,请重新输入!\n");
			count++;
		}
	}
	if (count == 3)
	{
		printf("exit\n");
	}
	return 0;
}

goto语句

C 语言中提供了可以随意滥用的 goto 语句和标记跳转的标号。
从理论上 goto 语句是没有必要的,实践中没有 goto 语句也可以很容易的写出代码。
但是某些场合下 goto 语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如:一次跳出两层或多层循环。  
多层循环这种情况使用 break 是达不到目的的。它只能从最内层循环退出到上一层的循环。
goto 语言真正适合的场景如下:
for(...)
    for(...)
   {
        for(...)
       {
            if(disaster)
                goto error;
       }
   }
    …
error:
 if(disaster)
         // 处理错误情况
下面是使用 goto 语句的一个例子,然后使用循环的实现方式替换 goto 语句:
一个关机程序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
	char input[12] = { 0 };
	system("shutdown -s -t 60");
	again:
	printf("请输入你是猪!否则你的电脑会关机!\n");
	scanf("%s", input);
	if (strcmp("我是猪",input) == 0)
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}
	return 0;
}

如果不使用goto,可以换为循环:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
	char input[10] = { 0 };
	system("shutdown -s -t 60");
	while (1)
	{
		printf("请输入:“我是猪!”\n");
		printf("否则你的电脑将会在1分钟后关机!\n");
		scanf("%s", input);
		if (strcmp("我是猪!", input) == 0)
		{
			system("shutdown -a");
			printf("还是输入了!\n");
			break;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值