文章目录
C语言梦开始的地方4
在上一章节我们了解了C语言各种操作符,通过算术操作符我们知道C语言中是怎么处理算术计算,通过位运算我们知道C语言是怎么处理2进制运算,通过赋值操作符我们知道C语言中初始化和赋值的区别等等一些知识点。
本章节我们继续了解C语言的其他操作符和选择与循环语句
选择语句
选择语句C语言提供了两个:一个是
if一个是switch
if
if语句的语法形式如下:
if(表达式) 语句;表达式为真时执行语句,表达式为假时语句不执行,在C语言中我们把0为假,非0为真;
也就是说
if中的表达式写非0那么它就必定执行如果写0那么它必定不执行。C语言通常将1认为真,0认为假。
c
int main()
{
int num = 0;
scanf("%d",&num);
if(num % 2 == 0)
{
printf("%d是偶数\n",num);
}
if(num % 2 != 0)
{
printf("%d是奇数\n",num);
}
return 0;
}
上述代码是一个简单判断num是否是奇偶数的代码
在我们的逻辑里面这个代码只会进一个if里面去实则不然它其实会将上述代码中的2个if都执行一遍,如果只输入一个num那么我们只需要判断2次,那么输入10次num就要判断20次以此类推那么n次就要判断n * 2次
那么C语言对这种需要多次判断是不是也提供了对应的解决方法呢?
是的,C语言提供了:
else
else
else语句的语法格式为:
if(表达式) 语句; else 语句;
此时我们再去修改刚才的代码
c
int main()
{
int num = 0;
scanf("%d",&num);
if(num % 2 == 0)
{
printf("%d是偶数\n",num);
}
else {
printf("%d是奇数\n",num);
}
return 0;
}
那么不管num是奇数还是偶数该程序只会判断1次
注意:
if和else在没有像上述代码的花括号时那么if和else默认只会控制一条语句- 浮点数在内存中是近似存储的,0.1 实际可能存成 0.100000001...,所以 if(0.1 * 3 == 0.3) 这种比较结果往往出乎意料。判断两个小数是否相等,应比较它们差的绝对值是否足够小:
if (fabs(a - b) < 0.000001
c
int main()
{
int num = 0;
scanf("%d",&num);
if(num % 2 == 0)
printf("%d是偶数\n",num);
printf("%d是奇数\n",num);
return 0;
}
此时num为偶数时都会打印,num为奇数时只会打印num是奇数
所以在编写这种程序时加上花括号会更好一点,减少歧义或不更改原本的含义
嵌套if
在
if else语句中,else可以与另一个if语句连用比如:我们要先判断一个数是否是正数,然后再判断这个数是偶数还是奇数
c
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;
}
注意:
- 我们需要注意的是C语言的语法中没有else if这种语法 ,也就是下面这个代码是等价于上述代码的,
else if只是如今行业里面的编写习惯- 层级越深,代码越难读。能合并的条件就用逻辑操作符合并(if(age >= 18 && age <= 36)),能用 switch 就用 switch,保持结构扁平。
但是我们不建议像下面这样写代码,因为悬空else的问题
c
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输入的数字是0\n");
else if(num > 0) //这里的if 相当于嵌套在else语句中,形成了嵌套结构
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
悬空else
在C语言中,else 总是与距离它最近的、且尚未配对的 if 相结合(即就近配对原则)。当 if 与 else 嵌套书写时,如果缩进不当或省略花括号,就容易产生歧义,这种现象被称为"悬空else"
c
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
比如上述代码最下面的
else是和第二个if匹配的,所以我们在写这些代码时能用花括号就用花括号。
switch语句
switch语句,选择语句的第二种语法。上述都是if语法的衍生写法我们来看看
switch语句的语法格式
switch(表达式) { case value1: 语句; case value2: 语句; default: 语句; }
switch规则如下:
- 表达式类型 必须是整型(int、char、enum 等),不能是浮点数或字符串
- case 值类型 必须是编译期常量(字面量、宏、枚举常量),不能是变量或表达式(如 score >= 80 绝对不行)
- case 唯一性 同一个 switch 中,case 的值不能重复
- break 和贯穿匹配后会顺序执行,遇到 break 才跳出;可故意利用贯穿来合并分支
- default 位置可选,通常放最后,用来处理所有未匹配的情况
- 变量定义在 case 中定义变量需要加 {} 限定作用域
我们看下面的
switch代码:
c
int main()
{
int score = 0;
scanf("%d",&score);
switch(score / 10)
{
case 10:
case 9:
case 8:
printf("优秀\n");
break;
case 7:
case 6:
printf("及格\n");
break;
default:
printf("不及格\n");
}
return 0;
}
关系操作符
经过刚才选择语句的了解我们就能很快的了解并上手关系操作符了
关系操作符:
> < >= <= == !=结果通常为1或0注意:
==和=极易混淆。因为if(score = 60) 是把 60 赋值给 score,表达式值为 60(非0为真),永远成立,编译器还不一定报错。建议把常量放左边写 if(60 == score),一旦漏写一个 =,编译器会立刻报错提醒你。
c
a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;
当我们要判断一个区间时在生活中是这样写的
当我们要判断当前年龄在哪个阶段,此时我们要判断当前年龄是青年这个阶段吗,那么在外面生活中就是这样写 18 <= age <= 36 这个区间内是青年
但是如果我们在C语言这样写会发生什么
c
int main()
{
int age = 0;
scanf("%d", &age);
if (18 <= age <= 36)
{
printf("青年\n");
}
return 0;
}
最终打印结果是青年。为什么?因为age = 10, 10 >= 18吗?很明显不>=,那么此时结果为0,0 <= 36吗?36 >= 0结果为1,那么为真if执行下面语句。
所以要这样写:
c
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18 && age <= 36) // &&是逻辑操作符
{
printf("青年\n");
}
return 0;
}
条件操作符
严格来说C语言中只有一个条件操作符又叫三元运算符
? :该操作符等价于
if else比如我们要求a,b最大值时可以这样写:
c
int main()
{
int a = 10,b = 20;
int max = (a > b) ? a : b;
printf("%d\n",max);
}
有时如果想代码简洁一点就可以用条件操作符来代替
if else但是我想说的是代码首先是给人看的,其次才是给编译器来看。
逻辑操作符
逻辑操作符:
! && ||
- ! :逻辑取反运算符(改变单个表达式的真假)。
- && :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
- || :逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。
注意:
&&和||是短路求值,&&左边为假不看右边,||左边为真不看右边我们写一个判断闰年的代码:什么是闰年?闰年是指能被4整除同时不能被100整除或能被400整除的是闰年
c
int main()
{
// 判断闰年
int year = 0;
scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
printf("%d是闰年\n", year);
else
printf("%d不是闰年\n", year);
return 0;
}
循环语句
循环语句C语言提供了三个:
while,do......while,for
while语句

