Хотя массивы и указатели синтаксически очень похожи, они не одинаковы.
Первый typedef
в вашем примере позволяет объявить объект введите mpz_t
, который будет одиночным _mpz_struct
объектом (массив размером 1
); однако, поскольку он объявлен как массив, его имя может использоваться как указатель (например, при переходе к функции, которая требует указателя на этот тип структуры).
Второй typedef
- это простой указатель. Любая объявленная таким образом переменная должна иметь адрес фактической структуры, присвоенный ей, прежде чем ее можно будет использовать (разыменовать).
Последний тип позволит изменять конкретный объект, на который он указывает к, тогда как первый тип - это «фиксированный» указатель на определенный объект (или «поддельный» массив), объявленный.
У меня нет доступа к библиотеке GMP, поэтому я не могу привести пример используя это, но следующий код может иллюстрировать тонкую разницу между двумя типами:
#include <stdio.h>
typedef struct {
int a;
int b;
double d;
} MyStruct;
typedef MyStruct MS_t[1];
typedef MyStruct* MS_ptr;
int main()
{
MS_t mt;
MS_ptr mp;
printf("Size of type = %zu; Size of pointer = %zu\n\n", sizeof(MS_t), sizeof(MS_ptr));
mt->a = 1; mt->b = 2; mt->d = 3.141; // Good - "mt" can be used as a pointer to first (only) element of the array.
// mp->a = 3; mp->b = 7; mp->d = 3.141; // UNDEFINED BEHAVIOUR - mp doesn't point to anything.
MyStruct ms1, ms2 = { 3, 8, 42.42 };
mp = &ms1;
mp->a = 2; mp->b = 4; mp->d = 2.718; // OK - mp now points to a valid structure (ms1)
printf("MT: %d %d %f\n", mt->a, mt->b, mt->d);
printf("MP: %d %d %f\n", mp->a, mp->b, mp->d);
// Let's try to change addresses:
mp = &ms2; // We can change what "mp" points to whenever we like
printf("MP: %d %d %f\n", mp->a, mp->b, mp->d); // Different address -> different structure -> different data!
// mt = &ms2; // ERROR: array type 'MS_t' (aka 'MyStruct [1]') is not assignable
mp = mt; // We can even use "mt" as an address to assign to "mp"
printf("MP: %d %d %f\n", mp->a, mp->b, mp->d); // This shows the 'first' data set values
return 0;
}