从C语言开始,模拟掷骰子

世界杯男子

前言 沃尔特·萨维奇的书 《Problem Solving with C++ 》中第四章 首先提到: 逐步求精 与 分而治之 实际上是一个思想,都是软件工程中学到的 自顶……

前言

沃尔特·萨维奇的书 《Problem Solving with C++ 》中第四章 首先提到:

逐步求精 与 分而治之 实际上是一个思想,都是软件工程中学到的 自顶向下设计,简单说就是:把任务分解成子任务,对子任务再次分解,直到分解得到的任务足够简单、可以实现。这些“子任务”,通常以“函数”的方式存在。

随后在 Chap.4.2 预定义函数 中介绍了:在包含了编译库中的 头文件之后,函数中可以调用产生随机数(random number)的预定义函数 rand()。

rand()函数有一个辅助函数srand(),它为rand()函数提供“种子值”(理论上,这个值经过复杂计算后得到rand()的返回值)。srand()不返回值,而获取一个无符号整数作为种子值。如果想要每次运行时都改变随机数的种子,可以把time(0)的返回值当作整数传给srand()。time函数需要 库文件。

正文

为了得到一个电子骰子,就是从 1 到 6 产生一个随机数。在stdlib.h函数库中,有一个产生 [0, INT_MAX] 范围内的随机数的函数 rand()。

基于提供的函数,可以写一个 diceroll.c 文件,这里为了后续拓展,引入了一个变量sides, 函数产生的点数在 [1,sides] 内。

// diceroll. C -- dice simulation program

#include

#include /* provides the prototype of rand() */

int roll_count = 0; /* this var is an external */

static int rollem(int sides) /* the function belongs to the private */

{

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;

}

// manydice.c

#include /* provide prototype for time() */

int main()

{

int dice, roll;

int sides;

srand((unsigned int)time(0)); /* prototype in */

// Do you want a 6-sided dice?

printf("输入每个骰子有多少面? 输入0退出。\n \n");

// You have rolled a %d using %d %d-sided dice.

// How many dices? Enter 0 to stop.

while (scanf("%d", &sides) == 1 && sides > 0)

{

printf("你要扔多少个骰子?\n");

scanf("%d",&dice);

roll = roll_n_dice(dice, sides);

printf("你掷出的总和为 %d, 用了共 %d 个 %d面的 骰子.\n", roll, dice, sides);

printf("你要玩的骰子有多少面? Enter 0 to stop.\n");

}

printf("The rollem() function was called %d times. \n", roll_count);

printf("Good Fortune!\n");

return 0;

}

大致如此,运行结果:

PS:

实际上C语言中的“头文件”,里面写的也只是“函数声明(函数原型)”,函数头和函数身子(函数体)可能并不在头文件里。具体在哪只有编译器知道。

但只要编辑器知道,那么在一份源代码的开头引入了库函数的“头文件”之后,代码内就可以随意地进行“函数调用”了。