初学者对分支和循环的理解(上)

1.if语句(分支结构)

1.1if

if(表达式)
  语句;
  • 默认if后面只能跟一条语句,想要跟多条语句要加{ }。(else一样)
  • c语言中0为假,非零为真 ,即表达式为0不执行语句,非零则执行语句

1.2else

if(表达式)
  语句;
else           //“二选一”
  语句;

例子:

输入一个整数,判断奇偶

#include 
int main()
{   int a = 0;
    scanf("%d",&a);
    if(a%2 == 0)
    printf("%d是偶数",a);
    else
    printf("%d是奇数",a);
    return o;
}

1.3嵌套if

在if语句中,else可以和if连用,形成嵌套if。

例子:

输入一个数,判断是0,还是正数或者负数。

int main()
{
	int num = 0;
	scanf("%d",&num);
	if (num == 0)
		printf("%d是0", num);
	else if (num > 0)
		printf("%d是正数", num);
	else printf("%d是负数", num);
	return 0;

1.4else的悬空问题

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

上述代码中第一个if与else对齐,容易造成误解,导致结果被误认为haha,而实际上结果什么也没有打印,好像else”悬空“了,其实else本就应该没被执行,在嵌套中我们可以理解成else和上边离它最近的if是一对if-else语句,他们共同嵌套在上方的if当中,上方的if条件不满足,下边的语句自然不会执行了。

  • 可能有人会疑惑,第一个if下边不是有两条语句吗(一条if、一条else)为什么不用{ }括住,其实在c中我们认为if和else只算一个语句,当然可以省略{ }了。

代码写成下边这样就好理解了

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

2.关系操作符

C 语⾔⽤于⽐较的表达式,称为 “关系表达式”(relational expression),⾥⾯使⽤的运算符就称
为“关系运算符”(relational operator),主要有下⾯6个。
  • > ⼤于运算符
  • < ⼩于运算符
  • >= ⼤于等于运算符
  • <= ⼩于等于运算符
  • == 相等运算符
  • != 不相等运算符

  关系表达式一般返回0或者1表示真假

注意==和=的区别

   防止不小心写错,可以在表达式中把常量写在左边(由于常量不可被赋值,所以如果打错了会报错)

操作符不要连用,会造成错误

比如:

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

上述if表达式中,第一步比较18和age,不管哪个大,返回值的结果不是0就是1,肯定比36小,导致后半段条件判断失真。

3.条件操作符(也叫三目操作符)

格式:exp1 ? exp2 : exp3
计算逻辑:如果1计算结果为真,则计算,2计算的结果是整个表达式的结果,否则计算3,计算的结果是整个表达式的结果
例子:使用条件操作符找出两个数中较大的那个
int main()
{
	int a = 0;
	int b = 0;
	int m = 0;
	scanf("%d,%d", &a, &b);
	m = (a > b ? a: b);
	printf("m=%d\n", m);
	return 0;
}

注意两个占位符中间的,不要输入成英文的,不然会出错。

4.逻辑操作符&&  ||  !

&&:逻辑与,有一个表达式是假,那整个表达式就是假。

||:逻辑或,有一个表达式是真,那整个表达式就是真。

!:逻辑否 真变假,假变真

练习:输入一个年份,判断它是否为润年(闰年:能被4整除,但是不能被100整除,或者能被400整除)

#include 
int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
       if (b == 2)
          printf("hehe \n") ;
    else 
       printf("haha\n");
    return 0;
}
  • 短路现象

c语言中逻辑操作符先算左边的表达式,再算右边的表达式,当左边表达式算出结果后已经确定了整个表达式的返回结果时,后边的表达式将不会再计算。

例子;

if(month >= 3 && month <= 5)
这边要是输入1,左边的表达返回值是0,右边的表达式将不会再计算,因为整个表达式的结果已经确定了,就是0。

练习:阅读下面代码,思考运行的结果

#include 
int main()
{
     int i = 0, a = 0, b = 2, c = 3, d = 4;
     i = a++ && ++b && d++;
     printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
     return 0;

}

运行结果是a=1,b=2,c=3,d=4,i=0 

解析:回忆我们之前学的自加运算符,++在后边表示a是先用后加,先用使得这个表达式的结果为0,而逻辑运算符从左往右算,从而整个表达式的结果已经确定(i=0),那么后边的表达式将不会再计算。而a在用完之后会给自己自加1。

思考一下,如果将a的初始值改成1,或者把++放到前边,结果又是什么?

5.switch语句(分支结构)

可以把switch语句理解成特殊的if-else语句,用来代替嵌套if语句,使结构更加清晰明白

5.1模板

switch(表达式)
{  case 值
    语句;
    break;
  case 值
    语句;
    break;
  default
    语句;
    break;
}

说明:根据表达式的结果,进入对应的case,如果结果找不到对应的case,则进入default,最后从break跳出switch语句。

注意

  1. 上述表达书的结果必须是整型或者是字符型(字符型属于整型家族)
  2. case后边要加空格
  3. case后边要是数,而不是变量
  4. 要加break跳出
  5. { }不能丢
  6. switch语句中case和default无顺序

