📄 03章 函数.txt
字号:
31 ++frequeneyS;
32 break;
33 case 6:
34 ++frequency6;
35 break;
36 default:
37 cout << "should never get here!";
38 }
39 }
40
41 cout << "Face" << setw{ 13 ) << "Frequency"
42 << "\n 1" << setw( I3 ) << frequencyl
43 << "\n 2" << setw( 13 ) << frequency2
44 << "\n 3" << setw( 13 ) << frequency3
45 << "\n 4" << setw( 13 ) << frequency4
46 << "\n 5" << setw( 13 ) << frequency5
47 << "\n 6" << setw( 13 ) << frequency6 << endl;
48
49 return 0;
50 }
输出结果:
Face Frequency
1 987
2 984
3 1029
4 974
5 1004
6 1022
图3.8模拟投骰子6000次
测试与调试提示3.1
即使能确切保证程序没有缺陷,也应在switch结 构中用一个default case来找到错误。
再次执行图3.7的程序得到:
5 5 3 5 5
2 4 2 5 5
5 3 2 2 1
5 1 4 6 4
注意打印的数值顺序与上一次完全相同,怎么能算是随机数呢,其实,这种可重复性是rand函数的一个重要特性。调试程序时,这种可重复性提供了证明修改后程序能正确工作的关键。
rand函数实际上产生的是伪随机数(pseudo-randomnumber)。重复调用rand函数产生一系列看上去是随机的数值,但每次执行程序时,这组数值本身是可重复的。一旦程序进行彻底调试之后,就可以调整为在每次执行程序时产生不同的随机数系列。这个过程称为随机化(randomizing),是用标准库函数srand完成的。srand函数取一个unsigned类型的整数参数并内嵌rand函数(即种子),
就可以在每次执行程序时产生不同的随机数系列。
srand函数的使用如图3.9所示。在这个程序中,我们使用数据类型unsigned(unsigned int的缩写)。int值至少占内存的两个字节,可以存正值或负值。unsignediht变量值也至少占内存的两个字节。2字节的unsigned int只能取O到65535的非负值,4字节的unsignediht只能取O到4294967295的非负值,srand函数取unsigned int值作参数。srand函数的函数原型在头文件<stdlibh>新C++标准的cstdlib)中。
下面将程序运行几次并观察结果。注意,只要提供不同的种子,即可在每次执行程序时产生不同的随机数系列。
1 // Fig. 3.9: fig0309.cpp
2 // Randomizing die-rolling program
3 #include <iostream.h>
4 #include <iomanip.h>
5 #include <stdlib.h>
6
7 int main( )
8 {
9 unsigned seed;
10
11 cout << "Enter seed: ";
12 cin >> seed;
13 srand{ seed );
14
15 for ( int i = 1; i <= 10; i++ ) {
16 cout << setw( 10 ) << 1 + rand( ) % 6;
17
18 if ( i % 5 == 0 )
19 cout << endl;
2O }
21
22 return 0;
23 }
输出结果:
Enter seed: 67
1 6 5 1 4
5 6 3 1 2
Enter seed:432
4 2 6 4 3
2 5 1 4 4
Enter seed: 67
1 6 5 1 4
5 6 3 1 2
图3.9投骰子随机化程序
如果不想每次输入种子值而随机化,则要用如下语句:
srand( time ( O ) );
使计算机通过时钟值自动取得种子值。time函数(上述语句中该函数的参数为0)返回当前“日历时间”的秒数,将这个值转换为无符号整数值,作为随机数产生器的种子。time函数的函数原型在<time>(新C++标准的ctime)中。
性能提示 3.2
srand函数只要在程序中调用一次即可得到所需的随机化结果,多次调用是多余的,会降低程序性能。
由rand函数直接产生的值总是取值为:
O≤rand()≤ RAND_MAX
前面介绍了如何用一个语句模拟投骰子,该语句如下所示:
face=1+rand( ) % 6;
总是对变量face指定1≤face≤6的整数(随机)。注意这个范围的宽度(即构成该范围的连续整数的个数)为6并从1开始。从上述语句可以看出,范围宽度是由求模运算符比例缩放rand的数值(6)确定的,开始值等于rand%6中加进的数值(即1)。可以将这个结果一般化,如下所示:
n = a + rand( ) %b;
其中a是位移值(等于所要的连续整数范围的开始值),b是比例因子(即由连续整数构成的该范围的宽度)。练习中将介绍如何从一组非连续整数中随机选择整数。
常见编程错误3.16
用srnd函数代替rand函数产生随机数是个语法错误,因为srnd函数不返回值。
3.9 案例:机会游戏与enum简介
一个最常见的机会游戏是投骰子游戏,游戏规则如下:
游戏者投两枚骰子,每个骰于有六面,这些面包含1、2、3、4、5、6个点。投两枚骰于之后,计算点数之和。如果第一次投时的和为7或11,则游戏者获胜。如果第一次投时的和2、3或12,则游戏者输,庄家赢。如果第一次投时的和为4、5、6、8、9或10,则这个和成为游戏者的点数。
要想赢,就要继续投骰子,直到赚到点数。如果投七次之后还没有赚到点数,则游戏者输。
图3.10中的程序模拟了投骰子游戏,图3.1l显示了几个示例的执行结果。
1 // Fig. 3.10: figO3_lO.cpp
2 // Craps
3 #include <iostream.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 int rollDice( void ); // function prototype
8
9 int main ( )
10 {
11 enum status{CONTINUE,WON,LOST};
12 int sum, myPoint;
13 status gameStatus;
14
15 srand( time( NULL ) );
16 sum = rollDice( ); // first roll of the dice
17
18 switch ( sum ) {
19 case 1:
20 case 11: // win on first roll
21 gameStatus = WON;
22 break;
23 case 2:
24 case 3:
25 case 12: // lose on first roll
26 gameStatus = LOST;
27 break;
28 default: // remember point
29 gameStatus = CONTINUE;
3O myPoint = sum;
31 cout << "point is "<< myPoint << endl;
32 break; // optional
33
34
35 while { gameStatus == CONTINUE ) { // keep rolling
36 sum = rollDice( );
37
38 if ( sum = myPoknt ) // win by making point
39 gameStatus = wON;
40 else
41 if ( sum == 7 } // lose by rolling 7
42 gameStatus = LOST;
43 }
44
45 if ( gameStatus == WON )
46 cout << "Player wins" << end1;
47 else
48 cout << "Player loses" << endl;
49
50 return 0;
51 }
52
53 int rollDice( void )
54 {
55 int diel, die2, workSum;
56
57 die1 = 1 + rand( ) % 6;
58 die2 = 1 + rand( ) % 6;
59 workSum = diel + die2;
60 cout << "Player rolled" << diel <<" + "<< die2
61 << " = " << workSum << endl;
62
63 return workSum;
64 }
图 3.10 模拟投骰子游戏的程序
Player rolled 6 + 5 = 11
Player wins
Player rolled 6 + 6 = 12
Player loses
Player rolled 4 + 6 = 10
Point is 10
Player rolled 2 + 4 = 6
Player rolled 6 + 5 11
Player rolled 3 + 3 = 6
Player rolled 6 + 4 10
Player wins
Player rolled 1 + 3 = 4
Point is q
Player rolled 1 + 4 = 5
Player rolled 5 + 4 9
Player rolled 4 + 6 - 10
Player rolled 6 + 3 - 9
Player rolled 1 + 2 = 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -