Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将结构传递给函数并将其赋值_C_Pointers_Struct - Fatal编程技术网

C 将结构传递给函数并将其赋值

C 将结构传递给函数并将其赋值,c,pointers,struct,C,Pointers,Struct,很抱歉,如果之前已经有人问过这个问题,但是我对传入和为结构赋值感到有点困惑 typedef struct test { int x; int y; } test_t; void func(test_t * test) { test_t second; second.x = 2; second.y = 3; *test = second; } void main() { test_t first; func(&firs

很抱歉,如果之前已经有人问过这个问题,但是我对传入和为结构赋值感到有点困惑

typedef struct test {
    int x;
    int y;
} test_t;

void func(test_t * test)
{
    test_t second;
    second.x = 2;
    second.y = 3;

    *test = second;
 }

void main()
{
    test_t first;
    func(&first);
}
这有效吗?如果我没记错的话,如果不在func()内mallock结构,就不应该将pointer*test in func()分配给第二个结构,因为它的作用域主要在func()内,并且在函数返回后将丢失。但是,在main()中打印时,这些值是正确的

实现这一结果的不同方式有哪些?这只是为了澄清一些混乱和健忘的记忆

编辑:

我想做的一个更清楚的例子是:

typedef struct args
{
    int status;
    int id;
    unsigned long long start_address;
    unsigned long long end_address;
    unsigned long long size;
} args_t;

void ioctl_call(args_t *args)
{
    args_t params;

    /* get values */
    ioctl(fd, cmd, params);

    *args = params;
}

void main()
{
    args_t args;
    iotcl_call(&args);
    printf("%d\n", args.id);
}
这段代码是完全有效的,尽管不是最优的

返回
second
的地址是非法的,但事实并非如此。当您说
*test=second
时,您是在将
second
的值分配给解除引用的指针。编译器将生成代码来复制结构的每个元素

它不理想的原因是因为那份拷贝。相反,考虑一下:

void func(test_t * test)
{
    test->x = 2;
    test->y = 3;
 }
这样,编译器将直接分配给指向结构的字段

这段代码是完全有效的,尽管不是最优的

返回
second
的地址是非法的,但事实并非如此。当您说
*test=second
时,您是在将
second
的值分配给解除引用的指针。编译器将生成代码来复制结构的每个元素

它不理想的原因是因为那份拷贝。相反,考虑一下:

void func(test_t * test)
{
    test->x = 2;
    test->y = 3;
 }

通过这种方式,编译器将直接分配给指向结构的字段。

参数
test
是函数
func
的本地参数,并且在函数外部不可见对其值的更改

但是,您没有更改
test
的值。您正在解引用它所指向的内存位置并写入该位置。在这种情况下,
test
包含
main
中第一个
变量的地址

因此,当您在
func
中分配给
*test
时,实际上是在
main
中首先分配给
。这就是为什么您可以在函数之外看到结果

因此,这段代码将按照您的预期工作,尽管它不是最优的。正如在另一个答案中提到的,将值分配给结构的本地实例,然后再将其分配给取消引用的指针,您只需取消引用指针并直接写入每个字段即可

void func(test_t * test)
{
    test->x = 2;
    test->y = 3;
 }

参数
test
是函数
func
的本地参数,其值的更改在函数外部不可见

但是,您没有更改
test
的值。您正在解引用它所指向的内存位置并写入该位置。在这种情况下,
test
包含
main
中第一个
变量的地址

因此,当您在
func
中分配给
*test
时,实际上是在
main
中首先分配给
。这就是为什么您可以在函数之外看到结果

因此,这段代码将按照您的预期工作,尽管它不是最优的。正如在另一个答案中提到的,将值分配给结构的本地实例,然后再将其分配给取消引用的指针,您只需取消引用指针并直接写入每个字段即可

void func(test_t * test)
{
    test->x = 2;
    test->y = 3;
 }

为什么要创建第二个
second
,然后用它跺
test
?为什么不直接操纵
test
。它并不意味着有用;这是为了指出一些事情。我的问题仍然存在。在什么情况下,直接操纵它不是更好的选择?@tadman Like HTNW说,这是测试代码。在应用程序方面,我有一个函数,可以通过ioctl调用设置结构的值。我试着看看我原来的(基本上是我的测试代码)是否有效,或者我是否应该更改它。我认为你的ioctl调用示例比这个人为的例子提供了更多信息。这个虚拟结构包含两个
int
值,所以笨拙地复制它不会有什么大不了的。另一些可能包含可能会出现问题的自引用指针。如果你能更好地说明你实际上在做什么,你可以确信你所做的是正确的。为什么要创建
second
,然后用它跺脚
test
?为什么不直接操纵
test
。它并不意味着有用;这是为了指出一些事情。我的问题仍然存在。在什么情况下,直接操纵它不是更好的选择?@tadman Like HTNW说,这是测试代码。在应用程序方面,我有一个函数,可以通过ioctl调用设置结构的值。我试着看看我原来的(基本上是我的测试代码)是否有效,或者我是否应该更改它。我认为你的ioctl调用示例比这个人为的例子提供了更多信息。这个虚拟结构包含两个
int
值,所以笨拙地复制它不会有什么大不了的。另一些可能包含可能会出现问题的自引用指针。如果你能更好地说明你实际上在做什么,你可以确信你所做的是正确的。谢谢你的快速回复!出于某种原因,我想得太多了,担心第二个会出现在堆栈上,一旦函数调用结束,值就会变成垃圾。感谢您的快速回复!出于某种原因,我想得太多了,担心第二个会出现在堆栈上,一旦函数调用结束,值就会变成垃圾。谢谢你的解释!我在考虑经典的“返回函数中声明的数组”以及这些值如何成为垃圾。那是