例子1:输入任意整数,计算初3以后的余数。


int main()
{
	int a = 0;
	scanf("%d", &a);
	switch (a % 3)
	{
	case 0:
		printf("余数是0");
		break;//break1
	case 1:
		printf("余数的是1");
		break;//break2
	case 2:
		printf("余数是2");
		
	}
	return 0;
}

如果不加break,那么程序会一直执行,直到遇到break,或者语句结束才会跳出switch语句。

上述代码中输入3,去掉break的情况如下

1.去掉break1,输出结果是:”余数是0余数是1“

2.去掉break2,输出结果是:”余数是0“

记住一点:“case决定入口,break决定出口”就行。

例子2:输入星期几,输出是工作日还是休息日

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

思考一下,假如没有break,而default被写在多个case之间,假如入口是第一个case,将会是什么结果。

6.while(循环结构)

6.1if与while

我们尝试从意思的角度来理解

if是如果的意思,”如果表达式结果为真“那就执行语句

while是当()时的意思,”当表达式为真时“那就执行语句

不知道大家有没有体会到二者之家的区别和联系,二者都是跟据表达式的真假来决定是否执行语句,但是不同的是while具有多次判断的能力,表达式为真,就能执行语句,直到表达式为假。而if只判断一次。

6.2while语句的执行流程

初学者对分支和循环的理解(上)_第1张图片

 6.3练习:在屏幕上打印1到10

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

6.4练习:输入一个正整数,倒序打印每一位

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	while (a != 0)
	{
		b = a % 10;
		printf("%d", b);
		a /= 10;
	}
	return 0;
}

7.for(循环语句)

7.1模板

for(表达式1; 表达式2; 表达式3)
语句;

三个表达式的意义分别是

1.初始化(只执行一次)

2.判断

3.调整

注意

1.在表达式一处初始化的变量只能在循环里用,若想在外部用,可以先在外部初始化

2.三个表达式之间是分号

7.2for循环的流程

初学者对分支和循环的理解(上)_第2张图片

7.3练习:打印1到10

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

	return 0;
}

 7.4练习:求和1到100之间3的倍数

int main()
{
	int sum = 0;
	int i = 0;
	for (i = 3;i < 100;i += 3)
		sum += i;
	printf("%d", sum);
	return 0;
}

8.do-while(循环语句)(用的很少)

8.1模板

do
语句;
while(表达式);

这里语句至少执行一次

8.2do-while执行流程

初学者对分支和循环的理解(上)_第3张图片

8.3练习:输入一个整数,输出它是几位数

int main()
{
	int num = 0;
	scanf("%d", &num);
	int cent = 0;
	do
	{
		cent++;
		num /= 10;

	} while (num != 0);
	return 0;
}

 思考一下,用for和while怎么写

9.break和continue语句

break:跳出这个循环

continue:跳过这循环中continue后边的代码

例子:

#include 
int main()
{
   int i = 1;
   while(i <= 10)
  {
      if(i == 5)
     break;//当i等于5后,就执⾏break,循环就终⽌了
     printf("%d ", i);
     i = i + 1;
  }
   return 0;
}





#include 
int main()
{
    int i = 1;
    while(i <= 10)
    {
       if(i == 5)
       continue;
//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅
//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环
        printf("%d ", i);
        i = i + 1;
    }
   return 0;
}

10.循环的嵌套

练习:找出100到200之间的素数

解析,首先要产生100到200 的数(for)

然后根据素数条件筛选,用2到i-1之间的数除i,如果有一个余数为0 的情况,即i被整除,那这个i就不是素数

int main()
{
	int i = 0;
	
	for (i = 100;i <= 200;i++)//100到二百的数
	{
		int flag = 1;//用flag的真假来标志i是否为素数,先假设它为真
		for (int j = 2;j < i;j++)//2到i-1的数
		{
			if (i % j == 0)
			{
				flag = 0;标志出这个i不是素数
				break;跳出的是第二个for循环
			}
		}
		if (flag ==1)如果i被j除完之后没有发现因数,那它就是素数
			printf("%d ", i);
	}
	return 0;
}

注意:flag不要放在第一层循环外面,因为放在第一层循环外边它只等于1一次,在第二层循环中flag等于0后,它就一直等于0了,由于第一个i=100不是素数,结果将变成啥也不打印。

将上述代码的算法优化

由于i是由俩个因数相乘得到的,故这两个因数至少有一个小于等于开根后的i,只要j小于等于开根号的i,那它一定包含一个因数。

#include 
int main()
{
	int i = 0;
	for (i = 100;i <= 200;i++)
	{
		int flag = 1;
		for (int j = 2;j <= sqrt(i);j++)
		{
			
			if (i % j == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag ==1)
			printf("%d ", i);
	}
	return 0;
}

注意用sqrt开方函数要加头文件。

11.goto语句

‘可实现从一个函数内调到设置好的标号处

但是不提倡使用,防止打乱程序流程

建议在多层嵌套函数中跳出使用

思考一下,为什么不用break?

你可能感兴趣的:(c语言,新手)