一.if-else语句
1.if语句
语法形式如下所示:
cpp
if ( 表达式 )
语句;
上述语法的意思是:当表达式为真 ,则执行该语句;表达式为假,则不执行该语句。语句中0表示假,非0表示真。
题目练习:输入一个正整数n,判断n是否为奇数。
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 2 == 1)
cout << n << "是奇数" << endl;
return 0;
}
上述代码的具体解释:创建一个整型变量用于接收键盘输入的值,随后判断是否能被2整除,如果不能的话,打印是奇数。这次代码用到了if语句,用于判断表达式n % 2 == 1是否成立。
2.else语句
一个正整数不是奇数,那就是偶数了。将上面的题目转换以下。
题目:输入一个正整数n,如果n是奇数就打印奇数,是偶数就打印偶数。代码如下:
cpp
//语法形式
//if ( 表达式 )
// 语句1;
//else
// 语句2;
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 2 == 1)
cout << n << "是奇数" << endl;
else
cout << n << "是偶数" << endl;
return 0;
}
根据else语句的语法形式,当输入的数能被2整除时,利用else语句,将是偶数打印在屏幕上了。
3.嵌套if语句
在if-else语句中,else可以与另一个if语句连用,构成多重判断。
cpp
//形式1
if()
语句1;
else
{
if()
语句2;
else
语句3;
}
//形式2
if()
语句1;
else if()
语句2;
else
语句3;
练习:判断数字的正负
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin>>n;
if(n>0)
cout << "positive" << endl;
else if(n < 0)
cout << "negative" << endl;
else
cout << "zero" << endl;
return 0;
}
上述代码的具体解释:首先创建了一个整形变量,用于接收键盘输入的值。当输入的值大于0时,输出正数的对应英文符号;当输出的值小于0时,输出负数对应的英文符号;当输出的值等于0时,输出zero。整个代码利用了嵌套if-else语句,将三重判断逻辑清晰的展现了出来。
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n >= 0)
{
if (n > 0)
cout << "positive" << endl;
else if (n == 0)
cout << "zero" << endl;
}
else
cout << "negative" << endl;
return 0;
}
这次的题解是上次代码的另外一种形式,只不过将n>0嵌套在n>=0的内部,相关的语法规则和输出内容是没有改变的。
4.悬空else
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
cout << "hehe" << endl;
else
cout << "haha" << endl;
return 0;
}
上述代码的输出内容是什么?
初学者会认为上述代码会输出haha,但是当真正运行代码时,输出结果竟是什么也不输出。这是什么原因呢?
这就是悬空else问题,上面代码的排版,else和第一个if语句对应,让我们误认为else和第一个if语句是匹配的。其实并不是,实际上,这个else语句是和第二个if语句相对应的。如果第一个if语句不成立,嵌套在第一个if语句的if-else语句就没有机会执行了,最终代码什么都不会打印在屏幕上。将上述代码换成下方代码的排版就更容易理解了:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
cout << "hehe" << endl;
else
cout << "haha" << endl;
}
return 0;
}
或者如果想要else和第一个if语句匹配,就可以这样写代码:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
cout << "hehe" << endl;
}
else
{
cout << "haha" << endl;
}
return 0;
}
上面的代码例子告诉我们一个道理:写if-else语句时,不要吝啬大括号的书写。特别是嵌套if语句时,就可以体现出大括号的好处了。
5.练习:
(1)整除判断
cpp
#include <iostream>
using namespace std;
int main()
{
int m = 0;
int n = 0;
cin >> m >> n;
if(m % n == 0)
printf("YES\n");
else
printf("NO\n");
return 0;
}
上述代码首先创建了两个整型变量,分别接受键盘输入的值,当第一个输入的数可以被第二个输入的数整除则打印YES,否则就打印NO。
(2)比较大小
cpp
#include <iostream>
using namespace std;
int main()
{
long long x = 0;
long long y = 0;
cin >> x >> y;
if (x > y)
cout << ">" << endl;
else if (x == y)
cout << "=" << endl;
else
cout << "<" << endl;
return 0;
}
上述代码的作用是:判断输入的两个值谁大谁小。利用if-else语句,当x>y时,输出大于的相关信息。当x=y时,输出两数相等的相关信息;最后就是x<y的情况了,输出x<y的相关信息。
(3)输出绝对值
cpp
#include <iostream>
using namespace std;
int main()
{
float n = 0;
scanf("%f", &n);
if (n >= 0)
printf("%.2f\n", n);
else
printf("%.2f\n", -n);
return 0;
}
上述代码的作用是求出输入数字的绝对值并打印在屏幕上。代码首先创建了一个整型变量,用于接收键盘输入的值。随后利用if-else语句进行相应的判断。当输入数字大于0时,将输入的值原封不动的输出;当输入的值小于0,则进行取反后输出。
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
float n = 0;
scanf("%f", &n);
n = fabs(n);
printf("%.2f\n", n);
return 0;
}
上述代码是求绝对值的另一种方法,利用C++的库函数进行专门的调用求绝对值的函数,这样会更加的方便。
(4)奇数偶数的判断
cpp
//代码1
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 2)
cout << "odd" << endl;
else
cout << "even" << endl;
return 0;
}
上述代码是错误的示范,n有可能为负数,所以对1取模有可能是-1。所以代码进行进一步的修改。
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 2 == 1)
cout << "odd" << endl;
else if(n % 2 == -1)
cout << "odd" << endl;
else
cout << "even" << endl;
return 0;
}
二.关系操作符
1.关系操作符的介绍
|-----|---------------------------------------------|
| 运算符 | 描述 |
| > | 大于运算符,用于比较两个数值,如果左侧数值大于右侧数值,则返回1,否则返回0。 |
| < | 小于运算符,用于比较两个数值,如果左侧数值小于右侧数值,则返回1,否则返回0。 |
| >= | 大于等于运算符,用于比较两个数值,如果左侧数值大于等于右侧数值,则返回1,否则返回0。 |
| <= | 小于等于运算符,用于比较两个数值,如果左侧数值小于等于右侧数值,则返回1,否则返回0。 |
| == | 相等运算符,用于比较两个数值是否相等,如果相等,则返回1,否则返回0 |
| != | 不相等运算符,用于比较两个数值是否不等,如果不等,则返回1,否则返回0 |
(1)关系运算符的连用
另外需要注意避免的错误是:多个关系运算符不适合连用。
i < j < k
上面实例中,连续使用两个小于操作符。这是合法表达式,不会报错。但是表示的意思达不到我们想要的效果,即不是保证变量j的值在i和k之间。因为关系运算符是从左到右的计算,所以实际执行的是下面的表达式。
(i < j) < k
上面式子中,i<j返回0或1,所以最终是0或1与变量k进行比较。如果想要判断j的值是否在i,k之间,应该换成下面的写法:
i < j && j < k
(2)浮点数比较
在比较浮点数时,由于浮点数在计算机中是以有限精度表示的,也就是说有些浮点数在内存中其实无法精确保存,这可能导致浮点数比较中的一些精度误差问题。如果直接使用==来比较两个浮点数,很可能会由于这些微小的误差导致不准确的结果。
cpp
#include <iostream>
using namespace std;
int main()
{
double a = 0.1;
double b = 0.2;
double c = 0.3;
if (a + b == c)
cout << "a + b == c" << endl;
else
cout << "a + b != c" << endl;
return 0;
}

