【零天赋C语言】——详解分支和循环语句

目录

一、什么是语句?

二、分支语句(选择结构)

2.1 if语句

2.1.1 语法结构

2.1.2 悬空else

2.2 switch语句

2.2.1 语法结构

2.2.2 在switch语句中的 break 

2.2.3 default子句

三、循环语句

3.1 while循环

3.1.1 语法结构

 3.1.2 while语句中的break和continue

 3.2 for循环

3.2.1 语法结构

3.2.2  for循环中的break和continue

3.2.3 for语句中的循环控制变量

3.3 do...while循环

3.3.1 语法结构

3.3.2 do...while循环中的break和continue

 3.3.3 练习

四、goto语句


一、什么是语句?

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

1、表达式语句

2、函数调用语句

3、控制语句

4、复合语句

5、空语句

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

可以分为以下三种:

1. 条件判断语句也叫分支语句:if语句、switch语句;
2. 循环执行语句:do while语句、while语句、for语句;
3. 转向语句:break语句、goto语句、continue语句、return语句。
2. 分支语句(选择结构)

二、分支语句(选择结构)

2.1 if语句

2.1.1 语法结构

if语句的语法结构有以下几种:

 if(表达式)

       语句;



if(表达式)

      语句1:;
   else

       语句2;


//多分支

if(表达式1)
      语句1;

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

else
       语句3;

代码演示:

    if:

#include <stdio.h>

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

if~else:

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

多分支:

#include <stdio.h>

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

注意:如果表达式的结果为真,则语句执行;

在C语言中 0 表示假,非零表示真。

再多分支语句中,要注意代码块的使用:

#include<stdio.h>

int main()
{
	if (表达式)
    {
	      语句1;
    }
	else
	{
          语句2;
    }
	return 0;
}

2.1.2 悬空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会与最近的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;
}

所以,适当的使用 {} 可以使代码逻辑更加清晰,养成良好的代码风格。

2.2 switch语句

2.2.1 语法结构

那语句项是什么呢?

是一些case语句:

case  整形常量表达式 :

                  语句;

2.2.2 在switch语句中的 break 

在switch语句中,我们无法真正的实现分支,搭配break才能真正的实现分支:

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期1\n");
		break;
	case 2:
		printf("星期2\n");
		break;
	case 3:
		printf("星期3\n");
		break;
	case 4:
		printf("星期4\n");
		break;
	case 5:
		printf("星期5\n");
		break;
	case 6:
		printf("星期6\n");
		break;
	case 7:		
        printf("星期天\n");
		break;
   }
    return 0;
}

如果要求变了,1~5输出工作日,6~7输出休息日呢?

我们的代码应该这样实现:

#include <stdio.h>
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;
   }
    return 0;
}

break语句的实际作用就是把语句列表划分为不同的分支部分。

注:编程好习惯——在最后一个 case 语句的后面加上一条 break语句。

2.2.3 default子句

如果表达的值与所有的case标签都不匹配怎么办呢?

这时程序并不会终止和报错,可以再语句列表中增加default:

当switch 表达式的值并不匹配所有case 标签的值时,这个default子句后面的语句就会执行。

所以,每一个switch语句中只能出现一条default子句。

注:编程好习惯——在每一个switch 语句中都放一条default子句,甚至可以在后面加一个break。

练习:

#include <stdio.h>
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;
}

答案:5  3

解析进入循环,n=1,执行case 1:,m++,然后因为没有break,就继续执行case 2:,case 3:这时的n=2,执行嵌套switch的case 2:,这时n=3,m=4,然后break跳出嵌套switch,执行case 4:,因为case 4:有break所以跳出循环,打印m和n的值,结果就是m=5,n=3;

三、循环语句

3.1 while循环

3.1.1 语法结构

 例如:在屏幕上打印1~10个数字

#include <stdio.h>

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

 3.1.2 while语句中的break和continue

思考break 例:

#include <stdio.h>

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

答案:1 2 3 4

解析:在while循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。


思考continue 例:

#include <stdio.h>

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

结果:1 2 3 4 死循环

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

思考下列代码:

#include <stdio.h>


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

 这个代码的作用是只打印数字字符跳过其他字符,其中while ((ch = getchar()) != EOF)用来清理缓存区的。

 3.2 for循环

3.2.1 语法结构

例如:

3.2.2  for循环中的break和continue

思考下列代码:

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

代码1 答案: 1 2 3 4

解析: 在for循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。

代码2  答案:1 2 3 4 6 7 8 9 10 

解析:continue在for循环中用于终止本次循环的,也就是continue后面的代码不会执行,而直接跳转到下一次循环的入口判断,并没有跳过i++。

3.2.3 for语句中的循环控制变量

建议:
1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。

//前闭后开的写法
for(i=0; i<10; i++)
{}


//两边都是闭区间
for(i=0; i<=9; i++)
{}

 思考代码1打印几个hehe呢?

#include <stdio.h>
int main()
{
	int i = 1;
	int j = 1;

	for (; i <= 10; i++)
	{
		for (; j <= 10; j++)
		{
			printf("hehe\n");
		}
	}
	return 0;
}

答案:

 解析:循环外 i=1,j=1;进入第一个for循环后,i=1<10,进入第二个for循环,

j=1<10,打印 hehe,打印10个hehe 之后,跳转到第一个for循环,此时i=2,j=10;

就不再进入第二个for循环了。

思考代码2,问循环执行多少次?

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

答案: 0次;

解析:因为在for循环的判断部分 k=0 把0赋值给k,k为0,及判断部分为假,循环不执行。

3.3 do...while循环

3.3.1 语法结构

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

3.3.2 do...while循环中的break和continue

思考下列代码:

//代码1
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			break;
		printf("%d\n", i);
            i++;
	} while (i < 10);
	return 0;
}
//代码2
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			continue;
		printf("%d\n", i);
             i++;
	} while (i < 10);
	return 0;
}

代码1 答案:1 2 3 4 

解析:在do...while循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。

代码2 答案:1 2 3 4 死循环
解析:continue在do...while循环中用于终止本次循环的,也就是continue后面的代码不会执行,而直接跳转到while语句的判断部分,进行下一次循环的入口判断,由于跳过了i++部分,所以 i 始终是5,一直循环下去。

 3.3.3 练习

猜数字游戏:

#include <stdio.h>
#include<stdlib.h>
#include <time.h>
void game()
{
	int ret = rand() % 100 + 1;
	int i = 0;
	while (1)
	{
	    printf("请猜数字:> ");
	    scanf("%d", &i);
		if (i < ret)
		{
			printf("猜小了,再猜一次\n");
			
		}
		else if (i > 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("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入。\n");
			break;
		}

	} while (input);

	return 0;
}

二分查找法:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int right = sz - 1;
	int k = 0;
	printf("请输入要查找的数字:");
	scanf("%d", &k);
	while (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);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到了\n");
	}
	return 0;
}

四、goto语句

C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如关机小程序:

int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的

	while (1)
	{
		printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
	    scanf("%s", input);

		//判断
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");//取消关机
			break;
		}
	}

	return 0;
}


 

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值