题目描述与分析
题目描述:
计算a+b,但输入方式有所改变。
输入描述:
第一行是一个整数N,表示后面会有N行a和b,通过空格隔开。
输出描述:
对于输入的每对a和b,你需要在相应的行输出a、b的和。
如第二对a和b,对应的和也输出在第二行。
输入示例:
2
2 4
9 21
输出示例:
6
30
本题仍然是计算a+b,但是我们要通过输入一个整数n来控制输入a,b的次数。既然是持续性的输入,说明在循环做输入n这个操作,那我们就需要使用到上一节中使用的while
连续输入n的代码如下:
// 多组数据,需要处理多次,使用while循环解决
while(cin >> n) {
}
一、for循环
之前学过while代表循环,怎么控制循环的次数呢?现实中,我们想要把一件事情做n次,比如数n只羊,就是说第一只羊,第二只羊,第n只羊,这样数,那在编程中是同样的逻辑,只不过这次我们使用的是for循环
for语句的语法格式是:
for(初始化语句;条件判断;操作) {
// 代码块
}
初次接触,或许不是很好理解,让我们使用计数的例子来类比,假设我们从1数到100
初始化语句:我们计数通常从1开始,也就是说,我们最开始初始化了一个值1
条件:判断值是否小于100,如果小于100,说明我们还没有计数完,需要继续计数,如果等于100,说明已经计数完毕,则结束计数
操作:如果本次计数值小于100,将值加1
重复步骤二,再次判断值是否小于100
重复步骤三,计数值再加1
根据上面的表述,我们可以将之转换为for语言的逻辑
for(初始化值为1;判断是否小于100;计数值+1) {
// 循环体代码
}
不过编程中初始化值一般都是从0开始,所以想要将循环体执行n次,C++的代码如下:
// int i = 0表示初始化值为0
// i < n用于判断,从0到n-1, 代码执行了n次,当i = n时退出循环
// i++表示i的值加1
for(int i = 0; i < n; i++) {
}
每次循环,都需要接收输入的a和b,并根据a和b计算出结果,这个代码和上一题的类似,就不再赘述,代码如下:
for(int i = 0; i < n; i++) {
cin >> a >> b; // 接收 a和b的输入
cout << a + b << endl; // 输出结果并换行
}
我们再来看一遍代码的执行流程:
初始化语句int i = 0, 循环开始时会执行一次初始化语句,这里表示初始化一个变量的值为0
条件判断i < n, 执行完初始化语句之后会进行条件判断,这里将i当前的值和n进行对比,想要让循环代码体执行n次,所需要计数的次数应该是0~n-1, 当还没有数到n时,则执行循环体的代码,当数到n时,n < n显然是错误的,就退出了循环,循环终止。
当还没有数到n的时候,也就是i < n的条件为真,执行循环体,循环体的含义是输入a和b并输出两者的和
循环体执行结束后,会执行i++, 表示当前的i值不符合条件,让变量i的值加1,进行下一轮判断
重复步骤二、步骤三和步骤四
完整代码如下:
#include<iostream>
using namespace std;
int main() {
// 定义变量n接收输入的次数,定义a和b接收输入的两个值
int n, a, b;
// 使用while循环接收持续输入的n
while (cin >> n) {
// 使用for循环执行n次的输入和输出
for(int i = 0; i < n; i++) {
// 键盘上输入a和b的值
cin >> a >> b;
// 屏幕上输出a和b的值
cout << a + b << endl;
}
}
}
二、++和–
刚才我们使用了i++表示计数值i的数值+1,实际上除了i++,还有++i,它们之间有什么区别呢?
++i 是前缀递增操作符,所谓前缀递增是指,它会先将变量增加 1,然后返回增加后的值,再将返回增加后的值参与别的运算
比如下面的代码:
int i = 99;
int result = ++i;
result的值是99还是100呢?答案是100。
++i会先从原来的99自增加到100,然后将增加后的值赋值给变量result,所以result的值就是100
i++ 是后缀递增操作符,它会先返回变量的当前值,然后再将变量增加 1。
int i = 99;
int result = i++;
这里result的值就是99了,它会先将i原来的值赋值给result, 所以result的值就是99, 然后i再执行自增操作,i的值增加为100。
总结来说,就是++i和i++的执行顺序不一样,前者是先自增后运算,后者是先运算后自增, 如果你想在表达式中使用变量的递增后的值,你可以使用 ++i。如果你想在表达式中使用变量的当前值,然后再将其递增,你可以使用 i++。
除了自增之外,C++还提供递减的运算,i–和–i , 都是用来减少一个整数变量的值的操作, 它们之间的区别和递增一样,前缀递减会在修改变量的值后返回修改后的值,而后缀递减会在返回变量的当前值后再进行减少操作
int i = 100;
int result = --i; // i 先减少为 99,然后赋值给 result
// 现在 i = 99, result = 99
int i = 100;
int result = i--; // 先赋值给 result,然后 i 减少为 99
// 现在 i = 99, result = 100
三、while循环重讲
上面问题采用for循环解决,可不可以用while循环来解决呢?
我们先来回顾上一节中学到的while基本语法:
while(条件) {
// 当条件为真时,就会一直执行
}
与上面的for循环对比就会发现,while只有条件判断,而没有初始化语句和操作语句,所以要在while结构之外进行书写。
所以按照for循环的逻辑,我们可以这样写代码:
while(cin >> n) {
// 提前初始化变量i
var i = 0;
// 条件判断, 判断 i是否小于n
while(i < n) {
cin >> a >> b;
cout << a + b << endl;
// 循环控制
i++;
}
}
这样这个循环才算是完整的,但是这样做引入了无关变量i, 又加了一个循环控制语句
由于我们先定义了变量n, 在输入N的时候,已经为这个变量n赋值了,相当于循环的次数已经被初始化了,想要让代码执行n次,我们可以“倒着数”,从n数到1,每次让n-1, 当n为0的时候退出循环,这样代码也执行了n次。
使用while的代码如下:
while (n--) {
cin >> a >> b;
cout << a + b << endl;
}
想一想,为什么是n–,而不是–n呢?
如果是while(–n),则计算n的值,再进行条件判断,此时n的值已经是n-1了,从n-1到1, 循环只执行了n-1次,而如果是while(n–) 可以控制这个循环只执行n次,当n为0的时候就终止了。
另外还有更重要的一点是,当判断语句为 while(–n),一旦n 初始为0 的话,此时while就会陷入死循环,因为只有0才会转换成false, 所以–n之后n会变成负数,while(负数) 会一直循环下去,
完整的代码如下:
#include<iostream>
using namespace std;
int main() {
int n, a, b;
// 使用while循环接收持续输入的n
while (cin >> n) {
// 使用while循环控制代码执行n次,当n为0的时候,结束循环
while (n--) {
cin >> a >> b;
cout << a + b << endl;
}
}
}
四、延伸
1.do while
其实除了for循环和while循环之外,还有一种循环结构,叫做do while, 它和 while 循环有些类似, 使用方法如下:
do {
// 循环体(代码块)
} while (条件判断);
do while循环会先去执行循环体内的代码块,然后再检查条件判断,如果条件判断为真,则继续执行下一次循环迭代;如果 条件判断为假,则终止循环,这意味着,无论条件的值如何,我们都至少执行一次循环。
int sum = 0;
int i = 11;
// 先去执行一次循环体中的代码,再去判断条件要不要执行
do {
sum = sum + i; // 将 sum + i的值赋值给sum
i++; // i的值自增
} while (i <= 10);
在这个例子中,虽然不满足于i < =10的条件,但是仍然会执行一次循环体中的代码。
2.数据类型转换
在上节中,我们提到了几种常见的数据类型,但是在某些情况下,可能会发生数据类型的转换,比如在while(条件判断)循环中,条件判断通常是一个布尔值,即true表示真,false表示假,但是假设我们给定的是一个整数类型的值,编译器会帮助我们进行数据类型转换,将之转换成布尔值,如果整数的值为0,则条件的值为false, 其他非0的数都会转换成true。