C语言入门——分支和循环

一、if语句

C语言是结构化的程序设计语言,分别是顺序结构、选择结构、循环结构,C语言是能够实现这三种结构的,if、switch实现分支结构,使用for、while、do while实现循环结构。表达式成立(为真),则语句执行,表达式不成立(为假)则语句不执行。
在C语言中,0为假,非0为真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。
例子:输入一个整数,判断是否为奇数或者偶数

int main() {
  int a = 0;
  scanf("%d", &a);
  if (a % 2 == 1) 
  	printf("是奇数\n");
  else
  	printf("是偶数\n");
}

在这里插入图片描述

1、分支中包含多条语句

默认在if 和else语句中默认都只控制一条语句,例如:

int main() {
	int a = 0;
	scanf("%d", &a);
	if (a >= 18)
		printf("成年了");
	    printf("谈恋爱");//输入值不管是大于18还是小于18,谈恋爱都会打印在屏幕上
		//因为if只能控制一条语句,就是成年了,对于谈恋爱这条语句,是独立存在的
		//不管if的条件为真假都会被执行,如果要if控制两条语句,那就需要用{}将代码括起来
	return 0;
}

上⾯的代码,会发现输⼊的值不管是>=18 还是⼩于18,"谈恋爱” 都会打印在屏幕上。
在这里插入图片描述
这是因为 if 语句只能控制⼀条语句,就是 printf(“成年了\n”); ,if语句为真,则打印成年了,
if语句为假,则不打印,对于 printf(“恋爱了\n”); 是独⽴存在的,不管if语句的条件的真假,都会被执⾏。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使⽤ {} 将代码括起来,else 后也可以跟上⼤括号。如下:

int main() {
	int a = 0;
	scanf("%d", &a);
	if (a >= 18)
	{
		printf("成年了\n");
		printf("谈恋爱\n");
	}
	else
	{
		printf("未成年\n");
		printf("不能谈恋爱\n");
	}
	return 0;
}

2、嵌套if

在if else 语句中,else可可以与另一个if语句连用,构成多重判断
例如:输入一个整数,判断输入的整数是0,还是正数或负数

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

上面代码就是嵌套在前⾯的 else ⼦句中的,构成了嵌套的if语句。
再⽐如:要求输⼊⼀个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出不
是整数。

int main() {
	int a = 0;
	scanf("%d", &a);
	if (a >= 0)
	{
		if (a % 2 == 0)//也是嵌套在 if 语句中的,构成了嵌套的 if 语句。
			printf("偶数");
		else
			printf("奇数");
	}
	else
		printf("是负数\n");
	return 0;
}

上⾯的的代码也是嵌套在 if 语句中的,构成了嵌套的 if 语句。

输⼊⼀个⼈的年龄,如果年龄<18岁,打印"少年"如果年龄在18岁⾄44岁打印"⻘年",如果年龄在45岁⾄59岁打印"中⽼年",如果年龄在60岁⾄89岁打印"⽼年",如果90岁以上打印"⽼寿星

int main() {
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("少年");
	}
	else if(age<=44)
	{
		printf("青年");
	}
	else if (age <= 59)
	{
		printf("中老年");
	}
	else if (age <= 89)
	{
		printf("老年");
	}
	else
	{
		printf("老寿星");
	}
	return 0;
}

3、悬空else问题

如果有多个if和 else,可以记住这样一条规则,else总是跟最接近的if匹配
⾸先从下⾯代码开始

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

很多初学者,上来以判断 a 是 0,不等于 1 ,那就执⾏ else ⼦句,打印 haha
但是当你去运⾏代码,输出的结果是:啥都不输出。
在这里插入图片描述
为什么呢?
这就是悬空 else 的问题,如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近
的 if 匹配。
上⾯的代码排版,让 else 和第⼀个 if 语句对⻬,让我们以为 else 是和第⼀个if匹配的,当 if
语句不成⽴的时候,⾃然想到的就是执⾏ else ⼦句,打印 haha ,但实际上 else 是和第⼆个 if
进⾏匹配的,这样后边的 if…else 语句是嵌套在第⼀个 if 语句中的,如果第⼀个 if 语句就不
成⽴,嵌套 if 和 else 就没机会执⾏了,最终啥都不打印。
可以修改成这样:

int main() {
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
			printf("hehe\n");
		else
			printf("haha\n");
	}
	else
		printf("xixi");//只要带上适当的⼤括号,代码的逻辑就会更加的清晰,
}

只要带上适当的⼤括号,代码的逻辑就会更加的清晰,所以⼤家以后在写代码的时候要注意括号的使
⽤,让代码的可读性更⾼。

4、多个关系运算符不宜连用。

1 i < j < k
连续使⽤两个⼩于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,
即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的
表达式。
1 (i < j) < k
上⾯式⼦中, i < j 返回 0 或 1 ,所以最终是 0 或 1 与变量 k 进⾏⽐较。如果想要判断变量 j
的值是否在 i 和 k 之间,应该使⽤下⾯的写法。
i < j && j < k
⽐如:我们输⼊⼀个年龄,如果年龄在18岁~36岁之间,输出⻘年。

int main() {
	int age = 0;
	scanf("%d", &age);
	if (18 <= age <= 36)
	{
		printf("青年");
	}	

当我们输⼊10的时候,依然输出⻘年,如下图:
在这里插入图片描述
这是因为,我们先拿18和age中存放的10⽐较,表达式18<=10为假, 18<=age 的结果是0,再拿0和
36⽐较,0<=36为真,所以打印了 ⻘年 ,所以即使当age是10的时候,也能打印 ⻘年 ,逻辑上是有
问题,这个代码应该怎么写呢?这就涉及到了逻辑操作符中的与运算&&,下面我们来讲一下

5、逻辑操作符:&& , || , !

逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式,主要有下⾯三个运算符。
• ! :逻辑取反运算符(改变单个表达式的真假)。
• && :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
• || :或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。
逻辑反操作

① 与运算符&&

&&就是与运算符,也是并且的意思,&&是一个双目操作符,使用的方式是a&&b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一个假,那整个表达式为假,那我们再用上面的代码重新写一次

int main() {
    int age = 0;
    scanf("%d", &age);
    if (age >= 18 && age <= 36)
        printf("青年");
    return 0;
}

在这里插入图片描述

②或运算符

||就是或运算符,也是或者的意思,||也是一个双目操作符,使用的方式是a||b,||两边的表达式只要有一个是真,整个表达式就是真,两边的表达式都为假的时候,才为假
⽐如:我们说⼀年中⽉份是12⽉或者1⽉或者2⽉是冬天,那么我们怎么使⽤代码体现呢?

int main() {
    int month = 0;
    scanf("%d", &month);
    if (month == 12 || month == 1 || month == 2)
    {
        printf("是冬季");
    }
    return 0;
}

在这里插入图片描述

③逻辑取反运算符

改变单个表达式的真假

int main() {
    int a = 5;
    if (!a)//a=5,本来为真,所以可以输出hehe,但是加上逻辑反操作符后变为假,所以不输出
    {
        printf("hehe\n");
    }
    return 0;
}

二、switch语句

除了if语句,C语言还提供了swith语句实现分支结构,用于判断有多个结果的情况,
switch 后边的 expression 的结果不是 value1 ,也不是 value2 的时候,就会执⾏
default ⼦句。

switch (expression) {
 case value1: statement
 case value2: statement
 default: statement
}

上⾯代码中,根据表达式 expression 不同的值,执⾏相应的 case 分⽀。如果找不到对应的值,
就执⾏ default 分⽀。
例如:输⼊任意⼀个整数值,计算除3之后的余数

int main() {
    int a = 0;
    scanf("%d", &a);
    switch (a%3)//switch后的expression必须是整形表达式
    {
    case 0://case和后面的数字必须有空格,后面的值必须是整形常量表达式
        printf ("余数为0");
        break;//每一个case语句中的代码执行后,需要加上break,才能跳出这个switch语句
        //break非常重要,如果没有break语句,代码就会继续向下执行其他case语句中的代码
    case 1:
        printf("余数为1");
        break;
    case 2:
        printf("余数为2");
        break;
    }
    return 0;
}

前⾯的代码中,如果我们去掉case语句中的break,会出现什么情况呢?
在这里插入图片描述
我们发现,3除以3本来余数是0,但是我们发现程序运⾏的结果多了良好⾏“余数是1”“余数是2”的打印。这是为什么呢?原因是 switch 语句也是分⽀效果的,只有在 switch 语句中使⽤ break 才能在跳出 switch 语句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续玩下执⾏,有可能执⾏其他 case语句中的代码,直到遇到 break 语句或者 switch 语句结束。就⽐如上⾯的代码就执⾏了 case
1,case2 中的语句。所以在 switch 语句中 break 语句是⾮常重要的,能实现真正的分⽀效果。
当然, break 也不是每个 case 语句都得有,这就得根据实际情况来看了。

再来一个例子:输⼊1-5,输出的是“⼯作⽇”输⼊6 - 7,输出“休息⽇”

int main() {
    int a = 0;
    scanf("%d", &a);
    switch (a)
    {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            printf("工作日\n");
            break;
        case 6:
        case 7:
            printf("休息日\n");
            break;
        default://使用switch语句的时候,遇到一种情况,比如switch后的表达式中的值
            //无法匹配代码中的case语句,要不就不做处理,要不就在switch语句中加入default字句
            printf("请输入1-7的数字\n");
            break;
    }
    return 0;
}

结束两种分支语句的学习

三、循环语句

1、while循环

int main() {
    int a = 1;
    while (a)//a=1,while后面的表达式满足条件,会一直死循环
    {
        printf("hehe");
    }
    return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/788e9b9b33be44a4aeea331a4e7651f4.png在这里插入图片描述

⾸先上来就是执⾏判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执⾏循环语
句,语句执⾏完后再继续判断,是否进⾏下⼀次判断。

在屏幕上打印1~10的值:

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

输⼊⼀个正的整数,逆序打印这个整数的每⼀位:

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

1.要想得到n的低位,可以使用n%10的运算,得到的余数就是低位,如1234%10得到4。
2要想去掉n的低位,找出倒数第二位,则使用n/10的操作就可以去掉最低位,如:1234/10得到123,去掉了4,再用去掉低位后的值赋值给a,就是n=n/10。
3.那么此时去掉低位的n又会回到while继续循环,123%10得到3,123/10得到12,循环1和2两个步骤,在n变成0之前,就能得到所有的位

2、for循环

for 循环是三种循环中使⽤最多的, for 循环的语法形式如下:

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

表达式1 ⽤于循环变量的初始化
表达式2 ⽤于循环结束条件的判断
表达式3 ⽤于循环变量的调整
在这里插入图片描述
首先执行表达式1初始化,然后进入表达式2判断,如果==0,就跳出循环,如果非0,就进入循环余军,执行完循环语句后,再来到表达式3,进行调整,调整后继续回到表达2进行判断,再根据是否非0来决定跳出循环或者是继续循环,继续判断,整个循环的过程中,表达式1初始化部分只被执⾏1次,剩下的就是表达式2、循环语句、表达式3在循环。

用for循环打印1-10的数字

int main() {
    int a = 0;
    for (a = 1; a <= 10; a++)//先执行表达式1 i=1,然后进入表达式2,a如果小于等于10就进入循环
    //进入表达式3,给a的值+1,执行完后回到表达式2,若还是<=10则继续循环,若大于,就跳出
    {
        printf("%d\n ", a);
    }
    return 0;
}

3、while 和for循环的对比

在这里插入图片描述

for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分⾮常集中,便于代码的维护,⽽如果代码较多的时候 while 循环的三个部分就⽐较分散,所以从形式上 for 循环要更优⼀些。

4、do while 循环

在循环语句中do while使用的最少,它的语法句式如下:

do
(语句)
while(表达式)

在这里插入图片描述
do while循环中,会先执行一次语句,执行完语句后,在执行表达式,表达式为0,结束循环,非0,继续执行语句,这就是do while特殊的地方,do while语句中的循环体是一定会先执行一次的

打印1-10的值:

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

输⼊⼀个正整数,计算这个整数是⼏位数?:

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

5、break语句和continue语句

在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常⻅的现象。C语⾔中提供了 break 和 continue 两个关键字,就是应该到循环中的。
• break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执
⾏。
• continue 的作⽤是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所
差异的。

while循环中的break运用

int main() {
    int a = 0;
    while (a <= 10)
    {
        if (a == 5)
            break;//当a=5的时候,循环就终止了,break的作用就是永久终止循环
        printf("%d", a);//输出结果是01234
        a++;
    }
    return 0;
}

for循环中的break运用

int main() {
    int a = 0;
    for (a = 0; a <= 10; a++)
    {
        if (a == 5)
            break;//当a=5,中止循环
        printf("%d", a);
    }
    return 0;
}

do while循环中的break运用

int main() {
    int a = 0;
    do
    {
        if (a == 5)
            break;//当a=5,循环中止
        printf("%d", a);
        a++;
    } while (a <= 10);
    return 0;
}

可以看到,在三种循环中,break的运用和得到的结果都是差不多的,一旦符合条件,立马结束循环,下面我们要讲一下continue语句,这个语句在三种循环的运用中会有差异

while循环中continue的运用

int main() {
    int a=1;
    while (a <= 10)
    {
        if (a == 5)
            continue;//当i=5,就跳过continue后面的代码,回到判断句进入循环
        //因为这里跳过了a++,所以导致a一直等于5无法增加,那么就会一直循环进入死循环
        //所以如果循环的调整是在continue后面,可能就会导致进入死循环
        printf("%d", a);
        a++;
    }
}

4后面的光标会一直闪动,说明进入了死循环(这里显示不出来光标)
在这里插入图片描述

for 循环中continue的运用

int main() {
    int a = 1;
    for (a = 1; a <= 10; a++) {
        if (a == 5)
            continue;//当i=5,跳过后面的代码,所以不输出5,得到的结果是1234678910
        //这就是和while有差异的地方,因为在for循环里面,循环的调整是在continue前面的
        printf("%d", a);    
    }
    return 0;
}

在这里插入图片描述

在这⾥我们也可以对⽐⼀下 while 循环和 for 循环中 continue 的区别:
在这里插入图片描述

do while 循环中continue的运用

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

得出的结果也是陷入死循环,因为循环的调整在continue后面,跳过了do.while 语句中的 break 和 continue 的作⽤和 while 循环中⼏乎⼀模⼀样

6、goto语句

C语⾔提供了⼀种⾮常特别的语法,就是 goto 语句和跳转标号, goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。

int main() {
    printf("此处打印\n");
    goto a;
    printf("此处会被跳过");

a:
    printf("跳过以后打印这里\n");
    return 0;
}

在这里插入图片描述
goto 语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以建议是能不⽤尽量不去使⽤;但是 goto 语句也不是⼀⽆是处,在多层循环的代码中,如果想快速跳出使⽤ goto 就⾮常的方便。

for(...)
{
  for(...)
 {
    for(...)
   {
     if(disaster)
       goto error;
   }
   }

}
error:
 //...

本来 for 循环想提前退出得使⽤ break ,⼀个 break 只能跳出⼀层 for 循环,如果3层循环嵌套就得使⽤3个 break 才能跳出循环,所以在这种情况下我们使⽤ goto 语句就会更加的快捷。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RayMi000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值