首页 > 其他分享 >[包教包会]C语言:详解分支语句(if , switch , goto)和循环语句(while , for , do while)

[包教包会]C语言:详解分支语句(if , switch , goto)和循环语句(while , for , do while)

时间:2024-10-20 16:21:27浏览次数:7  
标签:语句 do int case while 循环 printf

概览

控制语句用于控制程序的执行流程,以实现程序的各种结构方式

C语言支持三种结构:顺序结构、选择结构(分支)、循环结构 :

(其实显示中的事件也都是由这三者混合合成的)

它们由特定的语句定义符组成,C语言有九种控制语句

可分成以下三类:

1. 条件判断语句也叫分支语句:if 语句、switch 语句;

2. 循环执行语句:do while 语句、while 语句、for 语句;

3. 转向语句:break 语句、goto 语句、continue 语句、return 语句。

C语言中的真/假

不累子提醒你 : 在讲下面的内容前 , 请一定要看完这一节哦~

这里就有小伙伴要问了 : 哎呀不累子 , 那 C 语言中什么是真呀?

在 C 语言中 : 0(包括 0.0 , -0 , +0) 假 , 一切非 0 都为真 .

对于 C99 新增的布尔值 , 如果我们翻找 true 和 false 的定义不难得知 :

frue 就是值为 1 的常量 , false 则是值为 0 的常量

也就是说 : 该表达式 / 常量的值只要不等于 0 , 它就为真 .

补充

在 C 语言中 , 如果一个表达式为真 , 它的值默认是 1 

如果一个表达式为假 , 它的值默认是 0

这些都是 C 语言的执行标准中规定的 

实例

我们先定义两个变量 :

int a = 1;
int b = 0;

 接着思考 : 下面括号内的语句是否为真?

(a)
(b)
(a == 0)
(b == 0)
(a + b)
(a = 0)
(b = 1)

解析 :

(a)//真,因为 a 就是 1
(b)//假,因为 b 就是 0
(a == 0)//假,这里是判断语句,因为 a 不等于 0,所以这个表达式的值默认为 0
(b == 0)//真,因为 b 确实等于 0,这个表达式的值默认为 1
(a + b)//真,因为 a + b = 1
(a = 0)//假,这里是赋值表达式,赋值表达式的值等于赋给变量的值
(b = 1)//真,和上面的道理一样

分支语句(选择结构)

if 语句

语法

//语法结构:
        if(表达式)    
            语句;

当表达式为时 , 执行语句

if 默认只能控制一条语句,如果想同时执行多个语句则需要用代码块(即一对花括号)创建一个复合语句

什么意思呢?

就是说如果你这样写 :

#include <stdio.h>

int main()
{
	if (0)//括号里的 0 表示假
		printf("1\n");
	printf("2\n");

	return 0;
}

只会打印 2

即使你将语句对齐 :

	if (0)
		printf("1\n");
	    printf("2\n");

也不会改变输出结果 (想也知道这和对齐没关系吧)

那么怎么使一个 if 可以控制多条语句呢?如下 :

if(0)
{//一对大括号表示一个代码块
    printf("1\n");
    printf("2\n");
    ...//其他语句
}

这样 if 就可以控制多条语句了 .

不累子建议 : 即使在 if 后只有一条语句时 , 也尽量使用代码块 , 这样可以使得代码清晰易懂 .

使用 if 和 else 创造多个分支

#include <stdio.h>

int main()
{
	if (a)//这里的 a 可以为表达式/变量/值
	{
		printf("1\n");
	}
	else
	{
		printf("2\n");
	}

	return 0;
}

我们知道 , 英语中的 else 是 "除...之外" 的意思 , 以上代码的用意也很明显 :

如果 a 为真则打印 1 , 为假则打印 2 .

这是两个分支的情况 , 那么如果有 3 个或更多分支呢?

我们可以再把一条 if 语句写进 else 里 :

#include <stdio.h>

int main()
{
	if (a)//情况 a
	{
		printf("1\n");
	}
	else
	{
		if (b)//情况 b
		{
			printf("2\n");
		}
		else//除了上面的情况外
		{
			printf("3\n");
		}
	}

	return 0;
}