上述情况其实正是情理之中的,因为计算机在存储小数的时候会有些许的误差,两数相加后与第三数比较时,会造成误判。应该写成下方代码的形式:
cpp
#include <iostream>
using namespace std;
int main()
{
double a = 0.1;
double b = 0.2;
double c = 0.3;
if (fabs((a + b) - c) < 1e-9) // 1e-9 表⽰允许的误差范围
cout << "a + b 约等于 c" << endl;
else
cout << "a + b 不等于 c" << endl;
return 0;
}
上述代码利用fabs函数求出两数的差的绝对值,利用差小于可控误差这一内容来判断两小数是否相等。
2.练习
(1)不及格的学生
cpp
#include <iostream>
using namespace std;
int main()
{
int s1, s2, s3;
int c = 0;
cin >> s1 >> s2 >> s3;
if (s1 < 60)
c++;
if (s2 < 60)
c++;
if (s3 < 60)
c++;
if (c == 1)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
上述代码通过if-else语句,判断键盘输入的三门分数是否及格,不及格的话将计数器加1,从而做到统计不及格科目数的目的。
cpp
#include <iostream>
using namespace std;
int main()
{
int s1, s2, s3;
int c = 0;
cin >> s1 >> s2 >> s3;
if ((s1 < 60) + (s2 < 60) + (s2 < 60) == 1)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
将第一次的代码进行优化,因为一个关系操作符计算的结果,如果是真返回1;如果是假则返回0。所以这次代码的书写将三门成绩判断的结果相加,如果等于1就说明有一门成绩不合格。一定程度上简化了代码。
(2)等差数列末项计算
cpp
#include <iostream>
using namespace std;
int main()
{
int a1, a2, n;
cin >> a1 >> a2 >> n;
if (n == 1)
cout << a1 << endl;
else if (n == 2)
cout << a2 << endl;
else
cout << a2 + (n - 2) * (a2 - a1) << endl;
return 0;
}
上述代码的具体解释:首先创建三个变量,用于接收键盘输入的三个值。这三个值分别代表的是首项,第二项和项数。题目要求返回等差数列的末项,我们就需要分情况讨论。利用if-else语句,当项数为1时,直接返回首项的值;如果项数是2,直接返回第二项的值;如果不是上面的两种情况,那么带入数学公式,求出等差数列的末项,继而打印出末项的值。

三.条件操作符
1.操作符介绍
条件操作符也叫做三目操作符,三目的意思是,这个操作符有3个操作数。与双目操作符的目是一个道理和意思。具体形式如下:
exp1 ? exp2 : exp3
上述操作符的形式具体含义是:如果表达式1的真值为真时,返回表达式2的结果,否则返回表达式3的结果。上述操作符与if-else语句有些许相似,所以利用上述操作符可以简化if-else的代码长度。
练习:使用条件操作符简化下方代码的逻辑:
cpp
#include <iostream>
using namespace std;
//改造前:未使⽤条件操作符
int main()
{
int a = 0;
int b = 0;
cin >> a;
if (a > 5)
b = 3;
else
b = -3;
cout << b << endl;
return 0;
}
上述代码是没有用三目操作符的if-else语句的形式,代码的目的是:如果输入的数字大于5,则将3赋值给该变量;否则将-3赋值给该变量。下方代码是利用三目操作符简化的结果:
cpp
//改造后:使⽤了条件操作符
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
cin >> a >> b;
b = (a > 5 ? 3 : -3);
cout << b << endl;
return 0;
}
利用三目操作符,首先判断输入的变量是否大于5,如果该表达式为真就将3赋值给该变量;否则就将-3赋值给该变量。
2.练习
(1)最大值输出
cpp
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
int m = 0;
cin >> a >> b >> c;
m = (a > b ? a : b);
if (m < c)
m = c;
cout << m << endl;
return 0;
}
上述代码的目的是:判断输入的三个值中,谁是最大值。利用三目操作符先找出输入值的前两个的较大值。随后在较大值和第三个值之间找出最大值。即可满足题意。
三目操作符不仅仅可以像上方代码那样比较三个数的大小,在后续的学习中还有很多奇妙的用法。
(2)特殊计算
cpp
#include <iostream>
using namespace std;
int main()
{
long long x = 0;
long long y = 0;
long long z = 0;
cin >> x >> y;
if (y % x == 0)
z = x + y;
else
z = y - x;
cout << z << endl;
return 0;
}
//使⽤条件操作符
int main()
{
long long x = 0;
long long y = 0;
long long z = 0;
cin >> x >> y;
z = (y % x == 0 ? x + y : y - x);
cout << z << endl;
return 0;
}
上述代码给出了三目操作符写法和if-else语句两种写法。
第一种if-else写法,首先判断y是否能被x整除,能的话将两者之和赋值给z;否则将两者之差赋值给z。最后将z的值打印在屏幕上。
第二种通过三目操作符的写法,如果表达式1:y等否被x整除。为真,则将两者之和赋值给z;否则将两者之差赋值给z。最后同样将z的值打印在屏幕上。

