如何解决指向struct的指针作为函数参数的用途是什么?
该问题的原因是,似乎没有理由使用“ struct ** pointer”之类的双重间接方式。
要理解指针和结构作为函数参数的功能,我准备了一个示例。目的是查看功能在结构上所做的更改是保留在功能空间之外还是仅在功能内部引起影响。这是通过值或引用传递参数的常见问题。
#include <stdio.h>
/* A simple structure is defined to see the effect that the functions
* have on it. */
typedef struct est
{
int val1;
int val2;
} est_t;
/* These three functions simply assign the values val1 and val2 to the
* structure. Each of these functions uses a different way of passing
* the parameter to the function referring to the structure. There are
* more comments below,in the definition of each function. */
void foo(int,int,est_t);
void bar(int,est_t*);
void baz(int,est_t**);
/* This is a function to print the values of a structure and make the
* code cleaner. It also contains a parameter about a structure! */
void print_est(est_t*);
int main (int argc,char *argv[])
{
est_t a;
foo(10,11,a);
print_est(&a);
bar(20,21,&a);
print_est(&a);
est_t *p = &a;
baz(30,31,&p);
print_est(&a);
return 0;
}
void foo(int v1,int v2,est_t ve)
{
/* In this case the structure is "directly put" into the function.
* As the structure already is inside the function,the values of each
* element are assigned with the ". " */
ve.val1 = v1;
ve.val2 = v2;
/* With these printf you can see what is happening within the
* function. */
printf("[foo] val1 = %d\n",ve.val1);
printf("[foo] val2 = %d\n",ve.val2);
}
void bar(int v1,est_t *ve)
{
/* In this case the structure is passed into the function using a
* pointer. */
ve->val1 = v1;
ve->val2 = v2;
printf("\n[bar] val1 = %d\n",ve->val1);
printf("[bar] val2 = %d\n",ve->val2);
}
void baz(int v1,est_t **pp)
{
/* In this case the structure is passed into the function using a
* pointer to a pointer to a struct. */
(*pp)->val1 = v1;
(*pp)->val2 = v2;
printf("\n[baz] val1 = %d\n",(*pp)->val1);
printf("[baz] val2 = %d\n",(*pp)->val2);
}
void print_est(est_t *addr)
{
printf("[main] val1 = %d\n",addr->val1);
printf("[main] val2 = %d\n",addr->val2);
}
这是运行程序时的输出。
foo(10,a);
[foo] val1 = 10
[foo] val2 = 11
[main] val1 = -1238356256
[main] val2 = 32764
您可以看到在函数中分配的值没有保留在外部
让我们看一下 bar 和 baz 的输出。
bar(20,&a);
[bar] val1 = 20
[bar] val2 = 21
[main] val1 = 20
[main] val2 = 21
est_t *p = &a;
baz(30,&p);
[baz] val1 = 30
[baz] val2 = 31
[main] val1 = 30
[main] val2 = 31
似乎他们也这样做。我的意思是在两种情况下,值都保留在函数之外。
Foo 和 bar 是按值和按引用的典型情况,即使变化并不是永久的,从节省资源的角度来看,通过引用传递结构的想法可能会很有趣。参见advantage of passing pointer to a struct as argument?
但是就像 bar 和 baz 一样,有什么理由使用双指针将参数传递给函数吗?
解决方法
是否有任何理由使用双指针将参数传递给函数
是的。每当您想更改传递的参数时,都可以使用指针。因此,如果要更改指针,则需要一个指向该指针的指针。
简单的例子:
void foo(struct bar **ptr)
{
*ptr = malloc(10 * sizeof **ptr);
for(int i=0; i<10; i++)
(**ptr)->x = i;
}
,
函数接受T **
类型(对于任何T
类型)的参数通常有两个原因:
- 该参数对应于一个指针数组;
- 该函数用于更新指针值。
作为第一个示例,假设我们有类似的代码
int main( void )
{
char *strs[] = { "foo","bar","bletch","blurga",NULL };
func( strs );
...
}
strs
是一个指针数组,但是由于通常的衰减规则,func
收到的是指向指针的指针:
void func( char **s )
{
...
}
或者,您的函数用于更新指针值。假设我们已经动态分配了一个struct
类型的数组,我们需要使用realloc
对其进行扩展并初始化扩展的内存。为了更简洁一点,我们将其放在单独的函数中:
void extend( struct s **ptr,size_t *size )
{
struct s *tmp = realloc( *ptr,*size * 2 );
if ( tmp )
{
for ( size_t i = *size; i < *size * 2; i++ )
init ( &tmp[i] );
*ptr = tmp;
*size *= 2;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。