Next: , Previous: , Up: GMP Basics   [Index]


3.5 パラメータの利用法

GMPの変数を関数の引数として使用する際は,参照渡しすると遅延が防げますが,これを行うと, 関数内で値を代入すると,オリジナルの値とは別のものに書き換わってしまいます。入力値の ままにしておきたい場合は,const宣言をしておくと,意図しない代入の際にはコンパイルエラー もしくは警告が出るようになります。

GMPのデータ型を返り値とする関数を作る時には,GMPが提供する関数群がやっているように,引数に値を セットするようにして下さい。複数の値を返したい時は,複数の出力用引数を作ります。

下記は,mpz_t型の引数を取って計算を行い,結果を引数に渡す関数の例です。

void
foo (mpz_t result, const mpz_t param, unsigned long n)
{
  unsigned long  i;
  mpz_mul_ui (result, param, n);
  for (i = 1; i < n; i++)
    mpz_add_ui (result, result, i*7);
}

int
main (void)
{
  mpz_t  r, n;
  mpz_init (r);
  mpz_init_set_str (n, "123456", 0);
  foo (r, n, 20L);
  gmp_printf ("%Zd\n", r);
  return 0;
}

foo関数は,paramresultに同じ変数を指定しても,他のGMP関数同様 きちんと動作します。たまにこのような場合の動作がおかしかったり,この種の場合のサポートを サボったりすることもあるでしょうが。

興味のある人向きに解説しておくと,GMPのmpz_tのような多倍長数のデータ型は,これを定義した構造体の 配列1個分として実装されています。このようにしている理由は,型宣言した時点でGMPが必要とする構造体の 構成要素を持ったオブジェクトを生成するからです。また同時に,引数としてこれを使うと,オブジェクトへの ポインタを渡すことになるからでもあります。それぞれのmpz_tのようなGMPの多倍長数のデータ型に含まれる 構成要素は内部的に使われるだけで,直接アクセスして良いものではありません。そのような使い方をすると, 将来のGMPに対しては非互換になってしまう可能性が出てきます。