(3)苹果和虫子
cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int m,t,s;
cin >> m >> t >> s;
if(t == 0)
{
cout << 0 << endl;
return 0;
}
if(s % t == 0)
cout << ((m - s / t) > 0 ? (m - s / t) : 0) << endl;
else
cout << ((m - s / t -1) > 0 ? (m - s / t - 1) : 0) << endl;
return 0;
}
上述代码的具体解释:首先判断例外情况,当时间t为0时,直接打印吃的苹果为0即可;接下来判断其余情况,当过去的时间可以被吃一个苹果的时间整除则直接整除,如果不能则进行-1操作。最后不要忘记判断吃的苹果数不会大于现有苹果数这一逻辑。
这个题目需要注意:t时间有可能为0,会被当作除数,而除数不可以为0。根据题目的数据,算出吃掉的苹果数可能比真实的苹果数要多,这样会算出负数,这也是错误的,最大就是将苹果吃完,吃的苹果数量不会比现有的苹果还多。
四.逻辑操作符
逻辑运算符号主要用于逻辑判断,用于构建更为复杂的表达式,逻辑操作符有以下三种形式:
|------|---------|--------------------------------------------|
| 符号 | 名称 | 功能 |
| ! | 逻辑取反操作符 | 改变单个表达式的真假状态。如果表达式为真,则结果为假;如果表达式为假,则结果为真。 |
| && | 逻辑与运算符 | 两侧的表达式都需要为真时,结果才为真。如果任何一个表达式为假,结果就为假。 |
| || | 逻辑或运算符 | 两侧的表达式中,只要有⼀个为真,结果就为真。只有当两个表达式都为假时,结果 才为假。 |
1.逻辑取反操作符

比如,我们有一个变量叫flag,如果flag为假时,就做某些事情,就可以将代码写成下方形式:
cpp
#include <iostream>
using namespace std;
int main()
{
int flag = 0;
if (!flag)
{
cout << "do something" << endl;
}
return 0;
}
如果flag为真,那么!flag就为假;如果flag为假,!flag就为真。所以要想让上述代码打印出上述字符串,就需要让flag为假。
2.逻辑与运算符

&&就是逻辑与运算符,这个运算符相当于离散数学且的概念。当两操作数的表达式都为真,总表达式才为真。否则总表达式都为假。下面给出判断季节为春季的代码演示:
cpp
int month = 0;
cin >> month;
if (month >= 3 && month <= 5)
{
cout << "春季" << endl;
}
上述代码利用了逻辑与运算符,当输入的月份满足大于等于三,并且满足小于等于5就可以在屏幕上打印春季的字样。这样看来逻辑与运算符,也可以简化代码的形式。不用再用繁琐的嵌套if语句了。
3.逻辑或运算符