以上代码 : 如果 a 为真则打印 1 ,  a 不为真但 b 为真则打印 2 , a b 都不为真则打印 3 .

实际上我们在使用时并不会像上面那样写 , 而是直接在 else 后接 if :

	if (a)
	{
		printf("1\n");
	}
	else if (b)
	{
		printf("2\n");
	}
	else if(c)
	{
		printf("3\n");
	}
    else if(d)

    ...

    else
    {
    
    }

以上为什么不用多个 if ?

你也许会问 : 为什么不用多个 if 判断不同情况?

确实 , 下面这样也可以实现我们的目的 :

#include <stdio.h>

int main()
{
	if (a)
	{
        printf("1\n");
	}
	if (b)
	{
        printf("2\n");
	}
	if (c)
	{
        printf("3\n");
	}

	return 0;
}

但如果这样写 , 则每个 if 语句都要进行一次判断 , 降低了代码的执行效率

在顺序结构中 , 多增加几次判断造成的影响并不明显 , 但在循环结构中 , 使用这样的结构会使得代码的执行效率成倍下降

悬空else

思考 : 以下代码的执行结果是什么?

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
        if (b == 2)
            printf("BLZ\n");
    else
        printf("dL\n");
    return 0;
}

屏幕前未来的大佬们也许会拍案而起 : "这我知道 ! a 不等于 1 , 不就走 else 输出 dL 么"

其实这是个陷阱 , 本质上代码是这样的 :

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
        if (b == 2)
            printf("BLZ\n");
        else//这里的 else 和第二个 if 对应
            printf("dL\n");
    return 0;
}

所以该程序什么都不会输出!!!

没使用代码块的情况下 : else 是和上方最近的 if 配对的!!!

这里就能深刻体现出勤用代码块的好处了 , 如果你听不累子的 , 以上代码就会是下面这样 :

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
    {
        if (b == 2)
        {
            printf("BLZ\n");
        }
        else//这里的 else 和第二个 if 对应
        {
            printf("dL\n");
        }
    }
    return 0;
}

这样是不是就清晰明了?

当然你也可以改成这样 :

    if (a == 1)
    {
        if (b == 2)
        {
            printf("BLZ\n");
        }
    }
    else//这样 else 就和第一个 if 配对了
    {
        printf("dL\n");
    }

这样就会输出 dL 了

if 的不同书写形式

//代码1
if (某种情况) {
    return x;
}
return y;

//代码2
if (某种情况)
{
    return x;
}
else
{
    return y;
}

实际上代码 1 和 2 是等价的 , 但我们推荐使用代码 2 的形式 , 因为代码 2 显而易见地显而易懂

//代码3
int num = 1;
if (num == 5)
{
    printf("hehe\n");
}

//代码4
int num = 1;
if (5 == num)
{
    printf("hehe\n");
}

实际上代码 3 和代码 4 也是等价的 , 但我们推荐使用代码 4 的形式

因为如果你不小心漏了一个 = (这种情况很常见) , 在代码 3 中 , 这会使得原本的判断语句变成赋值语句 , 但编译器并不会报警告

但如果是代码 4 , 由于 5 不能被赋值 , 在编译时编译器就无法通过并会报警告 , 这可以提示你出错了

除非你确实有这种在 if 的括号内赋值的需求

switch 语句

语法

switch (整型表达式)//short | int | long | long long | char -->字符类型也可以
{
    语句项;
}

语句项是什么呢?

//语句项:
//是一些case/default语句:
//如下:
case 整形常量表达式://不能是变量、浮点型
    语句;

什么?难懂?1 2 3 , 上实例!!!

实例 / 运行方式

int main()
{
    int a = 0;
    scanf("%d", &a);
    switch (a)
    {
    case 1: 
        printf("1\n");
    case 2: 
        printf("2\n");
    case 3: 
        printf("3\n");
    case 4: 
        printf("4\n");
    case 5: 
        printf("5\n");
    case 6: 
        printf("6\n");
    default: 
        printf("7\n");
    }

    return 0;
}

