查看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;
据我所知,这定义了'形状'具有两个整数和mp_limb_t
的结构,并将其定义为__mpz_struct
然后是这一行:
typedef __mpz_struct mpz_t[1];
过了一会儿,另外一个:
typedef __mpz_struct *mpz_ptr;
我理解第二个是__mpz_struct *
到mpz_ptr
的类型定义(在函数原型中使用)
但我不明白第一个人做了什么以及它为什么有效,所以我可以宣布一个mpz_t。任何人都可以解释它为什么有用吗?
谢谢!
答案 0 :(得分:4)
理解typedef
的最简单方法是规则定义它就像使用它一样。换句话说,当您声明typedef
时,您正在创建一个新名称,但如果您删除typedef
关键字,则会获得一个别名类型的对象。
例如:
typedef __mpz_struct mpz_t[1];
这会产生一个名为“mpz_t”的新类型名称。但如果我们改写:
__mpz_struct some_obj[1];
我们立刻明白它会生成__mpz_struct
之类的数组。现在我们知道新类型mpz_t a
的作用:它使__mpz_struct
数组包含一个元素。
答案 1 :(得分:1)
第一个typedefs mpz_t到一个__mpz_struct的数组(typedef的语法与用于声明对象的语法相同,除了你声明一个类型)。
顺便说一句,typedef指针并不是一个非常好的主意,因为它很难正确地使用const
答案 2 :(得分: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包含一个指针。复制指针不是正确的事情,你想要复制指向的东西。
BTW va_list
有时以相同的方式定义,并解释了对其使用的限制。
答案 3 :(得分:0)
C中的数组实际上等同于指针,因为数组是指向数组第一个元素的指针。
在这里,mpz_t
被简单地定义为指向1 __mpz_struct
希望它有所帮助。