上述图片展示的是逻辑或运算符的真值表,逻辑或运算符相当于离散数学的或。当两个操作数表达式有一个为真,则总的表达式为真;否则就为假。下面给出判断季节的代码演示:
cpp
int month = 0;
cin >> month;
if (month == 12 || month == 1 || month == 2)
{
cout << "冬季" << endl;
}
上述代码中利用了逻辑或运算符,当输入的值为12或者1或者2时,将在屏幕上打印冬季的字样。
4.短路
逻辑运算符号有一个共同的特点,它总是先对左边的表达式求值,在对右边的表达式求值,这个顺序导致了逻辑运算符会有短路的现象:如果左边表达式的值计算完成之后,总表达式的真假已经判断出来的情况下,就不会再去计算右侧表达式的值了。如下方代码:
cpp
if(month >= 3 && month 5)
上述表达式中涉及到逻辑与运算符,左操作数是month小于等于3。当输入的值不满足左侧表达式时,这时候就不会继续判断右侧表达式是否满足了,因为只判断了左侧表达式就已经得出了总表达式的真值情况。那我们说这样就是出现了短路现象。
cpp
if(month == 12 || month == 1 || month == 2)
上述表达式涉及到逻辑或运算符,当输入的值为12时,就不会继续向右侧判断表达式了。因为此时已经得出了整个表达式的真值了。所以类似于此的现象就叫做短路。
5.练习
(1)闰年的判断
cpp
//代码1
#include <iostream>
using namespace std;
int main()
{
int year = 0;
cin >> year;
if (year % 4 == 0 && year % 100 != 0)
cout << "1" << endl;
else if (year % 400 == 0)
cout << "1" << endl;
else
cout << "0" << endl;
return 0;
}
上述代码利用嵌套的if-else语句和逻辑运算符,判断年份是否为闰年。众所周知,闰年的判断应该为:能被4整除且可以被100整除或者能被400整除。只要满足前者两条件的一个就可以证明输入的年份是闰年。
cpp
//代码2
#include <iostream>
using namespace std;
int main()
{
int year = 0;
cin >> year;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
cout << "1" << endl;
else
cout << "0" << endl;
return 0;
}
上述代码利用极致的逻辑运算符极度的简化了代码,将嵌套的if-else语句简化了很多。
(2)晶晶赴会
cpp
#include <iostream>
using namespace std;
int main()
{
int d = 0;
cin >> d;
if (d == 1 || d == 3 || d == 5)
cout << "NO" << endl;
else
cout << "YES" << endl;
return 0;
}
上述代码是对逻辑运算符的简单应用,判断输入的数字是否为1 3 5的其中一个,如果是的话就打印NO ,否则打印YES。这里需要注意的是大小写不能输出错误,大小写会影响代码的AC。
(3)三角形判断
cpp
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
cin >> a >> b >> c;
if (a + b > c && a + c > b && b + c > a)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
上述代码的作用是:判断输入的三个值是否能够组成三角形。如果能的话就打印1,否则就打印0。这里的判断用到了逻辑运算符,利用了相关数学原理:两边之和大于第三边即可完成本题目。
(4)判断整除情况
cpp
//⽅法1 - 暴⼒法
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 3 == 0 && n % 5 == 0 && n % 7 == 0)
cout << "3 5 7" << endl;
else if (n % 3 == 0 && n % 5 == 0)
cout << "3 5" << endl;
else if (n % 3 == 0 && n % 7 == 0)
cout << "3 7" << endl;
else if (n % 5 == 0 && n % 7 == 0)
cout << "5 7" << endl;
else if (n % 3 == 0)
cout << "3" << endl;
else if (n % 5 == 0)
cout << "5" << endl;
else if (n % 7 == 0)
cout << "7" << endl;
else
cout << "n" << endl;
return 0;
}
上述代码通过极致的暴力解决了问题。首先输入一个值存入变量n中,随后逐个进行判断,通过多层if-else嵌套最终得出答案。
cpp
//⽅法2
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n % 3 == 0)
{
cout << 3 << " ";
}
if (n % 5 == 0)
{
cout << 5 << " ";
}
if (n % 7 == 0)
{
cout << 7 << " " << endl;
}
if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0)
cout << "n" << endl;
return 0;
}
上述代码通过逻辑非运算符简化了代码,首先判断输入的数额能否被3 5 7 整除,随后判断是否同时不满足该整除条件。最终输出相应的数字。完成本题目的解答。
(5)数的本质
cpp
#include <iostream>
using namespace std;
int main()
{
int x = 0;
cin >> x;
//同时满⾜的情况
if (x % 2 == 0 && (x > 4 && x <= 12))
cout << 1;
else
cout << 0;
//⾄少满⾜⼀种情况
if (x % 2 == 0 || (x > 4 && x <= 12))
cout << " " << 1;
else
cout << " " << 0;
//只满⾜⼀种情况
if ((x % 2 == 0) + (x > 4 && x <= 12) == 1)
cout << " " << 1;
else
cout << " " << 0;
//⼀种情况都不满⾜
if ((x % 2 == 0) + (x > 4 && x <= 12) == 0)
cout << " " << 1;
else
cout << " " << 0;
return 0;
}
上述代码首先创建了一个变量x,随后键盘接收的值存入变量x中,为接下来的判断做准备。当输入的值能被2整除并且处于2和12之间时,在屏幕上打印1;随后继续利用逻辑运算符判断,最后打印出对应的值。最后我们不难发现逻辑运算符会大大简化我们的代码形式,并且提高代码的可阅读性。
五.switch语句
除了if语句外,C/C++语言还提供了switch语句来实现分支结构。switch语句是一种特殊形式的if-else结构,用于判断条件有多个结果的情况。它把多重的if-else改成可读性更好的形式。
cpp
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
上面代码中,根据表达式不同的值,执行相应的case分支。如果找不到对应的情况,就执行defalut分支。这里需要注意的是:switch语句后面的表达式必须是整形表达式。case后面的值必须是整型常量表达式。
1.if和while语句的对比
练习1:输入任意一个整数值,计算除以三后的余数,如果用if语句完成,如下:
cpp
#include <stdio.h>
int main()
{
int n = 0;
cin >> n;
if (n % 3 == 0)
cout << "余数为0" << endl;
else if (n % 3 == 1)
cout << "余数是1" << endl;
else
cout << "余数是2" << endl;
return 0;
}
上述代码的目的是判断键盘输入的值除以三后的余数是几?结果分为三种情况,利用if-else语句分别打印余数对应情况的信息。如果将if-else语句改写为switch语句如下方代码:
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch (n % 3)
{
case 0:
cout << "余数为0" << endl;
case 1:
cout << "余数是1" << endl;
case 2:
cout << "余数是2" << endl;
}
return 0;
}
上述是switch语句的错误运用,可是为什么会这样呢?这就与接下来我们学习的break关键字有关了。当键盘输入6时,输出内容为以下图片:

