0
#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 子例程,似乎没有在程序或我在 Internet 上找到的任何库中定义。

非常感谢。

4

3 回答 3

2

这看起来非常古老。

几个回答你的问题:

  1. 不,原型不需要是外部函数。这可能是最常见的,但不是必需的。
  2. initrnd()只需将全局seed变量设置为特定值,然后在 PRNG 中使用。
  3. 数据写入stdout;假定正在使用文件描述符1。这种神奇常数的使用不是很漂亮,应该写成stdout(from <stdio.h>)。
于 2011-05-18T17:04:14.750 回答
1
   /* type cast, why?? */
   sd = (double)(ne);

因为 ne 是整数而 sd 是双精度数,所以需要强制转换

   /* 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

于 2011-05-18T17:12:39.550 回答
0

该代码是准标准 C,因此它不使用原型(但确实声明了函数,尽管除非绝对必要,否则显然不会)。函数定义使用标准的 K&R 风格来声明函数的参数。对于非原型函数,程序员有责任确保使用正确的参数集调用函数,并且如果函数不返回任何内容,则不会对函数的“值”进行任何处理。

如果从函数返回的不是 an int,则必须声明该函数(不一定是原型),以便编译器知道从函数返回的数据类型。如果没有声明,编译器将假定int返回 an (但如果函数没有返回任何内容,只要您不尝试对函数 '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);
}
于 2011-05-18T22:06:08.140 回答