声明一个变量,意味着为该变量内容确定一个内存位置。那么,答案是,是的。首先考虑下面的代码段。
int i = 0;
int j = 0;
int k = 0;
这是三条语句,可以写成一条语句,如:
int i = 0, j = 0, k = 0;
有一个数据类型;表达式用逗号隔开。一条语句以一个分号结束。这里在一条语句中声明了多个变量。
现在,考虑一下下面的递增语句。
int i++;
int j++;
int k++;
这三条语句可以用一条语句代替,如下所示:
int i++, j++, k++;
这里,一个语句中有三个表达式,用于一个数据类型。
还可以考虑以下三个条件语句。
i < 10;
j < 10;
k < 10;
这三条语句,可以用一条语句代替,如下所示。
i < 10 && j < 10 && k < 10;
在这里,三个语句被合并成一个特殊形式的表达式。这些表达式不像上面的情况那样用逗号隔开,而是用逻辑AND组合。
这篇文章解释了如何在for-loop中声明和使用多个变量,并有规则的对应关系。用非常简单的例子来说明。
文章内容
一维for-loop
while循环
一个显示从0到9的数字的while-loop,如以下程序。
#include <iostream>
using namespace std;
int main()
{
int i=0;
while (i < 10) {
cout << i << endl;
i++;
}
return 0;
}
程序中的第一行包括cout对象的iostream库。程序中的下一行是一个声明。它确保所使用的任何名称都是来自C++标准库,除非另有说明。
在main()函数中,有一个初始化语句,为整数,i=0。然后是while-loop,它考虑了初始化语句。while条件是(i<10),只要i小于10(永远不等于10),while-loop主体中的cout iostream对象就会显示i的值。while-loop中的下一条语句会增加i(给i的值加1)。
输出结果如下,但是是垂直显示的。
0 1 2 3 4 5 6 7 8 9
一维for-loop
上面main()函数中的代码,在下面的程序中被复制为for-loop。
#include <iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
return 0;
}
输出结果与上述情况相同。上述代码的初始化语句现在是for-loop括号中的第一条语句,后面是一个分号。上述代码的while条件现在是for-loop括号中的第二条语句,后面是分号。对于前面的代码,while-loop主体中的增量语句现在是for-loop括号中的第三个语句。它后面没有分号,因为它是括号中的最后一条语句。for-loop中唯一的语句是显示i的值。
二维for-loop
嵌套while-loop
上面的一维for-loop显示了一列,每个单元格都有一个数字,即i的值。下面的程序说明了这一点。
#include <iostream>
using namespace std;
int main()
{
int i=0;
while (i < 5) {
int j=0;
while (j < 5) {
cout << j << ' ';
j++;
}
cout << endl;
i++;
}
return 0;
}
输出结果是:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
i变量决定了行的数量。j变量决定了列。在这段代码中,i和j的最大值都是4。不打印i的值。对于每一个j的值,j的值被水平打印。j被递增以水平打印每一行的下一个值。
有两个初始化语句:一个用于i,一个用于j,都初始化为零。j的初始化语句在外循环中。这样,每行(每条水平线)j都被重新初始化。这样,j可以为每一行产生从0到4的数字。i的值永远不会被打印出来,它只表示行号。i在嵌套循环的外面和下面被递增,i被递增的目的是为了下一个行。
嵌套for-loop
下面的嵌套for-loop产生的结果(表格)与上面的嵌套while-loop相同。
#include <iostream>
using namespace std;
int main()
{
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
cout << j << ' ';
}
cout << endl;
}
return 0;
}
每个for-loop的括号里都有自己的初始化语句,自己的条件语句,以及自己的增量语句。
一个while-loop
上表的输出可以由一个while-loop产生,有一个初始化语句和一个条件语句。然而,对j的重新赋值和对i的增量必须发生在一个if结构中。下面的代码说明了这一点。
#include <iostream>
using namespace std;
int main()
{
int i=0, j=0;
while (i < 5 && j <5) {
cout << j << ' ';
j++;
if (j == 5) {
cout << endl;
j=0;
i++;
}
}
return 0;
}
输出与上面的表格相同。
一个for-loop
上述表格的输出可以由一个for-loop产生,有一个初始化语句和一个条件语句。然而,重新分配零到j和增加i必须在if结构中进行。下面的程序说明了这一点。
#include <iostream>
using namespace std;
int main()
{
for (int i=0, j=0; i < 5 && j <5; j++) {
cout << j << ' ';
if (j == 4) {
cout << endl;
j = -1;
i++;
}
}
return 0;
}
输出与上面的表格相同。然而,在这里,由于j在循环结束时被递增,在括号里,if条件是(j == 4),j被重新分配,每行-1。
这里的空间是,在一个for-loop中已经声明了两个变量。因此,在一个for-loop中可以声明多个变量。
前导对角线寻址
在一个正方形表格中,前导对角线是指从左上角端到右下角端的对角线。 下面的程序显示了上述表格的前导对角线的坐标。
#include <iostream>
using namespace std;
int main()
{
for (int i=0, j=0; i < 5 && j <5; i++,j++) {
cout << i << ',' << j << ' ';
}
cout << endl;
return 0;
}
输出结果是:
0,0 1,1 2,23,3 4,4
请注意,在程序中,两个变量已经在for-loop的括号中声明;条件中有两个变量,通过逻辑AND联系起来;增量语句中有两个变量,每个变量增加1。在这个条件下,for-loop主体中的one语句打印出对角线的坐标。
三维for-loop
打印一个立方体的所有单元格的值是很麻烦的。下面的程序只是打印一个立方体的前沿对角线的坐标。
#include <iostream>
using namespace std;
int main()
{
for (int i=0,j=0,k=0; i<5&&j<5&&k<5; i++,j++,k++) {
cout << i << ',' << j << ',' << k << ' ';
}
cout << endl;
return 0;
}
输出的结果是:
0,0,0 1,1,1 2,2,2 3,3,3 4,4,4
注意,初始化语句有三个变量;条件语句有三个变量,增量语句有三个变量。在for-loop的主体中只有一条语句。
可能的优势
考虑用一个for-loop来显示一个正方形表格的所有单元格的值:
与嵌套一个循环的情况相比,在初始化语句和条件语句中拥有两个变量并不会带来任何速度上的优势。
然而,如果只访问表中的选定值,那么在初始化语句、条件语句和增量语句中设置这两个变量会带来速度上的优势;因为在消除许多值之前,所有的值都不会被访问。在下面的程序中,每一个其他的坐标对,在领先的对角线上,都被打印出来。
#include <iostream>
using namespace std;
int main()
{
for (int i=0, j=0; i < 10 && j <10; i+=2,j+=2) {
cout << i << ',' << j << ' ';
}
cout << endl;
return 0;
}
输出结果是:
0,0 2,24,4 6,6 8,8
在for-loop中仍然只有一条语句。以这种方式获得速度上的优势,需要在条件语句和/或增量语句中加入额外的选择逻辑。初始化语句中的初始化表达式可能不需要初始化为零。
在上面的代码中,增量语句是:
i+=2,j+=2
这意味着:
i = i+2, j = j+2;
结论
是的,我可以在一个for-loop中声明多个变量。而你现在也可以在for-loop中声明多个变量,如下所示。只要在初始化语句中用逗号把多个变量分开。不要忘记用分号来结束完整的初始化语句。如果对结构元素的访问必须是有选择的,那么这些变量可能也必须在条件和/或增量语句中使用,在for-loop的括号中,可能还要加上一些额外的逻辑。