#include <stdio.h>
double seed=0.579832467;
main(ac, av)
int ac;
char *av[];
{
/* declare variables */
float *buf, fac;
int sf, ne, i;
/* prototypes? ( shouldn't they be outside the main ) */
double rnd(), sd;
/* gets the number of elements from command line */
ne = atoi(av[1]);
/* assigns the size of float ( in bytes ) to integer value */
sf = sizeof(float);
/* allocates appropriate memory for random number generation */
buf = (float *)malloc(ne*sf);
/* type cast, why?? */
sd = (double)(ne);
/* no idea what initrnd does */
initrnd(sd/(sd+187.9753));
/* checks if memory allocation is successful */
if (buf == NULL)
{
fprintf(stderr, "rndneg: can't allocate %d bytes for buffer\n", ne*sf);
exit(-1);
}
/* fills buffer with random number */
for (i=0; i<ne; i++)
{
buf[i] = (float)(rnd());
}
/* writes the buffer, how does it know the file name? */
write(1, buf, ne*sf);
}
/* random number generating function */
double rnd()
{
seed *= 997.0;
seed -= (double)((int)(seed));
return(seed);
}
initrnd(sd)
/* again no idea, why isn't this function void */
double sd;
{
seed = sd;
return(0);
}
这是PRNG的一些代码。我对C不太熟悉,而且这段代码中的一些内容对我来说完全没有意义。我试图评论代码来跟踪发生了什么。如果我不明白的一些事情可以被清除,我将不胜感激。特别是具有相同名称的变量和函数的声明,以及initrnd子例程,似乎没有在程序或我在互联网上找到的任何库中定义。
非常感谢。
答案 0 :(得分:2)
这看起来很古老。
您的问题的几个答案:
initrnd()
只需将全局seed
变量设置为特定值,然后在PRNG中使用。stdout
;假设使用文件描述符1
。这种神奇常数的使用不是很漂亮,应该写成stdout
(来自<stdio.h>
)。答案 1 :(得分:1)
/* type cast, why?? */
sd = (double)(ne);
因为ne是一个整数而sd是double,所以需要强制转换
/* no idea what initrnd does */
initrnd(sd/(sd+187.9753));
它是最后一个函数,它使用参数
设置全局变量种子 /* writes the buffer, how does it know the file name? */
write(1, buf, ne*sf);
文件描述符是1,代表标准输出,所以这就像调用printf()
initrnd(sd)
/* again no idea, why isn't this function void */
这个函数是int,但它应该是void(无论如何都没有任何区别),也许原来的程序员很懒:P
答案 2 :(得分:0)
代码是预标准的C,所以它不使用原型(但确实声明了函数,但显然不是绝对必要的)。函数定义使用预标准K&amp; R样式来声明函数的参数。对于非原型类型的函数,程序员有责任确保使用正确的参数集调用函数,并且如果函数没有返回任何内容,则函数的“值”不会执行任何操作。
如果函数返回了int
以外的函数,则必须声明该函数(不一定是原型),因此编译器会知道函数返回的数据类型。如果没有声明,编译器将假定返回int
(但如果函数没有返回任何内容,只要您不尝试对函数'result'执行任何操作,那就没问题。)
以下是对您的问题的一些直接评论:
/* prototypes? ( shouldn't they be outside the main ) */
// this declares that function `rnd()` returns a double. Technically, it's
// not a prototype. Without the declaration the compiler would assume that it
// returns an `int` so trying to use it wouldn't work. It could be declared
// outside `main()`, but it's OK to have it declared within the scope of
// `main()`, just like it would be for a prototype. That just means that
// outside of `main()` the declaration is no longer in effect, so any calls
// to `rnd()` would assume that `int` is returned (incorrectly).
double rnd(), sd;
/* type cast, why?? */
// the cast is unnecessary and redundant, but OK
sd = (double)(ne);
/* no idea what initrnd does */
// apparently `initrnd()` initializes the rng seed (see below). There's
// no declaration in sight, so the compiler will default the return type
// to `int` (unless it's in `stdio.h`).
initrnd(sd/(sd+187.9753));
/* writes the buffer, how does it know the file name? */
// `1` is the file descriptor for `stdout`. Today this would probably
// be specified using `STDOUT_FILENO`, but even today `STDOUT_FILENO` is
// required to be 1 (by POSIX).
write(1, buf, ne*sf);
}
initrnd(sd)
/* again no idea, why isn't this function void */
// `void` didn't exist pre-ANSI standard.
// so this function 'returns' `int` by default.
double sd;
{
seed = sd;
return(0);
}