循环
编写延时循环
有时候,我们需要让程序等待一段时间。在之前的C语言课程设计之中,使用了Sleep(int milliseconds)函数来处理这个事情。while循环也可用于这种目的,一种早期的用于个人计算机的技术是,让其进行计数,以等待一段时间:1
2
3long wait = 0;
while (wait < 10000)
wait++; // counting silently
但潜在的问题是这受到计算机处理器处理速度的影响。更好的方法是用系统时钟来完成此项工作。
ANSI C和C++库中有一个函数有助于完成这样一项工作。这个函数就是clock(),返回程序开始执行后所用的系统时间。这有几个问题:首先,返回的时间单位不一定为秒;其次,返回值的类型与系统有关,可能是long也可能是unsigned long或其他。
头文件ctime(较早的实现中使用time.h)提供了解决方案。首先,它定义了一个符号常量——CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。因此将系统时间除以这个常量可以得到秒数,或是将秒数诚意CLOCK_PER_SEC就可以得到以系统时间单位为单位的时间。其次,ctime将clock_t作为clock()返回类型的别名(将会在后面提起),这意味着可以将变量声明为clock_t类型,编译器将进行转换以适应系统。
下列程序演示了使用clock()和头文件ctime创建延时循环:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// waiting.cpp -- using clock() in a time-delay loop
int main()
{
using namespace std;
cout << "Enter the delay time, in seconds: ";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC;
cout << "starting\a\n";
clock_t start = clock();
while (clock() - start < delay);
cout << "done \a\n";
return 0;
}
该程序以系统时间为单位计算延迟时间,避免了在每轮循环中将系统时间转换为秒。
类型别名
C++为类型建立别名的方式有两种。一种是使用预处理器:1
这样,预处理器将在编译程序时用char替换所有的BYTE,从而使BYTE成为char的别名。
第二种方法是使用C++(和C)的关键字typedef来创建别名。例如:1
typedef char type;
下面是通用格式:1
typedef typeName aliasName;
换句话说,如果要将aliasName作为某种类型的别名,可以声明aliasName,如同将aliasName声明为这种类型的变量那样,然后在声明的前面加上关键字typedef。例如,要让byte_pointer成为char指针的别名,可将byte_pointer声明为char指针,然后在前面加上typedef:1
typedef char * byte_pointer; // pointer to char type
也可以使用#define,不过声明一系列变量时,这种方法不适用。例如:1
2
FLOAT_POINTER pa, pb;
预处理器将声明转换为这样:1
float * pa, pb; // pa a pointer to float, pb just a float
typedef方法不会有这样的问题。它能够处理更复杂的类型别名。
注意,typedef不会创建新类型,而只是为已有的类型创建一个新名称。
基于范围的for循环(C++11)
C++11新增了一种循环:基于范围(range-based)的for循环。这简化了一种常见的循环任务:对数组(或容器类,如vector和array)的每个元素执行相同的操作,如下例所示:1
2
3double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49};
for (double x : prices)
cout << x << std::endl;
其中,x最初表示数组prices的第一个元素。显示第一个元素后不断执行循环,而x依次表示数组的其他元素。
要修改数组的元素,需要使用不同的循环变量语法:1
2for (double &x : prices)
x = x * 0.80;
符号&表明x是一个引用变量,这个将在后面学习。就这里而言,这种声明可以修改数组的内容,而第一种语法不行。
还可以结合使用基于范围的for循环和初始化列表:1
2
3for (int x : {3, 5, 2, 8, 6})
cout << x << " ";
cout << '\n';
然而,这种循环主要用于后面的各种模板容器类。
