3

查看 GMPlib(用于多精度计算的 Gnu 库)的源代码,我发现了这种用于构建其 mp*_t 结构的代码。我已经在我做过的各种其他作品中复制了它,但我并不完全理解它。

typedef struct
{
  int _mp_alloc;           /* Number of *limbs* allocated and pointed
                              to by the _mp_d field.  */
  int _mp_size;            /* abs(_mp_size) is the number of limbs the
                              last field points to.  If _mp_size is
                              negative this is a negative number.  */
  mp_limb_t *_mp_d;        /* Pointer to the limbs.  */
} __mpz_struct;

我知道这定义了具有两个整数和 a 的结构的“形状”,并将其mp_limb_ttypedefs 为__mpz_struct

然后是这一行:

typedef __mpz_struct mpz_t[1];

过了一会儿,另一个:

typedef __mpz_struct *mpz_ptr;

我知道第二个是类型定义(在函数原型中使用__mpz_struct *mpz_ptr

但我不明白第一个是做什么的以及它为什么起作用,所以我可以声明一个 mpz_t。谁能解释它为什么起作用?

谢谢!

4

4 回答 4

4

理解 a 的最简单方法typedef是规则Define it like you use it。换句话说,当您声明 a 时,typedef您正在创建一个新名称,但如果您删除typedef关键字,您将获得一个别名类型的对象

例如:

typedef __mpz_struct mpz_t[1];

这产生了一个新的类型名称,称为“mpz_t”。但是如果我们重写:

__mpz_struct some_obj[1];

我们立即明白它会生成一个数组__mpz_struct。所以现在我们知道了新类型的mpz_t a作用:它创建了一个__mpz_struct包含一个元素的数组。

于 2012-08-29T12:00:53.503 回答
1

第一个 typedef 将 mpz_t 定义为一个 __mpz_struct 的数组(typedef 的语法与用于声明对象的语法相同,不同之处在于您要声明一个类型)。

顺便说一句,typedef 指针不是一个非常好的主意,因为它很难正确地 const 正确

于 2012-08-29T12:01:38.133 回答
1
typedef __mpz_struct mpz_t[1];

将 mpz_t 定义为一个包含一个 __mpz_struct 的数组。有趣的是,如果你这样做

mpz_t x;

您将 x 定义为一个 __mpz_struct 的数组。如果你这样做

void f(mpz_t p) { ... }

您将 f 定义为带有指向 __mpz_struct 的指针的函数,因此您可以调用

f(x);

它会调用 f,传递给它一个指向 x 的第一个(也是唯一的)元素的指针,并且 f 可以修改 x。因此,您有一种方法可以模拟通过引用传递。第二个兴趣是您正在失去做事的可能性

mpz_t x, y;

x = y;

为什么有趣?因为 __mpz_struct 包含一个指针。并且复制指针不是正确的做法,您还想要复制所指向的内容。

BTWva_list有时以相同的方式定义,这解释了其使用的限制。

于 2012-08-29T12:13:27.927 回答
0

C 中的数组实际上等价于指针,因为数组是指向数组第一个元素的指针。在这里,mpz_t简单定义为指向一个数组 1__mpz_struct

希望它有所帮助。

于 2012-08-29T12:01:22.347 回答