对 C 中一个元素的数组执行结构的 typedef 可能产生的副作用
Possible side effects of doing a typedef of a struct to an array of one element in C
我看到了这段代码。
typedef __mpz_struct MP_INT;
typedef __mpz_struct mpz_t[1];
这里的结构 __mpz_struct
是一个类型定义为单个元素数组的结构。我理解这是C中通过引用传递的技巧。然后 mpz_t
被用作声明变量并将它们作为参数传递给函数的类型。另外,还有一条评论
/*
MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects
of single-element arrays mp*_t
*/
他们说的是什么副作用?
看看这个示例代码
typedef char type24[3];
与您的相同,但众所周知的数据类型 'char' 代替了您的结构 __mpz_struct
类型。
above type def 的意思是,我使用上面的 typedef 来表示 char[3]。
因此在您的示例代码中,
typedef __mpz_struct mpz_t[1];
mpz_t
应该是 __mpz_struct
类型。
我看到你的问题分为两个部分。第一部分,typedef 如何将参数传递给函数,最好用一个例子来说明。没有它,我将不得不猜测一下。
在 C 函数声明中,an array parameter is equivalent to a pointer。这就是为什么你看到(例如)等同于主要功能,
int main(int argc, char **argv)
和
int main(int argc, char *argv[])
同样,如果要声明程序中的函数
int func(__mpz_struct *arg)
相当于
int func(__mpz_struct arg[])
因此
int func(mpz_t arg)
此外,在调用方,如果您有一个类型为 mpz_t 的变量,因此是数组,并将其传递给一个函数,则“pointer decay”会生效:在一个表达式,如果你使用一个数组(的名称),它 "decays" 变成指向它的第一个元素的指针。
这样你就可以调用函数:
mpz_t value;
func(value);
当然,要在API函数之外修改这些mpz_t对象,你还是要了解它们的本质。
你说的副作用,我也要猜。可能这意味着您必须意识到您正在使用函数内部的指针。最好使用指针语法使其显式化。
将数组传递给函数让数组衰减到指向它的第一个元素的指针。
可以通过将 Address-Of 运算符 &
应用于与数组元素类型相同的简单变量来达到相同的效果。
示例:
struct S
{
int i;
float f;
};
这个
void set_S(struct S * ps)
{
ps->i = 40;
ps->f = 2.;
}
相当于
void set_S(struct S ps[1])
{
ps->i = 40;
ps->f = 2.;
}
相当于
void set_S(struct S * ps)
{
ps[0].i = 40;
ps[0].f = 2.;
}
相当于
void set_S(struct S ps[1])
{
ps[0].i = 40;
ps[0].f = 2.;
}
单元素数组方法:
typedef struct S Array_of_S_with_size_1[1];
int main(void)
{
Array_of_S_with_size_1 array_of_S_with_size_1;
array_of_S_with_size_1[0].i = 0;
array_of_S_with_size_1[0].f = 0.;
set_S(array_of_S_with_size_1);
...
}
以上 main()
提供与以下相同的功能:
int main(void)
{
struct S s;
s.i = 0;
s.f = 0.;
set_S(&s);
...
}
我没有看到使用“One-Element-Array”方法有任何好处。如果 &
-键在键盘上坏了,可能会有一个预期……;-)
您可以将 MP_INT 分配给另一个,但不能将 mpz_t 分配给另一个,因为没有为数组定义分配。如果你不希望你的客户分配变量而不是你的方法(可能会做内存管理和东西)这就是你的技巧。
我看到了这段代码。
typedef __mpz_struct MP_INT;
typedef __mpz_struct mpz_t[1];
这里的结构 __mpz_struct
是一个类型定义为单个元素数组的结构。我理解这是C中通过引用传递的技巧。然后 mpz_t
被用作声明变量并将它们作为参数传递给函数的类型。另外,还有一条评论
/*
MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects
of single-element arrays mp*_t
*/
他们说的是什么副作用?
看看这个示例代码
typedef char type24[3];
与您的相同,但众所周知的数据类型 'char' 代替了您的结构 __mpz_struct
类型。
above type def 的意思是,我使用上面的 typedef 来表示 char[3]。
因此在您的示例代码中,
typedef __mpz_struct mpz_t[1];
mpz_t
应该是 __mpz_struct
类型。
我看到你的问题分为两个部分。第一部分,typedef 如何将参数传递给函数,最好用一个例子来说明。没有它,我将不得不猜测一下。
在 C 函数声明中,an array parameter is equivalent to a pointer。这就是为什么你看到(例如)等同于主要功能,
int main(int argc, char **argv)
和
int main(int argc, char *argv[])
同样,如果要声明程序中的函数
int func(__mpz_struct *arg)
相当于
int func(__mpz_struct arg[])
因此
int func(mpz_t arg)
此外,在调用方,如果您有一个类型为 mpz_t 的变量,因此是数组,并将其传递给一个函数,则“pointer decay”会生效:在一个表达式,如果你使用一个数组(的名称),它 "decays" 变成指向它的第一个元素的指针。 这样你就可以调用函数:
mpz_t value;
func(value);
当然,要在API函数之外修改这些mpz_t对象,你还是要了解它们的本质。
你说的副作用,我也要猜。可能这意味着您必须意识到您正在使用函数内部的指针。最好使用指针语法使其显式化。
将数组传递给函数让数组衰减到指向它的第一个元素的指针。
可以通过将 Address-Of 运算符 &
应用于与数组元素类型相同的简单变量来达到相同的效果。
示例:
struct S
{
int i;
float f;
};
这个
void set_S(struct S * ps)
{
ps->i = 40;
ps->f = 2.;
}
相当于
void set_S(struct S ps[1])
{
ps->i = 40;
ps->f = 2.;
}
相当于
void set_S(struct S * ps)
{
ps[0].i = 40;
ps[0].f = 2.;
}
相当于
void set_S(struct S ps[1])
{
ps[0].i = 40;
ps[0].f = 2.;
}
单元素数组方法:
typedef struct S Array_of_S_with_size_1[1];
int main(void)
{
Array_of_S_with_size_1 array_of_S_with_size_1;
array_of_S_with_size_1[0].i = 0;
array_of_S_with_size_1[0].f = 0.;
set_S(array_of_S_with_size_1);
...
}
以上 main()
提供与以下相同的功能:
int main(void)
{
struct S s;
s.i = 0;
s.f = 0.;
set_S(&s);
...
}
我没有看到使用“One-Element-Array”方法有任何好处。如果 &
-键在键盘上坏了,可能会有一个预期……;-)
您可以将 MP_INT 分配给另一个,但不能将 mpz_t 分配给另一个,因为没有为数组定义分配。如果你不希望你的客户分配变量而不是你的方法(可能会做内存管理和东西)这就是你的技巧。