在C中通过引用传递指向struct的指针

时间:2017-01-17 00:02:47

标签: c pointers struct

请记住以下代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int a;
    int b;
    int c;
}A;

A *test;

void init(A* a)
{
    a->a = 3;
    a->b = 2;
    a->c = 1;
}
int main()
{
    test = malloc(sizeof(A));
    init(test);
    printf("%d\n", test->a);
    return 0;
}

运行良好!现在想象一下,我想在malloc本身之外使用main函数而不返回指向struct的指针。我会将malloc放在init内并传递test地址。但这似乎不起作用。

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int a;
    int b;
    int c;
}A;

A *test;

void init(A** a)
{
    *a = malloc(sizeof(A));
    *a->a = 3;
    *a->b = 2;
    *a->c = 1;
}
int main()
{
    init(&test);
    printf("%d\n", test->a);
    return 0;
}

当我使用指针时,它一直告诉我int a(或b / c)不是struct A的成员。

4 个答案:

答案 0 :(得分:5)

您必须添加括号:

void init(A **a)
{
    *a = malloc(sizeof(A)); // bad you don't verify the return of malloc
    (*a)->a = 3;
    (*a)->b = 2;
    (*a)->c = 1;
}

但这样做是很好的做法:

void init(A **a)
{
    A *ret = malloc(sizeof *ret); // we want the size that is referenced by ret
    if (ret != NULL) { // you should check the return of malloc
        ret->a = 3;
        ret->b = 2;
        ret->c = 1;
    }
    *a = ret;
}

答案 1 :(得分:4)

出于优先原因,您需要编写(*a)->a = 3;

答案 2 :(得分:4)

您的问题是运营商优先级。 ->运算符的优先级高于*(取消引用)运算符,因此*a->a的读取方式与*(a->a)相同。将*a->a更改为(*a)->a

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int a;
    int b;
    int c;
}A;

A *test;

void init(A** a)
{
    *a = malloc(sizeof(A));
    (*a)->a = 3;
    (*a)->b = 2;
    (*a)->c = 1;
}
int main()
{
    init(&test);
    printf("%d\n", test->a);
    return 0;
}

答案 3 :(得分:4)

即使它不是您问题的直接答案,但由于我们处于初始化的附近,我想指出C11为您提供了一种更好的语法来初始化结构:< / p>

void init(A **a)
{
    A *ret = malloc(sizeof *ret); // we want the size that is referenced by ret
    if (ret != NULL) { // you should check the return of malloc
        *ret = (A) {3, 2, 1};
        // or
        *ret = (A) { .a = 3, .b = 2, .c = 1 };
    }
    *a = ret;
}

另一个优点是任何未初始化的成员都归零。