分支语句和循环语句

前面介绍了初识C语言相关内容,这篇博客开始将正式对C语言的每一个章节进行深入学习,这篇主要讲解分支语句和循环语句!!!


本篇博客所学习的分支语句和循环语句主要依附于控制语句,所以何为控制语句?

控制语句 用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成, C 语言有九种控制语句,可分成以下三类:
1. 条件判断语句也叫分支语句: if 语句、 switch 语句;
2. 循环执行语句: do while 语句、 while 语句、 for 语句;
3. 转向语句: break 语句、 goto 语句、 continue 语句、 return 语句。


分支语句(选择结构)

前面初识C语言中我们举过这样一个例子,好好学习就可以拿一个好offer,摆烂的话你就得回家种地,这就是一种选择,不同的选择就会有不同的结果,在C语言中,这种不同的结果则会对应执行不同的语句(或代码块)。

 今天让我们一起来学习两种分支语句:if语句和switch语句。

if语句

if语句的语法结构

语法结构:
1. if ( 表达式 )
     语句 ;
2.  if (表达式 )
     语句 1 ;
    else
     语句 2 ;
3.  // 多分支    
    if ( 表达式 1 )
     语句 1 ;
    else if ( 表达式 2 )
     语句 2 ;
    else
     语句 3 ;

 代码示例分别如下:

1.

2.

3.

 注意:其中在写else if中的条件时,一定要用&&这个操作符,假设你写成(18<age<30),此时程序的执行过程是18如果<age,左边就会为真,此时18<age的运算结果就会为1(C语言默认的为1),然后再去执行1<30这个语句。

如果条件成立,要执行多条语句,应该使用代码块。

 此时编译会发生错误,因为执行多条语句时,应使用大括号,改正如下:

 以后在敲代码时,应该养成这种习惯,不管是一条语句还是多条语句,我们都要带上大括号,这样不仅不会出现错误,而且会增加我们的代码在逻辑上的可读性。

悬空else

我们一起来考虑一下这个代码的运行结果,大部分人可能都会这么想a = 0,不满足第一个if条件,则会执行与其对应的else里面的语句打印出haha,让我们一起来看一下编译结果:

#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,所以这里的else与第二个if匹配,当不满足第一个if的条件时会直接退出程序。这个例子也更加证明前面提到的书写大括号这个习惯的重要性!

改正如下:


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

若加上大括号,此时结果就会输出haha。

switch语句

前面的例子当我们遇到多个条件时,会一直重复书写else if,为了避免这种复杂形式我们就会采用switch语句。

switch语句的语法结构

switch ( 整型常量表达式 )
{
    语句项;
}
语句项:
// 是一些 case 语句:
// 如下:
   case 整形常量表达式 :
    语句 ;

 switch语句中的break

switch 语句中,我们没办法直接实现分支,搭配 break 使用才能实现真正的分支,执行完某个case语句后,我们一般采用break语句跳出switch达到分支的作用。
假如我们需要输出一个星期的某一天时,可采用switch语句,如下:
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;
 }

 有时候我们的需求变了:

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

 编程好习惯

在最后一个 case 语句的后面加上一条 break语句。
(之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句)。

default子句

default语句:写在任何一个 case 标签可以出现的位置。
switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个 switch 语句中只能出现一条 default 子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个 case 标签一样执行 default 子句。
编程好习惯
在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
小练习1:
#include <stdio.h>
int main()
{
    int n = 1;
    int m = 2;
    switch (n)
   {
    case 1:
            m++;
    case 2:
            n++;
    case 3:
            switch (n)
           {//switch允许嵌套使用
             case 1:
                    n++;
             case 2:
                    m++;
                    n++;
                    break;
           }
    case 4:
            m++;
            break;
    default:
            break;
   }
    printf("m = %d, n = %d\n", m, n);
    return 0;
}

答案:m = 5,n = 3,自行考虑!

小练习2:

int func(int a)
{
    int b;
    switch (a)
    {
        case 1: b = 30;
        case 2: b = 20;
        case 3: b = 16;
        default: b = 0;
    }
    return b;
}

此时fun(1) =  ?

答案为:0;

注意:在没有break语句中跳出switch时,switch中的任何语句都需要执行(包括default语句),其中default与case语句没有先后顺序。




循环语句

C语言中我们主要学习三个循环,分别为:
while 循环
for 循环
do while 循环

我们都知道if语句,满足条件时会执行,否则不执行,但是整个语句只能执行一次;由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。那我们怎么做呢? C语言中给我们引入了: while 语句,可以实现循环。

while语法结构