2.switch语句的break关键字
switch语句分支语句,在switch语句中,case语句决定了分支的入口,当表达式满足对应的情况时,就会进入相应的case语句。而break是决定分支出口的。当case语句执行完毕时,如果没遇到break语句的话,代码就会继续向下执行。根据上面的代码,我们需要在每个case语句执行完毕后加上break语句,就可以得到我们想要的效果。
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch (n % 3)
{
case 0:
cout << "整除,余数为0" << endl;
break;
case 1:
cout << "余数是1" << endl;
break;
case 2:
cout << "余数是2" << endl;
break;
}
return 0;
}

练习2.输入1-7的数字,打印对应的星期内容。
cpp
#include <cstdio>
int main()
{
int day = 0;
cin >> day;
switch (day)
{
case 1:
cout << "Monday" << endl;
break;
case 2: cout << "Tuesday" << endl;
break;
case 3:
cout << "Wednesday" << endl;
break;
case 4:
cout << "Thursday" << endl;
break;
case 5:
cout << "Friday" << endl;
break;
case 6:
cout << "Saturday" << endl;
break;
case 7:
cout << "Sunday" << endl;
break;
}
return 0;
}
上述代码通过运用switch语句,判断输入的值为1-7的哪一个,随后打印对应星期的英文。这次每个case后面都有break,防止了代码进入其他case语句中。如果将题目发生些许的变化呢?输入1-5打印周内;输入6-7打印周末。那么代码将会成为下面的样子:
cpp
#include <cstdio>
int main()
{
int day = 0;
cin >> day;
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
cout << "Workday" << endl;
break;
case 6:
case 7:
cout << "Weekend" << endl;
break;
}
return 0;
}
上述代码中,我们知道case语句具有穿透的性质,例如上述代码,当输入的值处于1-5之间时代码会打印周内,随后跳出整个switch语句。
3.switch语句的default关键字
在使用switch语句的时候,我们经常可能遇到一种情况:switch后的表达式中的值无法匹配代码的case语句,这时候就需要额外的情况语句进行代码的兜底,提高代码的健壮性。于是default关键字就出现了。
cpp
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
switch语句后面的表达式不是结果1和结果2时,就会执行default子句。具体解释请看下方代码的演示:
cpp
#include <cstdio>
int main()
{
int day = 0;
cin >> day;
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
cout << "Workday" << endl;
break;
case 6:
case 7:
cout << "Weekend" << endl;
break;
default:
cout << "input error!" << endl;
break;
}
return 0;
}
上述代码的具体解释:创建一个整型变量用于接收键盘输入的值,随后利用switch语句进行输入值的判断,当输入的值均不能与case后的结果匹配时,就打印default自句的内容。
4.case和default语句的顺序问题
在switch语句中case子句和default子句有要求顺序吗?
在switch语句中,case语句和default语句没有顺序要求,只要代码的顺序满足实际需求就可以,只不过大多程序员习惯将default语句放在switch语句的最后。
5.练习
(1)四季
cpp
//版本1
//输⼊的⽅式使⽤C语⾔的scanf的⽅式
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int year = 0, month = 0;
scanf("%4d%2d", &year, &month);
switch (month)
{
case 3:
case 4:
case 5:
cout << "spring" << endl;
break;
case 6:
case 7:
case 8:
cout << "summer" << endl;
break;
case 9:
case 10:
case 11:
cout << "autumn" << endl;
break;
case 12:
case 1:
case 2:
cout << "winter" << endl;
break;
}
return 0;
}
上述代码的具体解释:因为键盘会输入一个6位整形数字,前四个数字表示的是年份,后两个表示的是月份。所以scanf函数就需要如上写法。随后利用switch语句判断输入的月份的季节。最后进行对应的输出。
cpp
//版本2
//输⼊的⽅式使⽤C++中的cin
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int n = 0, month = 0;
cin >> n; //⼀次性读取到的是6位整数
month = n % 100; //获取最低2位,就是⽉份
switch (month)
{
case 3:
case 4:
case 5:
cout << "spring" << endl;
break;
case 6:
case 7:
case 8:
cout << "summer" << endl;
break;
case 9:
case 10:
case 11:
cout << "autumn" << endl;
break;
case 12:
case 1:
case 2:
cout << "winter" << endl;
break;
}
return 0;
}
上述代码用的是C++的cin函数,所以需要提前获取输入数的后两位,故而进行对100取模,得到的就是该年份的月份。之后利用switch语句对月份输出对应的季节即可。上面两种方法都是switch语句的方法,其实在判断范围是否满足的问题时,if-else语句反而更加方便,下面给出相关代码:
cpp
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int year = 0, month = 0;
scanf("%4d%2d", &year, &month);
if (month >= 3 && month <= 5)
cout << "spring" << endl;
else if (month >= 6 && month <= 8)
cout << "summer" << endl;
else if (month >= 9 && month <= 11)
cout << "autumn" << endl;
else
cout << "winter" << endl; //因为 n 的输⼊范围就是1~12
return 0;
}
(2)简单计算器
cpp
#include <iostream>
using namespace std;
int main()
{
int n1, n2;
char c;
cin >> n1 >> n2 >> c;
if (n2 == 0)
cout << "Divided by zero!" << endl;
else
{
switch (c)
{
case '+':
cout << n1 + n2 << endl;
break;
case '-':
cout << n1 - n2 << endl;
break;
case '*':
cout << n1 * n2 << endl;
break;
case '/':
cout << n1 / n2 << endl;
break;
default:
cout << "Invalid operator!" << endl;
break;
}
}
return 0;
}
上述代码实现了一个简单的计算器,下面来详细解释一下实现过程:首先创建两个整型变量和一个字符变量,用于接收键盘输入的三个值。前两个输入当作计算的两个操作数,第三个输入当作计算的方式。随后利用switch语句根据不同的计算方式返回不同的结果。其实函数更方便实现,但是现在我门还没有学。这就是用switch完成了创建一个类函数的操作。
六.while循环
C/C++中,循环有三种形式:for循环,while循环和do-while循环,下面我们先讲解下while循环:
1.语法形式
while语句和if语句的语法形式大致相同,但是while是用来实现循环语句的,而if语句是用来实现条件判断语句的。
cpp
//形式1
while ( 表达式 )
语句;
if(表达式)
语句;
//形式2
//如果循环体想包含更多的语句,需要加上
⼤括号
while ( 表达式 )
{
语句1;
语句2;
...
}
2.实践
题目:利用while循环在屏幕上打印1-10的值
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i <= 10)
{
cout << i << " ";
i = i+1;
}
return 0;
}