以上 switch 语句先从上往下进行判断,假如符合情况 a = 1 则会运行 printf("1\n");

然后再运行 case 1 下方的所有语句 , 即输出 :

1
2
3
4
5
6
7

如果输入 3 ,则输出:

3
4
5
6
7

default 在英文中的意思是 "默认

如果所有情况都无法匹配,则输出 default 后的语句

比如如果输入字符 a , 则输出 :

7

为了使 switch 语句能造多个独立的分支,需搭配 break 语句使用 :

int main()
{
	int a = 0;
	scanf("%d", &a);
	switch (a)
	{
	case 1: 
		printf("1\n");
		break;
	case 2: 
		printf("2\n");
		break;
	case 3: 
		printf("3\n");
		break;
	case 4: 
		printf("4\n");
		break;
	case 5: 
		printf("5\n");
		break;
	case 6: 
		printf("6\n");
		break;
	default: 
		printf("7\n");
		break;
	}

	return 0;
}

case 决定入口break 决定出口

多种情况对应一个输出

由上面的例子可知 : case 语句在执行完后如果后续无 break 语句,则会继续执行下一个 case 语句的输出 , 直到遇到 break

于是我们可以写出一个判断是否是工作日的程序 :

int main()
{
    int a = 0;
    scanf("%d", &a);
    switch (a)
    {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    {
        printf("工作日");
        break;//前 5 种情况直到这里才遇到 break , 故都会输出"工作日"
    }
    case 6:
    case 7:
    {
        printf("休息日");
        break;
    }
    default://如果前面的情况都匹配不了 , 则进入 default
    {
        printf("输入错误");
        break;
    }
    }
    return 0;
}

break 语句的补充

break 语句只会跳出对应的 switch 语句

如 :

下方实例 a 处的 break 语句执行完后只会跳出 b 处的 switch 语句 :

#include <stdio.h>
int main()
{
    int n = 1;
    int m = 2;
    switch (n)
    {
    case 1:
        m++;
    case 2:
        n++;
    case 3:
        switch (n)//b 处
        {//switch允许嵌套使用
        case 1:
            n++;
        case 2:
            m++;
            n++;
            break;//a 处
        }
    case 4:
        m++;
        break;
    default:
        break;
    }
    printf("m = %d, n = %d\n", m, n);
    return 0;
}

goto 语句

语法

goto (自定义的字符串);
...
自定义的字符串:
    ...

示例

goto 语句实现的一个打印 1 2 3 的死循环

#include<stdio.h>
int main()
{
a:
    printf("1\n");
    printf("2\n");
    printf("3\n");
    goto a;//去往 a 处
    return 0;
}

应用场景

理论上 goto 语句是不必要的,实践中没有goto语句也可以很容易的写出代码。

并且滥用 goto 语句还会导致代码可读性降低

但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如:一次跳出两层或多层循环:

for (...)
{    
    for (...)
    {
        for (...)
        {
            if (disaster)//错误情况的判断
                goto error;//发生错误 , 一步跳转至对应错误的处理处
        }
    }
}
...
error :
if (disaster)
// 处理错误情况

使用 goto 语句编写关机程序
这部分不累子先搁着啦 , 不久后出了文章这里会贴链接滴~

点点关注下次能更快地找到哦

循环语句

种类

while
for
do while

while 循环 

语法

while (表达式)//括号内为判断部分
    循环语句;//循环部分


//使用代码块创造多语句循环
while (表达式)
{
循环语句 1;
循环语句 2;
...
循环语句 n;
}

 

while 和 if 类似 , 只不过 if 是执行一次 , while 能执行多次

当 while 后面的圆括号的条件为时,一直循环直到跳出或不满足条件

while 默认也只能控制后面的一条语句

在使用时 , 不累子也建议你勤用代码块创造多语句循环提高代码可读性

示例

 以下程序会输出 1 ~ 10 : 

#include <stdio.h>
int main()
{
    int i = 1;
    while (i <= 10)
    {
        printf("%d ", i);
        i = i + 1;
    }
    return 0;
}

