前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分支和循环(上)

分支和循环(上)

作者头像
用户11290648
发布2024-09-25 13:39:11
370
发布2024-09-25 13:39:11
举报
文章被收录于专栏:学习

C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构,C语言是能够实现这三种结构的,其实我们如果仔细分析,我们日常所见的事情都可以拆分为这三种结构或者这三种结构的组合。 我们可以使用 if 、 switch 实现分支结构,使用 for 、 while 、 do while 实现循环结构。

1. if语句

1.1 if  

if语句的语法形式如下:

若表达式为真,则语句执行,否则不执行(表达式为假)。

在C语言中,0为假,非0表示真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。一个分号就是一个语句,也就是空语句,空语句不执行

例子:输入一个整数,判断是否为奇数

if语句的循环方式:

1.2 else

如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要清楚的判断是奇数还是偶数怎么表示呢? 这里就需要 if...else... 语句了,语法形式如下:

if (表达式)      语句1 else

例子:输入⼀个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数。

练习:输入一个年龄,>= 18岁就输出:成年,否则就输出:未成年

1.3 分支中包含多条语句

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

上面的代码,你会发现输入的值不管是>=18还是<18,"可以谈恋爱了"都会打印在屏幕上。

这是因为 if 语句只能控制⼀条语句,就是 printf("成年了\n"); ,if语句为真,则打印成年了, if语句为假,则不打印,对于 printf("可以谈恋爱了\n"); 是独立存在的,不管if语句的条件的真假,都会被执行。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使用 {} 括起来,else 后也可以跟上大括号。如下:

1.4 嵌套if  

在 if else 语句中, else 可以与另⼀个 if 语句连用,构成多重判断。

比如:要求输入⼀个整数,判断输入的整数是0,还是正数或者负数。请看如下代码:

这个就叫做嵌套,就是把 if (num > 0)     printf("输入的值是正数\n"); else     printf("输入的值是负数\n");  嵌套在 else {     if (num > 0)         printf("输入的值是正数\n");     else         printf("输入的值是负数\n"); } 里面去了,当然也有简便的写法 int main() {     int num = 0;     scanf("%d", &num);     if (num == 0)         printf("输入的值是0\n");     else if (num > 0)             printf("输入的值是正数\n");         else             printf("输入的值是负数\n");     return 0; } 其实相当于if else 也是嵌套在else里面的,只不过进行了简化。

 int main() {     int num = 0;     scanf("%d", &num);     if (num > 0)     {         if (num == 0)             printf("输入的值是0\n");         else             printf("输入的值是正数\n");     }     else     {         printf("输入的值是负数\n");     }     return 0; } 上面的代码中是嵌套在 if 语句中的,构成了嵌套的 if 语句。

1.5 悬空else问题  

如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的 if 匹配。 我们首先从下面代码开始

程序运行的结果是啥?

很多初学者,上来一判断 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 就没机会执行了,最终啥都不打印。

如果代码改成下面这样就更加容易理解了

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

2. 关系操作符 

C 语言用于比较的表达式,称为“关系表达式”(relationalexpression),里面使用的运算符就称为“关系运算符”(relationaloperator),主要有下面6个。

 > 大于运算符

< 小于运算符

>= 大于等于运算符

<= 小于等于运算符

== 相等运算符

!= 不相等运算符

关系表达式通常返回 0 或 1 ,表示真假。 C语言中, 0 表示假,所有非零值表示真。比如, 20 > 12 返回 1 , 12 > 20 返回 0 。 关系表达式常用于 if 或 while 结构。

注意:相等运算符 == 与赋值运算符 = 是两个不一样的运算符,不要混淆。有时候,可能会不小心写出下面的代码,它可以运行,但很容易出现意料之外的结果。

上面示例中,原意是 x == 3 ,但是不小心写成 x = 3 。这个式子表示对变量 x 赋值 3 ,它的返回值为 3 ,所以 if 判断总是为真。 为了防止出现这种错误,有的程序员喜欢将变量写在等号的右边。

这样的话,如果把 == 误写成 = ,编译器就会报错。

另⼀个需要避免的错误是:多个关系运算符不宜连用。

if这个里面是如何执行的呢?

首先执行a < b ,a是3,b是7,a < b为真, 这个表达示比完之后的结果为1,1 < 4成立,就进入if语句了。

上面示例中,连续使用两个小于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执行的是下面的表达式。

