目录
5.4 switch语句中的case和default的顺序问题
9.3 do while循环中的break和continue
介绍
C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构。C语言是能够实现这三种结构的,仔细分析,日常所见的事情都可以拆分为这三种结构或者这三种结构的组合。
我们可以使用if、switch实现分支结构,使用for、while、do while实现循环结构
1. if语句
1.1 if
if语句的语法格式如下:
if(表达式)
语句
表达式为真(成立),则语句执行,表达式为假(不成立)。则语句不执行
在c语言中0为假,非0为真
例1:输入一个整数,判断奇偶数
#include<stdio.h>
int main()
{
int num = 0;
printf("请输入一个数字:");
scanf("%d", &num);
if (num % 2 == 1)
printf("%d 奇数\n", num);
else
printf("%d 偶数\n", num);
return 0;
}
1.2 else
不是...就是...
例二:输入一个年龄,>=18就输出:成年,否则就输出:未成年
int main()
{
int age = 0;
printf("请输入年龄:");
scanf("%d", &age);
if (age >= 18)
printf("%d 岁成年了\n", age);
else
printf("%d 岁未成年\n", age);
return 0;
}
1.3 分支中包含多条语句
默认if和else语句只控制一条语句,比如:
int main()
{
int age = 0;
printf("请输入年龄:");
scanf("%d", &age);
if (age >= 18)
printf("%d 岁成年了\n", age);
printf("可以挣钱了");
return 0;
}
上述代码不管是>=18还是<18,都会打印”可以挣钱了“在屏幕上
这是因为if语句只能控制一条语句,如果想要if语句同时控制两条,就要使用{ }将代码括起来,else后也可以跟上大括号。如下:
int main()
{
int age = 0;
printf("请输入年龄:");
scanf("%d", &age);
if (age >= 18)
{
printf("%d 岁成年了\n", age);
printf("可以挣钱了\n");
}
else
{
printf("%d 岁还没有成年\n", age);
printf("认真学习,还不可以挣钱\n");
}
return 0;
}
1.4 嵌套if
在if else语句中,else可以与另一个语句连用,构成多重判断
例三:要求输入一个整数,判断输入的整数是0,还是正数或者负数。
int main()
{
int num = 0;
printf("请您输入一个数字:");
scanf("%d", &num);
if (num == 0)
printf("您输入的数字是0\n");
else if (num > 0)
printf("您输入的数字是正数\n");
else
printf("您输入的数字是负数\n");
return 0;
}
这个第二个if语句后面代码是嵌套在前面else子句中的,构成了嵌套的if语句。
例四:输入一个整数,如果是正数,在判断是奇数还是偶数,并输出;如果不是正数则输出负数。
int main()
{
int num = 0;
printf("请您输入一个数字:");
scanf("%d", &num);
if (num > 0)
{
if (num % 2 == 1)
{
printf("%d是奇数\n",num);
}
else
{
printf("%d是偶数\n",num);
}
}
else
{
printf("负数");
}
return 0;
}
上面判断奇偶数的代码嵌套在if语句中,构成了嵌套的if语句。
以上就是嵌套if语句的用法,有了嵌套if语句,就可以解决更多复杂逻辑的判断。
1.5 悬空else问题
如果有多个if和else,可以记住这样一条规则,else总是跟最接近的if匹配
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语句对齐,很容易误认为else是和第一个if匹配的,当if语句不成立的时候,就执行else子句,打印haha,但实际上else是和第二个if进行匹配的,这样后面的if...else语句是嵌套在第一个if语句中的,如果第一个语句不成立,嵌套if和else就没机会执行了,最终不会打印。如果希望else和第一个if匹配,可以这样修改代码:
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
像这样加上适当的大括号,代码的逻辑会更加清晰。
2. 关系操作符
CC语言用于比较的表达式,称为“关系表达式”(relational expression),里面使用的运算符就称为“关系运算符”(relational operator),主要有下面6个
- > 大于运算符
- < 小于运算符
- >= 大于等于运算符
- <= 小于等于运算符
- == 相等运算符
- != 不相等运算符
关系表达式通常返回0或1,表示真假。C语言中,0表示假,所有非0表示真。比如20>13返回1,13>20返回0,关系表达式常用于if或者while结构。
3. 条件操作符
条件操作符也叫三目操作符,需要接受三个操作数,形式如下
exp1 ? exp2 : exp3
条件操作符的计算逻辑是:如果exp1为真,exp2计算,计算的结果是整个表达式的结果;如果而exp1为假,exp3计算,计算的结果是整个表达式的结果。
例五:使用条件表达式实现找两个数中较大的值。
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int n = a > b ? a : b;
printf("%d", n);
return 0;
}
4. 逻辑操作符:&&,||,!
逻辑操作符提供逻辑判断功能,用于构建更复杂的表达式,只要有下面三个运算符。
- !:逻辑反运算符(改变单个表达式的真假)
- &&:与运算符,就是并且的意思(两侧的表达式都为真则为真,否则为假)。
- | |:或运算符,就是或者的意思(两侧至少有一个表达式为真则为真,否则为假)。
4.1 逻辑取反运算符
比如,我们有一个变量较flag,如果flag为假,要做一个什么事情,就可以这样写代码:
int main()
{
int flag = 0;
if (!flag)
{
printf("do something\n");
}
return 0;
}
如果flag为真,!flag就是假,如果flag为假,!flag就是真,所以上述代码的意思是flag为假,执行if语句中的代码。
4.2 与运算符
&&就是与运算符,也就是并且的意思,&&是一个双目操作符,使用的方式是a&&b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一=一个是假的,则则整个表达式为假。
4.3 或运算符
||就是或运算符,也就是或者的意思,||也是一个双目操作符,使用的方式是a || b,||两边的表达式只要有一个是真的,整个表达式就是真的,两边的表达式都为假的时候,才为假。
4.4 练习:闰年的判断
输入一个年份year,判断year是否是闰年,闰年的判断规则:
1.能被4整除并且不能被100整除的是闰年
2.能被400整除的是闰年
int main()
{
int year = 0;
printf("请输入一个年份:");
scanf("%d", &year);
if ((year % 4 == 0 && year & 100 != 0) || (year % 400 == 0))
{
printf("是闰年\n");
}
else
{
printf("不是闰年\n");
}
return 0;
}
4.5 短路
c语言运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。
如果左边的表达式满足逻辑运算符的条件,就不用再对右边的表达式求值,这种情况称为“短路”。
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语句完成,如下:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 3 == 0)
printf("整除,余数为0\n");
else if (n % 3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
使用switch语句改写,就可以是这样:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch (n % 3)
{
case 0:
printf("整除,余数为0\n");
break;
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
}
return 0;
}
上述代码中,需要注意的点有:
1.case和后边的数字之间必须有空格
2.每一个case语句中的代码执行完成后,需要加上break,才能跳出这个switch语句。
5.2 switch语句中的break
前面代码中,如果去掉case语句中的break,测试一下会出现如下的情况:
这是因为switch语句也是分支效果的,只有在switch语句中使用break才能在跳出switch语句,如果某一个case语句的后边没有break语句,代码就会继续执行下去,有可能执行qitacase语句中的代码,直到遇到break语句或者switch语句结束。比如上面的代码就执行了case2中的语句,所以在switch语句中break语句是非常重要的,能实现真正的分支效果。
练习:输入一个1~7的数字,打印对应的星期几,参考代码:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期⼀\n");
break;
case 2:
printf("星期⼆\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
}
return 0;
}
如果需求变为:1.输入1~5,输入的是“工作日”,输入6~7,输入“休息日”,参考代码如下:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("⼯作⽇\n");
break;
case 6:
case 7:
printf("休息⽇\n");
break;
}
return 0;
}
所以,我们可以根据实际情况,在代码中衡量是否使用break,在哪里使用break,才能正确完成实际的需求。
5.3 switch语句中的default
在使用switch语句的时候,我们经常可能遇到一种情况,比如switch语句后的表达式中的值无法匹配代码中的case语句的时候,这时候要不就不做处理,要不就得在switch语句中加入default子句。
5.4 switch语句中的case和default的顺序问题
在switch语句中case子句和default子句没有顺序要求,只要顺序是满足实际需求就可以。不过一般是把default子句放在最后处理。
6. while循环
C语言中提供了三种循环语句,while就是其中的一种,在语法结构方面,while语句和if语句非常相似。
6.1 if语句和while语句的对比
if (表达式)
语句;
while (表达式)
语句; //如果循环体想包含更多的语句,可以加上⼤括号
写个简单代码对比
//代码1
#include <stdio.h>
int main()
{
if (1)
printf("hehe\n"); //if后边条件满⾜,打印⼀次hehe
return 0;
}
//代码2
#include <stdio.h>
int main()
{
while (1)
printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehe
return 0;
}
whlie可以实现循环效果
7. for循环
7.1 语法形式
for循环是三种循环中使用最多的,for循环的语法形式如下:
for (表达式1; 表达式2; 表达式3)
语句; //如果循环体想包含更多的语句,可以加上⼤括号
表达式1:用于循环变量的初始化
表达式2:用于循环结束条件的判断
表达式3:用于循环变量的调整
7.2 练习
计算1~100之间3的倍数的数字之和
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 1; i <= 100; i++)
{
if (i % 3 == 0)
sum += i;
}
printf("%d\n", sum);
return 0;
}
//⼩⼩的优化
//如果能直接产⽣3的倍数的数字就省去了多余的循环和判断
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 3; i <= 100; i += 3)
{
sum += i;
}
printf("%d\n", sum);
return 0;
}
8. do while循环
8.1 语法形式
在循环中do while语句使用最少,它的语法格式为
do
语句;
while (表达式);
while和for这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;而do while循环是先直接进入循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。
8.2 练习
输入一个正整数,计算这个整数是几位数?例如:输入1234 输出:4
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int cnt = 0;
do
{
cnt++;
n = n / 10;
} while (n);
printf("%d\n", cnt);
return 0;
}
这里并非必须使用do while语句,但这个代码比较适合使用do while循环,因为n即是0,也是1位数,是要统计位数的
9. break和continue语句
在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了break和continue两个关键字,就是应用到循环中的。
- break的作用是用于永久的终止循环,只要break被执行,直接就会跳出循环,继续往后执行。
- continue的作用是跳过本次循环continue后边的代码,在for循环和while循环中有所差异。
9.1 while循环中的break和continue
9.1.1 break举例
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break; //当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i + 1;
}
return 0;
}
执行结果:
打印1,2,3,4后,当i等于5的时候,循环到break的地方终止,不再打印,不再循环。所以break的作用就是终止循环,只要break被执行,break外的第一层循环就终止了。
9.1.2 continue举例
continue是继续的意思,在循环中的作用就是跳过本次循环中的continue后边的代码,继续进行下一次循环的判断。
把上面的代码中break换成continue:
#include <stdio.h>
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也是用于终止循环的,不管循环还需要循环多少次,只要执行了breek,循环就彻底终止:
#include <stdio.h>
int main()
{
int i = 1;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
运行结果:
break的作用是永久的终止循环,如果在某个条件发生的时候不想再继续循环的时候,就可以使用break来完成。
9.2.2 continue
把上面代码中的break换成continue:
#include <stdio.h>
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来实现。
9.3 do while循环中的break和continue
do while语句中的break和continue的作用和while循环中几乎一模一样。
本节完