Next: Memory Management, Previous: Variable Conventions, Up: GMP Basics [Index]
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
関数は,param
とresult
に同じ変数を指定しても,他のGMP関数同様
きちんと動作します。たまにこのような場合の動作がおかしかったり,この種の場合のサポートを
サボったりすることもあるでしょうが。
興味のある人向きに解説しておくと,GMPのmpz_t
のような多倍長数のデータ型は,これを定義した構造体の
配列1個分として実装されています。このようにしている理由は,型宣言した時点でGMPが必要とする構造体の
構成要素を持ったオブジェクトを生成するからです。また同時に,引数としてこれを使うと,オブジェクトへの
ポインタを渡すことになるからでもあります。それぞれのmpz_t
のようなGMPの多倍長数のデータ型に含まれる
構成要素は内部的に使われるだけで,直接アクセスして良いものではありません。そのような使い方をすると,
将来のGMPに対しては非互換になってしまう可能性が出てきます。