【C语言+代码风格】认识分支与循环语句及代码风格

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    纸上得来终觉浅 绝知此事要躬行。
    主页June-Frost
    专栏C语言
    ⚡注此篇文章的 代码风格部分 将根据《高质量 C++/C 编程指南》 —— 林锐 进行说明。该部分将用紫色表示


    此篇文章将详细说明分支与循环语句 以及它们的 代码风格

    文章目录


    c语言是结构化的程序设计语言支持三种结构即 顺序结构 选择结构 循环结构 。

    语句的分类

    C语言的语句可以分为5类
    1.表达式语句;
    2.函数调用语句;
    3.控制语句;
    4.复合语句;
    5.空语句;

    控制语句 用于控制程序的执行流程以实现程序的各种结构方式C语言支持三种结构顺序结构、选择结构、循环结构它们由特定的语句定义符组成C语言有九种控制语句。

    将其分为3类

    1. 分支语句条件判断if语句switch语句;
    2. 循环执行语句do while语句 while语句for语句。
    3. 转向语句break语句goto语句continue语句return语句。

    良好的代码风格
    像 if、for、while 等关键字之后应留一个空格再跟左括号‘’以突出关键字。


    分支语句

    分支语句支持选择结构。
    例如进入图书馆选择书籍就是一种选择。

    if 语句

    if语句的语法结构为
    <单分支>

    if (condition)
    	statement;
    

    <双分支>

    
    	if (condition)
    		statement1;
    	else
    		statement2;
    

    <多分支>

    if (condition)
    		statement1;
    	else if
    		statement2;
    	else
    		statement3;
    

    对于if 语句的使用 举个例子判断成年
    <单分支>

    #include<stdio.h>
    int main()
    {
    	int age = 0;
    	scanf("%d", &age);
    
    	if (age >= 18)
    		printf("成年\n");
    
    	return 0;
    }
    

    如果要判断出来是成年的话做事需要完全承担责任。

    #include<stdio.h>
    int main()
    {
    	int age = 0;
    	scanf("%d", &age);
    
    	if (age >= 18)
    		printf("成年\n");
    	    printf("做事完全承担责任\n");
    	return 0;
    
    

    ❗️结果

    我们可以发现 结果出现了问题。

    if语句 默认情况下会控制一条语句如果要控制多条语句需要用{}也即是复合语句。

    正确书写

    #include<stdio.h>
    int main()
    {
    	int age = 0;
    	scanf("%d", &age);
    
    	if (age >= 18)
    	{
    		printf("成年\n");
    		printf("做事完全承担责任\n");
    	}
    	return 0;
    }
    

    if、for、while、do 等语句自占一行执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误。
    以下代码均为该形式

    例子判断年龄
    <双分支>

    #include<stdio.h>
    int main()
    {
    	int age = 0;
    	scanf("%d", &age);
    
    	if (age < 18)
    	{
    		printf("未成年\n");
    	}
    	else
    	{
    		printf("成年\n");
    	}
    
    	return 0;
    }
    

    判断多个年龄

    #include<stdio.h>
    int main()
    {
    	int age = 0;
    	scanf("%d", &age);
    
    	if ((age>0) && (age<14))
    	{
    		printf("儿童\n");
    	}
    	else if ((age >= 14) && (age < 35))
    	{
    		printf("青年\n");
    	}
    	else if ((age >= 35) && (age < 65))
    	{
    		printf("中年人\n");
    	}
    	else
    	{
    		printf("老年人\n");
    	}
    
    	return 0;
    }
    

    注意

    对于表达式比较长的 if 语句为了紧凑起见可以适当地去掉一些空格。例如if ((age>0) && (age<14)) 但是不要写成if((age>0)&&(age<14))

    不要把程序中的复合表达式与“真正的数学表达式”混淆。例如表示年龄在 0到14之间不可以写为 0<age<14,这是数学表达式在程序中这样子的表达式 会被理解为0<age)<14 。 在执行时若输入age为10 ——> 10>0 ——> (0<age)的结果就是1——> 1<14 这个式子就会永远为真。 所以需要写成if ((age>0) && (age<14))

    if语句可以嵌套
    例如

    if ((age>0) && (age<14))
    	{
    		printf("儿童\n");
    	}
    	else
    	{
    		if ((age >= 14) && (age < 35))
    		{
    			printf("青年\n");
    		}
    		else if ((age >= 35) && (age < 65))
    		{
    			printf("中年人\n");
    		}
    		else
    		{
    			printf("老年人\n");
    		}
    	}
    

    注意在c语言中0为假非0为真。


    悬空else

    代码示例

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

    ❗️结果如下

    注意 else 会和 最近的if 匹配 。 最好加入{} 使得代码中的匹配更加明确。


    switch 语句

    switch语句语法
    switch(整形表达式
    {
     语句项;
    }
    语句项是一些case语句
    case 整形常量表达式
       语句;

    ❓ if语句已经可以完成选择switch存在的理由是什么呢
    ❗️switch 是多分支选择语句。如果有大量的分支if…else if…else 这样的结构就会显得冗长。这时候switch就可以使用了。

    举个例子

    #include<stdio.h>
    int main()
    {
    	int day = 0;
    	scanf("%d", &day);
    	switch (day)
    	{
    	case 1:
    		printf("星期一");
    		break;
    	case 2:
    		printf("星期而");
    		break;
    	case 3:
    		printf("星期三");
    		break;
    	case 4:
    		printf("星期四");
    		break;
    	case 5:
    		printf("星期五");
    		break;
    	case 6:
    		printf("星期六");
    		break;
    	case 7:
    		printf("星期日");
    		break;
    	}
    	return 0;
    }
    

    case 决定入口break决定出口。整形变量的值决定从哪个入口进入。

    break既然决定出口那么就可以根据需求建立出口。
    例如 需求为

    1. 输入1-5输出的是“weekday”;
    2. 输入6-7输出“weekend”;
    #include<stdio.h>
    int main()
    {
    	int day = 0;
    	scanf("%d", &day);
    	switch (day)
        {
    	case 1:
    	case 2:
    	case 3:
    	case 4:
    	case 5:
    		printf("weekday\n");
    		break;
    	case 6:
    	case 7:
    		printf("weekend\n");
    		break;
    	}
    	return 0;
    }
    

    default子句

    如果表达式的值和case的标签都不一样这种情况下结构中的所有语言都会被跳过这种情况下c语言并不会报错但是如果不想忽略不匹配的值就可以使用default字句。

    即使程序真的不需要 default 处理也应该保留语句 default 。甚至可以加个break 。

    所以良好的习惯风格

    #include<stdio.h>
    int main()
    {
    	int day = 0;
    	scanf("%d", &day);
    	switch (day)
        {
    	case 1:
    	case 2:
    	case 3:
    	case 4:
    	case 5:
    		printf("weekday\n");
    		break;
    	case 6:
    	case 7:
    		printf("weekend\n");
    		break;
    	default:
    		printf("输入错误\n");
    		break;
    	}
    	return 0;
    }
    

    循环语句

    • while循环
    • for 循环
    • do while 循环

    while 循环

    while语句的语法结构 while(表达式

     循环语句;

    ✍while语句的执行流程

    举个例子 打印 1 到 10

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

    结果:


    while语句中的break和continue

    博主会用两个例子来说明功能

    ❗️break是用来永久终止循环的。在某些条件产生后想终止循环就可以使用break一次只能跳出一层循环。

    可以观察到在打印出4后该循环变为死循环这是因为continue可以跳过本次循环后面的代码再次进行判断由于i++ 被跳过i只能为5造成死循环。

    ❗️continue 跳过本次循环在continue之后的代码直接进入while循环的判断部分。


    while语句的应用

    了解getchar和putchar


    getchar 用来获取一个字符不需要参数返回字符的ASCLL码值。

    如果正确读取到一个字符则返回ASCll码值如果读取不正常则会返回EOFend of file文件结束标志EOF其实就是 -1

    为什么接收值为 int 而不是 char 呢

    对于char类型一些编译器定义的范围为 -128 ~ 127还有一些为 0~255 。如果是后者在返回 -1 时就会出错另外对于ASCll码表的扩展字符就算时 -128 ~ 127 也无法表示所以采取大范围的 int 更加合适。


    putchar 只能打印字符参数可以为ASCll码值。

    举个例子<输入密码>

    #include<stdio.h>
    int main()
    {
    	printf("请输入密码:>");
    	char password[20] = { 0 };
    	scanf("%s", password);
    	//清空缓冲区·
    	while (getchar() != '\n')
    	{
    		;
    	}
    	char input = 0;
    	printf("请确认(Y/N):> ");
    	scanf("%c", &input);
    	if ('Y' == input)
    	{
    		printf("确认成功\n");
    	}
    	else
    	{
    		printf("确认失败\n");
    	}
    	return 0;
    }
    

    ❗️结果

    这里需要注意输入缓冲区

    下图为对该程序中输入缓冲区的变化


    for循环

    影响循环的有三个因素循环变量的初始化判断调整。

    for存在的意义
    for循环可以将这三个因素整合在一起比较集中这就是一种相比while循环的一种优势。

    for循环的语法结构
    for (表达式1; 表达式2; 表达式3
     循环语句;

    表达式1 —— 初始化;
    表达式2—— 判断;
    表达式3——调整;
    ✍for语句的执行流程:

    好的代码习惯如下

    if、for、while、do 等语句自占一行执行语句不得紧跟其后。不论
    执行语句有多少都要加{}。这样可以防止书写失误

    如果‘;’不是一行的结束符号其后要留空格如 for (initialization; condition; update)。

    对于表达式比较长的 for 语句,为了紧凑起见可以适当地去掉一些空格如
    for (i=0; i<10; i++)不要写成for(i=0;i<10;i++)和for (i = 0; I < 10; i ++)。

    我们可以按照此要求写一个循环打印 1-10。

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

    如果循环体内存在逻辑判断并且循环次数很大宜将逻辑判断移到循环体的外面。

    如果N循环次数大可以采用该方式不会打断“流水线”作业能提高效率。

    if (condition) 
    { 
       for (i=0; i<N; i++) 
       {
        //业务处理
       }
    } 
    else 
    { 
       for (i=0; i<N; i++) 
       {
        //业务处理
       }
    } 
    

    如果N比较小两者差别不明显。以下这种更加简洁。

    for (i = 0; i < N; i++)
    {
    	if (condition)
    	{
           //业务处理
    	}
    	else
    	{
          //业务处理
    	}
    }
    

    for循环中的break和continue

    for循环中的break和continue的意义与while循环的一致。但是对于continue有时会有不同的结果例如

    对于上面类似的代码while循环的continue 会使得代码变为死循环while循环的continue使得调整部分被跳过但是由于for循环的调整部分不在循环体内所以不会造成死循环。


    对于for循环写法

    不可在 for 循环体内修改循环变量防止 for 循环失去控制。循环变量的调整只放在表达式3中可以防止出现问题。

    建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法。虽然for (i=0; i<=9; i++)和for (i=0; i<10; i++)都是循环10次但是第二个更加直观。


    表达式的省略带来的结果

    • 初始化和调整部分的省略就是什么都不执行;
    • 判断部分的省略即为判断恒为真;

    do while循环

    do while 循环语法结构

    do
    循环语句;
    while(表达式);

    ✍do while语句的执行流程:


    特点
    循环至少执行一次。

    do while 循环中的break和continue


    在这里插入图片描述
    可以见得
    与while和for 循环的break和continue的意义一致。


    goto语句

    C语言中提供了可以随意滥用的goto语句标记跳转的标号。只要在一个函数内就可以任意跳转。

    例如

    ❗️goto语句如果大量使用会导致逻辑不容易把控。
    ✍goto语句有自己的应用场景最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
    例如

    
    	for (...)
    	{
    		for (...)
    		{
    			for (...)
    			{
    				if (condition)
    				{
    					goto error;
    				}
    			}
    		}
    	}
    error:
         ...
    

    本来需要3次break才可以跳出现在只需要一个goto就可以直接跳出。


  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6