3.练习
(1)反向输出
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
while (n)
{
cout << n % 10;
n /= 10;
}
return 0;
}
上述代码的作用是:将输入的数进行反向输出。代码的具体解释:键盘输入的值利用while循环不断进行对10取模得到最低位的数,得到之后将该数除以10去掉最低位数,为下一次取最后一位数做准备。
(2)数位之和
cpp
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int ret = 0;
while (n)
{
ret += n % 10;
n /= 10;
}
cout << ret << endl;
return 0;
}
上述代码的具体解释:这个题目的代码演示是上一个题目的拓展,只需要多创建一个变量用于存储数位之和即可。每次进行每位数的相加输出在屏幕上便是数位之和。
(3)求和1
cpp
//参考代码1
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int i = 1;
long long sum = 0;
while (i <= n)
{
sum += i;
i++;
}
cout << sum << endl;
return 0;
}
上述代码的具体解释:利用while循环求出前n个数的总和。代码的具体解释:创建两个变量,一个为求和的末尾数字,另一个存储求和之后的结果。最终利用累计求和打印出前n项的结果。
cpp
//参考代码2
#include <iostream>
using namespace std;
int main()
{
long long n = 0;
cin >> n;
long long sum = (1 + n) * n / 2;
cout << sum << endl;
return 0;
}
上述代码的具体解释:利用数学的方法,将前n项的和用含n的式子表示出来,从而直接进行计算,计算后进行打印数据即可。
(4)含k个3的数
cpp
#include <iostream>
using namespace std;
int main()
{
long long m,k;
int c = 0;
cin >> m >> k;
while (m)
{
if (m % 10 == 3)
c++;
m /= 10;
}
if(c == k)
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
本题目的目的是:判断输入的两个数是否有3个三。代码的具体解释:首先获取输入的两个数的每一位数字,只要该位数字等于3就将计数器+1。最后判断计数器的值是否等于3,等于的话就打印YES,不是的话就打印NO。
(5)角谷猜想
cpp
//C的⽅式输出
#include <cstdio>
int main()
{
long long n = 0;
scanf("%lld", &n);
while (n != 1)
{
if (n % 2 == 1)
printf("%lld*3+1=%lld\n", n, n * 3 + 1), n = n * 3 + 1;
else
printf("%lld/2=%lld\n", n, n / 2), n /= 2;
}
printf("End\n");
return 0;
}
上述代码通过C语言的输入输出函数进行规定形式的输出,首先判断这个数是奇数还是偶数,如果该数是奇数就将该数乘3加上1,如果该数是偶数就将其除以2。以此类推,利用while循环实现上述问题。最终就会得到结果为1,这就是角谷猜想。
cpp
//C++⽅式输出
#include <iostream>
using namespace std;
int main()
{
long long n = 0;
cin >> n;
while (n != 1)
{
if (n % 2 == 1)
{
cout << n << "*3+1=" << n * 3 + 1 << endl;
n = n * 3 + 1;
}
else
{
cout << n << "/2=" << n / 2 << endl;
n /= 2;
}
}
cout << "End" << endl;
return 0;
}
上述代码不同于C语言的输入输出函数那样简单,在规定输出格式的情况下,建议使用C语言的输入输出函数。
(6)计算多项式的值
cpp
#include <iostream>
using namespace std;
int main()
{
double x;
int n;
double r = 1;
double tmp = 1;
cin >> x >> n;
while (n--)
{
tmp *= x;
r += tmp;
}
printf("%.2lf\n", r);
return 0;
}
上述代码想要求出多项式的值,首先创建两个变量,一个表示底数的x,另一个表示指数的n。利用循环,指数为n的另一种解释是将x与自己相乘,循环n次,最后将每次循环后的结果累加即可。
七.for循环
1.语法形式
for循环是三种循环形式中用的最多的,也是最重要的,下面是for循环的具体语法形式:
cpp
//形式1
for(表达式1; 表达式2; 表达式3)
语句;
//形式2
//如果循环体想包含更多的语句,可以加上
⼤括号
for(表达式1; 表达式2; 表达式3)
{
语句1;
语句2;
...
}
- 表达式1用来做循环变量的初始化。
- 表达式2用于循环结束条件的判断,当条件不满足时,就跳出循环。
- 表达式3用于循环变量的调整。
2.执行流程
首先执行表达式1,进行循环变量的初始化,接下来是表达式2的判断部分,如果满足条件就进入循环,否则不执行该循环语句;一次循环执行完之后执行表达式3,进行循环变量的调整,调整之后若还满足表达式2,则继续执行循环,否则跳出循环。整个循环过程中,表达式1初始化部分只执行一次,剩下就是表达式2,循环体,表达式3在循环。这次讲解的顺序与下来要学习的break和continue关键字有关。
3.实践
练习:使用for循环打印1-10的值
cpp
//代码1
#include <iostream>
using namespace std;
int main()
{
int i = 0;
for(i = 1; i <= 10; i++)
{
cout << i << " ";
}
return 0;
}
上述代码严格按照学习的for语句语法结构书写的代码,其实我们也可以将循环变量的初始化完全放在for关键字的括号内部,提高代码的阅读性和紧凑型。
cpp
//代码2
#include <iostream>
using namespace std;
int main()
{
for(int i = 1; i <= 10; i++)
{
cout << i << " ";
}
return 0;
}

4.while语句和for语句的对比


for循环和while循环在实现循环的过程中都有循环变量的初始化,判断循环条件,调整循环变量三部分,但是for循环的三个部分非常集中,便于代码的维护,而代码的循环体较多的时候,while循环的三个部分就会变得比较分散,所以for循环在形式上更优一点。
5.练习
(1)求和2
题目:计算1-100的三的倍数的数字之和
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 0;
int sum = 0;
for(i = 1; i <= 100; i++)
{
if(i % 3 == 0)
{
sum += i;
}
}
cout << sum << endl;
return 0;
}
上述代码的具体解释:首先遍历1-100的所有数字,之后判断每个数字谁是3的倍数,如果是3的倍数就相加,之后得到的和就是此题的结果。但是这种求解方法并不是最简单的,下面请看下方代码:
cpp
//⼩小的优化
//如果能直接产⽣3的倍数的数字就省去了多余的循环和判断
#include <iostream>
using namespace std;
int main()
{
int i = 0;
int sum = 0;
for(i = 3; i <= 100; i += 3)
{
sum += i;
}
cout << sum << endl;
return 0;
}
上述代码的for循环,直接产生了所有在1-100的3的倍数,直接相加所有的数即可,这样的代码比上一种代码的循环次数降低了不少,优化了代码的运行效率。
(2)求平均年龄
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
int t = 0;
int sum = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> t;
sum += t;
}
printf("%.2lf\n", sum * 1.0 / n);
return 0;
}
想要求年龄的和,先要得出循环的三部分的情况,第一部分循环变量的初始化,第二部分判断条件,当循环小于人数的时候进入循环,这样求出的年龄和就是在人数范围之内的。第三部分就是随着人数自增1即可。最后在循环内部将所有的年龄进行累加。最后将累加的结果除以人数就得到了年龄的平均数。
(3)奥运奖牌计数
cpp
#include <iostream>
using namespace std;
int n, p1, p2, p3, sum, a, b, c;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a >> b >> c;
p1 += a;
p2 += b;
p3 += c;
}
sum = p1 + p2 + p3;
cout << p1 << " " << p2 << " " << p3 << " "<< sum << endl;
return 0;
}
本题目涉及到多次输入,所以就需要将输入函数置于循环内部,将天数作为循环的次数,每一次循环求出当天的获奖数,最终将所有天数的奖牌数进行统计输出即可。
(4)鸡尾酒疗法
cpp
#include <iostream>
using namespace std;
int n;
float x,y;
int a, b;
int main()
{
cin >> n;
cin >> a >> b;
x = b * 1.0 / a;
for(int i = 0; i < n - 1; i++)
{
cin >> a >> b;
y = b * 1.0 / a;
if (y - x > 0.05)
cout << "better" << endl;
else if (x - y > 0.05)
cout << "worse" << endl;
else
cout<< "same" << endl;
}
return 0;
}
上述题目是循环和条件判断语句的综合。首先已知需要输入n行相同类型的内容,所以我们这里用到循环,且循环次数为输入的行数。每次输入之后进行相应的判断,紧接着就输出对应的内容。之后进入下一次循环以此类推。最后就可以得出每次的疗效情况。 ·
cpp
#include <iostream>
#include <cmath>
using namespace std;
int n;
double x, y;
int p;
int main()
{
cin >> n;
double t = 0;
for (int i = 0; i < n; i++)
{
cin >> x >> y >> p;
float dis = sqrt(x * x + y * y);
t += p * 1 + dis / 50 + p * 0.5 + dis / 50;
}
cout << (int)ceil(t) << endl;
return 0;
}
本题目类似于上一题,针对n行输入均需要用到循环,循环次数就是需要输入的行数,进入循环之后,紧接着就进行数学上的计算。每次循环以此类推。最终就可以得到每次输入对应的救援时间。
(6)计算分数加减表达式的值
cpp
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int i = 0;
float sum = 0;
int flag = 1;
for (i = 1; i <= n; i++)
{
sum += 1.0 / i * flag;
flag = -flag;
}
printf("%.4f\n", sum);
return 0;
}
本题目告诉了一个规则的多项式,要求出最终的结果。代码首先创建了变量用于接收键盘输入的值,输入的值就是循环的次数,即求出该项之前的结果。所以需要用到循环,循环次数就是输入的值。每次进入循环都进行结果的求解,结束循环后进行结果的打印。
(7)求分数系列和
cpp
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int n = 0;
cin >> n;
float sum = 0;
float q = 2;
float p = 1;
for (int i = 0; i < n; i++)
{
sum += q / p;
q = q + p; //计算新的q
p = q - p; //计算新的p
}
printf("%.4f\n", sum);
return 0;
}
本题目依然是求出有规律的多项式的前n项的结果,利用循环进行多次求解,每次循环将本次的前n项求出来,以此类推,最终就得到了前n项的结果。
八.do-while循环
1.语法形式
在循环语句的三种形式中,do-while循环是用的最少的一个,下面是它的语法结果:
cpp
//形式1
do
语句;
while( 表达式 );
//形式2
do
{
语句1;
语句2;
...
}
while( 表达式 );
while和for循环都是先判断,条件如果满足就进入循环,执行循环语句;如果不满足就跳出循环。而do-while循环却不是这样的逻辑,它是先进入循环体,执行循环语句,然后执行while括号的判断语句,如果条件满足就继续进入循环体,若不满足就只执行这一次就跳出循环不再继续循环。
2.执行流程
在do-while循环语句中,首先执行do后面的循环语句,执行完之后就去执行while后面的判断语句。如果判断语句的表达式成立就继续执行下一次循环;否则循环终止,只执行了一次循环就跳出循环,不再执行循环体的语句。所以该循环语句的循环体不论何种情况都会被执行一次,这就是该循环语句特殊的情况。
3.实践
题目:利用所学的循环语句在屏幕上打印1-10的数字
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 1;
do
{
cout << i << " ";
i = i + 1;
} while (i <= 10);
return 0;
}

