【C语言】分支(选择)与循环语句

目录

if语句

1.单分支结构

2.双分支结构

3.多分支结构

4.常见编程陷阱

4.1赋值符的区别

4.2悬空else

switch语句

1.语法结构

2.break在switch中的应用 

3.default在switch中的应用

while循环

1.基本语法

2.break在while循环中的应用

3.continue在while循环中的应用

for循环

1.基本语法

2.break与continue在for循环中的应用

3.特殊情况

do while循环

1.基本语法

2.break和continue在do while循环中的应用

应用练习

1.计算n的阶乘

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

3.在有序数组中查找某个数字(二分查找)


  在生活中我们会面临各种选择,它们代表着一个个分支,在选择做出的那一刻,我们便走上了那条分支,c语言中引入了两种语法用来描述分支。先来看看第一种语法。

if语句

1.单分支结构

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

   像这样的if语句还能往下写很多个,程序会依次判断两个表达式的真假,并根据判断结果执行语句。而在单分支结构中,第一个if表达式的判断结果不会影响第二个if表达式。

2.双分支结构

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

  与单分支结构不同,这种格式的if与else是互斥的,也就是说,第一个if的表达式成立,程序只会执行if的语句,而不会执行else的语句。if与else是一种非此即彼的关系。

3.多分支结构

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

  那么在这种格式下,程序会依次对三个表达式进行判断(当然可能还有更多的表达式),如果一个表达式成立,执行该表达式下的语句,不对其他表达式判断。(就是如果if的表达式为真,程序执行if下的语句,跳过else if与else代码块)

4.常见编程陷阱

4.1赋值符的区别

  思考一个问题,c语言中的‘=’是否与数学中的‘=’意义相同?

  再来看看下面两个代码

int i = 0;
	if (i = 0)//表达式1
	{
		printf("%d", i);
	}
	if (i == 0)//表达式2
	{
		printf("%d", i);
	}

  第一个代码什么都不输出,第二个代码输出0。这是因为在c语言中‘=’是赋值符,‘==’用来判断两个数是否相等。程序在判断表达式1时,将0赋值给i,这使得表达式的结果为假,所以第一个if连语句都没执行。而判断两数是否相等经常出现在if语句的表达式中,‘=’与‘==’的区别要时刻注意。

4.2悬空else

int main()
{
	int a = 2;
	int b = 3;
	if (a == 3)
		if (b == 2)
			printf("hello world");	
	else
		printf("hello bit");
	return 0;
}

  这串代码将会输出什么? hello bit?其实什么都不会输出。因为else与最近的if语句匹配。

并且这串代码连大括号也没加,有质量的代码风格应该像下面这样。

int main()
{
	int a = 2;
	int b = 3;
	if (a == 3)
	{
		if (b == 2)
		{
			printf("hello world");
		}
	    else
	    {
		    printf("hello bit");
	    }
    }
	return 0;
}

 这样写代码是不是可读性更高了?所以在敲代码时要非常注意这些细节,从而增加代码的可读性。

switch语句

1.语法结构

  switch与if一样是分支语句。switch多用与多分支情况。例如输入1~7,输出星期一到星期天。

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

 

  下面来看看switch的语法结构

switch (整形表达式)
{
	case:整形常量表达式
		语句;
}

 switch后面的整形表达式可以是一个变量,就像刚刚例子中的day,注意变量的值必须为整形。而case后要跟整形常量表达式,所以day这样的变量不能跟在case后面,但可以跟1,1 + 2,1 * 2...总之表达式算出来要是一个整形。

2.break在switch中的应用 

  不知道你们注意到没有,我在每条case语句最后加了break,如果没有这个break会有什么发生?

  想输出星期一时却输出了星期一到星期天... 其实程序在执行完case 1的语句后,会依次执行后面其他case的语句,想要只输出星期一,就需要在case最后加上一个break,使程序跳出整个switch语句。

