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サブルーチンは、インターネット上で見つけたプログラムやライブラリでは定義されていないようです。

どうもありがとう。

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は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ですが、無効にする必要があります(とにかく違いはありません)、おそらく元のプログラマーは怠惰でした:P

于 2011-05-18T17:12:39.550 に答える
0

コードは先行標準のCであるため、プロトタイプを使用していません(ただし、絶対に必要な場合を除いて、関数を宣言しますが、明らかにそうではありません)。関数定義は、関数へのパラメーターを宣言する先行標準のK&Rスタイルを使用します。プロトタイプ化されていない関数の場合、関数が正しい引数のセットで呼び出され、関数が何も返さない場合は、関数の「値」で何も行われないようにするのはプログラマーの責任です。

関数からa以外のものintが返される場合は、関数を宣言する必要があります(これは必ずしもプロトタイプではありません)。これにより、コンパイラーは関数から返されるデータのタイプを認識します。宣言がない場合、コンパイラはanが返されると想定します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);
}
于 2011-05-18T22:06:08.140 に答える