首先上来就是执行判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执行循环语句,语句执行完后再继续判断,是否进行下一次判断
while循环的语法结构:
while(表达式) 语句;我们来写两个代码看看
使用while循环实现打印1到10的值
c
int main()
{
int n = 1;
while(n <= 10)
{
printf("%d ",n);
n++;
}
return 0;
}
逆序输出num,比如num为1234就输出 4 3 2 1
c
int main()
{
int num = 0;
scanf("%d",&num);
while(num > 0)
{
printf("%d ",num % 10);
num /= 10;
}
printf("\n");
return 0;
}
for语句

三种循环中for循环用的最多也是最好掌握的循环
for循环的语法格式是
for(表达式1;表达式2;表达式3) 语句;使用for循环实现打印1到10的值
c
int main()
{
for(int i = 1;i <= 10;++i)
{
printf("%d ",i);
}
return 0;
}
再来写一个:计算1~100之间3的倍数的数字之和
c
int main()
{
int sum = 0;
for(int i = 0;i < 100;++i)
{
if(i % 3 == 0)
{
sum += i;
}
}
printf("%d\n",sum);
return 0;
}
for循环和while循环对比
for 和while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是for 循环的三个部
分非常集中,便于代码的维护,而如果代码较多的时候while 循环的三个部分就比较分散,所以从形
式上for 循环要更优一些。
do......while语句