4.练习
(1)统计正整数的位数
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int cnt = 0;
do
{
n = n / 10;
cnt++;
} while (n);
cout << cnt << endl;
return 0;
}
代码首先需要输入一个正整数,因为这个正整数起码有一位,所以用do-while循环直接将统计位数的变量自增1,随后将输入的值每次循环都除以10,便于判断输入的值的位数。循环判断条件为该数不为0就可以进入循环,当该数变为0时,循环终止。
(2)弹跳球高度的计算
cpp
#include <iostream>
using namespace std;
int main()
{
double h = 0;
cin >> h;
int i = 1;
double total = h;
do
{
h /= 2;
total += h * 2;
i++;
} while (i <= 9);
cout << total << endl;
cout << h / 2 << endl;
return 0;
}

上述代码利用do-while循环,首先计算了第一次小球的弹跳高度,随后每次弹跳进入一次循环,每次循环求出对应的高度,顺便求出它们的和。之后总体进行输出打印即可。
九.break和continue语句
1.break和continue语句的介绍
在循环执行的过程中,如果某些情况发生,需要提前结束循环,这是非常常见的现象。C++语言提供了break和continue两个关键字,可以应用到循环中进行循环的不同类型的终止。
- break的作用是:永久的终止循环,只要break语句被执行,就会立刻跳出整个循环,继续执行后面的语句。
- continue的作用是:跳过本次循环continue后面的代码,接下来执行下一次循环。这里需要注意的是在for和while循环中,执行顺序是有所差异的。
2.break语句举例
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
{
break; //当i等于5后,就执⾏break,循环就终⽌了
}
cout << i << " ";
i = i + 1;
}
return 0;
}