while ( 表达式 )
循环语句 ;
如何在屏幕上打印1-10的数字呢?
int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d ", i);
		i++;
	}
	return 0;
}

 我们只需要在while的判断语句中加上条件,然后每次打印后让i++就可以了。

while语句中的breakcontinue

break

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

此时结果为1 2 3 4,i=5时执行break语句会跳出循环,所以break的作用就是跳出整个循环,是永久的。

continue

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

 此时结果为1 2 3 4后面死循环,是因为continue只是跳出本次循环后面的语句,直接跳转到while语句的判断部分,进行下一次循环的入口判断。

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

 

 该编译结果自行理解。

总结:

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

 for循环

for循环语法

for ( 表达式 1 ; 表达式 2 ; 表达式 3 )
循环语句 ;
表达式 1
表达式 1 初始化部分 ,用于初始化循环变量的。
表达式 2
表达式 2 条件判断部分 ,用于判断循环时候终止。
表达式 3
表达式 3 调整部分 ,用于循环条件的调整。

类比于前面的while循环,我们都知道使用while循环时,需要先定义一个初始变量,然后while的括号需要写入判断条件,出while循环时也需要写调整语句;那么同样for循环也需要,只不过for循环把这三个部分的语句整合在了一个括号内。 那我们如何用for循环在屏幕上打印1-10的数字呢?如下:

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

 

其中for(i=1/*初始化*/; i<=10/*判断部分*/; i++/*调整部分*/)

对比for循环和while循环

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");
}
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较 远,这样 查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。

for循环中的break和continue

break

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

 结果为1 2 3 4,i= 5时遇到break语句直接跳出循环,所以break的作用就是跳出整个循环,是永久的。

continue

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

此时结果为1-10没有5,同while循环不同是因为i=5时,continue会跳过后面的代码,但是i++语句并没有跳过,所以i++之后=6进入for循环继续执行打印操作。 

for循环书写建议

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

1.示例:

 此时编译会出现死循环是因为在for循环体内加了一句i=0这个控制语句,造成每次进入循环时i始终等于1,所以不可在for 循环体内修改循环变量,防止 for 循环失去控制

2.

int i = 0 ;
// 前闭后开的写法
for ( i = 0 ; i < 10 ; i ++ )
{}
// 两边都是闭区间
for ( i = 0 ; i <= 9 ; i ++ )
{}
第一种写法更容易看出需要循环10次,逻辑上更容易被理解

一些for循环的变种

1.

int main()
{
 //代码1
 for(;;)
 {
 printf("hehe\n");
 }
    //for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问
题。

因为没有控制语句,会默认for循环的判断语句恒成立,此时会死循环打印hehe,故写for循环时最好不要省略。

2.

1.

int main()
{
	int i = 0;
	int j = 0;
	//这里打印多少个hehe?
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("hehe\n");
		}
	}
	return 0;
}

2.
int mian()
{
	int i = 0;
	int j = 0;
	//如果省略掉初始化部分,这里打印多少个hehe?
	for (; i < 3; i++)
	{
		for (; j < 3; j++)
		{
			printf("hehe\n");
		}
	}

	return 0;
}

 来比较两个代码,分别会打印多少个呵呵?

 第一个代码打印了9个hehe,因为外面三次循环,里面三次循环,所以一共3*3 = 9次循环,故打印9次hehe;

第二个代码为什么只打印了三个hehe呢?那是因为当i= 0进入第二个for循环时,内层循环j会一直++,当j=3时退出内层循环打印了三个hehe,但是此时j=3,当i++等于1时,j=3不满足第二个for循环的条件不会进入内层循环,故只打印了三个hehe。所以我们在书写代码时尽量不要省略初始条件!!!

do...while循环

do语句的语法

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

do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用。
示例:
int main()
{
	int i = 10;

	do
	{
		printf("%d\n", i);
	} while (i < 10);

	return 0;
}

虽然此时i=10不满足while里面的条件,但是do语句的特点至少执行一次,故输出10。

do while循环中的breakcontinue  

break

int main()
{
	int i = 10;

	do
	{
		if (5 == i)
			break;
		printf("%d\n", i);
	} while (i < 10);

	return 0;
}

continue

int main()
{
	int i = 10;

	do
	{
		if (5 == i)
			continue;
		printf("%d\n", i);
	} while (i < 10);

	return 0;
}

 

从编译结果可以看出,break和continue的结果都是10(同while语句类似),读者自行理解,不做过多赘述 。




狂肝将近6000字,希望读者可以耐心看完,那么循环和分支语句的介绍到这里,后面我会出一篇关于本章的相关题目以加强读者的理解,然后我们就得开启函数学习的篇章了,烦请点个关注和收藏,我们一起继续努力,加油!!!

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值