3.default在switch中的应用

  如果在输入时输错了值,程序是什么都不会执行的。要想让输入者知道自己输错了,我们可以在最后加上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;
    dafault:
        printf("输入错误,请重新输入\n");
        break;
	}
	return 0;
}

  如果输入除了1~7以外的其他整形,程序就会执行default后的语句。(这里最好在default后也加上一个break,养成好的代码风格)

  最后,如果我们想输出的结果只有工作日或周末,我们就能巧妙地用break来实现。

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;
    dafault:
        printf("输入错误,请重新输入\n");
        break;
	}
	return 0;
}

分支语句的讲解就到这啦,下面我们开始讲解循环。

  我们在生活中做出选择后,可能会不断地做一些事,不断地重复以实现我们的目标,达到心中对自己的期望。在c语言中引入了三种语法,这些语法就能让程序重复地做一些事。

while循环

1.基本语法

while(表达式)
{
    语句;
}

  表达式为真,while循环开始,执行语句,为假则不执行语句。而这个表达式可以看作条件判断部分,是对循环的一种限制。要实现循环,我们还要有循环变量和调整部分。

int main()
{
	int i = 1;     // 我们不妨把i叫做循环变量
	while (i <= 10)// 我们把"i <= 10"叫做条件判断部分
	{
		printf("%d ", i);
		i++;       // 这就是调整部分啦
	}
	return 0;
}

    怎么让程序输出1~10的数?首先我们要对循环变量初始化,这是循环的开始。接着我们要确定条件判断部分,这决定了循环的结束。当循环变量不满足该部分的条件时,循环跳出,也就是结束啦。为什么循环变量会不满足判断部分的条件?其实在循环中还有一个调整部分,这个调整使循环变量逐渐增大,最终循环变量会不满足判断部分的条件,所以上面的程序在打印完10后就停止了。

  总而言之,一个循环要有三个部分:循环变量的初始化部分,条件判断部分,调整部分。

2.break在while循环中的应用

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

  这串代码的结果是什么?答案是输出1~4。break在while循环中的作用是跳出整个循环,也就是使循环停止。当 i 的值为4时,下一步程序打印4 ,接着 i++ 使i的值变成5,满足if的表达式,程序执行break,循环也就结束了。

3.continue在while循环中的应用

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

  再看看这串代码,它的结果又是什么?答案是1 2 3 4 然后程序死循环。这也就是说continue不会使整个循环结束,它只会跳出一次循环,也可以理解成跳过continue后面的代码。当i为4时,程序打印4,i++ 后 i 为5,满足 if 的条件,程序执行continue,跳过printf与i++再循环,而i的值没变,i 再次满足if的条件,continue又跳过printf和i++...程序就这样子跑死了。所以我们在写continue时要注意不要把调整部分写在它的后面,跳过调整部分会使代码死循环的。

  总之我们明白continue的作用是跳过后面的代码,再进行循环。

  如果我们写了很多的代码,使得循环变量,条件判断部分和调整部分之间的距离太远,以至于我们很难分清谁是谁啦,这时候 for循环就能解决这个痛点。

for循环

1.基本语法

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

  表达式1就是循环变量的初始化部分,表达式2是条件判断部分,表达式3是调整部分。for循环将循环的三个部分放在一行,这使我们修改循环体变得容易。

  在首次进入for循环时,程序的执行过程是:表达式1 ->表达式2 -> 循环语句 -> 表达式3。也就是说,程序在第一次循环时先初始化变量,接着判断变量是否满足判断部分的条件,然后执行循环语句,最后进行变量的调整。

 

   画图理解就是这样的,看着有点点丑...第二次以后的循环是这样的。

   就像一个逆时针的圈,循环在不断地转。

2.break与continue在for循环中的应用

  这两个关键词的作用和while循环一样,唯一不一样的是,continue不会造成for的死循环。

   这是因为调整部分不在循环语句中,for循环中的continue不会跳过 i++,所以程序会跳过5打印1~10。

3.特殊情况

  1)在for循环中,三个循环的条件可以省略。

int main()
{
	for (;;)
	{
		printf("hehe\n");
	}
	return 0;
}

  而如果条件判断部分被省略,这意味着判断恒为真。此时屏幕上会不断的打印”hehe“。(这种情况只是了解一下,初学者最好不要这样写代码,容易导致很多问题)

  2)可以用两个变量控制for循环

int x, y;
    for (x = 0, y = 0; x<2 && y<5; ++x, y++)
   {
        printf("hehe\n");
   }
 return 0; }

  这时只会打印两个”hehe“。