上述循环正常执行,当i等于5时,循环在break语句的地方跳出循环,不再打印,不再循环。直接执行return 0语句。所以break语句的作用就是永久的终止循环。只要break语句被执行,break外的第一层循环就终止了。
3.continue语句举例
continue语句的意思是在循环中跳过本次continue后面的代码,继续执行下一次循环的代码语句。上面的代码语句,将break语句换成continue语句会是什么结果呢?请看下方的代码:
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;
cout << i << " ";
i = i + 1;
}
return 0;
}
上述代码就可以分析出来continue语句可以帮我们跳过某一次循环continue后的代码,直接执行下一次循环部分,进行下一次的循环判断,如果循环的调整位置是在continue语句的后面就会造成代码的死循环。但是在for循环语句加入continue语句就是下面的景象了:
cpp
#include <iostream>
using namespace std;
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
cout << i << " ";
}
return 0;
}
上述代码的输出结果为:1 2 3 4 6 7 8 9 10
原因是:在for循环中,continue跳过本次循环中continue后面的代码,接下来执行的是i++的操作,在这里循环变量得到了调整,就没有造成死循环,所以continue语句在for循环和while循环中略微有着些许的差异。这里需要额外的注意这个问题。
4.练习
题目:质因数分解
cpp
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int i = 0;
for (i = 2; i < n; i++)
{
if (n % i == 0)
{
cout << n / i << endl;
break;
}
}
return 0;
}
上述代码的具体解释:代码的目的是找出该数的最大质因数。代码首先创建了一个变量,用于接收键盘输入的数,用于接下来的因式分解。因式分解需要遍历从2到这个数字的所有值,将能被该数整除的留下来,将输入数除以该数就是输入数的最大质因数,最终将所求书予以输出即可。
十.循环嵌套
1.循环嵌套的使用
题目:写一个代码打印出标准的九九乘法表,如下图所示:
九九乘法表是分为九行的,第一行打印一项,第二行打印两项,第三行打印三项,以此类推......打印九行需要用9次循环解决,每次循环需要打印成列数乘行数的形式。认真观察就可以发现每次打印的内容是有规律的。将外层循环的循环变量设置为行数,那么内层循环就应该设置成列数。每一次打印的内容就是行数乘列数的表达式。但是这里还需要注意的是打印出来的形式应该一一对齐,结果是两位数需要对齐,一位数的情况下需要右对齐。
cpp
#include <cstdio>
int main()
{
for (int i = 1; i < 10; i++)
{
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%2d ", j, i, i * j);
}
printf("\n");
}
return 0;
}
上述代码用到了双层循环控制九九乘法表的打印,以行为外层循环的循环变量;以列为内层循环的循环变量。每次打印行数乘列数的表达式。每次打印还不忘了使用格式控制符将输出内容对齐。