上面式子中, i < j 返回 0 或 1 ,所以最终是 0 或 1 与变量 k 进行比较。如果想要判断变量 j 的值是否在 i 和 k 之间,应该使用下⾯的写法。

 上面的代码这样写就可以了。

3. 条件操作符

条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:

?和:构成了一个操作符叫做三目操作符, exp1和exp2和exp3是它的三个操作数。

条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果 exp1 为假, exp3 计算,计算的结果是整个表达式的结果。

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

逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。

! :逻辑取反运算符(改变单个表达式的真假)。

&& :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。

|| :逻辑或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。

注:C语言中,非0表示真,0表示假

4.1 逻辑取反运算符!

逻辑反操作 

比如,我们有一个变量叫 flag ,如果flag为假,要做一个什么事情,就可以这样写代码:

!flag就是假,如果flag为假,!flag就是真所以上面的代码的意思就是flag为假,执行 if 语句中的代码。

4.2逻辑与运算符

&&是一个双目操作符,使用的方式是 a && b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一个是假,则整个表达式为假。

4.3逻辑或运算符

||就是或运算符,也就是或者的意思,||也是⼀个双目操作符,使用的方式是a || b,||两边的表达式只要有一个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。

比如:我们说⼀年中月份是12月或者1月或者2月是冬天,那么我们怎么使用代码体现呢?

当我们输入的值为12、1、2的时候,打印的都是冬季。

4.4 练习:闰年的判断

输入一个年份year,判断year是否是闰年 

闰年判断的规则:

1. 能被4整除并且不能被100整除是闰年

2. 能被400整除是闰年

4.5 短路

短路这个概念在逻辑运算符中才有,C语言逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。

如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。

如前面的代码:

if(month >= 3 && month 5)

表达式中 && 的左操作数是 month >= 3 ,右操作数是 month ,当左操作数 month >= 3 的 结果是0的时候,即使不判断 month ,整个表达式的结果也是0(不是春季)。

所以,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执行。但是要左边操作数为真,右边操作数还是要算的。

对于 || 操作符是怎么样呢?我们结合前面的代码:

if(month == 12 || month==1 || month == 2)

如果month == 12,则不用再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。 所以, || 操作符的左操作数的结果不为0时,就无需执行右操作数。

像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。  

图中的代码可以这样看,a = 0,表达式为假,后面的就发生短路,不用算了,此时i = 0,a = 1,后面的值不变。

 图中的代码可以这样看,a = 1,++b = 3,d = 4,都不为0,表达式为真,i 的值就为1,a + 1为2,b + 1为3,d + 1为5。

 图中的代码可以这样看,a = 1为真,表达式就为真,后面的就发生短路了,a + 1 = 2,i = 1。

5. switch 语句

除了 if 语句外,C语言还提供了 switch 语句来实现分支结构。

switch 语句是一种特殊形式的 if...else 结构,用于判断条件有多个结果的情况。它把多重的 else if 改成更易用、可读性更好的形式。

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

上面代码中,根据表达式 expression 不同的值,执行相应的 case 分支。如果找不到对应的值, 就执行 default 分支。

注: • switch 后的 expression 必须是整型表达式

• case 后的值,必须是整形常量表达式

5.1 if语句和switch语句的对比

练习:输入任意⼀个整数值,计算除3之后的余数

如果使用 if 语句完成,如下:

int main() {     int n = 0;     scanf("%d", &n);     if (n % 3 == 0)         printf("余数为0\n", n);     else if (n % 3 == 1)         printf("余数是1\n", n);     else         printf("余数是2\n", n);     return 0;

 如果使用 switch 语句改写,就可以是这样

int main() {     int n = 0;     scanf("%d", &n);     switch (n % 3)     {     case 0:         printf("余数为0\n",n);         break;     case 1:         printf("余数是1\n",n);         break;     case 2:         printf("余数是2\n",n);         break;         }     return 0;}

这样子也是可行的: int main() {     char ch = 0;     scanf("%ch", &ch);     switch (ch)     {     case 'a':         break;     case 'b':         break;     }     return 0; }   switch语句使用的时候也可以使用char类型,字符类型也是归类到整型家族的,字符的本质是ASC||码值,这个值是整数,所以这里可以用字符。

上述的代码中,我们要注意的点有:

1. case 和后边的数字之间必须有空格

2. 每一个 case 语句中的代码执行完成后,需要加上 break ,才能跳出这个switch语句。

5.2 switch语句中的break

前面的代码中,如果我们去掉case语句中的break,会出现什么情况呢?

我们发现,7除以3本来余数是1,但是我们发现程序运行的结果多了一行“余数是2”的打印。

这是为什么呢?

原因是 switch 语句也是分支效果的,只有在 switch 语句中使用 break 才能在跳出 switch 语句,如果某一个 case 语句的后边没有 break 语句,代码会继续往下执行,有可能执行其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束。就比如上面的代码就执型了 case 2 中的语句。

所以在 switch 语句中 break 语句是非常重要的,能实现真正的分支效果。

当然, break 也不是每个 case 语句都得有,这就得根据实际情况来看了。

5.3 switch语句中的default

在使用 switch 语句的时候,我们经常可能遇到⼀种情况,比如 switch 后的表达式中的值无法匹配代码中的 case 语句的时候,这时候要不就不做处理,要不就得在 switch 语句中加入 default 子句。

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

如果case语句不加break,也是会执行default语句。

 5.4 switch语句中的case和default的顺序问题

在 switch 语句中 case 子句和 default 子句有要求顺序吗? default 只能放在最后吗? 其实,在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满足实际需求的就可以。

不过我们通常是把 default 子句放在最后处理的。default的意思就是默认缺省的意思。

6. while循环

C语言提供了3种循环语句, while 就是其中一种,接下来就介绍一下 while 语句。

while 语句的语法结构和 if 语句非常相似。

6.1 if 和 while的对比

if (表达式)     语句; while (表达式)     语句;//如果循环体想包含更多的语句,可以加上大括号

6.2 while语句的执行流程 

 while语句的执行流程图

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

6.3 while 循环的实践 

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

参考代码:

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

7. for循环

7.1 语法形式

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

for (表达式1; 表达式2; 表达式3)     语句;//如果循环体想包含更多的语句,可以加上大括号

表达式1 用于循环变量的初始化(初始化表达式)

表达式2 用于循环结束条件的判断(判断表达式)

表达式3 用于循环变量的调整 (调整)

7.2 for循环的执行流程

for循环的执行流程 

首先执行表达式 1 初始化循环变量,接下来就是执行表达式 2 的判断部分, 表达式 2 的结果如果 ==0,则循环结束; 表达式 2 的结果如果!=0则执行循环语句,循环语句执行完后,再去执行表达式 3 ,调整循环变量,然后再去表达式 2 的地方执行判断, 表达式 2 的结果是否为0,决定循环是否继续。for循环的初始化部分只被执行一次。

整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2、循环语句、表达式3在循环。 

7.3 for循环的实践

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

参考代码:

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

7.4 while循环和for循环的对比

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

8. do-while 循环

8.1 语法形式

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

do         语句; while(表达式);

while 和 for 这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳 出循环; 而 do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式,表达式为真,就会进行下⼀次,表达式为假,则不再继续循环。

8.2 do while循环的执行流程

do while 循环的执行流程  

在 do while 循环中先执行图上的“语句”,执行完语句,在去执行“判断表达式”,判断表达式的结果是!=0,则继续循环,执行循环语句;判断表达式的结果==0,则循环结束。所以在 do while 语句中循环体是至少执行一次的,这是 do while 循环比较特殊的地方。

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

 一般 do while 使用在循环体至少被执行一次的场景下,所以较少⼀些。

9. break和continue语句

在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了 break 和 continue 两个关键字,就是应用到循环中的。

• break 的作用是用于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执行。

• continue 的作用是跳过本次循环中 continue 后边的代码,在 for 循环和 while 循环中有所差异的。

9.1 while循环中的break和continue

9.1.1 break举例

break用于终止整个循环。打印了1,2,3,4后,当 i 等于5的时候,循环在 break 的地方终止,不再打印,不再循环。

所以 break 的作用就是永久的终止循环,只要 break 被执行, break 外的第一层循环就终止了。 那以后我们在循环中,想在某种条件下终止循环,则可以使用 break 来完成我们想要的效果。 

9.1.2 continue举例

continue 是继续的意思,在循环中的作用就是跳过本次循环中 continue 后边的代码,继续进行下一次循环的判断。 上面的代码,如果把 break 换成 continue 会是什么结果呢? 

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

到这里我们就能分析出来, continue 可以帮助我们跳过某一次循环 continue 后边的代码,直接到循环的判断部分,进行下一次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成 死循环。

9.2 for循环中的break和continue

9.2.1 break 举例

其实和 while 循环中的 break ⼀样, for 循环中的 break 也是用于终止循环的,不管循环还需要循环多少次,只要执行到了 break ,循环就彻底终止,我们上代码。

int main() {     int i = 1;     for (i = 1; i <= 10; i++)     {         if (i == 5)             continue;//这里continue跳过了后边的打印,来到了i++的调整部分          printf("%d ", i);     }     return 0; }

 所以在 for 循环中 continue 的作用是跳过本次循环中 continue 后的代码,直接去到循环的调 整部分。未来当某个条件发⽣的时候,本次循环⽆需再执⾏后续某些操作的时候,就可以使⽤ continue 来实现。

在这里我们也可以对比一下 while 循环和 for 循环中 continue 的区别:

9.3 do while循环中的break和continue

do.while 语句中的 break 和 continue 的作用和 while 循环中几乎一模⼀样,大家下来可以自行测试并体会。  

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

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

 10. 循环的嵌套

前面学习了三种循环 while , do while , for ,这三种循环往往会嵌套在一起才能更好的解决问题,就是我们所说的:循环嵌套,这里我们就看一个例子。

10.1 练习

找出100~200之间的素数,并打印在屏幕上。

注:素数又称质数,只能被1和本身整除的数字。

 10.2 题目解析:

1. 要从100~200之间找出素数,首先得有100~200之间的数,这里可以使用循环解决。

2. 假设要判断i是否为素数,需要拿2~i-1之间的数字去试除i,需要产生2~i-1之间的数字,也可以使用循环解决。

3. 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。

int main() {     int i = 0;     //循环产⽣100~200的数字      int count = 0;     for (i = 100; i <= 200; i++)     {         //判断i是否为素数          //循环产⽣2~i-1之间的数字          int j = 0;         int flag = 1;//假设i是素数          for (j = 2; j <= sqrt(i) ; j + 2)         {             if (i % j == 0)             {                 flag = 0;                 break;             }         }         if (flag == 1)         {             printf("%d ", i);             count = count + 1;         }      }     printf("\n%d", count);     return 0; }

这种方法叫做试除法。sqrt是一个库函数,用处:计算一个数或者一个变量的平方根。包含的头文件math.h.

11. goto 语句

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

goto 语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们的建议是能不用尽量不去使用;但是 goto 语句也不是一无是处,在多层循环的代码中,如果想快速跳出使用 goto 就非常的方便了。 

写一个关机程序:

1.程序运行起来的时候,就开始倒计时60秒关机

2.但是如果输入“我是猪”,就取消关机

system—库函数,可以执行系统命令

需要一个头文件stdlib.h。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. if语句
    • 1.1 if  
      • 1.2 else
        • 1.3 分支中包含多条语句
          • 1.4 嵌套if  
            • 1.5 悬空else问题  
            • 2. 关系操作符 
            • 3. 条件操作符
            • 4. 逻辑操作符:&& , || , !
              • 4.1 逻辑取反运算符!
                • 4.2逻辑与运算符
                  • 4.3逻辑或运算符
                    • 4.4 练习:闰年的判断
                      • 4.5 短路
                      • 5. switch 语句
                        • 5.1 if语句和switch语句的对比
                          • 5.2 switch语句中的break
                            • 5.3 switch语句中的default
                              •  5.4 switch语句中的case和default的顺序问题
                              • 6. while循环
                                • 6.2 while语句的执行流程 
                                  • 6.3 while 循环的实践 
                                  • 7. for循环
                                    • 7.1 语法形式
                                      • 7.2 for循环的执行流程
                                        • 7.3 for循环的实践
                                          • 7.4 while循环和for循环的对比
                                          • 8. do-while 循环
                                            • 8.1 语法形式
                                              • 8.2 do while循环的执行流程
                                              • 9. break和continue语句
                                                • 9.1 while循环中的break和continue
                                                  • 9.1.1 break举例
                                                  • 9.1.2 continue举例
                                                • 9.2 for循环中的break和continue
                                                  • 9.2.1 break 举例
                                              •  10. 循环的嵌套
                                                • 10.1 练习
                                                  •  10.2 题目解析:
                                                  • 11. goto 语句
                                                  领券
                                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档