3)省略初始化变量部分

    int i = 0;
    int j = 0;
    for(i=0; i<10; i++)
    {
        for(j=0; j<10; j++)
        {
            printf("hehe\n");
        }
    } //程序打印几个"hehe"?

   很简单,9个。那下面这串代码呢?

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

  9个还是3个?还是什么都没有?(建议把代码复制到IDE,自己调试感受程序的运行)

  答案是3个。i 为0时,j 从0增加到2,循环了三次。当 i 为1时,j 不再是0,而是3,因为我们没有重新把 j 赋值成0。所以 i 为1,2的循环中,j 不满足循环的判断条件,程序不执行打印。

do while循环

1.基本语法

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

  注意while那一行最后有一个' ; ' 。  

  在了解其他两种循环后,do while循环的语法可以说是一看就明白啦。这里说下do while循环的特点,和while循环很相似,唯一不同的是无论怎样,程序会先执行一遍循环语句,再进行条件的判断。所以说程序至少会执行一次。

2.break和continue在do while循环中的应用

  break和continue在do while循环中的作用和while循环一样,这里不再赘述。由于使用场景有限,do while循环很少使用。


应用练习

1.计算n的阶乘

要计算n的阶乘,首先要用循环产生1~n之间的数,让这些数相乘。所以我们创建一个变量并赋值为1,每产生一个数就乘上这个变量,最后打印这个数。接下来是代码的实现。

//计算n的阶乘
int main()
{
	int i = 0;
	int ret = 1;
	int n = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		ret = ret * i;//也能写成ret *= i;
	}
	printf("%d", ret);
	return 0;
}

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

刚刚写的代码能够计算n的阶乘,现在要把阶乘相加。我们只需要在for循环的外层在套一个for循环,假设外层的循环变量是i,i为1时,让内层的循环能计算1的阶乘,i为2时,让内层的循环计算2的阶乘...这样下去我们的代码就能实现了。

int main()
{
	int i = 0;
	int n = 0;
	int k = 0;
	int ret = 1;
	int sum = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		for (k = 1; k <= i; k++)
		{
			ret *= k;
		}
		sum += ret;
		ret = 1;//这行代码别忘啦
	}
	printf("%d", sum);
	return 0;
}

陷阱: 在计算出n的阶乘ret,并把ret的值加给sum后,我们需要把ret的值重新赋为1。假设我们没有重新赋值的操作,ret计算的结果便不再是n的阶乘了。

可这个算法的效率不够高,我们能再优化这串代码。假设我们要算1!+ 2!+3!,假设3!时,内层的for循环反复计算了2!,如果求和的个数比较多,是不是重复了很多次相同计算?其实我们只要在计算完一个数的阶乘后,把这个值加给另一个变量。上代码

int main()
{
	int i = 0;
	int n = 0;
	int sum = 0;
	int ret = 1;
	scanf("%d", &n);


	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
		sum += ret;
	}


	printf("%d", sum);
	return 0;
}

 有没有注意到我只是在计算n的阶乘的程序中加上两行代码。

3.在有序数组中查找某个数字(二分查找)

假设随机给出一个1~100的数,让你猜这个数,第一次我们都会猜中间数50,然后让对方说猜大了还是猜小了,之后还是说中间数...二分查找也是这个道理,我们先输入一个数 k,让程序判断数组的中间元素与n的大小,如果中间元素更小,我们下次只需要对中间元素右边的数组进行相同的操作,然后让程序不断地重复,直到中间元素等于n,我们退出程序,并且打印这个元素在数组中的下标。

int main()
{
	int k = 0;
	scanf("%d", &k);
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[1]) - 1;
         //数组下标从0开始
         //计算出数组元素个数后我们还要减一
	while (left <= right)
	{
		int mid = 0;
		mid = (right + left) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			printf("找到了,下标是%d", mid);
			break;
		}
	}
	if (left > right)
		printf("找不到");
	return 0;
}


  最后,这篇博文是对C语言学习的阶段性总结,文章内容相当的基础,虽然不多,但是写完它还是花了一个下午时间,如果有错误,欢迎指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值