C 语言学习历程:(第三章)分支与循环・代码世界的路径导航
第三章:分支与循环
文章目录
C 语言中有三种结构:
- 顺序结构
- 选择结构
- 循环结构
1.顺序结构
依照线性顺序从上到下依次执行
例如:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
printf("1");
printf("2");
printf("3");
return 0;
}
2. 选择结构
通过给定的条件进行判断,当条件为真或假时分别执行不同的程序语句。
2.1 if 语句
if (表达式)
{
语句1
}
else if (表达式)
{
语句2
}
else
{
语句3
}
执行流程:
当表达式成立(为真),语句执行,否则(为假)不执行。在 C 语言中,非零即为真
嵌套 if 练习:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int num = 0;
printf("请输入一个整数:");
int count = scanf("%d", &num);//定义变量接受 scanf 的返回值
if (count == 1) //如果 count 为 1,scanf 接收到数据执行,否则就是格式不对没有接收到
{
if (num == 0)
{
printf("输入的数字为0");
}
else if (num > 0) //判断是否为正数
{
if (num % 2 == 0)
{
printf("为偶数");
}
else if (num % 2 == 1)
{
printf("为奇数");
}
}
else
{
printf("您输入的数字为负数");
}
}
else
{
printf("您输入的不是整数");
}
return 0;
}
悬空 else 问题:
如果有多个 if 和 else,else 且没有带大括号,则 else 总是跟最接近的 if 匹配,就会导致程序运行不是我们理想的结果。
测试:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1) //此处不加大括号,编译器会识别成 else 和第二个 if 为一对代码块,就近原则
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
2.2 switch 语句
switch 是一种特殊形式的 if ... else 结构,用于判断条件有多个结果的情况。当表达式的值无法匹配 case 语句时,将匹配 default 语句。
switch (expression)
{
case value1:
语句1;
break;
case value2:
语句2;
break;
...
default:
语句3;
break;
}
switch后的expression必须是整形表达式case后的值,必须是整形常量表达式case和后边的数字之间必须有空格case语句中的代码执行完后,需要加上break,才能跳出这个switch,否则会继续向下执行
输入1~5 输出工作日,6~7 输出休息日:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//周一到周五为工作日,周六到周日为休息日,思路:不使用 break 实现 switch 的范围选择
int main()
{
int num = 0;
printf("请您输入1~7的数字:");
scanf("%d", &num);
switch (num)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日");//前面介绍过,switch 不加 break 程序会一直向下执行,直到遇到 break 或者 switch 语句结束
break;//所以可以通过此写法实现周一到周五都为休息日,不用在每个程序块都输出一句工作日
case 6:
case 7:
printf("休息日");
break;
default: //当所有 case 选项不匹配执行
printf("请输入合法的字符");
break;//default 放在最后,此时的 break 可加可不加,不加走到最后依然会跳出
}
return 0;
}
3. 操作符
3.1 关系操作符
关系表达式:用于比较的表达式
关系操作符(关系表达式中使用的运算符):
><>=<===!=
关系表达式通常返回 0 和 1 ,表示真假。
输入年龄,在18~36 之间,输出青年:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int age = 0;
printf("请输入你的年龄:");
scanf("%d", &age);
if (age >=18 && age <= 36)
{
printf("青年");
}
return 0;
}
注意:
== 是判断是否相等,= 是进行赋值
3.2 条件操作符
条件操作符需要接受三个操作数,也被称为三目操作符。
exp1 ? exp2 : exp3
当 exp1 为真,则执行 exp2,否则执行 exp3。计算后的结果是整个表达式的结果。
使用条件表达式找出两个输入数字最大值:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a,&b);
int m = (a > b ? a : b);//第一个表达式为真,则执行第二个表达式,否则执行第三个表达式。(相当于 if else)
//a > b ? printf("&d",a) : printf("%d",b);//第二种写法
printf("%d", m);
return 0;
}
3.3 逻辑操作符
!:逻辑取反&&:逻辑与(两侧的表达式都为真,则为真,否则为假)||:逻辑或(两侧至少有一个表达式为真,则为真,否则为假)
测试:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// !取反 ,&& 两者为真即为真 ,|| 最少一个为真即为真
int main()
{
int flag = 0;
scanf("%d", &flag);
//if () 括号内内容为真时才执行后续语句
// if (flag) 表示 (flag == true) 也就是非零
// if (!flag) 表示 if (flag != true) 即 flag == false 也就是等于 0 时
if (!flag)
{
printf("假");
}
return 0;
}
闰年的判断:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int year = 0;
printf("请输入一个年份:");
scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
{
printf("闰年");
}
else
{
printf("平年");
}
return 0;
}
C 语言逻辑运算符有一个特点,就是先对左侧的表达式求值,再对右边的表达式求值。如果坐标的表达式满足逻辑运算符的条件,就不会再对右边的表达式求值,这种情况被称为 短路。
测试:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 当使用 && 运算符时,左侧表达式为 0,便没有执行后面表达式的必要
// 当使用 || 运算符时,左侧表达式为 1,便没有执行后面表达式的必要
// 当左边表达式能够确定整个表达式的结果时,便不需要再执行右边表达式。这种情况称为“短路”
int main()
{
//试验一
int i = 0, a = 0, b = 2, c = 3, d = 4;
// 0
i = a++ && ++b && d++;//赋值运算符的优先级最低,右边整个表达式计算完再进行赋值
printf("i = %d\na = %d\nb = %d\nc = %d\nd = %d\n",i, a, b, c, d);// 0 1 2 3 4
printf("-------------------------------------------------------\n");
//解析:因为赋值运算符的优先级最低,此时执行 a++ 的时候,a 需要先使用再自增
//所以 a++ 整体代表 0,而且表达式还是 && 逻辑操作符,所以后面的表达式都没有被执行
//直到 printf 语句 再次输出 a,此时 a 已经完成自增,所以输出的是 1
//试验二
int i2 = 0, a2 = 1, b2 = 2, c2 = 3, d2 = 4;
//8 = 1 + 3 + 4
i2 = (a2++) + (++b2) + (d2++);
printf("i2 = %d\na2 = %d\nb2 = %d\nc2 = %d\nd2 = %d\n", i2, a2, b2, c2, d2);// 8 2 3 3 5
printf("-------------------------------------------------------\n");
//试验三
int i3 = 0, a3 = 1, b3 = 2, c3 = 3, d3 = 4;
// 1
i3 = a3++ || ++b3 || d3++;
printf("i3 = %d\na3 = %d\nb3 = %d\nc3 = %d\nd3 = %d\n", i3,a3, b3, c3, d3);// 1 2 2 3 4
printf("-------------------------------------------------------\n");
//执行 a++ 的时候,a 需要先使用再自增
//所以 a++ 整体代表 1,而且表达式是 || 逻辑操作符,所以后面的表达式不需要被执行
//直到 printf 语句 再次输出 a,此时 a 已经完成自增,所以输出的是 2
//试验四
int i4 = 0, a4 = 0, b4 = 2, c4 = 3, d4 = 4;
// 0 3
i4 = a4++ || ++b4 || d4++;
printf("i4 = %d\na4 = %d\nb4 = %d\nc4 = %d\nd4 = %d\n", i4, a4, b4, c4, d4);// 1 1 3 3 4
printf("-------------------------------------------------------\n");
//执行 a++ 的时候,a 需要先使用再自增
//所以 a++ 整体代表 0,表达式是 || 逻辑操作符,接着向后执行 ++b4,先自增再使用,此时 ++b4 为 3
//已经满足一个为真的情况,此时便不需要再执行后面的表达式
//直到 printf 语句再次输出 a,此时 a 已经完成自增,所以输出的是 1
return 0;
}
4. 循环结构
满足指定的条件,将会一直循环执行
4.1 while 循环
while (表达式)
{
循环语句;
}
执行流程:
首先判断表达式,表达式的值为 0 ,循环直接结束;表达式的值不为 0 ,则执行循环语 句,语句执行完后再继续判断,是否进行下一次执行。
输入一个正整数,逆序打印整数的每一位:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// while 循环:循环次数不知道,只知道循环结束条件
int main()
{
//输入一个正的整数,逆序打印这个整数的每一位
int num = 0;
printf("请输入一个整数");
scanf("%d", &num);
while (num)//当 num =0 时说明数字已经遍历完成,此时就不会进入循环体
{
printf("%d ", num % 10);// num % 10 获取数字的最后一位,例如 123 % 10 = 3
num /= 10;//此时已经获取到最后一位,接着让数字往前进一位
}
return 0;
}
4.2 for 循环
for(表达式1:循环变量初始化;表达式2:循环结束条件;表达式3:循环变量调整)
{
循环语句;
}
执行流程:
首先执行表达式 1 初始化循环变量,接着执行表达式 2 的判断部分,如果 表达式 2 的结果为假,则循环结束。否则执行循环语句,循环语句执行完后,再去执行表达式 3,调整循环变量,然后再去表达式 2 的地方进行判断,表达式的结果是否为假,决定循环是否继续。
注意:整个循环过程中,表达式 1 只被执行一次。
计算 1~100 之间3的倍数的数字之和
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// for 循环(知道循环次数)
//for (变量初始化;判断;调整)
int main()
{
int sum = 0;//定义一个变量记录和
//计算1~100之间3的倍数的数字之和
//写法一(循环一百次,判断一百次)
//for (int i = 1; i < 101; i++)
//{
// if (i % 3 == 0)//判断是否是3的倍数
// {
// sum += i;//当是3的倍数的时候相加
// }
//}
//写法二 (循环33次)
for (int i = 3; i < 101; i+=3)//直接从3开始,循环一次调整变量+3,即每次循环就是3的倍数
{
sum += i;
}
printf("数字之和为:%d", sum);
return 0;
}
for 循环相比 while 循环,在实现循环的过程中,初始化、判断和调整这三个部分,比 while 循环更集中,方便代码维护。
4.3 do while 循环
do
循环语句;
while(表达式);
执行流程:
while和for循环都是先判断,条件满足才进入循环。而do while则是先进入循环体执行循环语句,然后再执行while的判断表达式,表达式为真,才会进行下一次,为假则结束循环,所以在do while中,语句至少被执行一次。
输入一个正整数,计算这个整数是几位数:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
//输入一个正整数,计算这个整数是几位数,正整数不管输入几都是一位数,所以用 do while
int num = 0;
int count = 0;//定义变量计数
printf("请输入一个正整数:");
scanf("%d", &num);
do
{
count++;
num /= 10;
} while (num);// 当num == 0 时,程序便结束
printf("这个整数是%d位数", count);
return 0;
}
4.4 break 和 continue
- break:终止当前循环体
- continue:跳过本次循环并忽略之后的代码重新循环
找出 100~200 之间的素数:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
/*
break(终止整个循环程序) continue(跳过本次循环)
break: while和for执行都一样
continue:调整变量如果在 continue 后,do while 和 while 循环中可能会出现死循环,因为 continue 会跳过之后的代码,此时变量就不会发生调整。而 for 循环的调整变量是在循环体外,所以不会受影响
*/
#include <math.h> //sqrt 开平方需要的头文件
//循环的嵌套
int main()
{
//找出 100~200 之间的素数(只能被1和本身整除)
for (int i = 101; i < 201; i += 2)//外层循环代表 101~201 之间的偶数,偶数不可能是质数,所以只判断奇数
{
int count = 0;//定义一个变量来记录当前循环的数字可以被整除的次数,每次循环即每更换一个数字重置
//内层循环代表遍历外层所包含的数字,从2开始,到 i 开平方
//因为如果 i = a * b,a和b是i的因子,那么a和b中至少有一个数字 <= i 开平方
//不论是a还是b,只要在 i开平方之前的范围找到,便能找到与之对应的值
for (int j = 2; j <= sqrt(i); j++)
{
if ( i % j == 0)
{
count++;
break;//如果找到被整除的数字了,直接结束内层的整个循环体
}
}
if (count == 0)//如果次数为0,则代表只能被1和本身整除
{
printf("%d ", i);
}
}
return 0;
}
5. goto 语句
goto 语句可以实现在同一个函数内跳转到设置的标记处
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// goto 语句,同一个函数跳转
int main()
{
printf("hehe\n");
goto next;//忽略之后代码,跳入到next开始执行
printf("haha\n");
next:
printf("hhhhhhh\n");
return 0;
}
goto 语句如果使用不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,但是 goto 语句在多层循环的代码中,如果想快速跳 goto 就非常方便。
关机程序:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //system 函数头文件
#include <string.h>//字符串头文件
//写一个关机程序
//功能:程序运行起来后,电脑倒计时一分钟关机,如果一分钟内输入取消关机,则取消。
int main()
{
char str[20];//定义字符数组接受用户输入的字符串
again:
printf("请注意,您的电脑一分钟之后将关机,输入取消将会取消关机:");
//system 函数用于执行系统命令
system("shutdown -s -t 60");//shutdown -s 指定关机 -t 指定倒计时,单位为秒
scanf("%s", str);
//两个字符串在比较内容的时候,不能使用 ==,而是用 strcmp 函数
//如果两个字符串相等,strcmp 函数会返回 0
if (strcmp(str, "取消") == 0)
{
system("shutdown -a");//取消关机
}
else
{
goto again;//如果用户没有输入取消关机,则跳转到 again 地方,继续提醒用户实现循环的效果
}
return 0;
}
第四章:随机数生成
声明
本文是在鹏哥 C 语言集训营学习过程中所记录的学习笔记,梳理了核心知识点,同时也记录了本人实操验证的代码案例,供后续学习复盘使用。
更多推荐


所有评论(0)