while 循环中的 break

 结合本节开头的流程图 , 想想下面的代码运行后输出什么 :

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

上方的示例执行结果为 :

1 2 3 4

因为当 i 等于 5 时,满足 if 后的条件,执行下方的 break 语句,后续的语句(包括判断部分)被忽略

while 中的 break 是用于直接跳出循环的。

while 循环中的 continue

再结合本节开头的流程图 , 思考下面的代码运行后输出什么?

#include <stdio.h>
int main()
{
    int i = 1;
    while (i <= 10)//a 处
    {
        if (i == 5)
            continue;//b 处
        printf("%d ", i);
        i = i + 1;
    }
    return 0;
}

实际上输出的是 :

1 2 3 4 

且输出上述后程序并没结束 , 却也永远没有后续输出 , 这是为什么呢?

这是由于当 i 加到 5 时,if 语句的条件满足,执行 continue 语句

此后代码将不断从 b 处跳到 a 处 , 再运行到 b 处再跳到 a 处 ......

当部分更改后可以更直观地表现出上面的说法:

    while (i <= 10)
    {
        if (i == 5)
        {
            printf("BLZ\n");
            continue;
        }

每一次跳转都会输出 BLZ

总结 : while 循环中 continue 的作用为忽略 continue 后续的语句返回判断部分

for 循环

最常用 , 一定要熟练掌握

语法

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

表达式 1 为初始化部分

表达式 2 为判断部分

表达式 3 为调整部分

示例

#include<stdio.h>
int main()
{
    for (int a = 1; a <= 10; a++)
    {
        printf("%d ", a);
    }
    
    return 0;
}

输出结果 :

1 2 3 4 5 6 7 8 9 10

 同样是打印 1 ~ 10 , for 循环的写法比 while 不知道简单了多少 :

while 循环的缺陷

刚讲完 while , 这里不累子就背刺一下 while

从上面的实例不难看出 , for 循环可以方便我们管理循环变量(控制循环的变量)

因为 for 循环中,初始化、判断、调整部分放到了一处

如果后续循环中的代码量十分庞大 , 使用 for 循环无疑更易于我们管理

for 循环中的 continue

实例 :

结合本节开头的流程图 , 思考以下代码输出什么

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

输出结果 :

0 1 2 3 4 6 7 8 9//没有 5

可知在 for 循环中遇到 continue 时 , 也会直接忽视后续语句 , 直接跳转到表达式 3 , 并进行判断

也就是说 , continue 不会跳过 for 循环中的表达式 3

for 循环中的 break

break 在 for 循环内的作用与在 while 循环作用一致

都是直接跳出循环不执行表达式 3

for 循环的变种

for 循环的三个表达式可以省略一个或多个

省略了判断表达式的 for 循环
#include<stdio.h>
int main()
{
    for (;;)
    {
        printf("1\n");
    }
    return 0;
}

以上实例在运行后会重复打印 1 ,不会终止。

原因:for 默认循环中没有判断条件时,判断恒为真

省略了初始化表达式的 for 循环

思考以下代码输出什么 :

#include<stdio.h>
int main()
{
    int i = 0;
    int j = 0;
    for (; i < 3; i++)
    {
        for (; j < 3; j++)
        {
            printf("1\n");
        }
    }
    return 0;
}

输出结果 :

1
1
1

原因:

        在最初进入最外层 for 循环时,i < 3;故进入第二层 for 循环

        在第二层循环中,一共进行 3 次循环打印操作

        离开第二层 for 循环后,j 的值仍为 3

        而由于第二层 for 循环没有初始化部分

        故此后 j 的值永远为 3

        再也不会进入第二层 for 循环进行打印操作

如果加上第二层 for 循环的初始化部分,则打印 9 个 :

    for (; i < 3; i++)
    {
        for (j = 0; j < 3; j++)//加上了初始化部分,每次进入循环前都会先初始化
        {
            printf("1\n");
        }
    }

使用多个循环变量控制 for 循环

在使用 for 循环时,循环变量可以有多个(应该很容易理解吧) :

#include<stdio.h>//没必要细看,知道就行
int main()
{
    int x, y;
    for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)//由两个变量控制的循环
    {
        printf("1\n");
    }
    return 0;
}

