20-等待一段时间_编写延时循环
5.2.2 等待一段时间:编写延时循环
有时候,让程序等待一段时间很有用。例如,读者可能遇到过这样的程序,它在屏幕上显示一条消息,而还没来得及阅读之前,又出现了其他内容。这样读者将担心自己错过了重要的、无法恢复的消息。如果程序在显示其他内容之前等待5秒钟,情况将会好得多。while循环可用于这种目的。一种用于个人计算机的早期技术是,让计算机进行计数,以等待一段时间:
long wait = 0;
while (wait < 10000)
wait++; // counting silently
这种方法的问题是,当计算机处理器的速度发生变化时,必须修改计数限制。例如,有些为IBM PC编写的游戏在速度更快的机器上运行时,其速度将快得无法控制;另外,有些编译器可能修改上述代码,将wait设置为10000,从而跳过该循环。更好的方法是让系统时钟来完成这种工作。
ANSI C和C++库中有一个函数有助于完成这样的工作。这个函数名为clock(),返回程序开始执行后所用的系统时间。这有两个复杂的问题:首先,clock()返回时间的单位不一定是秒;其次,该函数的返回类型在某些系统上可能是long,在另一些系统上可能是unsigned long或其他类型。
但头文件ctime(较早的实现中为time.h)提供了这些问题的解决方案。首先,它定义了一个符号常量——CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。因此,将系统时间除以这个值,可以得到秒数。或者将秒数乘以CLOCKS_PER_SEC,可以得到以系统时间单位为单位的时间。其次,ctime将clock_t作为clock()返回类型的别名(参见本章后面的注释“类型别名”),这意味着可以将变量声明为clock_t类型,编译器将把它转换为long、unsigned int或适合系统的其他类型。
程序清单5.14演示了如何使用clock()和头文件ctime来创建延迟循环。
程序清单5.14 waiting.cpp
// waiting.cpp -- using clock() in a time-delay loop
#include <iostream>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
cout << "Enter the delay time, in seconds: ";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC; // convert to clock ticks
cout << "starting\a\n";
clock_t start = clock();
while (clock() - start < delay ) // wait until time elapses
; // note the semicolon
cout << "done \a\n";
return 0;
}
该程序以系统时间单位为单位(而不是以秒为单位)计算延迟时间,避免了在每轮循环中将系统时间转换为秒。
类型别名
C++为类型建立别名的方式有两种。第一种是使用预处理器:
#define BYTE char // preprocessor replaces BYTE with char
这样,预处理器将在编译程序时用char替换所有的BYTE,从而使BYTE成为char的别名。
第二种方法是使用C++(和C)的关键字typedef来创建别名。例如,要将byte作为char的别名,可以这样做:
typedef char byte; // makes byte an alias for char
下面是通用格式:
typedef typeName aliasName;
换句话说,如果要将aliasName作为某种类型的别名,可以声明aliasName,如同将aliasName声明为这种类型的变量那样,然后在声明的前面加上关键字typedef。例如,要让byte_pointer成为char指针的别名,可将byte_pointer声明为char指针,然后在前面加上typedef:
typedef char * byte_pointer; // pointer to char type
也可以使用#define,不过声明一系列变量时,这种方法不适用。例如,请看下面的代码:
#define FLOAT_POINTER float *
FLOAT_POINTER pa, pb;
预处理器置换将该声明转换为这样:
float * pa, pb; // pa a pointer to float, pb just a float
typedef方法不会有这样的问题。它能够处理更复杂的类型别名,这使得与使用#define相比,使用typedef是一种更佳的选择——有时候,这也是唯一的选择。
注意,typedef不会创建新类型,而只是为已有的类型建立一个新名称。如果将word作为int的别名,则cout将把word类型的值视为int类型。