掷骰子最广泛的形式是用两个6面骰子。ide
计算机能够设计一种具备任意面数的骰子,先从6面开始,再进行扩展。函数
咱们想获得从1到6之间的一个随机数。然而,rand()产生的是从0到RAND_MAX范围内的整数;RAND_MAX在stdlib.h中定义,它一般是INT_MAX。所以,须要作一些调整。下面是一种方法:设计
一、把随机数对6取模,将产生从0到5的整数。code
二、加1.新数将为从1到6范围内的整数。原型
三、为了方便扩展,将步骤1中的数字6用骰子面数来代替。编译器
下面的代码实现了这些想法:io
#include <stdlib.h> /*为rand()函数提供原型*/ int rollem(int sides) { int roll; roll = rand()%sides + 1; return roll; }
进一步,咱们想实现这样的功能:它容许掷任意个骰子,而且返回点数总和。程序清单12.11实现了这样的功能。编译
/*diceroll.c --掷骰子的模拟程序*/ #include "diceroll.h" #include <stdio.h> #include <stdlib.h> /*为rand()函数提供类库*/ int roll_count = 0; /*外部连接*/ static int rollem(int sides) /*这个文件的私有函数*/ { int roll; roll=rand()%sides+1; ++roll_count; /*计数函数调用*/ return roll; } int roll_n_dice (int dice,int sides) { int d; int total = 0; if(sides<2) { printf("Need at least 2 sides.\n"); return -2; } if(dice<1) { printf("Need at least 1 die.\n"); return -1; } for(d=0;d<dice;d++) total += rollem(sides); return total; }
这个文件中加入了一些新东西。首先,它把rollem()变成由该文件私有的函数,这个函数用于辅助roll_n_dice();其次,为了举例说明外部连接如何工做,文件声明了一个外部变量roll_count,这个变量跟踪记录函数rollem()的调用次数。例子自己有一点不妥,但它显示了外部变量的如何工做的。ast
再次,文件包含下面的语句:function
#include "diceroll.h"
若是使用诸如rand()的标准库函数,您须要在程序中包含标准头文件(对rand()来讲是stdlib.h),而不是声明函数,由于头文件中已经包含了正确的声明。咱们将效仿这一作法,提供一个头文件diceroll.h以供函数roll_n_dice()使用。将文件名置于双引号而非尖括号中, 是为了指示编译器在本地寻找文件,而不是到编译器存放标准头文件的标准位置去寻找文件。“在本地寻找”的意义取决于具体的C实现。一些常看法释是将头文件与源代码文件放在同一个目录或文件夹中。程序清单12.12显示了该头文件的内容。
程序清单12.12 diceroll.h文件
//diceroll.h extern int roll_count; int roll_n_dice(int dice,int sides);
这个头文件中包含函数原型声明一和个extern声明。由于文件diceroll.c包含了这一头文件,它也就实际上包含了roll_count的两个声明:
extern int roll_count; //来自头文件
int roll_count = 0; //来自源代码文件
这是能够的,一个变量只能够有一个定义声明,但使用extern的声明是一个引用声明,这样的声明想用多少就能够用多少。
使用roll_n_dice()的程序也应该包含这一头文件。这样作不单单提供roll_n_dice()原型,还使得roll_count对程序可用。程序清单12.13证实了这些。
//manydice.c --屡次掷骰子的模拟程序 //与diceroll.c一块儿编译 #include<stdio.h> #include<stdlib.h> //为srand()提供原型 #include<time.h> //为time()提供原型 #include"dicerlll.h" //为roll_n_dice()和roll-count提供原型 int main(void) { int dice ,roll; int sides; srand((unsigned int )time(0)); //随机化种子 printf("Enter the number of sides per die,0 to stop.\n"); while(scanf("%d",&sides)==1 && sides>0) { printf("How many dice?\n"); scanf("%d",&dice); roll = roll_n_dice(dice,sides); printf("You have rolled a %d using %d %d-sided dice.\n",roll,dice,sides); printf("How many sides?Enter 0 to stop.\n); } printf("The rollem() function was called %d times.\n",roll_count); /*使用外部变量*/ printf("Good Fortune To You!\n"); return 0; }
将程序清单12.13与包含程序清单12.11的文件一块儿编译。为了简化问题,把程序清单12.十一、12.12和12.13放在同一文件中或同一目录下。运行最后获得的程序,输出应该像下面这样:
Enter the number of sides per die,0 to stop. 6 How many dice? 2 You have rolled a 12 using 2 6-sided dece. How many sides?Enter 0 to stop. 6 How many dice? 2 You have rolled a 4 using 2 6-sided dice. How many sides?Enter 0 to stop. 6 How many dice? 2 You have rolled a 5 using 2 6-sided dice. How many sides?Enter 0 to stop. 0 The rollem() funcation was called 6 times. GOOD FORRUNE TO YOU!
由于程序使用srand()来随机肯定随机数种子,因此大多数状况下,即便有相同的输入也不可能获得相同的输出。注意,manydice.c中的main()确实能够访问diceroll.c中定义的变量roll_count。
能够使用多种方式使用roll_n_dice()。对于sides为2的情形,程序模仿掷硬币,面朝上为2,背朝上为1.您能够很容易地修改程序来像显示整体结果那样显示个别结果,或者建一个掷双骰子赌博模拟器。