一道笔试题

据(不累子)说 99% 的初学者这道题都错了

当然 , 不累子就是 99% 中的一个

以下代码运行后输出什么 :

#include <stdio.h>
int main()
{
    int i = 0;
    int k = 0;
    for (i = 0, k = 0; k = 0; i++, k++)
        k++;
    return 0;
}

以上代码运行后一次都不会循环

因为判断部分并不是一个判断语句

而是一个赋值语句

赋值语句的值为赋的值:即为 0

(0 为假 , 不进入循环 , 这出题人真会坑人 , 对吧)

实际上这只是坑我们初学者 , 相信大家这么错过几次之后都能发现问题

(应该?)

这里就知道不累子给你的提醒有什么用了吧 :

//代码3
int num = 1;
if (num == 5)
{
    printf("hehe\n");
}

//代码4
int num = 1;
if (5 == num)
{
    printf("hehe\n");
}

实际上代码 3 和代码 4 也是等价的 , 但我们推荐使用代码 4 的形式

因为如果你不小心漏了一个 = (这种情况很常见) , 在代码 3 中 , 这会使得原本的判断语句变成赋值语句 , 但编译器并不会报警告

但如果是代码 4 , 由于 5 不能被赋值 , 在编译时编译器就无法通过并会报警告 , 这可以提示你出错了

所以这么细心宠粉(根本没什么粉丝555)的不累子你忍心不关注嘛...qwq

do while 循环

少用 , 知道就行

语法

do
{
	循环语句 1;
	循环语句 2;
	循环语句 3;
    ...
	循环语句 n;
}
while (表达式);

先执行一次循环语句,如果 while 的条件满足则返回再执行循环语句

也就是说 do while 循环中,循环语句至少执行一次

do while 循环中的 continue

作用和 while 中的 continue 一样嘛

当运行到 continue 时,跳过后续循环语句,直接执行判断语句

#include<stdio.h>
int main()
{
    int i = 1;
    do
    {
        if (5 == i)
        {
            continue;
        }
        printf("%d ", i);
        i++;
    } 
    while (i < 10);

    return 0;
}

以上语句在输出 1 2 3 4 后进入无输出死循环。

do while 循环中的 break

break 在 do while 循环内的作用与在 while 循环、for 循环中的作用一致

都是直接跳出循环不执行后续语句

练习

计算 n 的阶乘

写一个程序 , 要求输入一个值 n , 输出 n! (n 的阶乘) 的值

注 : n! = 1 * 2 * 3 * 4 * 5 * 6 * ... * n

答案 :

#include<stdio.h>

int main()
{
    int a, b = 1;
    printf("n!\nn = ");//打印提示信息

    scanf("%d", &a);//输入一个值,并存放到 a 里

    for (int i = 1; i <= a; i ++)//每次循环 i 都加 1
    {
        b *= i;//等效于 b = b * i;
    }

    printf("n! = %d", b);//输出值

    return 0;
}

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

写一个程序 , 输出从 1 的阶乘加到 10 的阶乘的值

有了上面的例子 , 这个应该也能做出来吧

答案 :

#include<stdio.h>

int main()
{
    long long a, b=1, i= 1;//定义类型为 long long,防止数据溢出
    for (a = 10; a >= 10; a--)
    {
        for (i = 1; i <= a; i++)
        {
            b *= i;
        }
    }

    printf("%lld", b);//输出结果

    return 0;
}

拓展 : 打印 1! + 2! + ... + n!

(怎么就跟阶乘过不去呢)

这个就留给大家自己实现啦 , 不累子真的很累啦 , 饶了我吧qwq

答案 : 都说了自己实现 , 那哪来的答案嘛

总结

有了以上这些知识 , 相信以后 C 语言里的这些分支语句和循环语句就难不倒你啦...

如果你觉得在本文学到了点东西 , 不妨点点关注点点赞 , 将来不累子会更新更多知识

积少成多 , 希望你我都能学到属于自己的东西!!!

敲这么多真的很累的啊...可怜可怜不累子吧qwq

如果你能关注我 , 那是再好不过了 , 如果不想关注 , 至少也留下两句鼓励的话再走吧 , 让我知道有人在看我的文章并学到了东西

标签:语句,do,int,case,while,循环,printf
From: https://blog.csdn.net/Blaze_dL/article/details/143088864

相关文章

  • CentOs7.39 安装Docker
    ①先卸载原有的docker如果第一次安装忽略sudoyumremovedocker\docker-client\docker-client-latest\docker-common\docker-latest\docker-latest-logrotate\......
  • markdown学习
    1.掌握了基本的markdown格式,如标题,段落,强调以及列表等应遵循的格式,但并未精进,对markdown这种格式依旧有很大的割裂感和陌生感。2.提示词框架有问题导向型,任务驱动型,观点陈述型和案例分析型。3.#通用模板1.##主要问题首先清晰地描述主题,包括主题的背景、范围和主要关注点。例如......
  • MarkDown学习
    MarkDown学习标题二级标题三级标题四级标题字体Hello,World!Hello,World!Hello,World!Hello,World!引用选择狂神说java,走向人生巅峰分割线---或***图片超链接点击跳转到哔哩哔哩列表ACABC表格名字性别生日张三男1997.1.1代码......
  • Ubuntu中docker安装
    sudopasswdroot(设置root密码)Ubuntu14.04/16.04/18.04安装docker#step1:安装必要的一些系统工具sudoapt-getupdatesudoapt-get-yinstallapt-transport-httpsca-certificatescurlsoftwareproperties-common#step2:安装GPG证书curl-fsSLhttps://mirrors.aliyu......
  • Docker搭建Maven私服
    第一步:拉取nexus3的镜像拉取nexus3的镜像,也可指定版本,本文使用3.71.0版本进行安装dockerpullsonatype/nexus3//拉取最新版本或dockerpullsonatype/nexus3:3.71.0//拉取指定版本第二步:查看nexus3镜像输入dockerimages查看nexus3镜像是否下载成功,如图所示即下载成......
  • 【Docker项目实战】使用Docker部署HumHub社交网络平台
    【Docker项目实战】使用Docker部署HumHub社交网络平台一、HumHub介绍1.1HumHub简介1.2HumHub特点1.3主要使用场景二、本次实践规划2.1本地环境规划2.2本次实践介绍三、本地环境检查3.1检查Docker服务状态3.2检查Docker版本3.3检查dockerco......
  • CountdownEvent
    CountdownEvent是一种同步结构,主要用来协调多种同步处理后的结果场景使用。其含义为:定义一个多信号的结构,然后在应用时判断信号是否全部到达,如果全部到达则继续往下运行,否则进行阻塞,有意思的是,如果阻塞已过,那么再次运行到wait()时,线程是不会再次阻塞的,除非调用reset()重新初始化后......
  • 快速掌握Markdown极简语法
    这是总结笔记师从b站up主AXin视频链接8分钟让你快速掌握Markdown​标题标题一标题二标题三标题四标题五标题六引用这是一段引用有序列表打开冰箱把大象放进冰箱把冰箱门关上无序列表kyriekdjames任务列表吃饭睡觉打豆豆代码块pr......
  • 适用于 Windows 11/10/8/7/Vista/XP 的最佳免费分区软件
    无论您使用的是SSD、机械磁盘还是任何类型的RAID阵列,硬盘驱动器都是Windows计算机中不可或缺的组件。在将文件保存到全新磁盘之前,您应该初始化它,创建分区并使用文件系统格式化。在运行计算机一段时间后,您需要收缩、扩展、转换、复制磁盘分区等。可靠的磁盘分区工具可以帮......
  • Markdown基本语法
    1、标题:#符号表示标题,#的数量表示标题的级别。#一级标题##二级标题###三级标题####四级标题#####五级标题######六级标题注:“=”和“-”分别表示一级和二级标题(但这种用法不太常见):        我展示的是一级标题        =================     ......