C语言入门易错题第二弹——分支与循环语句

目录

一、关于用于判断的表达式

1.switch语句括号里的“表达式”,只能是int的类型。(错)

2.if后面都有表达式,只能为逻辑表达式或关系表达式。(错)解释:if语句中在if后面的表达式,一般为逻辑表达式或关系表达式。  例如:⁤⁤ 

3.while和if类似,而for其后类型相对固定,在此不赘述。

二、易忽略的格式错误

三、参与循环的变量初始化时的易错点


上一弹:C语言入门易错题第一弹

阅前提示:本文适合初学习分支与循环语句但并未有太多实战经验的观看。

一、关于用于判断的表达式

1.switch语句括号里的“表达式”,只能是int的类型。(错)

解释:switch语句括号里的“表达式”必须是整型,比如int和char(本质是ASCII码,也是整型)和枚举型,而其他类型应当使用if来进行判断。

2.if后面都有表达式,只能为逻辑表达式或关系表达式。(错)
解释:if语句中在if后面的表达式,一般为逻辑表达式或关系表达式。
  例如:
⁤⁤ 

if(x<0)
printf("%d是负数",x);
if(a==b&&x==y)
printf("a=b,x=y");


  但不仅限于此,if后面的表达式也可以是任意的数值类型(包括整型、实型、字符型、指针型数据)。
  例如:
  

⁤⁤  if(3)printf("O.K.");⁤⁤
  
⁤⁤  if('a')printf("%d","a");
  
⁤⁤  if(a=b)printf("%d",0);


  在执行if语句时先对表达式进行求解,若表达式的值为0,表示条件不成立;若表达式值不为0,表示条件成立,执行指定的语句。

3.while和if类似,而for其后类型相对固定,在此不赘述。

二、易忽略的格式错误

1.以下程序段的运行结果是()

int n='c'
switch(n)
{
    dfault:printf("error");break;
    case'a':
    case'b':printf("good");break;
    case'c':printf("pass");
    case'd':printf("warn");
}

A.pass    B.warn    C.pass warn    D.error

正确答案:C

解释:n对应到case中,打印pass,后面没有break,直接往下运行,显示warn,所以最后显示是C。

注意:每个case后面的break关键字不能省略,不然可能会发生向下穿透的问题。在switch()语句中,break;就像是灵魂,搭配break使用才能实现真正的分支。
 

2.如下程序段中,复合语句的执行与否和if的条件是否成立没有关系。()

if(a>b);
{

        t=a;
        a=b;
        b=t;
}


A.对
B.错


正确答案:A

解释:注意本题if(a>b)后直接是分号没有语句,等同于

if(a

这种代码不太明显,但有类似错误要能发现。另外介绍一种类似代码的妙用

while(getchar()=='\n');

此代码可以清空输入缓存区。

三、参与循环的变量初始化时的易错点

1.下面代码执行的结果是:( )

#include 

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

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

B. 5 5 5 5 5 5 5 5 5 5

C. 死循环的打印5

D. 0 1 2 3 4 5 6 7 8 9

正确答案:C

解析:

上述代码本来的想法应该是:循环10次,每次循环时如果i==5则打印i的结果。

但if语句中表达式的==写成了赋值,相当于每次循环尽量都是将i的值设置成了5,5为真,因此每次都会打印5

i每次修改成5打印后,i的值永远不会等于10,因此造成死循环

故:死循环的打印5

正确写法可为:

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

2.这里打印多少个hehe?

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

正确答案:10个

解析:第二个循环没有对 j 进行赋初值,所以当外层循环第一次结束时(此时i为1),j的值已经变成了10,并且由于没有对 j 进行赋初值,那么从外层循环第二次开始,内层循环就不执行了,直到程序结束。所以正确答案为10。

3.请问循环要循环多少次?

#include 
int main()
{
    int i = 0;
    int k = 0;
    for(i=0,k=0; k=0; i++,k++)
        k++;
return0;
}
正确答案:0次
解析: 在这里 k = 0 是 for(); 的判断条件,但k=0表达式的值为0,而0表示假,所以循环不执行。
4.计算“1!+2!+3!”
易错代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include 
int main()
{
	int i = 0, sum = 0, n = 0, ret = 1;
	for (i = 1; i <= 3; i++)
	{
		for (n = 1; n <= i; n++)
		{
			ret *= n;
		}
		sum += ret;
	}
	printf("%d", sum);

	return 0;
}

初学时写代码很可能会这样写,但是如果运行一下会发现是错误的。如下:  

C语言入门易错题第二弹——分支与循环语句_第1张图片

而导致错误的原因就是想当然以为每次运行内层循环时 ret 是1;而实际上因为 ret 并没有在内层循环初始化(令每次进入内层时 ret 都为1),这样每次运行内层循环时,ret 的值都在累加,导致程序错误。

正确方法可这样写:

#define _CRT_SECURE_NO_WARNINGS 1
#include 
int main()
{
	int i = 0, sum = 0, n = 0, ret = 1;
	for (i = 1; i <= 3; i++)
	{
		ret = 1;//初始化ret;
		for (n = 1; n <= i; n++)
		{
			ret *= n;
		}
		sum += ret;
	}
	printf("%d", sum);

	return 0;
}

不过,针对这道题,我们可以有更简单的代码。因为我们发现每次计算阶乘的时候都从头开始乘一遍,这样无形中重复了很多步骤,所以为了简化,我们可以这样写:

#define _CRT_SECURE_NO_WARNINGS 1
#include 
int main()
{
	int i = 0, sum = 0, n = 0, ret = 1;
	for (i = 1; i <= 3; i++)
	{
		ret *= i;//计算本次循环i的阶乘
		sum += ret;
	}
	printf("%d", sum);

	return 0;
}

这样我们就可以利用 ret 的累加效果,在直接拿本次阶乘的最后一项直接乘以上次阶乘(如3*2!),可以直接得到本次阶乘。

 上一弹:C语言入门易错题第一弹

你可能感兴趣的:(C语言,开发语言,c语言,经验分享,笔记,其他)