do while是三个循环中用的最少的,也是最不好用的
do while的语法格式:
do{ 语句; }while(表达式);while 和for 这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;
而 do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。
使用do while循环打印1到10
c
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
输入一个正整数,计算这个整数是几位数?
比如: 输入:1234,输出:4
c
int main()
{
int n = 1234;
int cnt = 0;
do{
cnt++;
n /= 10;
}while(n > 0);
printf("%d\n",cnt);
return 0;
}
break 和 continue语句
在循环中,break 和 continue 用来控制循环的走向:
- break:立即终止整个循环,跳出循环体,执行循环后面的代码
- continue:跳过本次循环的剩余语句,直接进入下一次循环的判断
在switch时我们就遇到过break,那么我们知道break时终止循环跳出循环体用的。那么为什么switch也可以用,因为switch的运行方式是类似循环的不过的是switch是从头到尾的运行且只运行一次
break和continue在三个循环中的代码如下:
while循环
c
int main()
{
//i等于5时退出循环
int i = 0;
while(i < 10)
{
i++;
if(i == 5)
{
break;
}
printf("%d ",i);
}
printf("\n");
//输出1到10以内的奇数
i = 0;
while(i < 10)
{
i++;
if(i == 5)
{
continue;
}
printf("%d ",i);
}
printf("\n");
return 0;
}
for循环
c
int main()
{
// i等于5时退出循环
int i;
for(i = 1; i <= 10; i++)
{
if(i == 5)
{
break;
}
}
printf("%d\n",i);
// 输出1到10以内除5以外的数
for(i = 1; i <= 10; i++)
{
if(i == 5)
{
continue;
}
printf("%d ",i);
}
printf("\n");
return 0;
}
do while循环
c
int main()
{
// i等于5时退出循环
int i = 0;
do
{
i++;
if(i == 5)
{
break;
}
} while(i < 10);
printf("%d\n",i);
// 输出1到10以内除5以外的数
i = 0;
do
{
i++;
if(i == 5)
{
continue;
}
printf("%d ",i);
} while(i < 10);
printf("\n");
return 0;
}
循环嵌套
循环嵌套:指一个循环的循环体内部再包含另一个完整的循环结构。外面的循环叫外层循环,里面的叫内层循环。
执行规则:
- 每执行一次外层循环,内层循环都要从头到尾完整执行一遍;
- 若外层循环执行 m 次、内层循环执行 n 次,则内层循环体总共执行 m × n 次;
- 常见写法中,外层循环通常控制"行",内层循环控制"列"(下面乘法表就是例子)。
while循环
c
int main()
{
int i = 1;
while(i <= 9)
{
int j = 1;
while(j <= i)
{
printf("%d×%d=%-2d ", j, i, i * j);
j++;
}
printf("\n");
i++;
}
return 0;
}
for循环嵌套
c
int main()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= i; j++)
{
printf("%d×%d=%-2d ", j, i, i * j);
}
printf("\n");
}
return 0;
}
do while循环嵌套
c
int main()
{
int i = 1;
do
{
int j = 1;
do
{
printf("%d×%d=%-2d ", j, i, i * j);
j++;
} while(j <= i);
printf("\n");
i++;
} while(i <= 9);
return 0;
}
goto语句
C语言提供了一种非常特别的语法,就是goto 语句和跳转标号, goto 语句可以实现在同一个函数内跳转到设置好的标号处。
goto 语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们建议是能不用尽量不去使用;但是goto 语句也不是一无是处,在多层循环的代码中,如果想快速跳出使用 goto 就非常的方便了。
它的语法格式
标签名: 语句; goto 标签名;
c
#include <stdio.h>
int main() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
printf("找到目标坐标: (%d, %d)\n", i, j);
goto end_loop; // 直接跳出两层循环
}
}
}
end_loop: // 跳转目标
printf("循环已彻底结束。\n");
return 0;
}